refined oneknob compressor
This commit is contained in:
@@ -63,49 +63,48 @@ inline void oneknob_init(oneknob_comp& comp, float samplerate, float window_ms)
|
|||||||
{
|
{
|
||||||
rms_init(comp.detector, samplerate, window_ms);
|
rms_init(comp.detector, samplerate, window_ms);
|
||||||
hp_filter_init(comp.filter, samplerate);
|
hp_filter_init(comp.filter, samplerate);
|
||||||
comp.amount = 0.0f;
|
|
||||||
|
|
||||||
const float attack_ms = 10.f;
|
const float attack_ms = 0.2f;
|
||||||
const float release_ms = 100.f;
|
const float release_ms = 150.f;
|
||||||
|
|
||||||
comp.attack_coef = expf(-1.0f / (samplerate * (attack_ms * 0.001f)));
|
comp.attack_coef = expf(-1.0f / (attack_ms * 1e-6 * samplerate));
|
||||||
comp.release_coef = expf(-1.0f / (samplerate * (release_ms * 0.001f)));
|
comp.release_coef = expf(-1.0f / (release_ms * 1e-3 * samplerate));
|
||||||
comp.envelope_level = 0.f;
|
comp.envelope_level = -60.f;
|
||||||
comp.sidechain_in = 0.f;
|
comp.sidechain_in = 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename sample>
|
template <typename sample>
|
||||||
inline void oneknob_process_block(oneknob_comp& comp, sample** audio, int frames)
|
inline void oneknob_process_block(oneknob_comp& comp, sample** audio, int frames)
|
||||||
{
|
{
|
||||||
const float threshold = -18.f;
|
const float min_user_ratio = 1.0f;
|
||||||
const float min_ratio = 1.0f;
|
const float max_user_ratio = 20.0f;
|
||||||
const float max_ratio = 10.0f;
|
const float threshold_db = -9.f;
|
||||||
float ratio = min_ratio + comp.amount * (max_ratio - min_ratio);
|
|
||||||
|
const float amount = fmaxf(0.0f, fminf(powf(comp.amount, 2.f), 1.0f)); // clamp to [0, 1]
|
||||||
|
float ratio = min_user_ratio + amount * (max_user_ratio - min_user_ratio);
|
||||||
|
|
||||||
for (int i = 0; i < frames; ++i) {
|
for (int i = 0; i < frames; ++i) {
|
||||||
float rms_value = rms_process(comp.detector, comp.sidechain_in);
|
float rms_value = rms_process(comp.detector, comp.sidechain_in);
|
||||||
float absolute_rms_db = lin_2_db(fabs(rms_value));
|
float envelope_in = lin_2_db(fmaxf(fabs(rms_value), 1e-20f));
|
||||||
|
|
||||||
// cut envelope below threshold
|
// attack
|
||||||
float overshoot = absolute_rms_db - threshold;
|
if (envelope_in > comp.envelope_level) {
|
||||||
if (overshoot < 0.f) overshoot = 0.f;
|
comp.envelope_level = envelope_in + comp.attack_coef * (comp.envelope_level - envelope_in);
|
||||||
|
}
|
||||||
if (overshoot > comp.envelope_level) {
|
// release
|
||||||
comp.envelope_level = overshoot + comp.attack_coef * (comp.envelope_level - overshoot);
|
else {
|
||||||
} else {
|
comp.envelope_level = envelope_in + comp.release_coef * (comp.envelope_level - envelope_in);
|
||||||
comp.envelope_level = overshoot + comp.release_coef * (comp.envelope_level - overshoot);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (comp.envelope_level < 0.f) comp.envelope_level = 0.f;
|
float x = comp.envelope_level;
|
||||||
|
float y;
|
||||||
|
|
||||||
float slope = 1.f / ratio;
|
if (x < threshold_db) y = x;
|
||||||
|
else y = threshold_db + (x - threshold_db) / ratio;
|
||||||
|
|
||||||
float gain_reduction_db = comp.envelope_level * (slope - 1.f);
|
float gain_reduction_db = y - x;
|
||||||
float gain_reduction_lin = db_2_lin(gain_reduction_db);
|
float gain_reduction_lin = db_2_lin(gain_reduction_db);
|
||||||
|
|
||||||
sample input_l = audio[0][i];
|
|
||||||
sample input_r = audio[1][i];
|
|
||||||
|
|
||||||
audio[0][i] *= gain_reduction_lin;
|
audio[0][i] *= gain_reduction_lin;
|
||||||
audio[1][i] *= gain_reduction_lin;
|
audio[1][i] *= gain_reduction_lin;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user