Skip to content

Commit 9118882

Browse files
committed
#33 Add sustain to the limiter.
1 parent fb7dc2f commit 9118882

File tree

3 files changed

+35
-10
lines changed

3 files changed

+35
-10
lines changed

Source/aeolus/dsp/limiter.cpp

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,25 @@ void Limiter::updateSpec(Limiter::Spec& spec)
3030
void Limiter::resetState(const Limiter::Spec& spec, Limiter::State& state)
3131
{
3232
state.gain = 1.0f;
33+
state.sustain = 0;
3334
}
3435

3536
float 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

Source/aeolus/dsp/limiter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@ struct Limiter
3333
float threshold;
3434
float attack;
3535
float release;
36+
int sustain;
3637
};
3738

3839
struct State
3940
{
4041
float gain;
42+
int sustain;
4143
};
4244

4345
static void updateSpec(Spec& spec);

Source/aeolus/engine.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -473,9 +473,10 @@ void Engine::prepareToPlay(float sampleRate, int frameSize)
473473
auto* g = EngineGlobal::getInstance();
474474
g->updateStops(SAMPLE_RATE_F);
475475

476-
_limiterSpec.threshold = 0.9f;
477-
_limiterSpec.attack = 1.001f;
478-
_limiterSpec.release = 1.00001f;
476+
_limiterSpec.threshold = 0.75f;
477+
_limiterSpec.attack = 10000.0f / sampleRate;
478+
_limiterSpec.release = 1.0f / sampleRate;
479+
_limiterSpec.sustain = std::max(0, int(sampleRate * 0.5f));
479480

480481
for (auto& state : _limiterState)
481482
dsp::Limiter::resetState(_limiterSpec, state);
@@ -590,12 +591,12 @@ void Engine::process(float* outL, float* outR, int numFrames, bool isNonRealtime
590591

591592
applyVolume(origOutL, origOutR, origNumFrames);
592593

593-
_volumeLevel.left.process(origOutL, origNumFrames);
594-
_volumeLevel.right.process(origOutR, origNumFrames);
595-
596594
// Apply limiter
597595
dsp::Limiter::process(_limiterSpec, _limiterState[0], origOutL, origOutL, origNumFrames);
598596
dsp::Limiter::process(_limiterSpec, _limiterState[1], origOutR, origOutR, origNumFrames);
597+
598+
_volumeLevel.left.process(origOutL, origNumFrames);
599+
_volumeLevel.right.process(origOutR, origNumFrames);
599600
}
600601

601602
void Engine::process(AudioBuffer<float>& out, bool isNonRealtime)

0 commit comments

Comments
 (0)