add program-dependent attack/release times
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "audio_math.h"
|
||||
#include "rms_detector.h"
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
namespace trnr {
|
||||
@@ -30,6 +31,7 @@ inline float hp_filter_process(hp_filter& f, float x)
|
||||
struct oneknob_comp {
|
||||
// params
|
||||
float amount = 0.f;
|
||||
bool multiplied = false;
|
||||
|
||||
// state
|
||||
rms_detector detector;
|
||||
@@ -38,9 +40,10 @@ struct oneknob_comp {
|
||||
float release_coef;
|
||||
float envelope_level;
|
||||
float sidechain_in;
|
||||
double samplerate;
|
||||
};
|
||||
|
||||
inline void oneknob_init(oneknob_comp& c, float samplerate, float window_ms)
|
||||
inline void oneknob_init(oneknob_comp& c, double samplerate, float window_ms)
|
||||
{
|
||||
rms_init(c.detector, samplerate, window_ms);
|
||||
hp_filter_init(c.filter, samplerate);
|
||||
@@ -48,6 +51,7 @@ inline void oneknob_init(oneknob_comp& c, float samplerate, float window_ms)
|
||||
const float attack_ms = 0.2f;
|
||||
const float release_ms = 150.f;
|
||||
|
||||
c.samplerate = samplerate;
|
||||
c.attack_coef = expf(-1.0f / (attack_ms * 1e-6 * samplerate));
|
||||
c.release_coef = expf(-1.0f / (release_ms * 1e-3 * samplerate));
|
||||
c.envelope_level = -60.f;
|
||||
@@ -59,11 +63,17 @@ inline void oneknob_process_block(oneknob_comp& c, sample** audio, int frames)
|
||||
{
|
||||
const float min_user_ratio = 1.0f;
|
||||
const float max_user_ratio = 20.0f;
|
||||
const float threshold_db = -9.f;
|
||||
const float threshold_db = -12.f;
|
||||
|
||||
const float amount = fmaxf(0.0f, fminf(powf(c.amount, 2.f), 1.0f)); // clamp to [0, 1]
|
||||
const float amount = fmaxf(0.0f, fminf(powf(c.amount, 2.f), 1.0f));
|
||||
float ratio = min_user_ratio + amount * (max_user_ratio - min_user_ratio);
|
||||
|
||||
const float fast_attack = 0.1f;
|
||||
const float slow_attack = 0.6f;
|
||||
const float fast_release = 90.f;
|
||||
const float slow_release = 300.f;
|
||||
const float max_gr = 24.f;
|
||||
|
||||
for (int i = 0; i < frames; ++i) {
|
||||
float rms_value = rms_process<sample>(c.detector, c.sidechain_in);
|
||||
float envelope_in = lin_2_db(fmaxf(fabs(rms_value), 1e-20f));
|
||||
@@ -89,8 +99,17 @@ inline void oneknob_process_block(oneknob_comp& c, sample** audio, int frames)
|
||||
audio[0][i] *= gain_reduction_lin;
|
||||
audio[1][i] *= gain_reduction_lin;
|
||||
|
||||
// calculate program-dependent attack/release times
|
||||
float norm_gr = std::clamp(gain_reduction_db / max_gr, 0.f, 1.f);
|
||||
float release_ms = fast_release + (slow_release - fast_release) * (1.f - norm_gr);
|
||||
float attack_ms = fast_attack + (slow_attack - fast_attack) * (1.f - norm_gr);
|
||||
|
||||
c.attack_coef = expf(-1.0f / (attack_ms * 1e-6 * c.samplerate));
|
||||
c.release_coef = expf(-1.0f / (release_ms * 1e-3 * c.samplerate));
|
||||
|
||||
// feedback compression
|
||||
float sum = sqrtf(0.5f * (audio[0][i] * audio[0][i] + audio[1][i] * audio[1][i]));
|
||||
if (c.multiplied) sum *= 3.f;
|
||||
c.sidechain_in = hp_filter_process(c.filter, sum);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user