39 template <
typename SampleType>
150 size_t numSamples)
override;
152 inline virtual void reset()
override;
177 template <
typename SampleType>
179 _attackMs(Parameters::ATTACK_MS.defaultValue),
180 _releaseMs(Parameters::RELEASE_MS.defaultValue),
181 _threshold(Parameters::THRESHOLD.defaultValue),
182 _ratio(Parameters::RATIO.defaultValue),
183 _kneeWidth(Parameters::KNEE_WIDTH.defaultValue),
184 _levelDetectorState(0),
191 template <
typename SampleType>
196 _attackCoef = _calcCoef(_attackMs);
197 _releaseCoef = _calcCoef(_releaseMs);
203 template <
typename SampleType>
205 if (_direction != val) {
211 template <
typename SampleType>
214 _attackCoef = _calcCoef(_attackMs);
217 template <
typename SampleType>
220 _releaseCoef = _calcCoef(_releaseMs);
223 template <
typename SampleType>
227 for (
size_t index {0}; index < numSamples; index++) {
230 const SampleType absdB {
static_cast<SampleType
>(
235 const SampleType gainComp {_computeGain(absdB)};
238 const SampleType level {_computeLevel(absdB - gainComp)};
243 inSamples[index] = inSamples[index] * _gainApplied;
247 template <
typename SampleType>
249 _levelDetectorState = 0;
253 template <
typename SampleType>
256 if (inSample > _levelDetectorState) {
257 _levelDetectorState = _attackCoef * _levelDetectorState + (1 - _attackCoef) * inSample;
259 _levelDetectorState = _releaseCoef * _levelDetectorState + (1 - _releaseCoef) * inSample;
262 return _levelDetectorState;
265 template <
typename SampleType>
268 SampleType retVal {inSample};
273 if (inSample - _threshold < -_kneeWidth / 2) {
276 }
else if (std::abs(inSample - _threshold) <= (_kneeWidth / 2)) {
278 retVal = inSample + (1 / _ratio - 1)
279 * std::pow(inSample - _threshold + (_kneeWidth / 2), 2);
283 retVal = _threshold + (inSample - _threshold) / _ratio;
289 if (inSample - _threshold < -_kneeWidth / 2) {
291 retVal = _threshold - (_threshold - inSample) / _ratio;
293 }
else if (std::abs(inSample - _threshold) <= (_kneeWidth / 2)) {
295 retVal = inSample + (1 - 1 / _ratio) \
296 * std::pow(inSample - _threshold - _kneeWidth / 2, 2) / (2 * _kneeWidth);
double getThreshold() const
Direction getDirection() const
double getKneeWidth() const
void setSampleRate(double val)
virtual ~SimpleCompressor() override=default
SampleType _computeLevel(SampleType inSample)
void setAttack(double val)
virtual void process1in1out(SampleType *inSamples, size_t numSamples) override
double _calcCoef(double timeMs)
virtual void reset() override
void setRatio(double val)
double getRelease() const
SampleType _levelDetectorState
void setThreshold(double val)
SampleType _computeGain(SampleType inSample)
SampleType getGainApplied() const
void setDirection(Direction val)
void setKneeWidth(double val)
void setRelease(double val)
double linearTodB(double val)
bool compareFloatsEqual(T x, T y, T tolerance=std::numeric_limits< T >::epsilon())
double dBToLinear(double val)
const ParameterDefinition::RangedParameter< double > THRESHOLD(-60, 0, 0)
const ParameterDefinition::RangedParameter< double > RELEASE_MS(1, 5000, 100)
const ParameterDefinition::RangedParameter< double > RATIO(1, 30, 2)
const ParameterDefinition::RangedParameter< double > KNEE_WIDTH(1, 10, 2)
const ParameterDefinition::RangedParameter< double > ATTACK_MS(0.1, 500, 10)