I attempted to code a BPM algorithm for a rhythm game using Void Update, but since it updates based on frames, any bpm that is not a multiple of 60 will not be properly synced. Can someone show me how to create a bpm algorithm that does not use framerate?
OnAudioFilterRead would be perfect for this. Have a look at GitHub - Ludomancer/Unity-Audio-Sequencer: A precise audio sequencer for Unity
It does look like something has changed. What did you do besides add the blue ‘0 HRV’?
Also, did you do anything to the Arduino code? It looks like from the picture that your data stream is not updating regularly.
I would avoid OnAudioFilterRead unless you need (simple) synthesis/custom DSP code.
Are you trying to play audio samples on beat or trying to trigger visual events?
For sample accurate sample playing you can use AudioSettings.dspTime to get sample accurate time and use PlayScheduled from Update sometime before you should hear the AudioSource.
For visual things, the latency doesn’t matter as much so you can trigger events after a certain amount of time has passed.
Are you trying to sequence audio data and need to figure out how many samples you need at a given BPM? If so here’s a script I wrote for this. You could use it to create an audiobuffer which has the correct size for the given BPM, and then read this buffer inside OnAudioFilterRead so you have sample accurate timing. Essentially you would create an array of floats, and the length of the array will be the number that the SamplesPerMeasure function returns. After this you can fill this buffer with audiodata and read it from OnAudioFilterRead. Now it’s also easy to subdivide the buffer in an x amount of steps, which is very useful in a rhythm game.
//Calculates the number of samples per measure based on a given bpm
public static int SamplesPerMeasure(int bpm)
{
int measures = 1;
int beatsPerMeasure = 4;
int sampleRate = 44100;
float beatsPerSecond = bpm / 60.0f;
int totalNumberOfBeats = beatsPerMeasure * measures;
float loopLength = UnityEngine.Mathf.Round((totalNumberOfBeats / beatsPerSecond) * 1000f) / 1000f;
int numberOfSamplesPerMeasure = UnityEngine.Mathf.CeilToInt((loopLength * sampleRate));
return numberOfSamplesPerMeasure;
}