105template <
typename SampleType =
float>
148 lifecycle_.set_curve(0.0);
149 lifecycle_.set_attack_ms(0.0);
150 lifecycle_.set_hold_ms(0.0);
151 lifecycle_.set_decay_ms(0.0);
152 lifecycle_.set_sustain(1.0);
162 sample_rate_ = sample_rate > 0.0 ? sample_rate : sample_rate_;
163 lfo_.prepare(sample_rate_);
164 lifecycle_.prepare(sample_rate_);
165 line_.prepare(worst_case_read_index(sample_rate_));
171 if (!std::isfinite(hz))
return;
173 lfo_.set_rate_hz(rate_hz_);
184 if (!std::isfinite(cents))
return;
195 if (!std::isfinite(ms))
return;
197 lifecycle_.set_delay_ms(delay_ms_);
203 if (!std::isfinite(ms))
return;
205 lifecycle_.set_attack_ms(fade_in_ms_);
223 return static_cast<std::size_t
>(
224 std::ceil(base_delay_samples_ + amplitude_samples_));
235 line_.discard_history();
242 if (!std::isfinite(
static_cast<double>(input))) {
244 return SampleType{0};
246 const double env = lifecycle_active_ ? advance_lifecycle() : 1.0;
247 const double modulation =
static_cast<double>(lfo_.next());
248 const double delay = base_delay_samples_ + amplitude_samples_ * env * modulation;
252 const int index =
static_cast<int>(std::floor(
delay));
253 const double frac =
delay -
static_cast<double>(index);
260 static_cast<double>(line_.read(index - 1)),
261 static_cast<double>(line_.read(index)),
262 static_cast<double>(line_.read(index + 1)),
263 static_cast<double>(line_.read(index + 2)));
264 return static_cast<SampleType
>(interpolated);
268 static constexpr double kTwoPi = 6.283185307179586476925286766559;
271 static double amplitude_seconds(
double cents,
double rate_hz) {
277 static int worst_case_read_index(
double sample_rate) {
284 amplitude_samples_ = amplitude_seconds(depth_cents_, rate_hz_) * sample_rate_;
285 base_delay_samples_ =
290 lifecycle_active_ = delay_ms_ > 0.0 || fade_in_ms_ > 0.0;
292 if (lifecycle_active_) lifecycle_.gate_on();
295 double advance_lifecycle() {
296 depth_env_ =
static_cast<double>(lifecycle_.next());
300 double sample_rate_ = 44100.0;
303 double delay_ms_ = 0.0;
304 double fade_in_ms_ = 0.0;
306 double amplitude_samples_ = 0.0;
308 double depth_env_ = 0.0;
309 bool lifecycle_active_ =
false;
311 DelayLineT<SampleType> line_{};
312 EffectLfoT<double> lfo_{};
313 DahdsrT<double> lifecycle_{};
331template <
typename SampleType =
float>
372 lfo_.set_rate_hz(rate_hz_);
376 sample_rate_ = sample_rate > 0.0 ? sample_rate : sample_rate_;
377 lfo_.prepare(sample_rate_);
378 for (
auto& stage : stages_) stage.prepare(
static_cast<SampleType
>(sample_rate_));
382 if (!std::isfinite(hz))
return;
384 lfo_.set_rate_hz(rate_hz_);
390 if (!std::isfinite(
depth))
return;
391 depth_ = std::clamp(
depth, 0.0, 1.0);
393 double depth()
const {
return depth_; }
396 if (!std::isfinite(hz))
return;
404 const int clamped = std::clamp(count, 1,
kMaxStages);
406 stage_count_ = clamped;
412 if (!std::isfinite(
mix))
return;
413 mix_ = std::clamp(
mix, 0.0, 1.0);
415 double mix()
const {
return mix_; }
426 for (
auto& stage : stages_) stage.reset();
427 corner_hz_ = center_hz_;
431 if (!std::isfinite(
static_cast<double>(input))) {
433 return SampleType{0};
435 const double modulation =
static_cast<double>(lfo_.next());
436 corner_hz_ = center_hz_ * std::exp2(depth_ *
kSweepOctaves * modulation);
438 double shifted =
static_cast<double>(input);
439 for (
int i = 0;
i < stage_count_; ++
i) {
440 auto& stage = stages_[
static_cast<std::size_t
>(
i)];
445 stage.set_cutoff(
static_cast<SampleType
>(corner_hz_));
446 shifted =
static_cast<double>(
447 stage.process_allpass(
static_cast<SampleType
>(shifted)));
450 const double direct =
static_cast<double>(input);
451 return static_cast<SampleType
>(
direct + mix_ * (shifted -
direct));
455 double sample_rate_ = 44100.0;
464 std::array<TptFilterT<SampleType>,
kMaxStages> stages_{};
489template <
typename SampleType =
float>
501 static constexpr std::array<double, kStageCount>
kStageBaseHz{200.0, 430.0, 900.0, 1900.0};
537 lfo_.set_rate_hz(rate_hz_);
544 sample_rate_ = sample_rate > 0.0 ? sample_rate : sample_rate_;
545 lfo_.prepare(sample_rate_);
546 vactrol_.prepare(sample_rate_);
547 for (
auto& stage : stages_) stage.prepare(
static_cast<SampleType
>(sample_rate_));
551 if (!std::isfinite(hz))
return;
553 lfo_.set_rate_hz(rate_hz_);
559 if (!std::isfinite(
depth))
return;
560 depth_ = std::clamp(
depth, 0.0, 1.0);
562 double depth()
const {
return depth_; }
568 double control()
const {
return vactrol_.control(); }
572 return corners_[
static_cast<std::size_t
>(std::clamp(index, 0,
kStageCount - 1))];
587 for (
auto& stage : stages_) stage.reset();
591 void process(SampleType input, SampleType& out_left, SampleType& out_right) {
592 if (!std::isfinite(
static_cast<double>(input))) {
594 out_left = out_right = SampleType{0};
597 const double lamp =
static_cast<double>(lfo_.next_unipolar());
598 const double control = vactrol_.process(lamp);
601 double shifted =
static_cast<double>(input);
603 const auto slot =
static_cast<std::size_t
>(
i);
605 stages_[slot].set_cutoff(
static_cast<SampleType
>(corners_[slot]));
606 shifted =
static_cast<double>(
607 stages_[slot].process_allpass(
static_cast<SampleType
>(shifted)));
610 const double direct =
static_cast<double>(input);
625 double sample_rate_ = 44100.0;
630 std::array<double, kStageCount> corners_{};
632 EffectLfoT<double> lfo_{};
633 VactrolConditionerT<SampleType> vactrol_{};
634 std::array<TptFilterT<SampleType>,
kStageCount> stages_{};
True pitch vibrato: a fractional delay whose tap position is modulated by a sine, which scales the fr...
Definition vibrato.hpp:106
void prepare(double sample_rate)
Sizes the delay line for the longest modulated read any legal parameter combination can ask for,...
Definition vibrato.hpp:161
void discard_history() noexcept
Definition vibrato.hpp:234
static constexpr double kDefaultRateHz
Definition vibrato.hpp:109
std::size_t latency_samples() const
Exactly ceil((D0 + A) * fs): the longest delay the tap can read, which is the conservative reading of...
Definition vibrato.hpp:222
static constexpr double kMinBaseDelaySamples
Definition vibrato.hpp:129
void set_rate_hz(double hz)
Definition vibrato.hpp:170
DelayVibratoT()
Definition vibrato.hpp:146
double depth_cents() const
Definition vibrato.hpp:189
double rate_hz() const
Definition vibrato.hpp:177
static constexpr double kMaxDepthCents
Definition vibrato.hpp:118
SampleType process(SampleType input)
Definition vibrato.hpp:241
static constexpr int kInterpolatorMarginSamples
Definition vibrato.hpp:133
void set_fade_in_ms(double ms)
Time for the depth to ramp 0 -> 1 after the delay, in ms. Re-arms.
Definition vibrato.hpp:202
static constexpr double kDefaultDepthCents
Definition vibrato.hpp:117
double base_delay_samples() const
Base delay in samples — the centre the modulation swings around.
Definition vibrato.hpp:210
double depth_envelope() const
Current lifecycle depth scale in [0, 1].
Definition vibrato.hpp:217
void reset()
Definition vibrato.hpp:227
static constexpr double kMinRateHz
Definition vibrato.hpp:110
static constexpr double kMaxRateHz
Definition vibrato.hpp:111
void set_depth_cents(double cents)
Peak pitch excursion in cents.
Definition vibrato.hpp:183
static constexpr double kBaseDelayHeadroom
Definition vibrato.hpp:123
static constexpr double kInterpolatorPeakGain
Definition vibrato.hpp:144
static constexpr double kMaxLifecycleMs
Definition vibrato.hpp:137
void set_delay_ms(double ms)
Silence before the vibrato starts, in ms.
Definition vibrato.hpp:194
double modulation_amplitude_samples() const
Peak modulation excursion in samples, before the lifecycle scales it.
Definition vibrato.hpp:213
Magnatone-style phase vibrato: N cascaded first-order allpass stages whose corner is driven straight ...
Definition vibrato.hpp:332
double rate_hz() const
Definition vibrato.hpp:387
static constexpr double kMinCenterHz
Definition vibrato.hpp:352
static constexpr double kDefaultMix
Definition vibrato.hpp:361
double mix() const
Definition vibrato.hpp:415
static constexpr int kDefaultStageCount
Definition vibrato.hpp:357
static constexpr double kSweepOctaves
Definition vibrato.hpp:347
SampleType process(SampleType input)
Definition vibrato.hpp:430
void prepare(double sample_rate)
Definition vibrato.hpp:375
double corner_hz() const
Corner the cascade is currently sitting at, in Hz.
Definition vibrato.hpp:419
static constexpr double kMaxRateHz
Definition vibrato.hpp:339
void set_rate_hz(double hz)
Definition vibrato.hpp:381
static constexpr int kMaxStages
Definition vibrato.hpp:358
void set_mix(double mix)
Definition vibrato.hpp:411
void reset()
Definition vibrato.hpp:424
double depth() const
Definition vibrato.hpp:393
static constexpr double kMaxCenterHz
Definition vibrato.hpp:353
static constexpr double kDefaultDepth
Definition vibrato.hpp:343
static constexpr double kDefaultRateHz
Definition vibrato.hpp:337
PhaseVibratoT()
Definition vibrato.hpp:370
void set_stage_count(int count)
Stages that become active are cleared first, so switching count in does not fold a stale state from a...
Definition vibrato.hpp:403
static constexpr double kDefaultCenterHz
Definition vibrato.hpp:351
static constexpr double kSinusoidalGainBound
Definition vibrato.hpp:368
double center_hz() const
Definition vibrato.hpp:399
void set_center_hz(double hz)
Definition vibrato.hpp:395
static constexpr double kMinRateHz
Definition vibrato.hpp:338
std::size_t latency_samples() const
Pure IIR: no bulk delay anywhere in the path.
Definition vibrato.hpp:422
void set_depth(double depth)
Definition vibrato.hpp:389
int stage_count() const
Definition vibrato.hpp:409
Univibe-style phase vibrato: four allpass stages at deliberately unequal corners, all swept together ...
Definition vibrato.hpp:490
UniVibeT()
Definition vibrato.hpp:535
double rate_hz() const
Definition vibrato.hpp:556
static constexpr double kChorusBlend
Definition vibrato.hpp:530
static constexpr std::array< double, kStageCount > kStageBaseHz
Definition vibrato.hpp:501
static constexpr double kDefaultDepth
Definition vibrato.hpp:509
void set_rate_hz(double hz)
Definition vibrato.hpp:550
Mode
The documented physical switch.
Definition vibrato.hpp:493
@ vibrato
Definition vibrato.hpp:493
@ chorus
Definition vibrato.hpp:493
static constexpr double kVactrolFallMs
Definition vibrato.hpp:518
double control() const
Conditioned control in [0, 1] — the photocell's state, after the lag.
Definition vibrato.hpp:568
static constexpr int kStageCount
Definition vibrato.hpp:495
static constexpr double kVactrolRiseMs
Definition vibrato.hpp:517
std::size_t latency_samples() const
Definition vibrato.hpp:582
void process(SampleType input, SampleType &out_left, SampleType &out_right)
Definition vibrato.hpp:591
static double corner_scale(double control, double depth)
The corner scale a given conditioned control produces.
Definition vibrato.hpp:578
void set_depth(double depth)
Definition vibrato.hpp:558
static constexpr double kVibratoMix
Definition vibrato.hpp:526
void set_mode(Mode mode)
Definition vibrato.hpp:564
static constexpr double kControlExponent
Definition vibrato.hpp:522
void prepare(double sample_rate)
Definition vibrato.hpp:543
Mode mode() const
Definition vibrato.hpp:565
double stage_corner_hz(int index) const
Live corner of stage index in Hz.
Definition vibrato.hpp:571
double depth() const
Definition vibrato.hpp:562
static constexpr double kSinusoidalGainBound
Definition vibrato.hpp:533
static constexpr double kMinRateHz
Definition vibrato.hpp:505
static constexpr double kDefaultRateHz
Definition vibrato.hpp:504
static constexpr double kMaxRateHz
Definition vibrato.hpp:506
void reset()
Definition vibrato.hpp:584
static constexpr double kSweepOctaves
Definition vibrato.hpp:512
The envelope family — AR, AD, AHD, DAHDSR, and a trigger-driven modulation envelope — plus a level-in...
High-quality sample interpolation for delay lines and resampling.
The house low-frequency oscillator: seven waveforms plus a continuous shape morph,...
T cents_to_ratio(T cents)
Cents → frequency ratio. +100 → 2^(1/12), +1200 → 2.
Definition units.hpp:118
Definition additive_bank.hpp:218
UniVibeT< double > UniVibe64
Definition vibrato.hpp:638
DelayVibratoT< double > DelayVibrato64
Definition vibrato.hpp:317
PhaseVibratoT< double > PhaseVibrato64
Definition vibrato.hpp:468
DelayVibratoT< float > DelayVibrato
Definition vibrato.hpp:316
@ delay
Definition envelope.hpp:57
PhaseVibratoT< float > PhaseVibrato
Definition vibrato.hpp:467
@ i
Definition formant_filter_bank.hpp:20
@ sine
Definition lfo_sampling.hpp:54
@ direct
set_shift_semitones. Detents and the pedal law are bypassed.
Definition pitch_shifter.hpp:194
UniVibeT< float > UniVibe
Definition vibrato.hpp:637
static SampleType lagrange(SampleType frac, SampleType ym1, SampleType y0, SampleType y1, SampleType y2)
4-point Lagrange interpolation.
Definition interpolator.hpp:60
First-order topology-preserving transform (TPT) filter.
The real-unit vocabulary shared by every DSP block in the catalog.
The vactrol control-conditioning law: an asymmetric one-pole whose rise and fall are deliberately dif...