Test scenario: MIDI in & out event logging are enabled as Playback switches from a 64.5bpm song to a 75bpm song. The two songs are “linked” in Playback (Playback auto-starts the second song when it ends the first). Cantabile’s transport is set to external clock sync. Cantabile’s meter is set to 6/8 throughout (although in Playback the first song is actually 4/4 and the second is 6/8). I wanted to see what midi info Playback sends to Cantabile under these circumstances.
Q1: At the point of the song-change, I see the following lines in the log file:
I assume this means Playback has sent midi clock-start (0xfa), but I don’t see any clock-stop (0xfc) before that except at the very beginning when the test began and at the very end when the test concludes. Does this mean that Playback sends clock-start with no clock-stop when it switches songs? (Seems like a violation of the midi clock protocol?)
Q2: After that, the bpm gradually rises toward 75bpm, the ppq (project position in quarter notes) continues to increase, but the sample position fluctuates. For example, here the sample position decreases while ppq increases:
I assume this is because Cantabile has “gotten ahead of itself” and is trying to backtrack the sample position, but I don’t understand why position isn’t reset to 0 due to clock-start.
Main question: Upon receiving a clock-start message, shouldn’t Cantabile reset the transport position to 0 and be willing to jump the tempo instead of gradually adjusting it? It’s my understanding that although hosts really should send clock-stop before clock-start if the clock is already running, many hosts don’t and that the expected behavior is for clients to treat it like clock-stop-then-start. That doesn’t seem to be what Cantabile does?
TL;DR for @Brad: I think Cantabile needs an extra checkbox in its MIDI Clock Synchronization options that selects whether Cantabile should ignore clock-start and clock-continue messages while the clock is already started. Cantabile currently ignores clock-start/continue for already-ticking clocks. Setting the new checkbox to not-ignore should cause Cantabile to act like the clock was previously stopped whenever it receives clock-start/continue (e.g., clock-start should reset the transport to 0).
My current best guess is that this is the root cause of many (maybe all) of the sync problems between Cantabile and certain external masters like Multitracks Playback, which send clock-start to reset the transport position without first sending clock-stop.
I’m wondering if this should just be the built-in behavior.
I did some research and it seems what you’re describing for clock-start should in fact reset the song position even if the transport is already running.
On the other hand, clock-continue on an already running transport should be a no-op.
I’d prefer not add a checkbox to enable correct behavior.
My research indicates that unfortunately the intended behavior is inconsistent between hosts:
Read the last two sentences of the MIDI clock specification over at Teragon Audio. They say Cantabile’s current behavior is correct—slaves should ignore clock-start while the clock is in play mode.
But now read “Note 3” of the spec published at Kent State. It seems to indicate that the extra clock-start should only be ignored when it is “superfluous” (whatever that means).
Hosts and slaves apparently interpret this guidance differently. Some ignore clock-start in play mode (see for example this project), while others reset the SPP to 0. Funnily enough, if you ask Google Gemini, “Should midi clock-start reset the position even when the clock is already playing?”, it will say reset the SPP and it will cite the Taragon Audio page as its source (which says the opposite)!
(The Teragon Audio spec is equally ambiguous about clock-continue, but I can’t find any documented instance where a host sends clock-continue in play mode and expects the transport to jump anywhere. So hopefully ignoring it is fine.)
I just played my first gig with this fix enabled, and Brad, it is a thing of beauty — for the first time my clock is perfectly synchronized across linked songs, even with ritardandos, accelerandos, meter changes, etc. I think this might finally be the vital missing piece needed for reliable external midi clock. Will keep testing..