#include "Compressor.h" template Compressor::Compressor() { } template Compressor::~Compressor() { } template void Compressor::prepare(SampleType sampleRate) { this->detector.prepare(sampleRate); this->detector.setOutputIndB(true); } template SampleType Compressor::processSample(SampleType sample) { SampleType xn = sample; SampleType detect_input = 0.0; detect_input = this->detector.processSample(xn); //Gain Reduction Calculation SampleType gainReduction = calaculateGain(detect_input); //Make-up Gain //SampleType muGain = GainUtilities::decibelsToGain(makeupGain); //return xn * gainReduction * muGain; return gainReduction; } template void Compressor::process(SampleType* data, int startSample, int endSample) { for(int sample = startSample; sample < endSample; ++sample) data[sample] = processSample(data[sample]); } template void Compressor::setThreshold(SampleType newThreshold) { threshold = newThreshold; //Bounds Check if (threshold > 0.0) threshold = 0.0; if (threshold < -80.0) threshold = -80.0; } template void Compressor::setRatio(SampleType newRatio) { ratio = newRatio; //Bounds Check if (ratio > 100.0) ratio = 100.0; if (ratio < 1.0) ratio = 1.0; } template void Compressor::setAttack(SampleType newAttack) { attack = newAttack; //Bounds Check if (attack > 100.0) attack = 100.0; if (attack < 1.0) attack = 1.0; this->detector.setAttackTime(attack); } template void Compressor::setRelease(SampleType newRelease) { release = newRelease; //Bounds Check if (release > 1000.0) release = 1000.0; if (release < 10.0) release = 10.0; this->detector.setReleaseTime(release); } template void Compressor::setGain(SampleType newGain) { makeupGain = newGain; } template void Compressor::setParameter(int index, SampleType newValue) { switch (index) { case Parameters::Threshold: setThreshold(newValue); break; case Parameters::Ratio: setRatio(newValue); break; case Parameters::Attack: setAttack(newValue); break; case Parameters::Release: setRelease(newValue); break; case Parameters::MakeupGain: setGain(newValue); break; } } template SampleType Compressor::getParameter(int index) { switch (index) { case Parameters::Threshold: return threshold; break; case Parameters::Ratio: return ratio; break; case Parameters::Attack: return attack; break; case Parameters::Release: return release; break; case Parameters::MakeupGain: return makeupGain; break; } } template void Compressor::setKneeType(int index) { switch (index) { case KneeTypes::Soft: kneeType = KneeTypes::Soft; break; case KneeTypes::Hard: kneeType = KneeTypes::Hard; break; } } template int Compressor::getKneeType() { return kneeType; } template SampleType Compressor::calaculateGain(SampleType input) { SampleType output = 0.0; switch (kneeType) { case KneeTypes::Soft: if (2.0 * (input - threshold) < -(kneeWidth)) output = input; else if (2.0 * (std::fabs(input - threshold)) <= kneeWidth) output = input + (((1.0 / ratio) - 1.0) * std::pow((input - threshold + (kneeWidth/ 2.0)), 2.0)) / (2.0 * kneeWidth); else if (2.0 * (input - threshold) > kneeWidth) output = threshold + (input - threshold) / ratio; break; case KneeTypes::Hard: if (input <= threshold) output = input; else output = threshold + (input - threshold) / ratio; break; } SampleType gainReduction_dB = output - input; SampleType gainReduction_Linear = std::pow(10.0, (gainReduction_dB) / 20.0); return gainReduction_Linear; } template class Compressor; template class Compressor;