True pitch vibrato: a fractional delay whose tap position is modulated by a sine, which scales the frequency of everything passing through it equally.
More...
|
| | DelayVibratoT () |
| void | prepare (double sample_rate) |
| | Sizes the delay line for the longest modulated read any legal parameter combination can ask for, so no set_* ever has to reallocate.
|
| void | set_rate_hz (double hz) |
| double | rate_hz () const |
| void | set_depth_cents (double cents) |
| | Peak pitch excursion in cents.
|
| double | depth_cents () const |
| void | set_delay_ms (double ms) |
| | Silence before the vibrato starts, in ms.
|
| void | set_fade_in_ms (double ms) |
| | Time for the depth to ramp 0 -> 1 after the delay, in ms. Re-arms.
|
| double | base_delay_samples () const |
| | Base delay in samples — the centre the modulation swings around.
|
| double | modulation_amplitude_samples () const |
| | Peak modulation excursion in samples, before the lifecycle scales it.
|
| double | depth_envelope () const |
| | Current lifecycle depth scale in [0, 1].
|
| std::size_t | latency_samples () const |
| | Exactly ceil((D0 + A) * fs): the longest delay the tap can read, which is the conservative reading of a time-varying delay's latency.
|
| void | reset () |
| void | discard_history () noexcept |
| SampleType | process (SampleType input) |
|
| static constexpr double | kDefaultRateHz = 5.5 |
| | Vibrato rate. [design parameter] default 5.5 Hz, range 0.1 .. 20 Hz.
|
| static constexpr double | kMinRateHz = 0.1 |
| static constexpr double | kMaxRateHz = 20.0 |
| static constexpr double | kDefaultDepthCents = 20.0 |
| | Peak pitch excursion.
|
| static constexpr double | kMaxDepthCents = 100.0 |
| static constexpr double | kBaseDelayHeadroom = 2.0 |
| | The base delay the modulation rides on, as a multiple of the modulation amplitude, so the read pointer never reaches the write pointer.
|
| static constexpr double | kMinBaseDelaySamples = 2.0 |
| | Floor on the base delay in samples.
|
| static constexpr int | kInterpolatorMarginSamples = 4 |
| | Guard samples past the longest read, covering the Lagrange window's i + 2 reach.
|
| static constexpr double | kMaxLifecycleMs = 5000.0 |
| | Ceiling on both lifecycle times.
|
| static constexpr double | kInterpolatorPeakGain = 1.25 |
| | Peak sample gain of the 4-point Lagrange kernel: the L1 norm of its weights, maximised at a half-sample offset where they are (-1, 9, 9, -1)/16.
|
template<typename SampleType = float>
class pulp::signal::DelayVibratoT< SampleType >
True pitch vibrato: a fractional delay whose tap position is modulated by a sine, which scales the frequency of everything passing through it equally.
100 % wet by design. A dry blend of a pitch-modulated tap against its own dry signal is a chorus — a different effect with a different doc — and mixing one in here would quietly turn the only true-pitch engine in the module into the thing it is meant to be distinguishable from.
The delay/fade-in lifecycle ("vibrato arrives once the note has settled") is a DahdsrT scaling the modulation depth, not a hand-rolled ramp. reset() re-arms it, which is what makes reset() mean "new note" here.
template<typename SampleType = float>
Sizes the delay line for the longest modulated read any legal parameter combination can ask for, so no set_* ever has to reallocate.
That worst case is the slowest rate at the deepest setting — the amplitude in seconds is inversely proportional to rate — which is a few hundred milliseconds of storage, not a few.
template<typename SampleType = float>
Peak sample gain of the 4-point Lagrange kernel: the L1 norm of its weights, maximised at a half-sample offset where they are (-1, 9, 9, -1)/16.
Provable, not fitted, and the reason this engine's worst-case gain is not exactly 0 dB despite being a single unit-gain tap. Asserted by the suite against a scan of the shipped interpolator.