Skip to content

Plug-in delay compensation

The solver is in session/pdc.rs, the delay lines in dsp/pdc.rs:

  • Each strip’s latency is the sum of its instrument and insert plug-ins’ getLatencySamples (a built-in effect’s latency(), read from its FxShared), bypassed ones included (the delay line stands in for a bypassed plug-in, so switching it doesn’t shift the mix).
  • solve walks the graph in processing order: a bus is due when its latest input arrives; each strip’s output and each send wait in the strip’s delay line until their destination is due. Stereo Out is due when its latest input arrives; its own plug-ins add to total.
  • update_pdc sends Cmd::Pdc only for tracks whose compensation changed, with a new DelayLine only when the old one is too short (lines have room for at least 8192 frames). Cmd::PdcGlobal carries total and the Low Latency Mode flag.
  • Changes glide: the output and each send read the line through a Tap (TrackDsp:: pdc_taps). When its delay changes (a new PdcParams, or the track going live), a tap crossfades from the old read position to the new one over FADE_SECS (15 ms, raised cosine); a change during a fade waits for it to finish. The line is written whenever it exists, read or not, so the position faded to always holds real audio, and a line replaced by a longer one takes the old one’s audio over (DelayLine::take_history). A post-fader send whose tap matches the output’s shares its read. Side-chain keys leave before the line, so they have no compensation to change.
  • Live tracks (an armed audio track that is recording; in Low Latency Mode any monitored track) skip their compensation delay, and in Low Latency Mode the plug-ins over the limit (low_latency_skip bits) are not run.
  • Recordings are moved earlier by total as well, since the performer heard the song that late.