Calculating BPM (beats per minute) using InvokeRepeating() - Issue


I am making a music based game/app and need to have a BPM system that fires off events in time. Obviously Unity works on Update() ticks and I need to find a way to convert these ticks to a system that I can use musically via BPM and 'Beats Per Bar' (the divisions that drum notes can play on between the pulse beats).

What i've tried already is having a method SetTempo( int bpm, int ticksPerBeat ) and using this to work out how often I should fire my own Update method called UpdateRepeating(), via the InvokeRepeating() method which basically just calls my method over and over again every x number of seconds. Using this, i'm able to write some procedural drum loops and they play out as i expect, but I'm getting slowdown by simply moving my mouse around the screen at any kind of speed or by scrolling over my Mac's dock. Is there another way I should be doing this that won't cause slowdown?

Should I be using a Timespan to give an accurate measurement of ticksPerMinute to somehow work out when my UpdateRepeating() should fire?



If you need something that is very regular, I would probably create a coroutine which yields WaitForFixedUpdate() and keeps track of time to call the your UpdateRepeating(). You could use WaitForSeconds, but in my experience, it is less regular than WaitForFixedUpdate.

IEumerator PeriodicUpdater()
  float waitTime = 10;  //10 seconds between updates

  float curTime = Time.time;
  while (true)
    if (Time.time >= curTime + waitTime)
      curTime += waitTime;
    yield return new WaitForFixedUpdate();

I know i am late for the party but for future references ill post my findings.

I dont know if unity released this at a later date but the Audio system features a AudioSettings.dspTime.
Documentation description:

This is a value specified in seconds and based on the actual number of samples the audio system processes and is therefore much more precise than the time obtained

The documentation has a nice example how to make a steady beat at 140 Bpm.