Subject: Re: [linux-audio-dev] Sequencer Sync Woes
From: Billy Biggs (bbiggs_AT_DIV8.NET)
Date: Wed Feb 07 2001 - 00:15:33 EET
Paul Davis (pbd_AT_Op.Net):
> > As I found out, even a simple sequence at 140bpm sounds horrendous
> > if you use a 10ms interrupt. [...]
>
> if you can find me anyone who is using Linux for MIDI sequencing in a
> way that would expose this problem, and with the ability to tell that
> it exists, i'd love to hear about it :)
But if I'm sending 24ppq sync pulses, at 140bpm, this means I need to
send a sync tick every 4.5ms. For 16th notes (a typical bassline or
snare roll or whatever), this means every 6.7ms. How can you not
notice if your resolution > 10ms?
> it wouldn't suprise me, though, if your code might have had some minor
> glitches in it.
Thanks alot for this fragment of code! It's soo nice to compare notes
on this stuff. :) Your code is almost identical to mine.
I find it interesting that you bothered to seperate it out into cases.
You really want to avoid doing that float divide? This code seems to be
equivalent:
struct timeval tcurrent_tick;
struct timezone tz;
unsigned long current_usecs;
unsigned long elapsed_usecs;
int inc;
gettimeofday (&tcurrent_tick, &tz);
current_usecs = (tcurrent_tick.tv_sec * 1000000) + tcurrent_tick.tv_usec;
elapsed_usecs = carry_usecs + (current_usecs - last_tick_usecs);
inc = (int) ((double) elapsed_usecs / (double) usecs_per_tick);
if (inc > 0) {
midi_ticks += inc;
last_tick_usecs = current_usecs;
carry_usecs = elapsed_usecs - (inc * usecs_per_tick);
carry_usecs = carry_usecs > 0 ? carry_usecs : 0;
}
My code doesn't bother with the divide, I simply have the code to do
the next notes in a loop like this:
struct timeval tv, tvdiff, result;
int diff;
gettimeofday( &tv, 0 );
diff = (tv.tv_sec - last_sec) * 1000 * 1000 + tv.tv_usec - last_usec;
if( diff > usecs_per_tick ) {
while( diff > usecs_per_tick ) {
diff -= tt;
++midiclockcounter;
// Handle current tick, send out notes,
// whatever.
}
tvdiff.tv_sec = 0;
tvdiff.tv_usec = diff;
// result = tv - tvdiff;
diffTimes( &result, &tv, &tvdiff );
last_sec = result.tv_sec;
last_usec = result.tv_usec;
}
I should probably do like you did and just keep around the usecs,
instead of always converting everything to struct timeval format.
-- Billy Biggs bbiggs_AT_dumbterm.net http://www.billybiggs.com/ wbiggs_AT_uwaterloo.ca
This archive was generated by hypermail 2b28 : Wed Feb 07 2001 - 00:27:07 EET