Refactoring AEC: AecCore struct made private
* Added aec_core_internal.h for private variables. * Moved aec_t struct to aec_core_internal.h * Name change aec_t -> AecCore * Moved additional declarations to aec_core_internal.h * Tested with audioproc_unittest and trybots TEST=none BUG=none Review URL: https://webrtc-codereview.appspot.com/1117004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@3553 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
71e91f3b64
commit
56a9ec30e9
@ -21,6 +21,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
|
||||
#include "webrtc/modules/audio_processing/aec/aec_core_internal.h"
|
||||
#include "webrtc/modules/audio_processing/aec/aec_rdft.h"
|
||||
#include "webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h"
|
||||
#include "webrtc/modules/audio_processing/utility/ring_buffer.h"
|
||||
@ -115,22 +116,22 @@ extern int webrtc_aec_instance_count;
|
||||
#endif
|
||||
|
||||
// "Private" function prototypes.
|
||||
static void ProcessBlock(aec_t* aec);
|
||||
static void ProcessBlock(AecCore* aec);
|
||||
|
||||
static void NonLinearProcessing(aec_t *aec, short *output, short *outputH);
|
||||
static void NonLinearProcessing(AecCore* aec, short *output, short *outputH);
|
||||
|
||||
static void GetHighbandGain(const float *lambda, float *nlpGainHband);
|
||||
|
||||
// Comfort_noise also computes noise for H band returned in comfortNoiseHband
|
||||
static void ComfortNoise(aec_t *aec, float efw[2][PART_LEN1],
|
||||
static void ComfortNoise(AecCore* aec, float efw[2][PART_LEN1],
|
||||
complex_t *comfortNoiseHband,
|
||||
const float *noisePow, const float *lambda);
|
||||
|
||||
static void InitLevel(PowerLevel* level);
|
||||
static void InitStats(Stats* stats);
|
||||
static void InitMetrics(aec_t *aec);
|
||||
static void InitMetrics(AecCore* aec);
|
||||
static void UpdateLevel(PowerLevel* level, float in[2][PART_LEN1]);
|
||||
static void UpdateMetrics(aec_t *aec);
|
||||
static void UpdateMetrics(AecCore* aec);
|
||||
// Convert from time domain to frequency domain. Note that |time_data| are
|
||||
// overwritten.
|
||||
static void TimeToFrequency(float time_data[PART_LEN2],
|
||||
@ -155,9 +156,9 @@ static int CmpFloat(const void *a, const void *b)
|
||||
return (*da > *db) - (*da < *db);
|
||||
}
|
||||
|
||||
int WebRtcAec_CreateAec(aec_t **aecInst)
|
||||
int WebRtcAec_CreateAec(AecCore** aecInst)
|
||||
{
|
||||
aec_t *aec = malloc(sizeof(aec_t));
|
||||
AecCore* aec = malloc(sizeof(AecCore));
|
||||
*aecInst = aec;
|
||||
if (aec == NULL) {
|
||||
return -1;
|
||||
@ -246,7 +247,7 @@ int WebRtcAec_CreateAec(aec_t **aecInst)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WebRtcAec_FreeAec(aec_t *aec)
|
||||
int WebRtcAec_FreeAec(AecCore* aec)
|
||||
{
|
||||
if (aec == NULL) {
|
||||
return -1;
|
||||
@ -274,7 +275,7 @@ int WebRtcAec_FreeAec(aec_t *aec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void FilterFar(aec_t *aec, float yf[2][PART_LEN1])
|
||||
static void FilterFar(AecCore* aec, float yf[2][PART_LEN1])
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < NR_PART; i++) {
|
||||
@ -295,7 +296,7 @@ static void FilterFar(aec_t *aec, float yf[2][PART_LEN1])
|
||||
}
|
||||
}
|
||||
|
||||
static void ScaleErrorSignal(aec_t *aec, float ef[2][PART_LEN1])
|
||||
static void ScaleErrorSignal(AecCore* aec, float ef[2][PART_LEN1])
|
||||
{
|
||||
int i;
|
||||
float absEf;
|
||||
@ -318,7 +319,7 @@ static void ScaleErrorSignal(aec_t *aec, float ef[2][PART_LEN1])
|
||||
|
||||
// Time-unconstrined filter adaptation.
|
||||
// TODO(andrew): consider for a low-complexity mode.
|
||||
//static void FilterAdaptationUnconstrained(aec_t *aec, float *fft,
|
||||
//static void FilterAdaptationUnconstrained(AecCore* aec, float *fft,
|
||||
// float ef[2][PART_LEN1]) {
|
||||
// int i, j;
|
||||
// for (i = 0; i < NR_PART; i++) {
|
||||
@ -342,7 +343,7 @@ static void ScaleErrorSignal(aec_t *aec, float ef[2][PART_LEN1])
|
||||
// }
|
||||
//}
|
||||
|
||||
static void FilterAdaptation(aec_t *aec, float *fft, float ef[2][PART_LEN1]) {
|
||||
static void FilterAdaptation(AecCore* aec, float *fft, float ef[2][PART_LEN1]) {
|
||||
int i, j;
|
||||
for (i = 0; i < NR_PART; i++) {
|
||||
int xPos = (i + aec->xfBufBlockPos)*(PART_LEN1);
|
||||
@ -389,7 +390,7 @@ static void FilterAdaptation(aec_t *aec, float *fft, float ef[2][PART_LEN1]) {
|
||||
}
|
||||
}
|
||||
|
||||
static void OverdriveAndSuppress(aec_t *aec, float hNl[PART_LEN1],
|
||||
static void OverdriveAndSuppress(AecCore* aec, float hNl[PART_LEN1],
|
||||
const float hNlFb,
|
||||
float efw[2][PART_LEN1]) {
|
||||
int i;
|
||||
@ -416,7 +417,7 @@ WebRtcAec_ScaleErrorSignal_t WebRtcAec_ScaleErrorSignal;
|
||||
WebRtcAec_FilterAdaptation_t WebRtcAec_FilterAdaptation;
|
||||
WebRtcAec_OverdriveAndSuppress_t WebRtcAec_OverdriveAndSuppress;
|
||||
|
||||
int WebRtcAec_InitAec(aec_t *aec, int sampFreq)
|
||||
int WebRtcAec_InitAec(AecCore* aec, int sampFreq)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -564,7 +565,7 @@ int WebRtcAec_InitAec(aec_t *aec, int sampFreq)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WebRtcAec_BufferFarendPartition(aec_t *aec, const float* farend) {
|
||||
void WebRtcAec_BufferFarendPartition(AecCore* aec, const float* farend) {
|
||||
float fft[PART_LEN2];
|
||||
float xf[2][PART_LEN1];
|
||||
|
||||
@ -583,7 +584,7 @@ void WebRtcAec_BufferFarendPartition(aec_t *aec, const float* farend) {
|
||||
WebRtc_WriteBuffer(aec->far_buf_windowed, &xf[0][0], 1);
|
||||
}
|
||||
|
||||
int WebRtcAec_MoveFarReadPtr(aec_t *aec, int elements) {
|
||||
int WebRtcAec_MoveFarReadPtr(AecCore* aec, int elements) {
|
||||
int elements_moved = WebRtc_MoveReadPtr(aec->far_buf_windowed, elements);
|
||||
WebRtc_MoveReadPtr(aec->far_buf, elements);
|
||||
#ifdef WEBRTC_AEC_DEBUG_DUMP
|
||||
@ -593,7 +594,7 @@ int WebRtcAec_MoveFarReadPtr(aec_t *aec, int elements) {
|
||||
return elements_moved;
|
||||
}
|
||||
|
||||
void WebRtcAec_ProcessFrame(aec_t* aec,
|
||||
void WebRtcAec_ProcessFrame(AecCore* aec,
|
||||
const short* nearend,
|
||||
const short* nearendH,
|
||||
int knownDelay,
|
||||
@ -679,7 +680,7 @@ void WebRtcAec_ProcessFrame(aec_t* aec,
|
||||
}
|
||||
}
|
||||
|
||||
int WebRtcAec_GetDelayMetricsCore(aec_t* self, int* median, int* std) {
|
||||
int WebRtcAec_GetDelayMetricsCore(AecCore* self, int* median, int* std) {
|
||||
int i = 0;
|
||||
int delay_values = 0;
|
||||
int num_delay_values = 0;
|
||||
@ -733,12 +734,12 @@ int WebRtcAec_GetDelayMetricsCore(aec_t* self, int* median, int* std) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WebRtcAec_echo_state(aec_t* self) {
|
||||
int WebRtcAec_echo_state(AecCore* self) {
|
||||
assert(self != NULL);
|
||||
return self->echoState;
|
||||
}
|
||||
|
||||
void WebRtcAec_GetEchoStats(aec_t* self, Stats* erl, Stats* erle,
|
||||
void WebRtcAec_GetEchoStats(AecCore* self, Stats* erl, Stats* erle,
|
||||
Stats* a_nlp) {
|
||||
assert(self != NULL);
|
||||
assert(erl != NULL);
|
||||
@ -750,13 +751,13 @@ void WebRtcAec_GetEchoStats(aec_t* self, Stats* erl, Stats* erle,
|
||||
}
|
||||
|
||||
#ifdef WEBRTC_AEC_DEBUG_DUMP
|
||||
void* WebRtcAec_far_time_buf(aec_t* self) {
|
||||
void* WebRtcAec_far_time_buf(AecCore* self) {
|
||||
assert(self != NULL);
|
||||
return self->far_time_buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
void WebRtcAec_SetConfigCore(aec_t* self, int nlp_mode, int metrics_mode,
|
||||
void WebRtcAec_SetConfigCore(AecCore* self, int nlp_mode, int metrics_mode,
|
||||
int delay_logging) {
|
||||
assert(self != NULL);
|
||||
assert(nlp_mode >= 0 && nlp_mode < 3);
|
||||
@ -771,18 +772,18 @@ void WebRtcAec_SetConfigCore(aec_t* self, int nlp_mode, int metrics_mode,
|
||||
}
|
||||
}
|
||||
|
||||
int WebRtcAec_system_delay(aec_t* self) {
|
||||
int WebRtcAec_system_delay(AecCore* self) {
|
||||
assert(self != NULL);
|
||||
return self->system_delay;
|
||||
}
|
||||
|
||||
void WebRtcAec_SetSystemDelay(aec_t* self, int delay) {
|
||||
void WebRtcAec_SetSystemDelay(AecCore* self, int delay) {
|
||||
assert(self != NULL);
|
||||
assert(delay >= 0);
|
||||
self->system_delay = delay;
|
||||
}
|
||||
|
||||
static void ProcessBlock(aec_t* aec) {
|
||||
static void ProcessBlock(AecCore* aec) {
|
||||
int i;
|
||||
float d[PART_LEN], y[PART_LEN], e[PART_LEN], dH[PART_LEN];
|
||||
float scale;
|
||||
@ -1001,7 +1002,7 @@ static void ProcessBlock(aec_t* aec) {
|
||||
#endif
|
||||
}
|
||||
|
||||
static void NonLinearProcessing(aec_t *aec, short *output, short *outputH)
|
||||
static void NonLinearProcessing(AecCore* aec, short *output, short *outputH)
|
||||
{
|
||||
float efw[2][PART_LEN1], dfw[2][PART_LEN1], xfw[2][PART_LEN1];
|
||||
complex_t comfortNoiseHband[PART_LEN1];
|
||||
@ -1355,7 +1356,7 @@ static void GetHighbandGain(const float *lambda, float *nlpGainHband)
|
||||
nlpGainHband[0] /= (float)(PART_LEN1 - 1 - freqAvgIc);
|
||||
}
|
||||
|
||||
static void ComfortNoise(aec_t *aec, float efw[2][PART_LEN1],
|
||||
static void ComfortNoise(AecCore* aec, float efw[2][PART_LEN1],
|
||||
complex_t *comfortNoiseHband, const float *noisePow, const float *lambda)
|
||||
{
|
||||
int i, num;
|
||||
@ -1464,7 +1465,7 @@ static void InitStats(Stats* stats) {
|
||||
stats->hicounter = 0;
|
||||
}
|
||||
|
||||
static void InitMetrics(aec_t* self) {
|
||||
static void InitMetrics(AecCore* self) {
|
||||
assert(self != NULL);
|
||||
self->stateCounter = 0;
|
||||
InitLevel(&self->farlevel);
|
||||
@ -1537,7 +1538,7 @@ static void UpdateLevel(PowerLevel* level, float in[2][PART_LEN1]) {
|
||||
}
|
||||
}
|
||||
|
||||
static void UpdateMetrics(aec_t *aec)
|
||||
static void UpdateMetrics(AecCore* aec)
|
||||
{
|
||||
float dtmp, dtmp2;
|
||||
|
||||
|
@ -15,10 +15,6 @@
|
||||
#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AEC_AEC_CORE_H_
|
||||
#define WEBRTC_MODULES_AUDIO_PROCESSING_AEC_AEC_CORE_H_
|
||||
|
||||
#ifdef WEBRTC_AEC_DEBUG_DUMP
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include "webrtc/typedefs.h"
|
||||
|
||||
#define FRAME_LEN 80
|
||||
@ -45,16 +41,6 @@ typedef float complex_t[2];
|
||||
// Metrics
|
||||
enum { kOffsetLevel = -100 };
|
||||
|
||||
typedef struct PowerLevel {
|
||||
float sfrsum;
|
||||
int sfrcounter;
|
||||
float framelevel;
|
||||
float frsum;
|
||||
int frcounter;
|
||||
float minlevel;
|
||||
float averagelevel;
|
||||
} PowerLevel;
|
||||
|
||||
typedef struct Stats {
|
||||
float instant;
|
||||
float average;
|
||||
@ -67,112 +53,24 @@ typedef struct Stats {
|
||||
int hicounter;
|
||||
} Stats;
|
||||
|
||||
typedef struct {
|
||||
int farBufWritePos, farBufReadPos;
|
||||
typedef struct AecCore AecCore;
|
||||
|
||||
int knownDelay;
|
||||
int inSamples, outSamples;
|
||||
int delayEstCtr;
|
||||
|
||||
void *nearFrBuf, *outFrBuf;
|
||||
|
||||
void *nearFrBufH;
|
||||
void *outFrBufH;
|
||||
|
||||
float dBuf[PART_LEN2]; // nearend
|
||||
float eBuf[PART_LEN2]; // error
|
||||
|
||||
float dBufH[PART_LEN2]; // nearend
|
||||
|
||||
float xPow[PART_LEN1];
|
||||
float dPow[PART_LEN1];
|
||||
float dMinPow[PART_LEN1];
|
||||
float dInitMinPow[PART_LEN1];
|
||||
float *noisePow;
|
||||
|
||||
float xfBuf[2][NR_PART * PART_LEN1]; // farend fft buffer
|
||||
float wfBuf[2][NR_PART * PART_LEN1]; // filter fft
|
||||
complex_t sde[PART_LEN1]; // cross-psd of nearend and error
|
||||
complex_t sxd[PART_LEN1]; // cross-psd of farend and nearend
|
||||
complex_t xfwBuf[NR_PART * PART_LEN1]; // farend windowed fft buffer
|
||||
|
||||
float sx[PART_LEN1], sd[PART_LEN1], se[PART_LEN1]; // far, near, error psd
|
||||
float hNs[PART_LEN1];
|
||||
float hNlFbMin, hNlFbLocalMin;
|
||||
float hNlXdAvgMin;
|
||||
int hNlNewMin, hNlMinCtr;
|
||||
float overDrive, overDriveSm;
|
||||
int nlp_mode;
|
||||
float outBuf[PART_LEN];
|
||||
int delayIdx;
|
||||
|
||||
short stNearState, echoState;
|
||||
short divergeState;
|
||||
|
||||
int xfBufBlockPos;
|
||||
|
||||
void* far_buf;
|
||||
void* far_buf_windowed;
|
||||
int system_delay; // Current system delay buffered in AEC.
|
||||
|
||||
int mult; // sampling frequency multiple
|
||||
int sampFreq;
|
||||
WebRtc_UWord32 seed;
|
||||
|
||||
float mu; // stepsize
|
||||
float errThresh; // error threshold
|
||||
|
||||
int noiseEstCtr;
|
||||
|
||||
PowerLevel farlevel;
|
||||
PowerLevel nearlevel;
|
||||
PowerLevel linoutlevel;
|
||||
PowerLevel nlpoutlevel;
|
||||
|
||||
int metricsMode;
|
||||
int stateCounter;
|
||||
Stats erl;
|
||||
Stats erle;
|
||||
Stats aNlp;
|
||||
Stats rerl;
|
||||
|
||||
// Quantities to control H band scaling for SWB input
|
||||
int freq_avg_ic; // initial bin for averaging nlp gain
|
||||
int flag_Hband_cn; // for comfort noise
|
||||
float cn_scale_Hband; // scale for comfort noise in H band
|
||||
|
||||
int delay_histogram[kHistorySizeBlocks];
|
||||
int delay_logging_enabled;
|
||||
void* delay_estimator_farend;
|
||||
void* delay_estimator;
|
||||
|
||||
#ifdef WEBRTC_AEC_DEBUG_DUMP
|
||||
void* far_time_buf;
|
||||
FILE *farFile;
|
||||
FILE *nearFile;
|
||||
FILE *outFile;
|
||||
FILE *outLinearFile;
|
||||
#endif
|
||||
} aec_t;
|
||||
|
||||
typedef void (*WebRtcAec_FilterFar_t)(aec_t *aec, float yf[2][PART_LEN1]);
|
||||
extern WebRtcAec_FilterFar_t WebRtcAec_FilterFar;
|
||||
typedef void (*WebRtcAec_ScaleErrorSignal_t)(aec_t *aec, float ef[2][PART_LEN1]);
|
||||
extern WebRtcAec_ScaleErrorSignal_t WebRtcAec_ScaleErrorSignal;
|
||||
typedef void (*WebRtcAec_FilterFar_t)(AecCore* aec, float yf[2][PART_LEN1]);
|
||||
typedef void (*WebRtcAec_ScaleErrorSignal_t)
|
||||
(AecCore* aec, float ef[2][PART_LEN1]);
|
||||
typedef void (*WebRtcAec_FilterAdaptation_t)
|
||||
(aec_t *aec, float *fft, float ef[2][PART_LEN1]);
|
||||
extern WebRtcAec_FilterAdaptation_t WebRtcAec_FilterAdaptation;
|
||||
(AecCore* aec, float *fft, float ef[2][PART_LEN1]);
|
||||
typedef void (*WebRtcAec_OverdriveAndSuppress_t)
|
||||
(aec_t *aec, float hNl[PART_LEN1], const float hNlFb, float efw[2][PART_LEN1]);
|
||||
extern WebRtcAec_OverdriveAndSuppress_t WebRtcAec_OverdriveAndSuppress;
|
||||
(AecCore* aec, float hNl[PART_LEN1], const float hNlFb,
|
||||
float efw[2][PART_LEN1]);
|
||||
|
||||
int WebRtcAec_CreateAec(aec_t **aec);
|
||||
int WebRtcAec_FreeAec(aec_t *aec);
|
||||
int WebRtcAec_InitAec(aec_t *aec, int sampFreq);
|
||||
int WebRtcAec_CreateAec(AecCore** aec);
|
||||
int WebRtcAec_FreeAec(AecCore* aec);
|
||||
int WebRtcAec_InitAec(AecCore* aec, int sampFreq);
|
||||
void WebRtcAec_InitAec_SSE2(void);
|
||||
|
||||
void WebRtcAec_BufferFarendPartition(aec_t *aec, const float* farend);
|
||||
void WebRtcAec_ProcessFrame(aec_t* aec,
|
||||
void WebRtcAec_BufferFarendPartition(AecCore* aec, const float* farend);
|
||||
void WebRtcAec_ProcessFrame(AecCore* aec,
|
||||
const short* nearend,
|
||||
const short* nearendH,
|
||||
int knownDelay,
|
||||
@ -182,26 +80,27 @@ void WebRtcAec_ProcessFrame(aec_t* aec,
|
||||
// A helper function to call WebRtc_MoveReadPtr() for all far-end buffers.
|
||||
// Returns the number of elements moved, and adjusts |system_delay| by the
|
||||
// corresponding amount in ms.
|
||||
int WebRtcAec_MoveFarReadPtr(aec_t* aec, int elements);
|
||||
int WebRtcAec_MoveFarReadPtr(AecCore* aec, int elements);
|
||||
// Calculates the median and standard deviation among the delay estimates
|
||||
// collected since the last call to this function.
|
||||
int WebRtcAec_GetDelayMetricsCore(aec_t* self, int* median, int* std);
|
||||
int WebRtcAec_GetDelayMetricsCore(AecCore* self, int* median, int* std);
|
||||
// Returns the echo state (1: echo, 0: no echo).
|
||||
int WebRtcAec_echo_state(aec_t* self);
|
||||
int WebRtcAec_echo_state(AecCore* self);
|
||||
// Gets statistics of the echo metrics ERL, ERLE, A_NLP.
|
||||
void WebRtcAec_GetEchoStats(aec_t* self, Stats* erl, Stats* erle, Stats* a_nlp);
|
||||
void WebRtcAec_GetEchoStats(AecCore* self, Stats* erl, Stats* erle,
|
||||
Stats* a_nlp);
|
||||
#ifdef WEBRTC_AEC_DEBUG_DUMP
|
||||
void* WebRtcAec_far_time_buf(aec_t* self);
|
||||
void* WebRtcAec_far_time_buf(AecCore* self);
|
||||
#endif
|
||||
// Sets local configuration modes.
|
||||
void WebRtcAec_SetConfigCore(aec_t* self, int nlp_mode, int metrics_mode,
|
||||
void WebRtcAec_SetConfigCore(AecCore* self, int nlp_mode, int metrics_mode,
|
||||
int delay_logging);
|
||||
// Returns the current |system_delay|, i.e., the buffered difference between
|
||||
// far-end and near-end.
|
||||
int WebRtcAec_system_delay(aec_t* self);
|
||||
int WebRtcAec_system_delay(AecCore* self);
|
||||
// Sets the |system_delay| to |value|. Note that if the value is changed
|
||||
// improperly, there can be a performance regression. So it should be used with
|
||||
// care.
|
||||
void WebRtcAec_SetSystemDelay(aec_t* self, int delay);
|
||||
void WebRtcAec_SetSystemDelay(AecCore* self, int delay);
|
||||
|
||||
#endif // WEBRTC_MODULES_AUDIO_PROCESSING_AEC_AEC_CORE_H_
|
||||
|
125
webrtc/modules/audio_processing/aec/aec_core_internal.h
Normal file
125
webrtc/modules/audio_processing/aec/aec_core_internal.h
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2013 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.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AEC_AEC_CORE_INTERNAL_H_
|
||||
#define WEBRTC_MODULES_AUDIO_PROCESSING_AEC_AEC_CORE_INTERNAL_H_
|
||||
|
||||
#include "webrtc/modules/audio_processing/aec/aec_core.h"
|
||||
|
||||
#ifdef WEBRTC_AEC_DEBUG_DUMP
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include "webrtc/typedefs.h"
|
||||
|
||||
typedef struct PowerLevel {
|
||||
float sfrsum;
|
||||
int sfrcounter;
|
||||
float framelevel;
|
||||
float frsum;
|
||||
int frcounter;
|
||||
float minlevel;
|
||||
float averagelevel;
|
||||
} PowerLevel;
|
||||
|
||||
struct AecCore {
|
||||
int farBufWritePos, farBufReadPos;
|
||||
|
||||
int knownDelay;
|
||||
int inSamples, outSamples;
|
||||
int delayEstCtr;
|
||||
|
||||
void *nearFrBuf, *outFrBuf;
|
||||
|
||||
void *nearFrBufH;
|
||||
void *outFrBufH;
|
||||
|
||||
float dBuf[PART_LEN2]; // nearend
|
||||
float eBuf[PART_LEN2]; // error
|
||||
|
||||
float dBufH[PART_LEN2]; // nearend
|
||||
|
||||
float xPow[PART_LEN1];
|
||||
float dPow[PART_LEN1];
|
||||
float dMinPow[PART_LEN1];
|
||||
float dInitMinPow[PART_LEN1];
|
||||
float *noisePow;
|
||||
|
||||
float xfBuf[2][NR_PART * PART_LEN1]; // farend fft buffer
|
||||
float wfBuf[2][NR_PART * PART_LEN1]; // filter fft
|
||||
complex_t sde[PART_LEN1]; // cross-psd of nearend and error
|
||||
complex_t sxd[PART_LEN1]; // cross-psd of farend and nearend
|
||||
complex_t xfwBuf[NR_PART * PART_LEN1]; // farend windowed fft buffer
|
||||
|
||||
float sx[PART_LEN1], sd[PART_LEN1], se[PART_LEN1]; // far, near, error psd
|
||||
float hNs[PART_LEN1];
|
||||
float hNlFbMin, hNlFbLocalMin;
|
||||
float hNlXdAvgMin;
|
||||
int hNlNewMin, hNlMinCtr;
|
||||
float overDrive, overDriveSm;
|
||||
int nlp_mode;
|
||||
float outBuf[PART_LEN];
|
||||
int delayIdx;
|
||||
|
||||
short stNearState, echoState;
|
||||
short divergeState;
|
||||
|
||||
int xfBufBlockPos;
|
||||
|
||||
void* far_buf;
|
||||
void* far_buf_windowed;
|
||||
int system_delay; // Current system delay buffered in AEC.
|
||||
|
||||
int mult; // sampling frequency multiple
|
||||
int sampFreq;
|
||||
WebRtc_UWord32 seed;
|
||||
|
||||
float mu; // stepsize
|
||||
float errThresh; // error threshold
|
||||
|
||||
int noiseEstCtr;
|
||||
|
||||
PowerLevel farlevel;
|
||||
PowerLevel nearlevel;
|
||||
PowerLevel linoutlevel;
|
||||
PowerLevel nlpoutlevel;
|
||||
|
||||
int metricsMode;
|
||||
int stateCounter;
|
||||
Stats erl;
|
||||
Stats erle;
|
||||
Stats aNlp;
|
||||
Stats rerl;
|
||||
|
||||
// Quantities to control H band scaling for SWB input
|
||||
int freq_avg_ic; // initial bin for averaging nlp gain
|
||||
int flag_Hband_cn; // for comfort noise
|
||||
float cn_scale_Hband; // scale for comfort noise in H band
|
||||
|
||||
int delay_histogram[kHistorySizeBlocks];
|
||||
int delay_logging_enabled;
|
||||
void* delay_estimator_farend;
|
||||
void* delay_estimator;
|
||||
|
||||
#ifdef WEBRTC_AEC_DEBUG_DUMP
|
||||
void* far_time_buf;
|
||||
FILE *farFile;
|
||||
FILE *nearFile;
|
||||
FILE *outFile;
|
||||
FILE *outLinearFile;
|
||||
#endif
|
||||
};
|
||||
|
||||
extern WebRtcAec_FilterFar_t WebRtcAec_FilterFar;
|
||||
extern WebRtcAec_ScaleErrorSignal_t WebRtcAec_ScaleErrorSignal;
|
||||
extern WebRtcAec_FilterAdaptation_t WebRtcAec_FilterAdaptation;
|
||||
extern WebRtcAec_OverdriveAndSuppress_t WebRtcAec_OverdriveAndSuppress;
|
||||
|
||||
#endif // WEBRTC_MODULES_AUDIO_PROCESSING_AEC_AEC_CORE_INTERNAL_H_
|
@ -12,13 +12,14 @@
|
||||
* The core AEC algorithm, SSE2 version of speed-critical functions.
|
||||
*/
|
||||
|
||||
#include "aec_core.h"
|
||||
#include "webrtc/modules/audio_processing/aec/aec_core.h"
|
||||
|
||||
#include <emmintrin.h>
|
||||
#include <math.h>
|
||||
#include <string.h> // memset
|
||||
|
||||
#include "aec_rdft.h"
|
||||
#include "webrtc/modules/audio_processing/aec/aec_core_internal.h"
|
||||
#include "webrtc/modules/audio_processing/aec/aec_rdft.h"
|
||||
|
||||
__inline static float MulRe(float aRe, float aIm, float bRe, float bIm)
|
||||
{
|
||||
@ -30,7 +31,7 @@ __inline static float MulIm(float aRe, float aIm, float bRe, float bIm)
|
||||
return aRe * bIm + aIm * bRe;
|
||||
}
|
||||
|
||||
static void FilterFarSSE2(aec_t *aec, float yf[2][PART_LEN1])
|
||||
static void FilterFarSSE2(AecCore* aec, float yf[2][PART_LEN1])
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < NR_PART; i++) {
|
||||
@ -71,7 +72,7 @@ static void FilterFarSSE2(aec_t *aec, float yf[2][PART_LEN1])
|
||||
}
|
||||
}
|
||||
|
||||
static void ScaleErrorSignalSSE2(aec_t *aec, float ef[2][PART_LEN1])
|
||||
static void ScaleErrorSignalSSE2(AecCore* aec, float ef[2][PART_LEN1])
|
||||
{
|
||||
const __m128 k1e_10f = _mm_set1_ps(1e-10f);
|
||||
const __m128 kThresh = _mm_set1_ps(aec->errThresh);
|
||||
@ -127,7 +128,7 @@ static void ScaleErrorSignalSSE2(aec_t *aec, float ef[2][PART_LEN1])
|
||||
}
|
||||
}
|
||||
|
||||
static void FilterAdaptationSSE2(aec_t *aec, float *fft, float ef[2][PART_LEN1]) {
|
||||
static void FilterAdaptationSSE2(AecCore* aec, float *fft, float ef[2][PART_LEN1]) {
|
||||
int i, j;
|
||||
for (i = 0; i < NR_PART; i++) {
|
||||
int xPos = (i + aec->xfBufBlockPos)*(PART_LEN1);
|
||||
@ -340,7 +341,7 @@ static __m128 mm_pow_ps(__m128 a, __m128 b)
|
||||
extern const float WebRtcAec_weightCurve[65];
|
||||
extern const float WebRtcAec_overDriveCurve[65];
|
||||
|
||||
static void OverdriveAndSuppressSSE2(aec_t *aec, float hNl[PART_LEN1],
|
||||
static void OverdriveAndSuppressSSE2(AecCore* aec, float hNl[PART_LEN1],
|
||||
const float hNlFb,
|
||||
float efw[2][PART_LEN1]) {
|
||||
int i;
|
||||
|
@ -61,7 +61,7 @@ typedef struct {
|
||||
|
||||
int lastError;
|
||||
|
||||
aec_t* aec;
|
||||
AecCore* aec;
|
||||
} aecpc_t;
|
||||
|
||||
#endif // WEBRTC_MODULES_AUDIO_PROCESSING_AEC_ECHO_CANCELLATION_INTERNAL_H_
|
||||
|
@ -41,6 +41,7 @@
|
||||
'aec/echo_cancellation_internal.h',
|
||||
'aec/aec_core.h',
|
||||
'aec/aec_core.c',
|
||||
'aec/aec_core_internal.h',
|
||||
'aec/aec_rdft.h',
|
||||
'aec/aec_rdft.c',
|
||||
'aec/aec_resampler.h',
|
||||
|
Loading…
Reference in New Issue
Block a user