/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "rtc_base/checks.h"
#include "common_audio/signal_processing/include/signal_processing_library.h"
#include "common_audio/third_party/fft4g/fft4g.h"
#include "modules/audio_processing/ns/noise_suppression.h"
#include "modules/audio_processing/ns/ns_core.h"
#include "modules/audio_processing/ns/windows_private.h"
// Set Feature Extraction Parameters.
static void set_feature_extraction_parameters(NoiseSuppressionC* self) {
// Bin size of histogram.
self->featureExtractionParams.binSizeLrt = 0.1f;
self->featureExtractionParams.binSizeSpecFlat = 0.05f;
self->featureExtractionParams.binSizeSpecDiff = 0.1f;
// Range of histogram over which LRT threshold is computed.
self->featureExtractionParams.rangeAvgHistLrt = 1.f;
// Scale parameters: multiply dominant peaks of the histograms by scale factor
// to obtain thresholds for prior model.
// For LRT and spectral difference.
self->featureExtractionParams.factor1ModelPars = 1.2f;
// For spectral_flatness: used when noise is flatter than speech.
self->featureExtractionParams.factor2ModelPars = 0.9f;
// Peak limit for spectral flatness (varies between 0 and 1).
self->featureExtractionParams.thresPosSpecFlat = 0.6f;
// Limit on spacing of two highest peaks in histogram: spacing determined by
// bin size.
self->featureExtractionParams.limitPeakSpacingSpecFlat =
2 * self->featureExtractionParams.binSizeSpecFlat;
self->featureExtractionParams.limitPeakSpacingSpecDiff =
2 * self->featureExtractionParams.binSizeSpecDiff;
// Limit on relevance of second peak.
self->featureExtractionParams.limitPeakWeightsSpecFlat = 0.5f;
self->featureExtractionParams.limitPeakWeightsSpecDiff = 0.5f;
// Fluctuation limit of LRT feature.
self->featureExtractionParams.thresFluctLrt = 0.05f;
// Limit on the max and min values for the feature thresholds.
self->featureExtractionParams.maxLrt = 1.f;
self->featureExtractionParams.minLrt = 0.2f;
self->featureExtractionParams.maxSpecFlat = 0.95f;
self->featureExtractionParams.minSpecFlat = 0.1f;
self->featureExtractionParams.maxSpecDiff = 1.f;
self->featureExtractionParams.minSpecDiff = 0.16f;
// Criteria of weight of histogram peak to accept/reject feature.
self->featureExtractionParams.thresWeightSpecFlat =
(int)(0.3 * (self->modelUpdatePars[1])); // For spectral flatness.
self->featureExtractionParams.thresWeightSpecDiff =
(int)(0.3 * (self->modelUpdatePars[1])); // For spectral difference.
}
// Initialize state.
int WebRtcNs_InitCore(NoiseSuppressionC* self, uint32_t fs) {
int i;
// Check for valid pointer.
if (self == NULL) {
return -1;
}
// Initialization of struct.
if (fs == 8000 || fs == 16000 || fs == 32000 || fs == 48000) {
self->fs = fs;
} else {
return -1;
}
self->windShift = 0;
// We only support 10ms frames.
if (fs == 8000) {
self->blockLen = 80;
self->anaLen = 128;
self->window = kBlocks80w128;
} else {
self->blockLen = 160;
self->anaLen = 256;
self->window = kBlocks160w256;
}
self->magnLen = self->anaLen / 2 + 1; // Number of frequency bins.
// Initialize FFT work arrays.
self->ip[0] = 0; // Setting this triggers initialization.
memset(self->dataBuf, 0, sizeof(float) * ANAL_BLOCKL_MAX);
WebRtc_rdft(self->anaLen, 1, self->dataBuf, self->ip, self->wfft);
memset(self->analyzeBuf, 0, sizeof(float) * ANAL_BLOCKL_MAX);
memset(self->dataBuf, 0, sizeof(float) * ANAL_BLOCKL_MAX);
memset(self->syntBuf, 0, sizeof(float) * ANAL_BLOCKL_MAX);
// For HB processing.
memset(self->dataBufHB,
0,
sizeof(float) * NUM_HIGH_BANDS_MAX * ANAL_BLOCKL_MAX);
// For quantile noise estimation.
memset(self->quantile, 0, sizeof(float) * HALF_ANAL_BLOCKL);
for (i = 0; i < SIMULT * HALF_ANAL_BLOCKL; i++) {
self->lquantile[i] = 8.f;
self->density[i] = 0.3f;
}
for (i = 0; i < SIMULT; i++) {
self->counter[i] =
(int)floor((float)(END_STARTUP_LONG * (i + 1)) / (float)SIMULT);
}
self->updates = 0;
// Wiener filter initialization.
for (i = 0; i < HALF_ANAL_BLOCKL; i++) {
self->smooth[i] = 1.f;
}
// Set the aggressiveness: default.
self->aggrMode = 0;
// Initialize variables for new method.
self->priorSpeechProb = 0.5f; // Prior prob for speech/noise.
// Previous analyze mag spectrum.
memset(self->magnPrevAnalyze, 0, sizeof(float) * HALF_ANAL_BLOCKL);
// Previous process mag spectrum.
memset(self->magnPrevProcess, 0, sizeof(float) * HALF_ANAL_BLOCKL);
// Current noise-spectrum.
memset(self->noise, 0, sizeof(float) * HALF_ANAL_BLOCKL);
// Previous noise-spectrum.
memset(self->noisePrev, 0, sizeof(float) * HALF_ANAL_BLOCKL);
// Conservative noise spectrum estimate.
memset(self->magnAvgPause, 0, sizeof(float) * HALF_ANAL_BLOCKL);
// For estimation of HB in second pass.
memset(self->speechProb, 0, sizeof(float) * HALF_ANAL_BLOCKL);
// Initial average magnitude spectrum.
memset(self->initMagnEst, 0, sizeof(float) * HALF_ANAL_BLOCKL);
for (i = 0; i < HALF_ANAL_BLOCKL; i++) {
// Smooth LR (same as threshold).
self->logLrtTimeAvg[i] = LRT_FEATURE_THR;
}
// Feature quantities.
// Spectral flatness (start on threshold).
self->featureData[0] = SF_FEATURE_THR;
self->featureData[1] = 0.f; // Spectral entropy: not used in this version.
self->featureData[2] = 0.f; // Spectral variance: not used in this version.
// Average LRT factor (start on threshold).
self->featureData[3] = LRT_FEATURE_THR;
// Spectral template diff (start on threshold).
self->featureData[4] = SF_FEATURE_THR;
self->featureData[5] = 0.f; // Normalization for spectral difference.
// Window time-average of input magnitude spectrum.
self->featureData[6] = 0.f;
memset(self->parametricNoise, 0, sizeof(float) * HALF_ANAL_BLOCKL);
// Histogram quantities: used to estimate/update thresholds for features.
memset(self->histLrt, 0, sizeof(int) * HIST_PAR_EST);
memset(self->histSpecFlat, 0, sizeof(int) * HIST_PAR_EST);
memset(self->histSpecDiff, 0, sizeof(int) * HIST_PAR_EST);
self->blockInd = -1; // Frame counter.
// Default threshold for LRT feature.
self->priorModelPars[0] = LRT_FEATURE_THR;
// Threshold for spectral flatness: determined on-line.
self->priorModelPars[1] = 0.5f;
// sgn_map par for spectral measure: 1 for flatness measure.
self->priorModelPars[2] = 1.f;
// Threshold for template-difference feature: determined on-line.
self->priorModelPars[3] = 0.5f;
// Default weighting parameter for LRT feature.
self->priorModelPars[4] = 1.f;
// Default weighting parameter for spectral flatness feature.
self->priorModelPars[5] = 0.f;
// Default weighting parameter for spectral difference feature.
self->priorModelPars[6] = 0.f;
// Update flag for parameters:
// 0 no update, 1 = update once, 2 = update every window.
self->modelUpdatePars[0] = 2;
self->modelUpdatePars[1] = 500; // Window for update.
// Counter for update of conservative noise spectrum.
self->modelUpdatePars[2] = 0;
// Counter if the feature thresholds are updated during the sequence.
self->modelUpdatePars[3] = self->modelUpdatePars[1];
self->signalEnergy = 0.0;
self->sumMagn = 0.0;
self->whiteNoiseLevel = 0.0;
self->pinkNoiseNumerator = 0.0;
self->pinkNoiseExp = 0.0;
set_feature_extraction_parameters(self);
// Default mode.
WebRtcNs_set_policy_core(self, 0);
self->initFlag = 1;
return 0;
}
// Estimate noise.
static void Nois