39 : time_convention_(time_convention) {}
42 sample_rate_ = sample_rate;
43 update_coefficients();
47 if (!std::isfinite(
static_cast<double>(ms)))
49 attack_ms_ = std::max(SampleType{0.01f}, ms);
50 update_coefficients();
54 if (!std::isfinite(
static_cast<double>(ms)))
56 release_ms_ = std::max(SampleType{0.01f}, ms);
57 update_coefficients();
65 if (!std::isfinite(
static_cast<double>(input))) {
69 if (!std::isfinite(
static_cast<double>(state_)) || state_ < SampleType{0})
72 const SampleType magnitude = std::abs(input);
73 SampleType value = magnitude;
75 const SampleType square_limit = std::sqrt(std::numeric_limits<SampleType>::max());
76 value = magnitude > square_limit ? std::numeric_limits<SampleType>::max()
77 : magnitude * magnitude;
79 SampleType coeff = (value > state_) ? attack_coeff_ : release_coeff_;
84 if (!std::isfinite(
static_cast<double>(state_)) || state_ < SampleType{0}) {
88 return (mode_ ==
Mode::rms) ? std::sqrt(state_) : state_;
91 void process(
const SampleType* input, SampleType* output,
int num_samples) {
92 for (
int i = 0;
i < num_samples; ++
i) {
98 if (!std::isfinite(
static_cast<double>(state_)) || state_ < SampleType{0})
100 return (mode_ ==
Mode::rms) ? std::sqrt(state_) : state_;
107 SampleType
current_db(SampleType floor_db = SampleType{-160})
const {
108 if (!std::isfinite(
static_cast<double>(floor_db)) || floor_db > SampleType{0})
109 floor_db = SampleType{-160};
110 const SampleType value =
current();
111 if (!(value > SampleType{0}))
113 const SampleType db = SampleType{20} * std::log10(value);
114 return std::isfinite(
static_cast<double>(db)) ? std::max(floor_db, db) : floor_db;
124 return attack_coeff_;
127 return release_coeff_;
136 if (!std::isfinite(
static_cast<double>(ms)) ||
137 !std::isfinite(
static_cast<double>(sample_rate)) || !(sample_rate > SampleType{0}))
138 return SampleType{0};
139 if (!(ms > SampleType{0.01f}))
140 return SampleType{1};
141 return SampleType{1} -
142 std::exp(SampleType{-2.2f} / (ms * SampleType{0.001f} * sample_rate));
147 if (!std::isfinite(
static_cast<double>(ms)) ||
148 !std::isfinite(
static_cast<double>(sample_rate)) || !(sample_rate > SampleType{0}))
149 return SampleType{0};
150 if (!(ms > SampleType{0.01f}))
151 return SampleType{1};
152 return SampleType{1} -
153 std::exp(-std::log(SampleType{9}) / (ms * SampleType{0.001} * sample_rate));
157 state_ = SampleType{0.0f};
166 state_ = std::isfinite(
static_cast<double>(
state)) &&
state >= SampleType{0}
172 SampleType sample_rate_ = SampleType{44100.0f};
173 SampleType attack_ms_ = SampleType{1.0f};
174 SampleType release_ms_ = SampleType{100.0f};
175 SampleType attack_coeff_ = SampleType{0.0f};
176 SampleType release_coeff_ = SampleType{0.0f};
177 SampleType state_ = SampleType{0.0f};
181 void update_coefficients() {
182 if (sample_rate_ <= 0)
184 attack_coeff_ = time_constant(attack_ms_);
185 release_coeff_ = time_constant(release_ms_);
188 SampleType time_constant(SampleType ms)
const {
Envelope follower with configurable attack and release times.
Definition ballistics_filter.hpp:31
SampleType current() const
Definition ballistics_filter.hpp:97
SampleType release_coefficient() const noexcept
Definition ballistics_filter.hpp:126
static SampleType exact_coefficient_for_time_ms(SampleType ms, SampleType sample_rate)
Pure coefficient for an exact 10-to-90-percent state-domain interval.
Definition ballistics_filter.hpp:146
void set_mode(Mode m)
Definition ballistics_filter.hpp:60
void set_attack_ms(SampleType ms)
Definition ballistics_filter.hpp:46
SampleType current_db(SampleType floor_db=SampleType{-160}) const
Current envelope in dBFS, floored at floor_db.
Definition ballistics_filter.hpp:107
void prepare(SampleType sample_rate)
Definition ballistics_filter.hpp:41
BallisticsFilterT()=default
void set_release_ms(SampleType ms)
Definition ballistics_filter.hpp:53
TimeConvention
Definition ballistics_filter.hpp:34
@ exact_10_to_90
Definition ballistics_filter.hpp:34
@ legacy_nominal
Definition ballistics_filter.hpp:34
Mode
Definition ballistics_filter.hpp:33
@ peak
Definition ballistics_filter.hpp:33
@ rms
Definition ballistics_filter.hpp:33
SampleType attack_coefficient() const noexcept
Definition ballistics_filter.hpp:123
BallisticsFilterT(TimeConvention time_convention)
Definition ballistics_filter.hpp:38
static SampleType coefficient_for_time_ms(SampleType ms, SampleType sample_rate)
Legacy nominal coefficient retained for bit-identical BallisticsFilter output.
Definition ballistics_filter.hpp:135
void process(const SampleType *input, SampleType *output, int num_samples)
Definition ballistics_filter.hpp:91
SampleType attack_ms() const noexcept
Definition ballistics_filter.hpp:117
void reset()
Definition ballistics_filter.hpp:156
SampleType release_ms() const noexcept
Definition ballistics_filter.hpp:120
SampleType detector_state() const noexcept
Definition ballistics_filter.hpp:161
void synchronize_detector_state(SampleType state) noexcept
Definition ballistics_filter.hpp:165
SampleType process(SampleType input)
Definition ballistics_filter.hpp:64
Definition additive_bank.hpp:218
BallisticsFilterT< float > BallisticsFilter
Definition ballistics_filter.hpp:195
BallisticsFilterT< double > BallisticsFilter64
Definition ballistics_filter.hpp:196
@ i
Definition formant_filter_bank.hpp:20
T snap_recursion_state(T x)
Snap a per-sample recursion's state: snap_to_zero() where subnormals are slow, the identity where kSu...
Definition denormal.hpp:84
SequencerStateChannel is the audio-safe transport for a plugin's structured NON-parameter state: the ...
Definition audio_device_manager.hpp:48