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: Paul Davis (pbd_AT_Op.Net)
Date: Tue Feb 06 2001 - 23:45:01 EET


> As I found out, even a simple sequence at 140bpm sounds horrendous if
>you use a 10ms interrupt. Does this mean that people only use MIDI on
>machines with a working RTC?

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 :)

it wouldn't suprise me, though, if your code might have had some minor
glitches in it. when i was doing softwerk, it took me *forever* to get
the code right that figured out how many "internal ticks" had
passed. the variability of the timing source that i was using made
this a very difficult task. the actual code contains this comment:

        /* If you can come up with a simpler way to provide the same
           reliability as this tricky mess of code, I'd love to hear about
           it. Several times, I thought I had it, but immediately found
           common situations where simpler code just wouldn't work right.
        */

actually, its not that complex, and it looks like this:

        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);

        if (usecs_per_tick > CLOCK_INTERVAL) {
        
                /* Each timer signal does not necessarily correspond to one
                   tick. So, check whether the cumulative elapsed
                   time is enough, we have a new tick.
                */
        
                if (elapsed_usecs < usecs_per_tick) {
                        inc = 0;
                } else if (elapsed_usecs > usecs_per_tick) {
                        inc = (int) ((double) elapsed_usecs /
                                     (double) usecs_per_tick);
                } else {
                        inc = 1;
                }

        } else {

                /* every timer signal corresponds to at least one
                   tick. Found out how much time has elapsed, and
                   figure out just how many ticks have gone by. But
                   note that the elapsed time might not be greater
                   than usecs_per_tick, so we have to allow some slop
                   here.
                */

                if (elapsed_usecs >= (usecs_per_tick*2)) {
                        inc = (int) ((double) elapsed_usecs /
                                     (double) usecs_per_tick);
                } else {
                        inc = 1;
            
                }

        }

        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;
        }
}

--p


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

This archive was generated by hypermail 2b28 : Tue Feb 06 2001 - 23:59:15 EET