Cantabile and external clock sync

One more tweak which yielded interesting results.
I’ll start by saying the worst metronome offset I saw in this tempo region was 13 ms. Cantabile’s output was recorded back into Cubase and compared.
The cool bit is that by making a midi file at 100 BPM, with the sync bump of 112.75 in the first 8th note, the whole file could be sped up or slowed down using the % function in the media player.
80% = 80 BPM. 135% =135 BPM etc.
The bump appears to adapt quite well, I tested 185 BPM and the worst offset was 20 ms. Of course, if necessary one could make a dedicated file for faster tempos.
The original 112.75 bump jumped to 208.588 with the media player at 185%. It was just interesting to see how useful this one midi file might be when manipulated in this way, although it appears that % cannot be set with State Behavior, so not much use unless @Brad can provide some thoughts on how to recall that parameter.

Just out of interest, what are you syncing on Cantabile?

Yes, and there’s some influence from binding order but not too much. The delays I see seem to cause all bindings to fire slightly late (probably because the entire bindings thread is sometimes delayed by other taxing operations during song switches).

I’m using Playback MIDI cues (a custom CC message sendable from Playback) during the song’s count-in. I can’t use the MIDI Start message because Playback doesn’t send MIDI Start for chained songs.

No, I’m making Playback send a CC event on the last 8th or 16th beat of the song’s count-in, and then creating a Cantabile binding with a delay equal to one 8th or 16th note. (I don’t think it’s possible to position Playback MIDI cues at the precision of clock cycles, but you can put them on any beat.)

I’m having Playback and Cantabile both play their metronomes and comparing them by ear. Once I find a delay that aligns them well, I try repeating the song switch many times to see whether the binding reliably aligns them. What I’m finding is that a delay that works well for a while suddenly stops working consistently even due to tiny environmental changes (rebooting the machine, playing too many notes during a song switch, tweaking my patches). The unreliability occurs for complex environments (song sets with tens of VSTs per song), not bare bones tests.

I’m using Omnisphere 2 with tempo-sync’ed LFOs, Envelopes, and Arpeggiator, and I’m playing Kontakt 7 with tempo-sync’ed patches (e.g., from Straylight and Gravity 2).

Yesterday I finally had a chance during an on-stage rehearsal to really nail down why External Clock Sync doesn’t solve this, and I’m pretty sure I now understand what’s going on (but still not sure how to solve it):

  1. Master behavior: When songs are chained (played back-to-back), Playback does not send MIDI Stop or MIDI Start between songs. It just changes the rate at which it sends MIDI Clock messages to conform to the new song tempo. In MIDI standards, chained songs are just one big song with tempo changes in it. Based on MIDI spec docs, this appears to be the “correct” way to do things, so I don’t think it’s a bug or omission.

  2. Slave behavior: MIDI Clock messages don’t explicitly encode tempos or tempo changes; the slave is supposed to just measure the timing between them to infer the tempo. Cantabile does this brilliantly as far as I can tell (yet another testament to Brad’s wizardry!). It then communicates the inferred new tempo to plugins via their APIs during audio cycles. So this too is not a bug.

  3. Plugin behavior: But many plugins apparently can’t handle (or choose not to handle?) big changes in tempo unaccompanied by a reset of the song position. They keep playing at the old tempo, possibly adjusting it very gradually to move toward the new tempo, with the result that their tempo is completely off for pretty much the entirety of non-first songs in a chain. I suspect this is because they try to interpret tempo changes unaccompanied by a song position reset as natural fluctuations in external sync timing, which makes a certain amount of sense since otherwise tiny deviations in external clock sync would probably cause clicks and pops as waveform x-positions jump around chaotically.

So it’s nobody’s fault. :roll_eyes:

The only way I can think to solve this (while still using external clock sync) would be to somehow get Cantabile to send transport stop-and-restart when it detects a big tempo change. The stop-and-restart messages would have to be sent right before the MIDI Clock message corresponding to the downbeat of the next available measure (to keep measure-sync’ed patches happy). I don’t think there’s any way to do this within Cantabile, but this leads me to a question:

Question: Is there any Windows app that listens on a MIDI port, lets you modify incoming MIDI messages (e.g., via scripting), and then outputs the result on a new virtual MIDI port? I feel like I’ve heard of such things mentioned on this forum but can’t quite remember the details…

If I had such an app, I could try modifying the MIDI clock stream sent to Cantabile just to see what happens.

So how exactly are you transitioning between songs? I’m picking up that there is one start point and then things just continue on auto pilot? How are you anticipating interacting with Cantabile at the transition point?

In the tests I have run, I haven’t sensed any detectable syncing issue with Omnisphere.

The band director controls Playback. He prepares for a gig by organizing songs into a playlist. Some of the songs are “linked”, causing them to play back-to-back without human intervention. Others are stand-alone. He uses an external controller to start/stop any song or song-chain.

For chains, I have a Cantabile “song” that actually consists of multiple racks, one for each song in the chain. To switch songs in the chain, I have a binding that allows me to hit a controller button to un-suspend the next song’s rack and disable MIDI routes to the previous song’s rack (without suspending that one yet). So as the previous song in the chain ends, I play its last chord, hold down the sustain pedal, and hit the “next song” button on my controller. This causes the final chord to continue playing, but future MIDI notes will go to the next song’s rack. I start playing the next song, lifting my foot from the pedal, causing the previous song’s final chord to fade out as the next song comes in overtop of it. (Another binding later suspends the previous song’s rack to save resources once its output volume goes to near-zero.)

One wrinkle in the above is worth noting: Usually the final instruments played during a song fade-out are not tempo-sync’ed. So the change of tempo is ignored by the previous song’s plugins; only the new song’s plugins must match the new tempo (i.e., the question raised by this thread). In the rare case that the fade-out needs tempo-sync too (at the old tempo), I have a way to get two different racks to temporarily play at two different tempos within Cantabile. I do it by running their tempo-sync’ed plugins inside separate Unify instances, which has an option for ignoring the host’s tempo and using the one set in Unify’s transport controls. But the start-time of Unify’s transport is still controlled by Cantabile, so that trick doesn’t solve the problem I raised here—how to get plugins for the non-first song in a chain to reliably get synchronized with the correct tempo in the first place.

When songs aren’t linked in a chain, all of this works perfectly. It’s only when chaining causes the tempo to change without an intervening transport stop+start that things break.

In answer to your question, there was an app I tried a while back when trying to slave Cantabile to a DAW, I’m away from my gig rack but I believe it was called Time code live or something like that. However I don’t think it allows editing from scripts, and if I understand your use - case correctly, it might work but I’m not sure. I never could get it to work properly slaving cantabile, but it did work when cantabile was the master.
As you and others mention, midi clock is probably the root of your issue. I can’t remember if cantabile will work with MTC? Anyway, IIRC I was using that app to translate midi clock to MTC or SMPTE. And it did allow for a time offset, which I believe is what you want. So maybe look for an app that will translate and give you an offset? Sorry I couldn’t be of more help.
Tom

If you eliminate the inherent unreliability of MIDI clock you’re doing better, I think we can agree.
The entire issue revolves around stable start time.
Playback issues its start command only at the beginning of a chain. Seems to me that your only solution is a MIDI file which can respond to a start command and issue tempo changes automatically.
I’m not sure you’ve checked out this possibility yet?

This turns out to be a good lead — thanks for this, @twaw. After reading more about SMPTE and MTC, I’ve learned that Playback has a special option for SMPTE that repositions the SMPTE song pointer at song part boundaries (where most tempo changes occur). This seems like exactly what I need, except that unfortunately Cantabile can’t read SMPTE, and converting SMPTE to MIDI Clock seems difficult (see below). And Playback lacks an equivalent option for MIDI output. :face_with_diagonal_mouth:

After reading more about MIDI Clock, MTC, and SMPTE, I’m starting to think that MIDI clock unreliability isn’t actually the root problem. The MIDI clock specification seems to say that MIDI Clock messages can’t unambiguously communicate abrupt tempo changes. Any change to their frequency can be interpreted by slaves as synchronization variance, not a tempo change, which causes some plugins to gradually adjust to new tempos (very, very slowly). To unambiguously communicate an abrupt tempo change with MIDI Clock, the master must instead send a Transport Stop message, then a Song Position message, then a Transport Continue message, and then resume Clock messages. Playback fails to do this — it has a suitable SMPTE option but not an equivalent option for MIDI.

If this is correct, then it seems like the real solution is to either have MIDI reposition support in Playback (I won’t hold my breath), SMPTE-slave support in Cantabile (which I bet is not easy to implement), or to find something that converts SMPTE to MIDI as @twaw recommended. But the conversion would need to generate the aforementioned MIDI Transport messages when translating SMPTE position changes, not just Clock messages. If it just sent Clock messages, I think the same sync problems would result. But I can’t seem to find anything that does such a conversion.

I didn’t jump on the MTC suggestion because Cantabile only transmits - doesn’t receive, as you’ve already stated. Even if it could, you’re still facing the issue of reliable start. You’ve essentially solved the issue of multi tempo crossover by ignoring external tempo and allowing plugins like Unify to run internally.
That’s your entire solution for stable tempo.

Your issue is one of reliable start and dealing with tempo changes on chained songs. Would that be a fair summing up?
Eliminate external sync completely and just focus on start. Whatever follows you can address at the timeline or via a midi file.
So, where are you at establishing reliable start?

BTW I did find that app that I was working with about a year ago, it’s called Time code expert 2. It doesn’t specifically mention midi clock in the brief intro description, but if I recall correctly I was able to get it to read the output from cantabile midi-clock and convert it to SMPTE. I’m just spitballing here but assuming you can get it to sync, for the transport commands you mentioned, could you create bindings? Don’t know if that would be fast enough or if it would work at all.

FWIW sometimes when we run into roadblocks like that, I’ve found that I need to give up some of the functionality I thought I couldn’t live without :grin:. Or a completely different solution. For example, and this may be a very bad example, instead of playing a transition chord that carries over to the next song, could you record that chord, or even an entire passage preceding the transition, and dump it into a media player as a pseudo sample? And since you are essentially running in sync up until the transition, you could even program it to play at a specific time so you don’t even have to think about it and focus on doing your transport switch?
Or separate the multi-song song file into actual separate song filess, and have another hardware keys that will handle the transition tones? Anyway, I hope you find a solution!
Tom

Thanks both for all your input—it’s really helped me understand the nature of the problem, even if I haven’t quite solved all aspects of it yet.

Only the latter now (tempo changes on chained songs). I’m using MIDI Clock for non-chained songs, and I love it for those. It gives me a beautiful, no-fuss, reliable start on all stand-alone songs and first songs in chains. Even if something incurs high load during a song start, Cantabile’s external sync method gracefully adapts, and everything sounds great by the time I start playing notes. Only the starts of non-first songs in chains are a problem (because of the tempo change without transport stop-start).

For those I’m currently resorting to something very painful and error-prone: I manually reach over and switch off external clock sync (I really wish I could bind a button to transport source!), and then I attempt to manually hit the transport start button on my controller in sync with the count-in click. It’s really hard to do accurately, especially if I’m holding a chord from the previous song at the same time. In live situations I’m always terrified I’ll get it wrong. But since all other approaches have sometimes backfired, this way at least allows me multiple attempts if/when disaster strikes. (I can stop the transport and attempt to restart it on the beat again—even mid-song if something is sounding off and I’m desperate.)

Thanks for the link! It looks like a great product, but I think it’s backwards from what I need in this case. From what I understand, I’d need a conversion from Playback’s SMPTE to MIDI Clock (since Cantabile only reads the latter), but Timecode Expert 2 seemingly only does the opposite.

I’ve considered that, but unfortunately the song transitions can be so unpredictable. For example, during final rehearsal (about 1 hr before live), the band director will often make last-minute changes like, “The vocalist wants song #1 two semitones lower, so we’re gonna transpose it down and transition with a pivot chord to song #2”. I have no problem playing such changes last minute, but anything pre-recorded instantly becomes unusable.