A single decaying resonance: one complex pole pair, excited by whatever the caller feeds it.
More...
template<typename SampleType = float>
class pulp::signal::TwoPoleResonatorT< SampleType >
A single decaying resonance: one complex pole pair, excited by whatever the caller feeds it.
This is the smallest useful physical model. A struck body rings at a frequency and dies away at a rate, and a two-pole recurrence reproduces exactly that, so a percussion body is an impulse into one of these rather than an oscillator plus an envelope. The difference is audible: an oscillator with a decay envelope restarts at a known phase and decays on a schedule, while a resonator's ring is a function of what excited it, so the same body struck by a click and by a noise burst sounds different, and a second strike during the tail interferes with what is already ringing instead of replacing it.
ModalBankT is the same mathematics for many modes at once, laid out for SIMD and driven a block at a time. Use the bank for a body with a spectrum (a membrane, a plate, a shell); use this when there is one resonance and the surrounding code is per-sample.
The decay is specified as a T60 because that is how long a body is heard to ring.
Excitation is scaled by the sine of the pole angle, which makes the ring's peak roughly the excitation's amplitude at any tuning and any decay. Both normalisations that look more obvious are traps. Unit input gain leaves the impulse response peaking at one over that sine, so a body tuned to 50 Hz rings about fifty times louder than the same body at 5 kHz and the tuning knob becomes a volume knob. Scaling by one minus the pole radius normalises a sustained tone instead, which makes a longer decay produce a quieter strike. This scaling leaves the two controls doing only what they are named for.
RT contract: every member allocates nothing and takes no locks. The frequency and decay may be changed per sample; the state is the ring itself, so a coefficient change carries it rather than reinterpreting it.