mirror of
https://codeberg.org/armin/chromaflock.git
synced 2026-09-01 20:30:47 +02:00
44 lines
1.2 KiB
C++
44 lines
1.2 KiB
C++
#pragma once
|
|
#include <cmath>
|
|
#include <algorithm>
|
|
|
|
class Limiter {
|
|
public:
|
|
void prepare(double sr) {
|
|
sampleRate = sr;
|
|
envelope = 0.0f;
|
|
}
|
|
|
|
void setParameters(float threshold, float ceiling, float releaseMs) {
|
|
thresholdGain = threshold;
|
|
ceilingGain = ceiling;
|
|
releaseCoeff = std::exp(-1.0f / (std::max(releaseMs, 1.0f) * 0.001f * static_cast<float>(sampleRate)));
|
|
dryWet = 1.0f;
|
|
}
|
|
|
|
float process(float input) {
|
|
float absIn = std::abs(input);
|
|
if (absIn > envelope)
|
|
envelope = absIn;
|
|
else
|
|
envelope = releaseCoeff * envelope + (1.0f - releaseCoeff) * absIn;
|
|
|
|
float target = std::max(thresholdGain, ceilingGain);
|
|
float gain = 1.0f;
|
|
if (envelope > target && envelope > 1e-6f) {
|
|
float desired = target / envelope;
|
|
gain = std::min(1.0f, desired);
|
|
}
|
|
|
|
float wet = input * gain;
|
|
return input + (wet - input) * dryWet;
|
|
}
|
|
|
|
private:
|
|
double sampleRate = 44100.0;
|
|
float thresholdGain = 1.0f;
|
|
float ceilingGain = 1.0f;
|
|
float releaseCoeff = 0.0f;
|
|
float dryWet = 1.0f;
|
|
float envelope = 0.0f;
|
|
};
|