@maruaudio/dsp/modulation/glide holds the stages of a gong's amplitude-dependent pitch glide, applied as a frequency multiplier per resonator mode:
detune0 = direction × depth × amount × velocity² // Duffing backbone
scale_m = 1 + detune0 × 1/(1 + m) × env // mode m
env' = env − coeff × env, coeff = 1 − exp(−1/(seconds × updateRate))env decays from 1 to 0, so every mode ends at its nominal frequency. Direction +1 (a hardening plate, the daluo) starts sharp and glides down; −1 (a softening plate, the xiaoluo) starts flat and glides up. The source comment cites "Effects of internal resonances in the pitch glide of Chinese gongs" (JASA 144(1), 2018) for the model.
Parameters
There are no setters or state. glideInitialDetune, glideModeFalloff, glideDecayCoefficient, glideEnvelopeStep, glideFrequencyScale and glideIsActive take their values as arguments. glideDecayCoefficient uses 0.1 ms for shorter times and 375 Hz for a non-positive update rate.
Lifecycle
Stateless stage functions. At a strike the caller computes detune0 and sets the envelope; it then steps the envelope at its own update rate (the gong voice uses once per 128-frame render quantum) and recomputes mode frequencies while glideIsActive is true, that is while |detune0 × env| > GLIDE_SETTLED (1e-6). Nothing allocates or does I/O.
When to use it
A struck modal voice whose pitch should move as the note decays, with the depth scaling with how hard it is struck and the upper modes moving less than the fundamental.
Limits
- With
detune0exactly 0 the multiplier is exactly 1, so the nominal frequencies stay bit-exact and the glide is never active. - The envelope is rounded to f32; the multiplier is a double.
- The coefficient must be computed for the rate the caller actually steps at, not the sample rate.