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; }
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); } }
// Invoke the Beat event private void OnBeat() { if (BeatEvent != null) { BeatEvent.Invoke(); } }
private void Start() { _audioSource = GetComponent <AudioSource>(); if (null != BeatEvent) { BeatEvent.Invoke(_currentBeat, _accentBeats[(int)_currentBeat]); } }
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; }
void UpdateIndex() { int nextIndex = (int)(GetSequencerPosition() / GetDivisionLength()); if (currentIndex != nextIndex) { if (OnBeat != null) { OnBeat(nextIndex); } if (beatEvent != null) { beatEvent.Invoke(nextIndex); } } currentIndex = nextIndex; }
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(); }
/// <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; }
/// <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); } }
public void PlayEvent(int i) { BeatEvent?.Invoke(i); }