143template <
typename SampleType =
float>
201 sample_rate_ = sample_rate > 0.0 ? sample_rate : sample_rate_;
203 const auto capacity =
static_cast<std::size_t
>(std::llround(
206 lookahead_.assign(capacity, SampleType{0});
208 update_coefficients();
217 gain_reduction_db_ = 0.0;
219 std::fill(lookahead_.begin(), lookahead_.end(), SampleType{0});
221 lookahead_valid_ = 0;
263 update_coefficients();
271 update_coefficients();
331 double active_ratio() const noexcept {
return negative_ratio_ ? neg_ratio_ : ratio_; }
338 double level_db() const noexcept {
return level_db_; }
356 if (!std::isfinite(
static_cast<double>(input))) {
357 recover_audio_fault();
358 return SampleType{0};
360 level_db_ = detect_level_db(
static_cast<double>(input));
367 const double dry =
static_cast<double>(delayed(input));
368 return static_cast<SampleType
>(dry * (mix_ * gain_linear_ + (1.0 - mix_)));
376 void recover_audio_fault() noexcept {
379 gain_reduction_db_ = 0.0;
382 lookahead_valid_ = 0;
388 double detect_level_db(
double x) {
389 const double p = x * x;
390 const double a = p > mean_square_ ? attack_coef_ : release_coef_;
391 mean_square_ =
snap_to_zero(mean_square_ +
a * (p - mean_square_));
392 return 10.0 * std::log10(std::max(mean_square_,
kFloorLinear));
397 SampleType delayed(SampleType input) {
398 if (lookahead_samples_ <= 0 || lookahead_.empty())
return input;
399 const std::size_t size = lookahead_.size();
400 const std::size_t read =
401 (write_index_ + size -
static_cast<std::size_t
>(lookahead_samples_)) % size;
402 const SampleType out = lookahead_valid_ >=
static_cast<std::size_t
>(lookahead_samples_)
405 lookahead_[write_index_] = input;
406 write_index_ = (write_index_ + 1) % size;
407 if (lookahead_valid_ < size) ++lookahead_valid_;
416 void update_coefficients() {
421 void update_lookahead() {
424 const auto capacity = lookahead_.size();
425 if (capacity > 0 && lookahead_samples_ >=
static_cast<int>(capacity))
426 lookahead_samples_ =
static_cast<int>(capacity) - 1;
427 if (lookahead_samples_ < 0) lookahead_samples_ = 0;
430 double sample_rate_ = 44100.0;
432 double threshold_db_ = -20.0;
434 double neg_ratio_ = -4.0;
435 double knee_db_ = 10.0;
436 double time_ms_ = 30.0;
438 double makeup_db_ = 0.0;
439 double lookahead_ms_ = 0.0;
442 bool negative_ratio_ =
false;
444 double attack_coef_ = 0.0;
445 double release_coef_ = 0.0;
446 int lookahead_samples_ = 0;
448 double mean_square_ = 0.0;
449 double level_db_ = 10.0 * -12.0;
450 double gain_reduction_db_ = 0.0;
451 double gain_linear_ = 1.0;
453 std::vector<SampleType> lookahead_{};
454 std::size_t write_index_ = 0;
455 std::size_t lookahead_valid_ = 0;
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
True-RMS, log-domain, single-time-constant feedforward compressor.
Definition vca_compressor.hpp:144
static constexpr double kTimeMsMax
Definition vca_compressor.hpp:181
SampleType process(SampleType input)
Definition vca_compressor.hpp:352
static constexpr double kLookaheadMsMax
Definition vca_compressor.hpp:183
static constexpr double kTimeMsMin
Definition vca_compressor.hpp:180
double gain_computer_db(double input_db) const
Gain reduction in dB (SIGNED, ≤ 0 — see the file doc block) the static curve commands at input_db,...
Definition vca_compressor.hpp:319
void reset()
Zeroes the detector and the delay line. Never allocates.
Definition vca_compressor.hpp:214
void set_lookahead_ms(double ms)
Clamped to the ceiling prepare() sized for, so this can never need an allocation.
Definition vca_compressor.hpp:281
static constexpr double kCeilingDbMax
Definition vca_compressor.hpp:193
static constexpr double kThresholdDbMin
Definition vca_compressor.hpp:172
void set_ceiling_db(double db)
Definition vca_compressor.hpp:293
static constexpr double kMakeupDbMax
Definition vca_compressor.hpp:182
double attack_coef() const noexcept
The detector's two one-pole coefficients, in the a of y += a·(x − y) convention of units::ms_to_onepo...
Definition vca_compressor.hpp:347
double level_db() const noexcept
Definition vca_compressor.hpp:338
double mean_square() const noexcept
Definition vca_compressor.hpp:339
void set_time_ms(double ms)
THE time control — one knob for both directions.
Definition vca_compressor.hpp:260
double current_gain_linear() const noexcept
Definition vca_compressor.hpp:340
static constexpr double kKneeDbMin
Definition vca_compressor.hpp:178
static constexpr double kThresholdDbMax
Definition vca_compressor.hpp:173
static constexpr double kRatioKMax
Definition vca_compressor.hpp:167
double gain_reduction_db() const noexcept
Metering taps, as of the last processed sample.
Definition vca_compressor.hpp:334
void set_mix(double mix01)
Dry/wet.
Definition vca_compressor.hpp:289
static constexpr double kRatioMin
Definition vca_compressor.hpp:174
void set_knee_db(double db)
0 = hard knee; > 0 = OverEasy-style soft knee, total width in dB (±width/2 around threshold).
Definition vca_compressor.hpp:253
static constexpr double kCeilingDbMin
Definition vca_compressor.hpp:192
static constexpr double kRatioMax
Definition vca_compressor.hpp:175
static constexpr double kCeilingDbDefault
Definition vca_compressor.hpp:191
static constexpr double kNegRatioMin
Definition vca_compressor.hpp:176
void set_threshold_db(double db)
Definition vca_compressor.hpp:226
void prepare(double sample_rate)
Sizes the lookahead ring for the worst case in the declared range.
Definition vca_compressor.hpp:200
double active_ratio() const noexcept
The ratio currently in force: the negative amount in "infinity+" mode, the positive ratio otherwise.
Definition vca_compressor.hpp:331
void set_ratio(double r)
Positive compression ratio, used when negative-ratio mode is off.
Definition vca_compressor.hpp:232
static constexpr double kKneeDbMax
Definition vca_compressor.hpp:179
void set_attack_release_ratio_k(double k)
The fixed attack/release lock.
Definition vca_compressor.hpp:268
int latency_samples() const noexcept
The module's entire latency contribution: the lookahead delay, exactly.
Definition vca_compressor.hpp:304
static constexpr double kNegRatioMax
Definition vca_compressor.hpp:177
GainReduction gain_reduction() const noexcept
Definition vca_compressor.hpp:335
static constexpr double kFloorLinear
Definition vca_compressor.hpp:156
static constexpr double kRatioKMin
Definition vca_compressor.hpp:166
static constexpr double kRatioKDefault
Definition vca_compressor.hpp:165
void set_makeup_db(double db)
Definition vca_compressor.hpp:274
void set_negative_ratio_mode(bool enabled)
"Infinity+": lets the static curve run with a NEGATIVE ratio, so output keeps falling as input rises ...
Definition vca_compressor.hpp:241
void set_neg_ratio_amount(double r)
The ratio used when negative-ratio mode is on.
Definition vca_compressor.hpp:246
double gain_computer_unclamped_db(double input_db) const
The same value UNCLAMPED, so a test can show where the floor engages and where it does not.
Definition vca_compressor.hpp:325
void process_block(SampleType *io, int n)
Definition vca_compressor.hpp:371
double release_coef() const noexcept
Definition vca_compressor.hpp:348
double static_curve_db(double input_db) const
The static characteristic's output level for an input level, in dB — the gain computer alone,...
Definition vca_compressor.hpp:313
Shared envelope and gain-reduction vocabulary for dynamics processors.
The published compressor equations, once.
double soft_knee_output_db(double input_db, double threshold_db, double knee_db, double ratio)
The characteristic in the OUTPUT-LEVEL domain: input dB → output dB.
Definition dynamics_core.hpp:193
double retain_finite(double candidate, double current) noexcept
Control setters retain their last valid value when automation supplies a non-finite sample.
Definition dynamics_core.hpp:117
T ms_to_onepole_coef(T ms, T sample_rate)
A time constant in ms → the a in the one-pole smoother y += a·(x − y), i.e.
Definition units.hpp:202
T ms_to_samples(T ms, T sample_rate)
Milliseconds → samples at sample_rate Hz.
Definition units.hpp:147
T db_to_linear(T db)
Amplitude dB → linear gain. 0 dB → 1, −6.0206 dB → 0.5.
Definition units.hpp:71
Definition additive_bank.hpp:218
VcaCompressorT< float > VcaCompressor
Definition vca_compressor.hpp:458
VcaCompressorT< double > VcaCompressor64
Definition vca_compressor.hpp:459
T snap_to_zero(T x)
Returns 0 if |x| < snap_threshold, else x.
Definition denormal.hpp:45
@ a
Definition formant_filter_bank.hpp:20
@ i
Definition formant_filter_bank.hpp:20
@ e
Definition formant_filter_bank.hpp:20
The real-unit vocabulary shared by every DSP block in the catalog.