|
| | LadderBankT () |
| void | set_sample_rate (SampleType sample_rate) |
| | Set the sample rate every voice runs at, and recompute every voice's coefficient for its current frequency.
|
| SampleType | sample_rate () const |
| void | set_frequency (std::size_t voice, SampleType hz) |
| void | set_resonance (std::size_t voice, SampleType resonance) |
| SampleType | frequency (std::size_t voice) const |
| SampleType | resonance (std::size_t voice) const |
| SampleType | stage_coefficient (std::size_t voice) const |
| | The voice's per-stage one-pole coefficient (Filter::stage_coefficient()).
|
| void | process (const SampleType *in, SampleType *out) |
| | Advance every voice by one sample: out[v] = voice v's output for in[v].
|
| void | process_voices (SampleType *const *buffers, std::size_t num_samples) |
| | Advance every voice by num_samples samples in place, one buffer per voice (buffers[v] holds voice v's input and receives its output).
|
| void | reset (std::size_t voice) |
| | Clear one voice's state.
|
| void | reset () |
| | Clear every voice's state.
|
template<typename SampleType = float, std::size_t Voices = 16>
class pulp::signal::LadderBankT< SampleType, Voices >
Voices independent LadderFilterT voices advanced together.
Contract:
Selects inside the per-voice loops are bit operations (detail:: select_bits) with the same values as the scalar filter's conditionals, so the loops vectorize under GCC's default -ftrapping-math too.
Why it is faster: a ladder sample is a chain of five dependent saturations, so one voice at a time is latency-bound. The bank computes stage 1 of every voice, then stage 2 of every voice, and so on, with the voices' state in structure-of-arrays form; each stage is then a loop over independent voices that the compiler vectorizes and that keeps many recursions in flight.
RT contract: storage is fixed-size; every member function allocates no memory.