[sdiy] Beat timing calculations

Andre Majorel aym-htnys at teaser.fr
Wed Jul 27 10:49:21 CEST 2011


On 2011-07-26 21:02 -0700, Joel B wrote:

> I'm contemplating writing a drum machine like program and i'm
> not sure how to calculate the timing to trigger a note, say a
> 16th note pattern, for instance. Here is what I have so far:
> 
> 130 bpm= bps=60/130=0.46153846 

Yes.

> 1000ms per second * bps 
> ms =461.53846  per beat division

Yes.

> 16 beats=16*461.53846 =7,384.61536
> Milliseconds per loop

What ?

If by "16th note pattern" you mean a whole 4/4 bar of 16
semiquavers, a semiquaver is 1/4th of a quarter note so about 60
/ 130 / 4 = 0.115 s and a whole bar lasts about 60 / 130 * 4 =
1.846 s.

> but there probably has to be something to handle things that
> don't land on a proper digital boundary like 33.3333333333...
> without throwing the tempo off with rounding or truncation
> errors?

There will always be errors but if you work with floats, or at
least fixed-point numbers, they don't accumulate (too much).

For a PCM drum machine,

  double sample_rate = 48000;
  double tempo = 130;
  double notes_per_beat = 4;
  double notes_per_bar = 16;
  double frames_per_note = sample_rate * 60 / tempo / notes_per_beat;

  double frames_until_next_note = 0;
  int note_num = 0;
  for (unsigned long frame_num = 0; ; frame_num++) {
    if (frames_until_next_note <= 0) {
      start_note(note_num);
      note_num = (note_num + 1) % notes_per_bar;
      frames_until_next_note += frames_per_note;
    }
    write_sample();
    frames_until_next_note--;
  }

If you want even less drift, you will have to recompute the note
number every time from frame_num.

-- 
André Majorel http://www.teaser.fr/~amajorel/



More information about the Synth-diy mailing list