The Quad Delay (QuadDelay in private/src/QuadDelay.hpp) is a highly complex, time-warped delay effect deeply integrated with the Theory of Time.
A traditional delay line implements the equation D(t + d) = X(t), where t is wall-clock time, d is the delay time, and X is the input signal.
The Smart Grid One implements a time-warped version of this equation. Let F(t) be the post-modulation logical time from the Theory of Time. The quad delay implements:
D(F⁻¹(t + d)) = X(F⁻¹(t))
This means: “At the wall-clock time that produces the warped time t + d, output the sample that was recorded at the wall-clock time that produced the warped time t.”
Assuming F is injective (which it sometimes is, though extreme modulation can break this), this can be rewritten as:
D(t) = X(F⁻¹(F(t) - d))
To implement this, the delay requires a “moveable writehead.” It must compute and store the inverse function F⁻¹.
DelayLineMovableWriter maintains two parallel circular buffers:
m_delayLine: The audio samples X(t).m_writeHeadInverse: The wall-clock time t at which each warped time F(t) occurred.F(t) - d in the inverse buffer, the delay can find the exact wall-clock time t_old when that warped time occurred, and then read the audio sample X(t_old).QuadDelayInputSetter)The read and write heads are produced in QuadDelayInputSetter::Process (private/src/QuadDelay.hpp) per quad channel i.
m_totLoopSelector[i] is chosen from the delay loop-selector knob, but changes are only accepted when both old and new loops are simultaneously at top (m_top) to avoid discontinuities.m_glue[i] that preserves continuity across transport stops, loop-selector changes, and tempo-scale changes.
m_glue[i] is initialized from the current write head, then incremented each sample.m_glue[i] is rescaled so absolute position continuity is maintained.m_glue[i] is shifted by the difference of unwound-sample positions between old and new loops.0.8, 2/3, 1.0, 3/4, 5/8
and stored as m_bufferFrac[i].The final head equations are:
writeHead = PhasorUnwoundSamples(selectedLoop) + gluedelayInput.m_writeHeadPosition[i]readHead = LoopSamplesFraction(selectedLoop, bufferFrac * widen) + gluedelayInput.m_readHeadPosition[i]So both heads live in the same unwound sample coordinate system and differ by a loop-fraction delay term shaped by quantized ratio and widener.
Because the read head is moving through the audio buffer at a variable rate (due to the time warping), a simple read would result in severe pitch shifting (like scratching a vinyl record).
To preserve the original pitch while allowing the time-warping to stretch and compress the audio, the delay uses a Phase Vocoder (Resynthesizer in private/src/Resynthesis.hpp).
GrainManager).F⁻¹(F(t) - d).H (hop size) unwound samples before that position.The Quad Delay supports a rich set of features:
PostFeedbackFilter) to dampen the echoes.