300template <
typename SampleType =
float>
362 static constexpr double kPi = 3.14159265358979323846;
370 return fc_hz * std::tan(odd_phase_fraction(k, stages));
378 double sample_rate) {
379 const double prewarped = std::tan(
kPi * fc_hz / sample_rate);
380 return sample_rate /
kPi *
381 std::atan(prewarped * std::tan(odd_phase_fraction(k, stages)));
385 static constexpr int notch_count(
int stages) {
return stages / 2; }
411 if (sample_rate > 0.0) sample_rate_ = sample_rate;
412 for (
auto& channel : stages_)
413 for (
auto& stage : channel)
414 stage.prepare(
static_cast<SampleType
>(sample_rate_));
415 for (
auto& lfo : lfo_) lfo.prepare(sample_rate_);
422 for (
auto& channel : stages_)
423 for (
auto& stage : channel) stage.reset();
424 feedback_state_.fill(SampleType{0});
425 for (
auto& lfo : lfo_) lfo.reset();
426 for (
int ch = 0; ch < kChannels; ++ch) sweep_hz_[ch] = center_hz_;
437 stage_count_ = clamped - (clamped % 2);
443 if (!std::isfinite(hz))
return;
444 for (
auto& lfo : lfo_) lfo.set_rate_hz(hz);
446 double rate_hz()
const {
return lfo_[0].rate_hz(); }
451 if (!std::isfinite(
static_cast<double>(depth01)))
return;
452 depth_ = std::clamp(
static_cast<double>(depth01), 0.0, 1.0);
454 double depth()
const {
return depth_; }
458 if (!std::isfinite(fc))
return;
459 center_hz_ = clamp_hz(fc);
469 if (!std::isfinite(
static_cast<double>(fb)))
return;
470 feedback_ = std::clamp(
static_cast<double>(fb), -
kFeedbackMax,
477 if (!std::isfinite(
static_cast<double>(mix01)))
return;
478 mix_ = std::clamp(
static_cast<double>(mix01), 0.0, 1.0);
480 double mix()
const {
return mix_; }
485 if (!std::isfinite(
static_cast<double>(cycles01)))
return;
486 spread_ = std::clamp(
static_cast<double>(cycles01), 0.0, 0.5);
487 lfo_[1].set_stereo_offset(spread_);
499 for (
auto& lfo : lfo_) lfo.set_wave(
wave);
506 if (!std::isfinite(
ratio))
return;
510 stagger_pow_[
static_cast<std::size_t
>(
i)] = p;
520 for (
auto& lfo : lfo_) lfo.set_seed(seed);
529 return sweep_hz_[
static_cast<std::size_t
>(
530 std::clamp(channel, 0, kChannels - 1))];
538 void process(
const SampleType* in_l,
const SampleType* in_r,
539 SampleType* out_l, SampleType* out_r,
int n_frames) {
540 const double dry = 1.0 - mix_;
541 for (
int i = 0;
i < n_frames; ++
i) {
542 const SampleType xl = in_l[
i];
543 const SampleType xr = in_r[
i];
544 if (!std::isfinite(
static_cast<double>(xl)) ||
545 !std::isfinite(
static_cast<double>(xr))) {
547 out_l[
i] = out_r[
i] = SampleType{0};
550 const double wl = run_cascade(0, advance_sweep(0), xl);
551 const double wr = run_cascade(1, advance_sweep(1), xr);
552 out_l[
i] =
static_cast<SampleType
>(dry *
static_cast<double>(xl) +
554 out_r[
i] =
static_cast<SampleType
>(dry *
static_cast<double>(xr) +
563 void process_mono(
const SampleType* in, SampleType* out,
int n_frames) {
564 const double dry = 1.0 - mix_;
565 for (
int i = 0;
i < n_frames; ++
i) {
566 const SampleType x = in[
i];
567 if (!std::isfinite(
static_cast<double>(x))) {
569 out[
i] = SampleType{0};
572 const double w = run_cascade(0, advance_sweep(0), x);
574 out[
i] =
static_cast<SampleType
>(dry *
static_cast<double>(x) +
580 static constexpr int kChannels = 2;
584 static double odd_phase_fraction(
int k,
int stages) {
585 return static_cast<double>(2 * k - 1) *
kPi /
586 (2.0 *
static_cast<double>(stages));
589 double clamp_hz(
double hz)
const {
598 double advance_sweep(
int ch) {
599 const auto c =
static_cast<std::size_t
>(ch);
600 const double lfo =
static_cast<double>(lfo_[
c].next());
609 double run_cascade(
int ch,
double fc, SampleType x) {
610 const auto c =
static_cast<std::size_t
>(ch);
611 auto& stages = stages_[
c];
612 SampleType
v =
static_cast<SampleType
>(
613 static_cast<double>(
x) +
614 feedback_ *
static_cast<double>(feedback_state_[
c]));
615 for (
int i = 0;
i < stage_count_; ++
i) {
616 const auto s =
static_cast<std::size_t
>(
i);
617 stages[
s].set_cutoff(
618 static_cast<SampleType
>(clamp_hz(fc * stagger_pow_[s])));
619 v = stages[
s].process_allpass(v);
622 return static_cast<double>(
v);
625 double sample_rate_ = 44100.0;
626 double center_hz_ = 400.0;
630 double spread_ = 0.0;
634 std::array<double, kMaxStages> stagger_pow_{};
635 std::array<double, kChannels> sweep_hz_{};
636 std::array<SampleType, kChannels> feedback_state_{};
637 std::array<std::array<TptFilterT<SampleType>,
kMaxStages>, kChannels>
644 std::array<EffectLfoT<double>, kChannels> lfo_{};
A cascaded first-order-allpass phaser.
Definition phaser_stages.hpp:301
double center_hz() const
Definition phaser_stages.hpp:461
static constexpr int notch_count(int stages)
How many notches an N-stage cascade produces. N/2, for even N.
Definition phaser_stages.hpp:385
static constexpr double kSweepRangeRatio
Definition phaser_stages.hpp:328
static double notch_frequency_analog_hz(int k, int stages, double fc_hz)
The cited analog-prototype notch law: f_k = fc · tan((2k−1)π/2N).
Definition phaser_stages.hpp:369
PhaserStagesT()
A default instance is a Small Stone: 4 stages, 0.5 Hz triangle, 400 Hz centre, full depth,...
Definition phaser_stages.hpp:401
double stagger_ratio() const
Definition phaser_stages.hpp:514
static constexpr double kColorOnFeedback
Definition phaser_stages.hpp:323
int stage_count() const
Definition phaser_stages.hpp:439
static constexpr int kStageCountDefault
Definition phaser_stages.hpp:315
static constexpr double kColorOffFeedback
Definition phaser_stages.hpp:322
static constexpr double kPi
Definition phaser_stages.hpp:362
static constexpr double kSweepCeilingRatio
Definition phaser_stages.hpp:340
Wave wave() const
Definition phaser_stages.hpp:501
void set_stage_count(int n)
Active stage count.
Definition phaser_stages.hpp:435
static constexpr int latency_samples()
Zero. The dry path is a wire and the TPT stages add no buffering.
Definition phaser_stages.hpp:395
double mix() const
Definition phaser_stages.hpp:480
static constexpr double kStaggerDefault
Definition phaser_stages.hpp:347
double rate_hz() const
Definition phaser_stages.hpp:446
void set_wave(Wave wave)
LFO shape, forwarded verbatim to both channels' LFOs.
Definition phaser_stages.hpp:498
double sweep_frequency_hz(int channel) const
The channel's current swept corner frequency in Hz, after clamping — the quantity the notch laws take...
Definition phaser_stages.hpp:528
static constexpr double kSweepFloorHz
Definition phaser_stages.hpp:335
static constexpr double kRateDefaultHz
Definition phaser_stages.hpp:357
static constexpr double kStaggerMin
Definition phaser_stages.hpp:348
static constexpr double kMixDefault
Definition phaser_stages.hpp:352
void set_depth(float depth01)
Sweep excursion, 0..1.
Definition phaser_stages.hpp:450
void set_mix(float mix01)
Dry/wet, 0..1. 0.5 is the full-notch point; 1.0 is a flat allpass.
Definition phaser_stages.hpp:476
static constexpr int kMaxStages
Definition phaser_stages.hpp:313
static constexpr double worst_case_gain()
The worst-case output/input magnitude over all frequencies, mixes and feedback settings — the number ...
Definition phaser_stages.hpp:390
static constexpr double kFeedbackMax
Definition phaser_stages.hpp:320
void set_stagger_ratio(double ratio)
Per-stage corner ratio; 1.0 (the default) means every stage shares one fc, which is the documented si...
Definition phaser_stages.hpp:505
double stereo_spread() const
Definition phaser_stages.hpp:489
void process_mono(const SampleType *in, SampleType *out, int n_frames)
Mono block process, driving channel 0 only.
Definition phaser_stages.hpp:563
static double notch_frequency_hz(int k, int stages, double fc_hz, double sample_rate)
The exact notch law for the shipped TPT cascade: f_k = (fs/π)·arctan( tan(π·fc/fs) · tan((2k−1)π/2N) ...
Definition phaser_stages.hpp:377
void set_seed(std::uint32_t seed)
Seeds both LFOs identically, so the stochastic shapes stay a phase-shifted copy of each other rather ...
Definition phaser_stages.hpp:519
void process(const SampleType *in_l, const SampleType *in_r, SampleType *out_l, SampleType *out_r, int n_frames)
Stereo block process.
Definition phaser_stages.hpp:538
void reset()
Clears every stage's integrator, the feedback memories, and both LFO phases, so a render from here is...
Definition phaser_stages.hpp:421
double depth() const
Definition phaser_stages.hpp:454
void set_stereo_spread(float cycles01)
Right-channel LFO lead in CYCLES, 0..0.5.
Definition phaser_stages.hpp:484
void prepare(double sample_rate)
Sets the sample rate and returns the instance to a fresh, silent state.
Definition phaser_stages.hpp:410
void set_feedback(float fb)
Feedback ("Color"), clamped to ±kFeedbackMax.
Definition phaser_stages.hpp:468
static constexpr double kStaggerMax
Definition phaser_stages.hpp:349
double feedback() const
Definition phaser_stages.hpp:473
static constexpr int kMinStages
Definition phaser_stages.hpp:311
LfoWave Wave
The LFO shape enum, forwarded verbatim.
Definition phaser_stages.hpp:305
void set_rate_hz(double hz)
LFO rate in Hz. Forwarded to both channels' LFOs.
Definition phaser_stages.hpp:442
void set_center_hz(double fc)
Allpass corner frequency at the LFO's midpoint.
Definition phaser_stages.hpp:457
The house low-frequency oscillator: seven waveforms plus a continuous shape morph,...
Definition additive_bank.hpp:218
PhaserStagesT< double > PhaserStages64
Definition phaser_stages.hpp:648
@ c
Definition spectrum_trace.hpp:35
T snap_to_zero(T x)
Returns 0 if |x| < snap_threshold, else x.
Definition denormal.hpp:45
PhaserStagesT< float > PhaserStages
Definition phaser_stages.hpp:647
@ ratio
base_frequency_hz * ratio.
Definition fm_operator_engine.hpp:20
@ i
Definition formant_filter_bank.hpp:20
LfoWave
The effect-wave vocabulary, shared by these functions and by EffectLfoT (lfo.hpp),...
Definition lfo_sampling.hpp:53
@ s
Definition input_events.hpp:41
@ x
Definition input_events.hpp:41
@ v
Definition input_events.hpp:41
First-order topology-preserving transform (TPT) filter.