In my unrelenting quest to reduce latency in my WindSynth rig, I have begun using the Direct Monitoring provided by the RME interfaces for my direct signal. This avoids the 4.16msec round trip latency cost of routing my dry signal through my UCX-II.
This post is an outline of how one might implement Direct Monitoring in Cantabile. Its taken me 8 months to get to this point, and I hope this post can speed things along for other low-latency fanatics. However, note that (as Brad has been known to say): “The scope of this work is a bit daunting, but I was determined to see it through.”
My approach is a dual-mixing strategy that replaces a simple Cantabile route for my dry signal with a path in TotalMix. This required some gnarly complexities in my Cantabile setup. Some key elements:
- Dummy routes in Cantabile to hold Gain values from physical rotary encoders.
- Bindings that map rotary encoder input to adjust Gain sliders in Cantabile (for FX) and Faders in TotalMix (the dry signal) simultaneously.
- A custom .cantabileControlCurve file that aligns the Gain sliders in Cantabile with the faders of TotalMix (RME’s mixing App).
- An adjustment of the lower bounds of Value Mapping in Cantabile to accommodate the lower bound of TotalMix faders.
- An internal MIDI routing app – LoopMIDI – to feed MIDI data from Cantabile to TotalMix.
- Play my brains out, enjoying the new, lower latency.
Here is the general scheme, showing routing of MIDI with yellow arrows:
The route named TotalMix Main Gain is controlled by a rotary encoder and holds the current value of what the Prim 1/2 fader should be in TotalMix. Bindings output MIDI commands through LoopMIDI to TotalMix, which has to be configured to listen to the LoopMIDI port (and have [X] Enable Protocol Support enabled).
Note that the popup slider is a different scale than the one typically used by Cantabile. I could have kept Cantabile’s standard Gain control curve. However, I felt that Cantabile and TotalMix are so different, that it would be a constant pain trying to keep the two straight and handling end conditions.
Here’s a comparison of all the curves used by Cantabile versus the control curve of TotalMix:
The default Cantabile (New) curve (light blue) is significantly different from TotalMix (dashed red) at the low end.
I recorded the dB fader values of TotalMix resulting from each of the 128 MIDI values it can receive, plotted them and tried to discern the formula used by TotalMix. No joy.
However, Matthias Carstens (an RME founder) was kind enough to send me the formulas that allowed me to create a custom .cantabileControlCurve file.
The key formulas in the control curve file are implemented by a pair of fuctions. The default control curve file (Cantabile (New)) uses these functions:
"positionToScalar(x)": "pow(10, (log(x, 10) * slope - (log(zeroDbPos, 10) * slope)) / 20)", "scalarToPosition(x)": "pow(10, (log(x, 10) * 20 + (log(zeroDbPos, 10) * slope)) / slope)",
The corresponding functions for TotalMix are:
"positionToScalar(x)": "pow (10, ((x > 0.63440860215) ? ((x*32.8235294145) - 26.8235294118) : ((x * x * -94.8544366899) + (x * 153.176470567) - 65)) / 20)", "scalarToPosition(x)": "clamp( ((log(x,10)*20 >= -6) ? ((log(x,10)*20 + 26.8235294118) * 31.1666666641) : (826 - Sqrt(-34869 - 220660*log(x,10)))) / 1023, 0, 1)",
The derivation and manipulation of these functions is contained in detail in the TotalMix.cantabileControlCurve file that I developed, available HERE.
Value Mapping Limitation
The lower bound of the explicit range of the Source of a Value Mapping in Cantabile is -59.9dB. Since the lower bound of TotalMix sliders is -65 dB, the Cantabile limitation make the two sliders out of step, especially at lower dB settings.
The problem was addressed by @Brad, who provided a temporary workaround, and will change the lower bound in the next C4 release.
Full details in the Value Mapping Limitation for Bindings post.
For safety and fallback reasons, I decided to implement a hardware (MIDI) switch to allow me to go back to the older, non-direct monitoring “All In Cantabile” setup. At the push of a button I can switch direct monitoring on and off. This is useful in a few situations (described below) and also use for testing the change of 4msec latency.
I can no longer simply record an output of Cantabile to get my final-mix sound. The final mix is coming only from the RME audio interface. And, since I’ve run out input ports on my RME (UCX-II), I can’t take a feed back from the RME. To record something specific (a riff I want to preserve), I switch back to [non-Direct Monitoring] routing, or record it to a thumb drive with the Direct USB Recording feature of the UCX-II.
MIDI control of TotalMix is problematic (for me, at least). I was lucky to find out how to control the Output faders. There is apparently some issue with a non-disclosure that RME signed with Mackie, and they don’t publish all of their MIDI implementation. Because of this, I’ve had to use two stereo ADAT channels and a physical ADAT loopback (0.25 msec added latency … Grrrr) simply to be able to mute a channel and control a separate monitor output feed.
Was it worth it?
Conventional wisdom is that we can’t detect latency less than 20msec. That’s hogwash in my book. I suspect this was done by a “Listen to this” … “Now listen to this” type of test – not representative of how we actually play.
I can reliably hear (in a blind test – 9 out of 9 times) the effect of lowering the latency by 4msec. But, again, that’s not the point.
When actually playing, I now believe that a minimal latency setup dramatically affects the way I play. I’m now playing short, fast runs and ornaments that I always played on physical wind instruments, but had fallen away over the last 2 years on the WindSynth. They’ve come back into my fingers almost immediately with the lower latency, and it’s now a true pleasure to play.