On Thu, Jul 01, 2004 at 09:19:06AM -0400, Paul Davis
wrote:
getting a general purpose computer to output MIDI
Clock (and/or MIDI
Time Code, just so nobody confuses the two of them) is a very hard
problem. There are 24 MIDI Clock messages per quarter note. This means
that for a piece in 4/4 at 120bpm, you need to output 1 MIDI byte
every 20ms. Not so bad - its a nice even multiplier of the system
interrupt frequency. However, just change the tempo or the time
signature, and all of a sudden you have situations where the MIDI
Clock byte needs to be output every 18ms or every 32ms or ever 9.7ms
or every 56.5ms.
This by itself is not the main problem. Using a 1000 Hz RTC to schedule
MIDI output as suggested by Tim, this requires something similar to the
Bresenham algorithm. Assuming there are no further random delays, the timing
jitter will be +/- 0.5 ms, or 0.29 ms RMS. A well designed receiver, using
an adaptive bandwidth PLL or an adaptive open loop algorithm, should be
able to estimate instantenuous tempo to within say a percent relative
error and be able to follow tempo changes up to say 5 Hz. (based on some
quicky calculations).
The real problem is probably that most Midi clock receivers are not designed
to tolerate too much jitter.
FWIW: My experience with external sequencers is that they'll output all
notes due up to the most recently received time, which is also what is
expected. Real People do flat steptime compositions and then later
manually add a slight ritadando (slowing down) close to the end.
I remember Roland had some device where you could adaptively tap the
tempo with your finger (or attach to the kickdrum), but this is
different from Midi clock.
Midi clock devices will never go further than the most recently received
clock. You are supposed to be able to conduct the tempo of your music in
realtime even to the point of a full stop.
SMPTE time would be the one to call for if you want to lock timing
between devices.
mvh // Jens M Andreasen
BTW: Outputting a single byte makes no sense. You can safely write (at
least) a full 3 byte message and let the hardware (or driver) take care
of buffering.