Example #1
0
    void Update()
    {
        // Restart microphone if audio stopped playing.
        if (!_audioSource.isPlaying)
        {
            StartMicrophone();
        }

        // Gets volume and pitch values.
        FFTAnalyser.AnalyseSound(_audioSource, out samples, out spectrum, out dbValue, out hzValue);

        // If frequency value is not zero.
        if (hzValue != 0)
        {
            isSoundDetected = true;

            // If program is calibrated.
            if (ProgramManager.isProgramCalibrated)
            {
                if (ProgramManager.pitchFreqDict.Any(pitch => hzValue == pitch.Value))
                {
                    Debug.Log(ProgramManager.pitchFreqDict.First(pitch => hzValue == pitch.Value).Key);
                }
                else
                {
                    // Find a frequency value that is lower the current value.
                    for (int i = 0; i < ProgramManager.pitchFreqDict.Count; i++)
                    {
                        if (ProgramManager.pitchFreqDict.ElementAt(i).Value < hzValue)
                        {
                            try {
                                int avgPoint = (ProgramManager.pitchFreqDict.ElementAt(i).Value +
                                                ProgramManager.pitchFreqDict.ElementAt(i - 1).Value) / 2;

                                if ((int)hzValue >= avgPoint)
                                {
                                    Debug.Log(ProgramManager.pitchFreqDict.ElementAt(i).Key);
                                }
                                else
                                {
                                    Debug.Log(ProgramManager.pitchFreqDict.ElementAt(i - 1).Key);
                                }
                            }

                            // If the program cannot find a frequency in the dictionary that is higher than the detected frequency.
                            catch (System.Exception) {
                                Debug.Log("Pitch too high.");
                            }

                            return;
                        }
                    }

                    Debug.Log("Pitch too low.");
                }
            }

            // If program is not calibrated.
            else
            {
                PitchCalibrator.lastFrequency = hzValue;
            }
        }
        else
        {
            isSoundDetected = false;
        }
    }
Example #2
0
    void Update()
    {
        if (_audioSource.isPlaying)
        {
            int hzValue;

            if (!ProgramManager.instance.useDefaultDict && ProgramManager.isProgramCalibrated)
            {
                // Uses calibrated dictionary.
                FFTAnalyser.AnalyseSound(_audioSource, ProgramManager.pitchFreqDict, out samples, out spectrum, out hzValue);
            }
            else
            {
                // Uses default dictionary.
                FFTAnalyser.AnalyseSound(_audioSource, ProgramManager.defaultPitchDict, out samples, out spectrum, out hzValue);
            }
            ComputeAverages(spectrum);

            // The sum of volumes in all bands in the spectrum.
            float onset = 0;
            for (int i = 0; i < NO_OF_BANDS; i++)
            {
                // Volume of this band.
                float dbValue = ((float)System.Math.Max(-100.0f, 20.0f * (float)System.Math.Log10(averages [i]) + 160)) * 0.025f;
                // The difference in volume from the last frame.
                float dbDiff = dbValue - spec [i];
                // Store value for use in next loop.
                spec [i] = dbValue;
                onset   += dbDiff;
            }

            onsets [currTimeIndex] = onset;

            // Updates autocorrelator and find peak lag (estimated tempo).
            auco.NewVal(onset);
            // Record largest value in (weighted) autocorrelation as it is the most likely tempo.
            float aMax    = 0.0f;
            int   tempopd = 0;
            for (int i = 0; i < maxlag; ++i)
            {
                float acVal = (float)System.Math.Sqrt(auco.AutoCo(i));
                if (acVal > aMax)
                {
                    aMax    = acVal;
                    tempopd = i;
                }
                // Store in array backwards in line with traces.
                acVals [maxlag - 1 - i] = acVal;
            }

            // Calculates DP-ish function to update the best-score function.
            float smax   = -999999;
            int   smaxix = 0;
            alph = 100 * threshold;
            for (int i = tempopd / 2; i < System.Math.Min(colmax, 2 * tempopd); ++i)
            {
                // objective function - this beat's cost + score to last beat + transition penalty
                float score = onset + scorefun [(currTimeIndex - i + colmax) % colmax] - alph * (float)System.Math.Pow(System.Math.Log((float)i / (float)tempopd), 2);
                // To keep track of the best-scoring predecesor.
                if (score > smax)
                {
                    smax   = score;
                    smaxix = i;
                }
            }

            scorefun [currTimeIndex] = smax;
            float smin = scorefun [0];
            for (int i = 0; i < colmax; ++i)
            {
                if (scorefun [i] < smin)
                {
                    smin = scorefun [i];
                }
            }
            for (int i = 0; i < colmax; ++i)
            {
                scorefun [i] -= smin;
            }

            smax   = scorefun [0];
            smaxix = 0;
            for (int i = 0; i < colmax; ++i)
            {
                if (scorefun [i] > smax)
                {
                    smax   = scorefun [i];
                    smaxix = i;
                }
            }

            dobeat [currTimeIndex] = 0;
            sinceLast++;
            // If current value is largest in the array, it is probably a beat
            if (smaxix == currTimeIndex)
            {
                // Makes sure that the most recent beat was not too recent
                if (sinceLast > tempopd / 4)
                {
                    if (callbacks != null && hzValue != 0)
                    {
                        foreach (AudioCallbacks callback in callbacks)
                        {
                            callback.OnBeatDetected(hzValue);
                        }
                    }
                    blipDelay [0] = 1;
                    // Records that there was a beat at this frame.
                    dobeat [currTimeIndex] = 1;
                    // Resets counter of frames since previous beat.
                    sinceLast = 0;
                }
            }

            if (++currTimeIndex == colmax)
            {
                currTimeIndex = 0;
            }
        }
    }