Commit 7ba369bb authored by Alexandre Savard's avatar Alexandre Savard

#5915: Implement different slope for attack tme and release time for gain control

parent 65088111
......@@ -371,6 +371,7 @@ void AudioRtpRecordHandler::processDataDecode (unsigned char *spkrData, unsigned
_audioRtpRecord._spkrFadeInComplete = fadeIn (spkrDataDecoded, nbSample, &_audioRtpRecord._micAmplFactor);
}
// Normalize incomming signal
gainController.process(spkrDataDecoded, nbSample);
// test if resampling is required
......
......@@ -6,14 +6,17 @@
#include "global.h"
#include "gaincontrol.h"
#define SFL_GAIN_ATTACK_RELEASE_TIME 10
#define SFL_GAIN_ATTACK_TIME 10
#define SFL_GAIN_RELEASE_TIME 300
#define SFL_GAIN_LIMITER_RATIO 0.1
#define SFL_GAIN_LIMITER_THRESHOLD 0.6
#define SFL_GAIN_LOGe10 2.30258509299404568402
GainControl::GainControl(double sr, double target) : averager(sr, SFL_GAIN_ATTACK_RELEASE_TIME)
#define DUMP_GAIN_CONTROL_SIGNAL
GainControl::GainControl(double sr, double target) : averager(sr, SFL_GAIN_ATTACK_TIME, SFL_GAIN_RELEASE_TIME)
, limiter(SFL_GAIN_LIMITER_RATIO, SFL_GAIN_LIMITER_THRESHOLD)
, targetGaindB(target)
, targetGainLinear(0.0)
......@@ -48,7 +51,7 @@ void GainControl::process(SFLDataFormat *buf, int bufLength)
out = limiter.limit(in);
#ifdef DUMP_GAIN_CONTROL_SIGNAL
tmpRms.write(retinterpret_cast<char *>(&out), sizeof(double));
tmpOut.write(reinterpret_cast<char *>(&out), sizeof(double));
#endif
buf[i] = (short)(out * (double)SHRT_MAX);
......@@ -62,17 +65,24 @@ double GainControl::RmsDetection::getRms(double in)
return in * in;
}
GainControl::DetectionAverage::DetectionAverage(double sr, double t) :
g(0.0), teta(t), samplingRate(sr), previous_y(0.0)
GainControl::DetectionAverage::DetectionAverage(double sr, double ta, double tr) :
g_a(0.0), teta_a(ta), g_r(0.0), teta_r(tr), samplingRate(sr), previous_y(0.0)
{
g = exp(-1.0 / (samplingRate * (teta / 1000.0)));
g_a = exp(-1.0 / (samplingRate * (teta_a / 1000.0)));
g_r = exp(-1.0 / (samplingRate * (teta_r / 1000.0)));
std::cout << "GainControl: g: " << g << ", teta: " << teta << std::endl;
std::cout << "GainControl: g_attack: " << g_a << ", teta_attack: " << teta_a
<< ", g_release: " << g_r << ", teta_release: " << teta_r << std::endl;
}
double GainControl::DetectionAverage::getAverage(double in)
{
previous_y = ((1.0 - g) * in) + (g * previous_y);
if(in > previous_y) {
previous_y = ((1.0 - g_a) * in) + (g_a * previous_y);
}
else {
previous_y = ((1.0 - g_r) * in) + (g_r * previous_y);
}
return previous_y;
}
......
......@@ -51,8 +51,11 @@ private:
public:
/**
* Constructor for this class
* /param Sampling rate
* /param Attack ramping time
* /param Release ramping time
*/
DetectionAverage(double, double);
DetectionAverage(double, double, double);
/**
* Process average
......@@ -61,14 +64,24 @@ private:
private:
/**
* Average factor
* Average factor for attack
*/
double g;
double g_a;
/**
* Attack and release ramp time (in ms)
* Attack ramp time (in ms)
*/
double teta;
double teta_a;
/**
* Average factor for release
*/
double g_r;
/**
* Release ramp time (in ms)
*/
double teta_r;
/**
* Samplig rate
......
......@@ -55,11 +55,13 @@ SpeexEchoCancel::SpeexEchoCancel()
_micData->createReadPointer();
_spkrData->createReadPointer();
#ifdef DUMP_ECHOCANCEL_INTERNAL_DATA
micFile = new ofstream("test_mic_data.raw");
spkrFile = new ofstream("test_spkr_data.raw");
micProcessFile = new ofstream("test_mic_data_process.raw", std::ofstream::out);
spkrProcessFile = new ofstream("test_spkr_data_process.raw", std::ofstream::out);
echoFile = new ofstream("test_echo_data.raw");
#endif
_spkrStopped = true;
}
......@@ -80,11 +82,13 @@ SpeexEchoCancel::~SpeexEchoCancel()
delete _spkrData;
_spkrData = NULL;
#ifdef DUMP_ECHOCANCEL_INTERNAL_DATA
delete micFile;
delete spkrFile;
delete micProcessFile;
delete spkrProcessFile;
delete echoFile;
#endif
}
......@@ -101,7 +105,9 @@ void SpeexEchoCancel::putData (SFLDataFormat *inputData, int nbBytes)
_spkrStopped = false;
}
#ifdef DUMP_ECHOCANCEL_INTERNAL_DATA
spkrFile->write(reinterpret_cast<char *>(inputData), nbBytes);
#endif
// Put data in speaker ring buffer
_spkrData->Put (inputData, nbBytes);
......@@ -131,7 +137,9 @@ int SpeexEchoCancel::process (SFLDataFormat *inputData, SFLDataFormat *outputDat
memset (_tmpMic, 0, 5000 * sizeof(SFLDataFormat));
memset (_tmpOut, 0, 5000 * sizeof(SFLDataFormat));
#ifdef DUMP_ECHOCANCEL_INTERNAL_DATA
micFile->write(reinterpret_cast<char *>(inputData), nbBytes);
#endif
// Put mic data in ringbuffer
_micData->Put (inputData, nbBytes);
......@@ -153,8 +161,10 @@ int SpeexEchoCancel::process (SFLDataFormat *inputData, SFLDataFormat *outputDat
_spkrData->Get (_tmpSpkr, byteSize);
_micData->Get (_tmpMic, byteSize);
#ifdef DUMP_ECHOCANCEL_INTERNAL_DATA
micProcessFile->write(reinterpret_cast<char *>(_tmpMic), byteSize);
spkrProcessFile->write(reinterpret_cast<char *>(_tmpSpkr), byteSize);
#endif
int32_t tmp;
for(int i = 0; i < nbSamples; i++) {
......@@ -172,7 +182,9 @@ int SpeexEchoCancel::process (SFLDataFormat *inputData, SFLDataFormat *outputDat
speex_echo_cancellation (_echoState, _tmpMic, _tmpSpkr, _tmpOut);
speex_preprocess_run(_preState, reinterpret_cast<short *>(_tmpOut));
#ifdef DUMP_ECHOCANCEL_INTERNAL_DATA
echoFile->write(reinterpret_cast<char *>(_tmpOut), byteSize);
#endif
for(int i = 0; i < nbSamples; i++) {
_tmpOut[i] *= 3;
......
......@@ -85,11 +85,13 @@ class SpeexEchoCancel : public Algorithm
SFLDataFormat _tmpMic[5000];
SFLDataFormat _tmpOut[5000];
#ifdef DUMP_ECHOCANCEL_INTERNAL_DATA
ofstream *micFile;
ofstream *spkrFile;
ofstream *micProcessFile;
ofstream *spkrProcessFile;
ofstream *echoFile;
#endif
};
#endif
......@@ -40,7 +40,9 @@ void GainControlTest::testGainProcessing()
int fileSize;
SFLDataFormat buf[SFL_GAIN_BUFFER_LENGTH];
GainControl gcontrol(8000);
// Sampling rate is 8000
// Target level is 0 dB
GainControl gcontrol(8000, 0.0);
/*
fstream inputFile("testgaininput.raw", fstream::in);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment