예제 #1
0
    private void UpdateCConstantBeatDetection()
    {
        float i     = CalculateInstantEnergy();
        float a     = CalculateAverageLocalEnergy();
        float v     = CalculateEnergyVariance(a);
        float c     = (-0.0025714f * v) + 1.5142857f;
        float diff  = Mathf.Max(0f, i - c * a);
        float diff2 = Mathf.Max(0f, diff - GetSpectrumAverage());

        float[] _shiftedHistoryBuffer = _historyBuffer;

        for (int b = 0; b < _historyBuffer.Length - 1; b++)
        {
            _shiftedHistoryBuffer[b + 1] = _historyBuffer[b];
        }

        _shiftedHistoryBuffer[0] = i;
        _historyBuffer           = _shiftedHistoryBuffer;
        _shiftedHistoryBuffer    = null;

        if (_beatDetectionTime - _energyBeatTimer > beatSensitivity && diff2 > 0f)
        {
            onBeatDetected?.Invoke(i, a, c * a);
            _energyBeatTimer = _beatDetectionTime;
        }
        _beatDetectionTime += (FFTSpectrumDataChannel0.Length / SampleRate) * 2f;
    }
예제 #2
0
        void CustomDetection(float audioTime)
        {
            if (index >= sampleBuffer.Length)
            {
                index = 0;
            }
            frequency           = AudioSampler.instance.GetFrequencyVol(audioIndex, frequencyRange, false, AudioSampler.instance.silentAudio.useSilentAudio); // get the root means squared value of the audio right now
            sampleBuffer[index] = frequency;                                                                                                                  // replace the oldest sample in our runningAvg array with the new sample
            index++;
            avgEnergy = GetAvgEnergy();                                                                                                                       // compute the current average


            //if instantEnergy is > beatThreshold*avgEnergy
            if (frequency > beatThreshold * avgEnergy)
            {
                float deltaTime = audioTime - lastBeatTime;
                if (deltaTime < beatLimiter)
                {
                    if (debug)
                    {
                        Debug.Log("BEAT LIMITED, reduce beatLimiter to allow more beats through.");
                    }
                    //do not register a beat if the time since the last beat is < beatLimiter
                    return;
                }

                lastBeatTime   = audioTime;
                totalBeatTime += deltaTime;
                numBeats++;
                avgBeatTime = totalBeatTime / numBeats;
                if (automaticLimiter)
                {
                    beatLimiter = avgBeatTime * .5f; // don't allow consecutive beats < half of the avgBeatTime apart
                }

                float volume = AudioSampler.instance.GetRMS(audioIndex, false, AudioSampler.instance.silentAudio.useSilentAudio);

                //Debug.Log("Live Beat: " + audioTime);
                OnBeat.Invoke();                                          // call the public OnBeat methods
                if (OnBeatRecognized != null)                             // if we have a listener for this event
                {
                    OnBeatRecognized.Invoke(new Beat(audioTime, volume)); // send the event
                    if (debug)
                    {
                        Debug.Log("Beat Detected");
                    }
                }
            }

            if (debug)
            {
                Debug.Log("FreqVolume: " + frequency + " beatThreshold: " + beatThreshold * avgEnergy);
            }
        }
예제 #3
0
 // Invoke the Beat event
 private void OnBeat()
 {
     if (BeatEvent != null)
     {
         BeatEvent.Invoke();
     }
 }
예제 #4
0
 private void Start()
 {
     _audioSource = GetComponent <AudioSource>();
     if (null != BeatEvent)
     {
         BeatEvent.Invoke(_currentBeat, _accentBeats[(int)_currentBeat]);
     }
 }
예제 #5
0
        private void SimpleBeatDetection()
        {
            var instantEnergy = 0.0f;

            for (var i = 0; i < samples; i++)
            {
                instantEnergy += samplesLeft[i] * samplesLeft[i] + samplesRight[i] * samplesRight[i];
            }

            var averageEnergy = 0.0f;

            for (var i = 0; i < energyHistory.Length; i++)
            {
                averageEnergy += energyHistory[0, i] * energyHistory[0, i];
            }

            averageEnergy /= energyHistory.Length;

            var variance = 0.0f;

            for (var i = 0; i < energyHistory.Length; i++)
            {
                var localVariance = (energyHistory[0, i] - averageEnergy);
                variance += localVariance * localVariance;
            }

            variance /= energyHistory.Length;

            var sensitivity = (-0.0025714f * variance) + 1.5142857f; // high energy variance = lower sensitivity

            if (instantEnergy > averageEnergy * sensitivity)
            {
                OnBeat.Invoke(new int[] { 0 }, new float[] { instantEnergy });
            }

            for (var i = energyHistory.Length - 2; i >= 0; i--)
            {
                energyHistory[0, i + 1] = energyHistory[0, i]; // TODO: Could make this faster without the array.
            }

            energyHistory[0, 0] = instantEnergy;
        }
예제 #6
0
        void UpdateIndex()
        {
            int nextIndex = (int)(GetSequencerPosition() / GetDivisionLength());

            if (currentIndex != nextIndex)
            {
                if (OnBeat != null)
                {
                    OnBeat(nextIndex);
                }
                if (beatEvent != null)
                {
                    beatEvent.Invoke(nextIndex);
                }
            }
            currentIndex = nextIndex;
        }
예제 #7
0
 IEnumerator BeatIt(Song song)
 {
     if (timePlaying <= currentSong.songLength)
     {
         if (beatCount < song.beats.Count)
         {
             beatEvent.Invoke(song.beats[beatCount]);
         }
         timePlaying += Time.deltaTime;
         beatCount++;
         yield return(new WaitForSeconds(currentSong.beatTimeStepInMilliseconds / 1000));
     }
     else
     {
         yield return(null);
     }
 }
        //the AudioSampler update loop for staying in sync with the audio
        void AudioUpdate(float audioTime, float deltaTime)
        {
            //wait until we've initialized
            if (audioData == null)
            {
                return;
            }

            float loopTime = audioTime % audioData.clipLength;

            //Debug.Log(loopTime + "/" + audioData.clipLength + "> " + (nextBeatTime - preBeatOffset));

            //check to see if we've looped
            if (loopTime < lastLooptime)
            {
                //Debug.Log("LOOP ---------------------");
                ResetBeats();
            }
            lastLooptime = loopTime;

            //if we're looping, reset the beat counter
            if (beatIndex >= audioData.beats.Count)
            {
                return;
            }


            if (loopTime >= nextBeatTime - preBeatOffset)
            {
                //Debug.Log("Play File Beat: " + nextBeatTime + " audioTime: " + audioTime);
                Beat beat = audioData.beats[beatIndex];
                nextBeatTime = beat.time;
                beatIndex++;
                OnBeat.Invoke();

                if (OnBeatRecognized != null)
                {
                    OnBeatRecognized.Invoke(beat);
                }
            }

            HandleFrequencyEvents();
        }
예제 #9
0
    /// <summary>
    /// Audio callback, called ever ~20ms. About as close to the beat as we can get.
    /// </summary>
    /// <param name="data"></param>
    /// <param name="channels"></param>
    private void Update()
    {
        double beat = (_audioSource.time) / (.5 * 60.0 / _bpm);

        beat %= 8;
        _currentBeatUnQuantized = beat;
        beat = (int)beat;
        if (lastTime != beat)
        {
            BeatEvent.Invoke((int)beat, _accentBeats[(int)beat]);
            lastTime = (int)beat;
        }

        if (_isPlaying && !_audioSource.isPlaying)
        {
            _roundManager.EndRound();
            _isPlaying = false;
        }
        _timeElapsed += Time.deltaTime;
    }
예제 #10
0
        /// <summary>
        /// Detect beats, and automatically adjust beatTreshold.
        /// </summary>
        /// <param name="audioTime"></param>
        void AutomaticDetection(float audioTime)
        {
            if (index >= sampleBuffer.Length)
            {
                //canDetect = true;
                index = 0;
            }

            frequency           = AudioSampler.instance.GetFrequencyVol(audioIndex, frequencyRange, false, AudioSampler.instance.silentAudio.useSilentAudio); // get the root means squared value of the audio right now
            sampleBuffer[index] = frequency;                                                                                                                  // replace the oldest sample in our runningAvg array with the new sample
            index++;
            //don't do anything until we have filled our buffer up completely
            if (sampleBuffer[sampleBuffer.Length - 1] == 0)
            {
                return;
            }

            avgEnergy     = GetAvgEnergy();                           // compute the current average
            variance      = GetAvgVariance(avgEnergy);                // compare everything in the sample buffer to the current average
            varyPercent   = 1 - ((avgEnergy - variance) / avgEnergy); //how much variance are we seeing?
            beatThreshold = 1 + varyPercent;                          //beatThreshold in range 1-2


            //if we can't detect beats
            if (!canDetect)
            {
                //check to see if we should be able to detect them again.
                //we can start looking for new beats once freq drops
                if (frequency < (2 - beatThreshold) * avgEnergy)
                {
                    canDetect = true;
                }
            }

            //if instantEnergy is > beatThreshold*avgEnergy
            if (frequency > beatThreshold * avgEnergy && canDetect)
            {
                //Debug.Log("\n Beat Detected, (" + freq + " > " + beatThreshold*avgEnergy + " ) \n");
                canDetect    = false;       //reset the flag. we can't detect another beat, until freq drops below 'lastFreq'
                lastFreq     = frequency;   //record the frequency of the last beat
                lastVariance = varyPercent; // record the variancePercent of the last beat

                float deltaTime = audioTime - lastBeatTime;
                if (deltaTime < beatLimiter)
                {
                    if (debug)
                    {
                        Debug.Log("BEAT LIMITED, reduce beatLimiter to allow more beats through.");
                    }
                    //do not register a beat if the time since the last beat is < beatLimiter
                    return;
                }

                lastBeatTime   = audioTime;
                totalBeatTime += deltaTime;
                numBeats++;
                avgBeatTime = totalBeatTime / numBeats;
                if (automaticLimiter)
                {
                    beatLimiter = avgBeatTime * .5f; // don't allow consecutive beats < half of the avgBeatTime apart
                }

                OnBeat.Invoke(); // call the public OnBeat methods
                //Debug.Log("Live Beat: " + audioTime);
                //Debug.Log("frequency: " + frequency + " > " + beatThreshold + "*" + avgEnergy);
                float rms = AudioSampler.instance.GetRMS(audioIndex, false, AudioSampler.instance.silentAudio.useSilentAudio);

                if (OnBeatRecognized != null)                          // if we have a listener for this event
                {
                    OnBeatRecognized.Invoke(new Beat(audioTime, rms)); // send the event
                    if (debug)
                    {
                        Debug.Log("Beat Detected at " + audioTime);
                    }
                }
            }

            if (debug)
            {
                Debug.Log("Freq: " + frequency + " beatThreshold: " + beatThreshold * avgEnergy);
            }
        }
예제 #11
0
 public void PlayEvent(int i)
 {
     BeatEvent?.Invoke(i);
 }