[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