34 static constexpr SampleType
min_q = SampleType{0.1};
35 static constexpr SampleType
max_q = SampleType{12};
43 SampleType
q = SampleType{1};
57 parameters_ = clamp_(parameters_);
58 detector_.prepare(sample_rate_);
59 detector_.set_attack_ms(parameters_.attack_ms);
60 detector_.set_release_ms(parameters_.release_ms);
68 if (!finite_(requested))
70 requested = clamp_(requested);
71 const bool filter_changed =
72 requested.frequency_hz != parameters_.frequency_hz || requested.q != parameters_.q;
73 parameters_ = requested;
74 detector_.set_attack_ms(parameters_.attack_ms);
75 detector_.set_release_ms(parameters_.release_ms);
85 SampleType
process(SampleType input)
noexcept {
86 if (!std::isfinite(
static_cast<double>(input))) {
91 const SampleType band = band_filter_.process(input);
92 if (!std::isfinite(
static_cast<double>(band))) {
97 detector_level_ = detector_.process(band);
98 const SampleType level_db = detector_.current_db(SampleType{-160});
99 const SampleType over_db = level_db - parameters_.threshold_db;
100 activity_ = std::clamp(over_db / parameters_.transition_db, SampleType{0}, SampleType{1});
101 dynamic_gain_db_ = parameters_.range_db * activity_;
103 if (parameters_.range_db == SampleType{0})
105 const SampleType band_gain = std::pow(SampleType{10}, dynamic_gain_db_ / SampleType{20});
106 const SampleType output = input + band * (band_gain - SampleType{1});
107 if (!std::isfinite(
static_cast<double>(output))) {
109 return SampleType{0};
115 if (samples ==
nullptr && frames != 0)
117 for (std::size_t
i = 0;
i < frames; ++
i)
123 band_filter_.reset();
125 detector_level_ = SampleType{0};
126 activity_ = SampleType{0};
127 dynamic_gain_db_ = SampleType{0};
131 return detector_level_;
137 return dynamic_gain_db_;
143 return band_filter_.coefficients();
153 static bool valid_sample_rate_(SampleType
sample_rate)
noexcept {
154 return std::isfinite(
static_cast<double>(
sample_rate)) &&
158 static bool finite_(
const Parameters& p)
noexcept {
159 return std::isfinite(
static_cast<double>(p.frequency_hz)) &&
160 std::isfinite(
static_cast<double>(p.q)) &&
161 std::isfinite(
static_cast<double>(p.threshold_db)) &&
162 std::isfinite(
static_cast<double>(p.range_db)) &&
163 std::isfinite(
static_cast<double>(p.transition_db)) &&
164 std::isfinite(
static_cast<double>(p.attack_ms)) &&
165 std::isfinite(
static_cast<double>(p.release_ms));
169 const SampleType max_frequency =
175 p.transition_db = std::clamp(
p.transition_db, SampleType{0.1}, SampleType{60});
176 p.attack_ms = std::clamp(
p.attack_ms, SampleType{0.01}, SampleType{2000});
177 p.release_ms = std::clamp(
p.release_ms, SampleType{0.01}, SampleType{2000});
183 parameters_.q, sample_rate_);
186 BiquadT<SampleType> band_filter_{};
187 EnvelopeFollowerT<SampleType> detector_{};
189 SampleType sample_rate_ = SampleType{48000};
190 SampleType detector_level_ = SampleType{0};
191 SampleType activity_ = SampleType{0};
192 SampleType dynamic_gain_db_ = SampleType{0};
@ bandpass
Definition biquad.hpp:58
One internally keyed dynamic-EQ band.
Definition dynamic_eq.hpp:30
bool set_parameters(Parameters requested)
Apply one coherent parameter set.
Definition dynamic_eq.hpp:67
BiquadCoefficientsT< SampleType > band_coefficients() const noexcept
Definition dynamic_eq.hpp:142
void reset() noexcept
Definition dynamic_eq.hpp:122
static constexpr float min_q
Definition dynamic_eq.hpp:34
bool process_block(SampleType *samples, std::size_t frames) noexcept
Definition dynamic_eq.hpp:114
SampleType detector_level() const noexcept
Definition dynamic_eq.hpp:130
static constexpr float max_sample_rate
Definition dynamic_eq.hpp:33
static constexpr int latency_samples() noexcept
Definition dynamic_eq.hpp:148
static constexpr float min_threshold_db
Definition dynamic_eq.hpp:36
SampleType process(SampleType input) noexcept
Definition dynamic_eq.hpp:85
void prepare(SampleType sample_rate)
Definition dynamic_eq.hpp:55
Parameters parameters() const noexcept
Definition dynamic_eq.hpp:81
static constexpr float max_threshold_db
Definition dynamic_eq.hpp:37
SampleType activity() const noexcept
Definition dynamic_eq.hpp:133
static constexpr float min_frequency_hz
Definition dynamic_eq.hpp:32
static constexpr float min_range_db
Definition dynamic_eq.hpp:38
SampleType dynamic_gain_db() const noexcept
Definition dynamic_eq.hpp:136
GainReduction gain_reduction() const noexcept
Definition dynamic_eq.hpp:139
static constexpr float max_q
Definition dynamic_eq.hpp:35
DynamicEqBandT()
Definition dynamic_eq.hpp:51
float sample_rate() const noexcept
Definition dynamic_eq.hpp:145
static constexpr float max_range_db
Definition dynamic_eq.hpp:39
Canonical gain-reduction meter value.
Definition dynamics_contract.hpp:27
static GainReduction from_signed_db(double signed_db) noexcept
Adapt a signed gain value, where attenuation is negative dB.
Definition dynamics_contract.hpp:32
Shared envelope and gain-reduction vocabulary for dynamics processors.
Definition additive_bank.hpp:218
DynamicEqBandT< double > DynamicEqBand64
Definition dynamic_eq.hpp:196
@ i
Definition formant_filter_bank.hpp:20
DynamicEqBandT< float > DynamicEqBand
Definition dynamic_eq.hpp:195
@ p
Definition input_events.hpp:40
Definition dynamic_eq.hpp:41
SampleType transition_db
Definition dynamic_eq.hpp:46
SampleType range_db
Definition dynamic_eq.hpp:45
SampleType release_ms
Definition dynamic_eq.hpp:48
SampleType frequency_hz
Definition dynamic_eq.hpp:42
SampleType threshold_db
Definition dynamic_eq.hpp:44
SampleType q
Definition dynamic_eq.hpp:43
SampleType attack_ms
Definition dynamic_eq.hpp:47