Re: [linux-audio-dev] Sequencer Sync Woes

New Message Reply About this list Date view Thread view Subject view Author view Other groups

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


New Message Reply About this list Date view Thread view Subject view Author view Other groups

This archive was generated by hypermail 2b28 : Wed Feb 07 2001 - 00:27:07 EET