Moved the filter calculation from analyze to process in ns_core

It makes sense to have it there if the analyze and process methods are called in different stages.
Tested over the entire QA set for bit exactness.

BUG=webrtc:3811
R=bjornv@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/29549004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@7287 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
aluebs@webrtc.org 2014-09-24 13:23:49 +00:00
parent 634c926928
commit 275dac2c1d
2 changed files with 84 additions and 70 deletions

View File

@ -764,22 +764,18 @@ int WebRtcNs_AnalyzeCore(NSinst_t* inst, float* speechFrame) {
int updateParsFlag;
float energy;
float signalEnergy, sumMagn;
float snrPrior, currentEstimateStsa;
float tmpFloat1, tmpFloat2, tmpFloat3, probSpeech, probNonSpeech;
float gammaNoiseTmp, gammaNoiseOld;
float noiseUpdateTmp, fTmp;
float winData[ANAL_BLOCKL_MAX];
float magn[HALF_ANAL_BLOCKL], noise[HALF_ANAL_BLOCKL];
float theFilter[HALF_ANAL_BLOCKL], theFilterTmp[HALF_ANAL_BLOCKL];
float snrLocPost[HALF_ANAL_BLOCKL], snrLocPrior[HALF_ANAL_BLOCKL];
float previousEstimateStsa[HALF_ANAL_BLOCKL];
float real[ANAL_BLOCKL_MAX], imag[HALF_ANAL_BLOCKL];
// Variables during startup
float sum_log_i = 0.0;
float sum_log_i_square = 0.0;
float sum_log_magn = 0.0;
float sum_log_i_log_magn = 0.0;
float parametric_noise = 0.0;
float parametric_exp = 0.0;
float parametric_num = 0.0;
@ -834,8 +830,6 @@ int WebRtcNs_AnalyzeCore(NSinst_t* inst, float* speechFrame) {
(float)(real[inst->magnLen - 1] * real[inst->magnLen - 1]);
sumMagn = magn[0] + magn[inst->magnLen - 1];
if (inst->blockInd < END_STARTUP_SHORT) {
inst->initMagnEst[0] += magn[0];
inst->initMagnEst[inst->magnLen - 1] += magn[inst->magnLen - 1];
tmpFloat2 = log((float)(inst->magnLen - 1));
sum_log_i = tmpFloat2;
sum_log_i_square = tmpFloat2 * tmpFloat2;
@ -853,7 +847,6 @@ int WebRtcNs_AnalyzeCore(NSinst_t* inst, float* speechFrame) {
magn[i] = ((float)sqrt(fTmp)) + 1.0f;
sumMagn += magn[i];
if (inst->blockInd < END_STARTUP_SHORT) {
inst->initMagnEst[i] += magn[i];
if (i >= kStartBand) {
tmpFloat2 = log((float)i);
sum_log_i += tmpFloat2;
@ -901,31 +894,29 @@ int WebRtcNs_AnalyzeCore(NSinst_t* inst, float* speechFrame) {
inst->pinkNoiseExp += tmpFloat3;
// Calculate frequency independent parts of parametric noise estimate.
if (inst->pinkNoiseExp == 0.0f) {
// Use white noise estimate
parametric_noise = inst->whiteNoiseLevel;
} else {
if (inst->pinkNoiseExp > 0.0f) {
// Use pink noise estimate
parametric_num =
exp(inst->pinkNoiseNumerator / (float)(inst->blockInd + 1));
parametric_num *= (float)(inst->blockInd + 1);
parametric_exp = inst->pinkNoiseExp / (float)(inst->blockInd + 1);
parametric_noise =
parametric_num / pow((float)kStartBand, parametric_exp);
}
for (i = 0; i < inst->magnLen; i++) {
// Estimate the background noise using the white and pink noise
// parameters
if ((inst->pinkNoiseExp > 0.0f) && (i >= kStartBand)) {
if (inst->pinkNoiseExp == 0.0f) {
// Use white noise estimate
inst->parametricNoise[i] = inst->whiteNoiseLevel;
} else {
// Use pink noise estimate
parametric_noise = parametric_num / pow((float)i, parametric_exp);
float use_band = (float)(i < kStartBand ? kStartBand : i);
inst->parametricNoise[i] =
parametric_num / pow(use_band, parametric_exp);
}
theFilterTmp[i] =
(inst->initMagnEst[i] - inst->overdrive * parametric_noise);
theFilterTmp[i] /= (inst->initMagnEst[i] + (float)0.0001);
// Weight quantile noise with modeled noise
noise[i] *= (inst->blockInd);
tmpFloat2 = parametric_noise * (END_STARTUP_SHORT - inst->blockInd);
tmpFloat2 =
inst->parametricNoise[i] * (END_STARTUP_SHORT - inst->blockInd);
noise[i] += (tmpFloat2 / (float)(inst->blockInd + 1));
noise[i] /= END_STARTUP_SHORT;
}
@ -949,12 +940,12 @@ int WebRtcNs_AnalyzeCore(NSinst_t* inst, float* speechFrame) {
}
// previous post snr
// previous estimate: based on previous frame with gain filter
previousEstimateStsa[i] = inst->magnPrev[i] /
inst->previousEstimateStsa[i] = inst->magnPrev[i] /
(inst->noisePrev[i] + (float)0.0001) *
(inst->smooth[i]);
// DD estimate is sum of two terms: current estimate and previous estimate
// directed decision update of snrPrior
snrLocPrior[i] = DD_PR_SNR * previousEstimateStsa[i] +
snrLocPrior[i] = DD_PR_SNR * inst->previousEstimateStsa[i] +
((float)1.0 - DD_PR_SNR) * snrLocPost[i];
// post and prior snr needed for step 2
} // end of loop over freqs
@ -1037,57 +1028,9 @@ int WebRtcNs_AnalyzeCore(NSinst_t* inst, float* speechFrame) {
} // end of freq loop
// done with step 2: noise update
// STEP 3: compute dd update of prior snr and post snr based on new noise
// estimate
for (i = 0; i < inst->magnLen; i++) {
// post and prior snr
currentEstimateStsa = (float)0.0;
if (magn[i] > noise[i]) {
currentEstimateStsa = magn[i] / (noise[i] + (float)0.0001) - (float)1.0;
}
// DD estimate is sume of two terms: current estimate and previous
// estimate
// directed decision update of snrPrior
snrPrior = DD_PR_SNR * previousEstimateStsa[i] +
((float)1.0 - DD_PR_SNR) * currentEstimateStsa;
// gain filter
tmpFloat1 = inst->overdrive + snrPrior;
tmpFloat2 = (float)snrPrior / tmpFloat1;
theFilter[i] = (float)tmpFloat2;
} // end of loop over freqs
// done with step3
for (i = 0; i < inst->magnLen; i++) {
// flooring bottom
if (theFilter[i] < inst->denoiseBound) {
theFilter[i] = inst->denoiseBound;
}
// flooring top
if (theFilter[i] > (float)1.0) {
theFilter[i] = 1.0;
}
if (inst->blockInd < END_STARTUP_SHORT) {
// flooring bottom
if (theFilterTmp[i] < inst->denoiseBound) {
theFilterTmp[i] = inst->denoiseBound;
}
// flooring top
if (theFilterTmp[i] > (float)1.0) {
theFilterTmp[i] = 1.0;
}
// Weight the two suppression filters
theFilter[i] *= (inst->blockInd);
theFilterTmp[i] *= (END_STARTUP_SHORT - inst->blockInd);
theFilter[i] += theFilterTmp[i];
theFilter[i] /= (END_STARTUP_SHORT);
}
// smoothing
inst->smooth[i] = theFilter[i];
}
// keep track of noise and magn spectrum for next frame
// keep track of noise spectrum for next frame
for (i = 0; i < inst->magnLen; i++) {
inst->noisePrev[i] = noise[i];
inst->magnPrev[i] = magn[i];
}
} // end of if inst->outLen == 0
@ -1104,8 +1047,13 @@ int WebRtcNs_ProcessCore(NSinst_t* inst,
int i;
float energy1, energy2, gain, factor, factor1, factor2;
float snrPrior, currentEstimateStsa;
float tmpFloat1, tmpFloat2;
float fTmp;
float fout[BLOCKL_MAX];
float winData[ANAL_BLOCKL_MAX];
float magn[HALF_ANAL_BLOCKL];
float theFilter[HALF_ANAL_BLOCKL], theFilterTmp[HALF_ANAL_BLOCKL];
float real[ANAL_BLOCKL_MAX], imag[HALF_ANAL_BLOCKL];
// SWB variables
@ -1196,17 +1144,81 @@ int WebRtcNs_ProcessCore(NSinst_t* inst,
imag[0] = 0;
real[0] = winData[0];
magn[0] = (float)(fabs(real[0]) + 1.0f);
imag[inst->magnLen - 1] = 0;
real[inst->magnLen - 1] = winData[1];
magn[inst->magnLen - 1] = (float)(fabs(real[inst->magnLen - 1]) + 1.0f);
if (inst->blockInd < END_STARTUP_SHORT) {
inst->initMagnEst[0] += magn[0];
inst->initMagnEst[inst->magnLen - 1] += magn[inst->magnLen - 1];
}
for (i = 1; i < inst->magnLen - 1; i++) {
real[i] = winData[2 * i];
imag[i] = winData[2 * i + 1];
// magnitude spectrum
fTmp = real[i] * real[i];
fTmp += imag[i] * imag[i];
magn[i] = ((float)sqrt(fTmp)) + 1.0f;
if (inst->blockInd < END_STARTUP_SHORT) {
inst->initMagnEst[i] += magn[i];
}
}
// Compute dd update of prior snr and post snr based on new noise estimate
for (i = 0; i < inst->magnLen; i++) {
// post and prior snr
currentEstimateStsa = (float)0.0;
if (magn[i] > inst->noisePrev[i]) {
currentEstimateStsa =
magn[i] / (inst->noisePrev[i] + (float)0.0001) - (float)1.0;
}
// DD estimate is sume of two terms: current estimate and previous
// estimate
// directed decision update of snrPrior
snrPrior = DD_PR_SNR * inst->previousEstimateStsa[i] +
((float)1.0 - DD_PR_SNR) * currentEstimateStsa;
// gain filter
tmpFloat1 = inst->overdrive + snrPrior;
tmpFloat2 = (float)snrPrior / tmpFloat1;
theFilter[i] = (float)tmpFloat2;
} // end of loop over freqs
for (i = 0; i < inst->magnLen; i++) {
// flooring bottom
if (theFilter[i] < inst->denoiseBound) {
theFilter[i] = inst->denoiseBound;
}
// flooring top
if (theFilter[i] > (float)1.0) {
theFilter[i] = 1.0;
}
if (inst->blockInd < END_STARTUP_SHORT) {
theFilterTmp[i] =
(inst->initMagnEst[i] - inst->overdrive * inst->parametricNoise[i]);
theFilterTmp[i] /= (inst->initMagnEst[i] + (float)0.0001);
// flooring bottom
if (theFilterTmp[i] < inst->denoiseBound) {
theFilterTmp[i] = inst->denoiseBound;
}
// flooring top
if (theFilterTmp[i] > (float)1.0) {
theFilterTmp[i] = 1.0;
}
// Weight the two suppression filters
theFilter[i] *= (inst->blockInd);
theFilterTmp[i] *= (END_STARTUP_SHORT - inst->blockInd);
theFilter[i] += theFilterTmp[i];
theFilter[i] /= (END_STARTUP_SHORT);
}
// smoothing
inst->smooth[i] = theFilter[i];
real[i] *= inst->smooth[i];
imag[i] *= inst->smooth[i];
}
// keep track of magn spectrum for next frame
for (i = 0; i < inst->magnLen; i++) {
inst->magnPrev[i] = magn[i];
}
// back to time domain
winData[0] = real[0];
winData[1] = real[inst->magnLen - 1];

View File

@ -72,6 +72,7 @@ typedef struct NSinst_t_ {
int counter[SIMULT];
int updates;
// parameters for Wiener filter
float previousEstimateStsa[HALF_ANAL_BLOCKL];
float smooth[HALF_ANAL_BLOCKL];
float overdrive;
float denoiseBound;
@ -97,6 +98,7 @@ typedef struct NSinst_t_ {
float initMagnEst[HALF_ANAL_BLOCKL]; // initial magnitude spectrum estimate
float pinkNoiseNumerator; // pink noise parameter: numerator
float pinkNoiseExp; // pink noise parameter: power of freq
float parametricNoise[HALF_ANAL_BLOCKL];
NSParaExtract_t featureExtractionParams; // parameters for feature extraction
// histograms for parameter estimation
int histLrt[HIST_PAR_EST];