@@ -30,15 +30,25 @@ void Limiter::updateSpec(Limiter::Spec& spec)
3030void Limiter::resetState (const Limiter::Spec& spec, Limiter::State& state)
3131{
3232 state.gain = 1 .0f ;
33+ state.sustain = 0 ;
3334}
3435
3536float Limiter::tick (const Limiter::Spec& spec, Limiter::State& state, float in)
3637{
3738 const float level = std::abs (in);
3839
3940 const float targetGain = (level > spec.threshold ) ? spec.threshold / level : 1 .0f ;
40- state.gain = (state.gain > targetGain) ? std::max (state.gain / spec.attack , targetGain)
41- : std::min (state.gain * spec.release , targetGain);
41+
42+ if (state.gain > targetGain) {
43+ state.gain = std::max (state.gain + (targetGain - state.gain ) * spec.attack , targetGain);
44+ state.sustain = spec.sustain ;
45+ } else {
46+ if (state.sustain > 0 ) {
47+ state.sustain --;
48+ } else {
49+ state.gain = std::min (state.gain + (targetGain - state.gain ) * spec.release , targetGain);
50+ }
51+ }
4252
4353 return in * state.gain ;
4454}
@@ -47,16 +57,28 @@ void Limiter::process(const Limiter::Spec& spec, Limiter::State& state, const fl
4757{
4858 float targetGain = 1 .0f ;
4959 float gain = state.gain ;
60+ int sustain = state.sustain ;
5061
5162 for (size_t i = 0 ; i < size; ++i) {
5263 const float level = std::abs (in[i]);
5364 targetGain = (level > spec.threshold ) ? spec.threshold / level : 1 .0f ;
54- gain = (gain > targetGain) ? std::max (gain / spec.attack , targetGain)
55- : std::min (gain * spec.release , targetGain);
65+
66+ if (gain > targetGain) {
67+ gain = std::max (gain + (targetGain - gain) * spec.attack , targetGain);
68+ sustain = spec.sustain ;
69+ } else {
70+ if (sustain > 0 ) {
71+ sustain--;
72+ } else {
73+ gain = std::min (gain + (targetGain - gain) * spec.release , targetGain);
74+ }
75+ }
76+
5677 out[i] = in[i] * gain;
5778 }
5879
5980 state.gain = gain;
81+ state.sustain = sustain;
6082}
6183
6284} // namespace dsp
0 commit comments