[sdiy] MIDI Clock sync advice

brianw brianw at audiobanshee.com
Sat Mar 9 06:24:13 CET 2024

On Mar 8, 2024, at 3:29 PM, Tom Wiltshire wrote:
> At the same time, you need something that is keeping track of how long has passed since the last MIDI Clock pulse. That's going to be *another* timer peripheral, prescaled to to give you a good number of counts for likely tempos. There's no point counting 64MHz clock pulses with a 16-bit timer if it's going to overflow five times before you even get your next pulse. Equally, you don't want to lose resolution by finishing up with counts of only a few dozen for typical tempos. If realistic tempos are in the range 30BPM to 300BPM (a decade) then we'd ideally like those tempos to give timer results between (say) 60,000 and 6000 for a 16-bit timer. Reality will intrude here and we'll take whatever we can get that's closest, but that's the general idea.

I just realized an easy optimization: Since MIDI runs at 31250 baud, you probably only need to feed the measurement timer / counter at 3.125 kHz.

One the one hand, MIDI is asynchronous serial, meaning that there is no framing or other restriction on precisely when when a 'byte' starts. The whole point of the Start Bit is that there it could come at any time. If a MIDI connection is carrying nothing but MIDI Clock (0xF8) messages, then it will go idle after every byte, and then the next 0xF8 can start on any bit of the serial clock that the transmitting serial interface is using. i.e. The gap between bytes does not have to be a multiple of 10 serial bits (1 start + 8 data + 1 stop).

On the other hand, I suppose it's possible that a serial transmitter can be running at something like 64x the MIDI rate of 31250 baud, and thus the idle phase can transition to a Start Bit with even finer resolution. However, I think it should be sufficient to just count time in 32 microsecond intervals, at least for measuring the timing of MIDI input.

I think that a 16-bit timer / counter clocked at 3.125 kHz should be able to handle tempo as low as 4.768 BPM up to whatever the maximum is that MIDI can handle. If the MIDI line were saturated with 100% MIDI Timing Clock bytes, that would be 31250 bpm, but there'd be no room left for any other data. The actual maximum is not very important, but if you want to go below 5 BPM then you'll need to count 16-bit overflow, or reduce the resolution (which probably wouldn't hurt) to count a longer period.


p.s. I just noticed that the MIDI Specification uses 96 clocks per beat in one example.

The spec also states, "If Timing Clocks (F8H) are sent during idle time they should be sent at the current tempo setting of the transmitter even while it is not playing. Receivers which are slaved to incoming Real Time message (MIDI Sync mode) can thus phase lock their internal clocks while waiting for a Start (FAH) or Continue (FBH) command." - this strongly implies they were using phase-locked loops even in the eighties to align an internal clock (maybe 96 ppqn) to the MIDI Clock (24 ppqn).

p.p.s. I recall that many asynchronous serial devices run their internal clock at 8x to 64x the serial baud rate. This is most useful for the receiver, because the Start Bit can be timed with a little extra precision, and then the bit cells for the given baud rate can be a little bit off from perfect timing. I'm just not sure whether the transmitter section of the same device would be ready to transition from idle to Start Bit on any tick of the higher clock, or only on the actual baud clock tick.

Sorry for the deep dive, and apologies if I got any of the math wrong.

More information about the Synth-diy mailing list