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:
parent
634c926928
commit
275dac2c1d
@ -764,22 +764,18 @@ int WebRtcNs_AnalyzeCore(NSinst_t* inst, float* speechFrame) {
|
|||||||
int updateParsFlag;
|
int updateParsFlag;
|
||||||
float energy;
|
float energy;
|
||||||
float signalEnergy, sumMagn;
|
float signalEnergy, sumMagn;
|
||||||
float snrPrior, currentEstimateStsa;
|
|
||||||
float tmpFloat1, tmpFloat2, tmpFloat3, probSpeech, probNonSpeech;
|
float tmpFloat1, tmpFloat2, tmpFloat3, probSpeech, probNonSpeech;
|
||||||
float gammaNoiseTmp, gammaNoiseOld;
|
float gammaNoiseTmp, gammaNoiseOld;
|
||||||
float noiseUpdateTmp, fTmp;
|
float noiseUpdateTmp, fTmp;
|
||||||
float winData[ANAL_BLOCKL_MAX];
|
float winData[ANAL_BLOCKL_MAX];
|
||||||
float magn[HALF_ANAL_BLOCKL], noise[HALF_ANAL_BLOCKL];
|
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 snrLocPost[HALF_ANAL_BLOCKL], snrLocPrior[HALF_ANAL_BLOCKL];
|
||||||
float previousEstimateStsa[HALF_ANAL_BLOCKL];
|
|
||||||
float real[ANAL_BLOCKL_MAX], imag[HALF_ANAL_BLOCKL];
|
float real[ANAL_BLOCKL_MAX], imag[HALF_ANAL_BLOCKL];
|
||||||
// Variables during startup
|
// Variables during startup
|
||||||
float sum_log_i = 0.0;
|
float sum_log_i = 0.0;
|
||||||
float sum_log_i_square = 0.0;
|
float sum_log_i_square = 0.0;
|
||||||
float sum_log_magn = 0.0;
|
float sum_log_magn = 0.0;
|
||||||
float sum_log_i_log_magn = 0.0;
|
float sum_log_i_log_magn = 0.0;
|
||||||
float parametric_noise = 0.0;
|
|
||||||
float parametric_exp = 0.0;
|
float parametric_exp = 0.0;
|
||||||
float parametric_num = 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]);
|
(float)(real[inst->magnLen - 1] * real[inst->magnLen - 1]);
|
||||||
sumMagn = magn[0] + magn[inst->magnLen - 1];
|
sumMagn = magn[0] + magn[inst->magnLen - 1];
|
||||||
if (inst->blockInd < END_STARTUP_SHORT) {
|
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));
|
tmpFloat2 = log((float)(inst->magnLen - 1));
|
||||||
sum_log_i = tmpFloat2;
|
sum_log_i = tmpFloat2;
|
||||||
sum_log_i_square = tmpFloat2 * 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;
|
magn[i] = ((float)sqrt(fTmp)) + 1.0f;
|
||||||
sumMagn += magn[i];
|
sumMagn += magn[i];
|
||||||
if (inst->blockInd < END_STARTUP_SHORT) {
|
if (inst->blockInd < END_STARTUP_SHORT) {
|
||||||
inst->initMagnEst[i] += magn[i];
|
|
||||||
if (i >= kStartBand) {
|
if (i >= kStartBand) {
|
||||||
tmpFloat2 = log((float)i);
|
tmpFloat2 = log((float)i);
|
||||||
sum_log_i += tmpFloat2;
|
sum_log_i += tmpFloat2;
|
||||||
@ -901,31 +894,29 @@ int WebRtcNs_AnalyzeCore(NSinst_t* inst, float* speechFrame) {
|
|||||||
inst->pinkNoiseExp += tmpFloat3;
|
inst->pinkNoiseExp += tmpFloat3;
|
||||||
|
|
||||||
// Calculate frequency independent parts of parametric noise estimate.
|
// Calculate frequency independent parts of parametric noise estimate.
|
||||||
if (inst->pinkNoiseExp == 0.0f) {
|
if (inst->pinkNoiseExp > 0.0f) {
|
||||||
// Use white noise estimate
|
|
||||||
parametric_noise = inst->whiteNoiseLevel;
|
|
||||||
} else {
|
|
||||||
// Use pink noise estimate
|
// Use pink noise estimate
|
||||||
parametric_num =
|
parametric_num =
|
||||||
exp(inst->pinkNoiseNumerator / (float)(inst->blockInd + 1));
|
exp(inst->pinkNoiseNumerator / (float)(inst->blockInd + 1));
|
||||||
parametric_num *= (float)(inst->blockInd + 1);
|
parametric_num *= (float)(inst->blockInd + 1);
|
||||||
parametric_exp = inst->pinkNoiseExp / (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++) {
|
for (i = 0; i < inst->magnLen; i++) {
|
||||||
// Estimate the background noise using the white and pink noise
|
// Estimate the background noise using the white and pink noise
|
||||||
// parameters
|
// 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
|
// 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
|
// Weight quantile noise with modeled noise
|
||||||
noise[i] *= (inst->blockInd);
|
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] += (tmpFloat2 / (float)(inst->blockInd + 1));
|
||||||
noise[i] /= END_STARTUP_SHORT;
|
noise[i] /= END_STARTUP_SHORT;
|
||||||
}
|
}
|
||||||
@ -949,12 +940,12 @@ int WebRtcNs_AnalyzeCore(NSinst_t* inst, float* speechFrame) {
|
|||||||
}
|
}
|
||||||
// previous post snr
|
// previous post snr
|
||||||
// previous estimate: based on previous frame with gain filter
|
// 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->noisePrev[i] + (float)0.0001) *
|
||||||
(inst->smooth[i]);
|
(inst->smooth[i]);
|
||||||
// DD estimate is sum of two terms: current estimate and previous estimate
|
// DD estimate is sum of two terms: current estimate and previous estimate
|
||||||
// directed decision update of snrPrior
|
// 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];
|
((float)1.0 - DD_PR_SNR) * snrLocPost[i];
|
||||||
// post and prior snr needed for step 2
|
// post and prior snr needed for step 2
|
||||||
} // end of loop over freqs
|
} // end of loop over freqs
|
||||||
@ -1037,57 +1028,9 @@ int WebRtcNs_AnalyzeCore(NSinst_t* inst, float* speechFrame) {
|
|||||||
} // end of freq loop
|
} // end of freq loop
|
||||||
// done with step 2: noise update
|
// done with step 2: noise update
|
||||||
|
|
||||||
// STEP 3: compute dd update of prior snr and post snr based on new noise
|
// keep track of noise spectrum for next frame
|
||||||
// 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
|
|
||||||
for (i = 0; i < inst->magnLen; i++) {
|
for (i = 0; i < inst->magnLen; i++) {
|
||||||
inst->noisePrev[i] = noise[i];
|
inst->noisePrev[i] = noise[i];
|
||||||
inst->magnPrev[i] = magn[i];
|
|
||||||
}
|
}
|
||||||
} // end of if inst->outLen == 0
|
} // end of if inst->outLen == 0
|
||||||
|
|
||||||
@ -1104,8 +1047,13 @@ int WebRtcNs_ProcessCore(NSinst_t* inst,
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
float energy1, energy2, gain, factor, factor1, factor2;
|
float energy1, energy2, gain, factor, factor1, factor2;
|
||||||
|
float snrPrior, currentEstimateStsa;
|
||||||
|
float tmpFloat1, tmpFloat2;
|
||||||
|
float fTmp;
|
||||||
float fout[BLOCKL_MAX];
|
float fout[BLOCKL_MAX];
|
||||||
float winData[ANAL_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];
|
float real[ANAL_BLOCKL_MAX], imag[HALF_ANAL_BLOCKL];
|
||||||
|
|
||||||
// SWB variables
|
// SWB variables
|
||||||
@ -1196,17 +1144,81 @@ int WebRtcNs_ProcessCore(NSinst_t* inst,
|
|||||||
|
|
||||||
imag[0] = 0;
|
imag[0] = 0;
|
||||||
real[0] = winData[0];
|
real[0] = winData[0];
|
||||||
|
magn[0] = (float)(fabs(real[0]) + 1.0f);
|
||||||
imag[inst->magnLen - 1] = 0;
|
imag[inst->magnLen - 1] = 0;
|
||||||
real[inst->magnLen - 1] = winData[1];
|
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++) {
|
for (i = 1; i < inst->magnLen - 1; i++) {
|
||||||
real[i] = winData[2 * i];
|
real[i] = winData[2 * i];
|
||||||
imag[i] = winData[2 * i + 1];
|
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++) {
|
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];
|
real[i] *= inst->smooth[i];
|
||||||
imag[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
|
// back to time domain
|
||||||
winData[0] = real[0];
|
winData[0] = real[0];
|
||||||
winData[1] = real[inst->magnLen - 1];
|
winData[1] = real[inst->magnLen - 1];
|
||||||
|
@ -72,6 +72,7 @@ typedef struct NSinst_t_ {
|
|||||||
int counter[SIMULT];
|
int counter[SIMULT];
|
||||||
int updates;
|
int updates;
|
||||||
// parameters for Wiener filter
|
// parameters for Wiener filter
|
||||||
|
float previousEstimateStsa[HALF_ANAL_BLOCKL];
|
||||||
float smooth[HALF_ANAL_BLOCKL];
|
float smooth[HALF_ANAL_BLOCKL];
|
||||||
float overdrive;
|
float overdrive;
|
||||||
float denoiseBound;
|
float denoiseBound;
|
||||||
@ -97,6 +98,7 @@ typedef struct NSinst_t_ {
|
|||||||
float initMagnEst[HALF_ANAL_BLOCKL]; // initial magnitude spectrum estimate
|
float initMagnEst[HALF_ANAL_BLOCKL]; // initial magnitude spectrum estimate
|
||||||
float pinkNoiseNumerator; // pink noise parameter: numerator
|
float pinkNoiseNumerator; // pink noise parameter: numerator
|
||||||
float pinkNoiseExp; // pink noise parameter: power of freq
|
float pinkNoiseExp; // pink noise parameter: power of freq
|
||||||
|
float parametricNoise[HALF_ANAL_BLOCKL];
|
||||||
NSParaExtract_t featureExtractionParams; // parameters for feature extraction
|
NSParaExtract_t featureExtractionParams; // parameters for feature extraction
|
||||||
// histograms for parameter estimation
|
// histograms for parameter estimation
|
||||||
int histLrt[HIST_PAR_EST];
|
int histLrt[HIST_PAR_EST];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user