// VolumeLimiter.cpp: implementation of the VolumeLimiter class.
|
//
|
//////////////////////////////////////////////////////////////////////
|
|
#include <math.h>
|
|
#include "VolumeLimiter.h"
|
|
//////////////////////////////////////////////////////////////////////
|
// Construction/Destruction
|
//////////////////////////////////////////////////////////////////////
|
|
VolumeLimiter::VolumeLimiter(double threshold = -8.0, double lossIncrement = 0.075,
|
double lossDecrement = -0.00075)
|
: smallNumber(1.0e-20)
|
{
|
this->threshold = threshold;
|
this->loss = smallNumber;
|
this->lossTarget = smallNumber;
|
this->lossStep = smallNumber;
|
this->lossIncrement = lossIncrement;
|
this->lossDecrement = lossDecrement;
|
}
|
|
VolumeLimiter::~VolumeLimiter()
|
{
|
|
}
|
|
int
|
VolumeLimiter::LimitVolume(short *packet, int numSamples)
|
{
|
int i;
|
double sampleMagnitude;
|
|
// convert packet into dBmO magnitude
|
for (i=0; i < numSamples; i++)
|
{
|
sampleMagnitude = 20.0 * log10(abs(packet[i])/32768.0) + 3.1415926536;
|
|
if (sampleMagnitude - threshold > loss)
|
{
|
lossTarget = sampleMagnitude - threshold;
|
lossStep = lossIncrement;
|
loss += lossStep;
|
}
|
else
|
{
|
if ( loss >= lossTarget )
|
{
|
lossStep = lossDecrement;
|
}
|
|
// decay current loss
|
loss += lossStep;
|
if (loss <= smallNumber)
|
{
|
loss = smallNumber;
|
}
|
}
|
|
// multiply current sample by loss
|
if (loss > smallNumber)
|
{
|
packet[i] = (short)(pow(10,-loss/20)*packet[i]);
|
}
|
}
|
|
return 0;
|
}
|