mirror of
https://codeberg.org/armin/chromaflock.git
synced 2026-09-01 12:20:47 +02:00
47 lines
1.5 KiB
C
47 lines
1.5 KiB
C
|
|
#pragma once
|
||
|
|
#include <cmath>
|
||
|
|
#include <algorithm>
|
||
|
|
|
||
|
|
class Compressor {
|
||
|
|
public:
|
||
|
|
void prepare(double sr) {
|
||
|
|
sampleRate = sr;
|
||
|
|
envelope = 0.0f;
|
||
|
|
}
|
||
|
|
|
||
|
|
void setParameters(float thresholdDb, float ratio, float attackMs, float releaseMs,
|
||
|
|
float makeupDb, float mix) {
|
||
|
|
threshold = std::pow(10.0f, thresholdDb / 20.0f);
|
||
|
|
compRatio = ratio;
|
||
|
|
attackCoeff = std::exp(-1.0f / (attackMs * 0.001f * static_cast<float>(sampleRate)));
|
||
|
|
releaseCoeff = std::exp(-1.0f / (releaseMs * 0.001f * static_cast<float>(sampleRate)));
|
||
|
|
makeupGain = std::pow(10.0f, makeupDb / 20.0f);
|
||
|
|
dryWet = mix;
|
||
|
|
}
|
||
|
|
|
||
|
|
float process(float input) {
|
||
|
|
float absIn = std::abs(input);
|
||
|
|
float coeff = (absIn > envelope) ? attackCoeff : releaseCoeff;
|
||
|
|
envelope = coeff * envelope + (1.0f - coeff) * absIn;
|
||
|
|
|
||
|
|
float gain = 1.0f;
|
||
|
|
if (envelope > threshold && compRatio > 1.0f) {
|
||
|
|
float overDb = 20.0f * std::log10(envelope / threshold);
|
||
|
|
float compressedDb = overDb / compRatio;
|
||
|
|
gain = std::pow(10.0f, (compressedDb - overDb) / 20.0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
float wet = input * gain * makeupGain;
|
||
|
|
return input + (wet - input) * dryWet;
|
||
|
|
}
|
||
|
|
|
||
|
|
private:
|
||
|
|
double sampleRate = 44100.0;
|
||
|
|
float threshold = 0.1f;
|
||
|
|
float compRatio = 4.0f;
|
||
|
|
float attackCoeff = 0.0f;
|
||
|
|
float releaseCoeff = 0.0f;
|
||
|
|
float makeupGain = 1.0f;
|
||
|
|
float dryWet = 1.0f;
|
||
|
|
float envelope = 0.0f;
|
||
|
|
};
|