add program-dependent attack/release times
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "audio_math.h"
|
#include "audio_math.h"
|
||||||
#include "rms_detector.h"
|
#include "rms_detector.h"
|
||||||
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
namespace trnr {
|
namespace trnr {
|
||||||
@@ -30,6 +31,7 @@ inline float hp_filter_process(hp_filter& f, float x)
|
|||||||
struct oneknob_comp {
|
struct oneknob_comp {
|
||||||
// params
|
// params
|
||||||
float amount = 0.f;
|
float amount = 0.f;
|
||||||
|
bool multiplied = false;
|
||||||
|
|
||||||
// state
|
// state
|
||||||
rms_detector detector;
|
rms_detector detector;
|
||||||
@@ -38,9 +40,10 @@ struct oneknob_comp {
|
|||||||
float release_coef;
|
float release_coef;
|
||||||
float envelope_level;
|
float envelope_level;
|
||||||
float sidechain_in;
|
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);
|
rms_init(c.detector, samplerate, window_ms);
|
||||||
hp_filter_init(c.filter, samplerate);
|
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 attack_ms = 0.2f;
|
||||||
const float release_ms = 150.f;
|
const float release_ms = 150.f;
|
||||||
|
|
||||||
|
c.samplerate = samplerate;
|
||||||
c.attack_coef = expf(-1.0f / (attack_ms * 1e-6 * samplerate));
|
c.attack_coef = expf(-1.0f / (attack_ms * 1e-6 * samplerate));
|
||||||
c.release_coef = expf(-1.0f / (release_ms * 1e-3 * samplerate));
|
c.release_coef = expf(-1.0f / (release_ms * 1e-3 * samplerate));
|
||||||
c.envelope_level = -60.f;
|
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 min_user_ratio = 1.0f;
|
||||||
const float max_user_ratio = 20.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);
|
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) {
|
for (int i = 0; i < frames; ++i) {
|
||||||
float rms_value = rms_process<sample>(c.detector, c.sidechain_in);
|
float rms_value = rms_process<sample>(c.detector, c.sidechain_in);
|
||||||
float envelope_in = lin_2_db(fmaxf(fabs(rms_value), 1e-20f));
|
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[0][i] *= gain_reduction_lin;
|
||||||
audio[1][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
|
// feedback compression
|
||||||
float sum = sqrtf(0.5f * (audio[0][i] * audio[0][i] + audio[1][i] * audio[1][i]));
|
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);
|
c.sidechain_in = hp_filter_process(c.filter, sum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user