aecm_core.h revision 14b43beb7ce4440b30dcea31196de5b4a529cb6b
1/* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11// Performs echo control (suppression) with fft routines in fixed-point 12 13#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AECM_AECM_CORE_H_ 14#define WEBRTC_MODULES_AUDIO_PROCESSING_AECM_AECM_CORE_H_ 15 16#include "typedefs.h" 17#include "signal_processing_library.h" 18 19#include "aecm_defines.h" 20 21#ifdef _MSC_VER // visual c++ 22#define ALIGN8_BEG __declspec(align(8)) 23#define ALIGN8_END 24#else // gcc or icc 25#define ALIGN8_BEG 26#define ALIGN8_END __attribute__((aligned(8))) 27#endif 28 29extern const WebRtc_Word16 WebRtcAecm_kSqrtHanning[] ALIGN8_END; 30 31typedef struct { 32 WebRtc_Word16 real; 33 WebRtc_Word16 imag; 34} complex16_t; 35 36typedef struct 37{ 38 int farBufWritePos; 39 int farBufReadPos; 40 int knownDelay; 41 int lastKnownDelay; 42 int firstVAD; // Parameter to control poorly initialized channels 43 44 void *farFrameBuf; 45 void *nearNoisyFrameBuf; 46 void *nearCleanFrameBuf; 47 void *outFrameBuf; 48 49 WebRtc_Word16 farBuf[FAR_BUF_LEN]; 50 51 WebRtc_Word16 mult; 52 WebRtc_UWord32 seed; 53 54 // Delay estimation variables 55 void* delay_estimator; 56 WebRtc_UWord16 currentDelay; 57 // Far end history variables 58 // TODO(bjornv): Replace |far_history| with ring_buffer. 59 uint16_t far_history[PART_LEN1 * MAX_DELAY]; 60 int far_history_pos; 61 int far_q_domains[MAX_DELAY]; 62 63 WebRtc_Word16 nlpFlag; 64 WebRtc_Word16 fixedDelay; 65 66 WebRtc_UWord32 totCount; 67 68 WebRtc_Word16 dfaCleanQDomain; 69 WebRtc_Word16 dfaCleanQDomainOld; 70 WebRtc_Word16 dfaNoisyQDomain; 71 WebRtc_Word16 dfaNoisyQDomainOld; 72 73 WebRtc_Word16 nearLogEnergy[MAX_BUF_LEN]; 74 WebRtc_Word16 farLogEnergy; 75 WebRtc_Word16 echoAdaptLogEnergy[MAX_BUF_LEN]; 76 WebRtc_Word16 echoStoredLogEnergy[MAX_BUF_LEN]; 77 78 // The extra 16 or 32 bytes in the following buffers are for alignment based Neon code. 79 // It's designed this way since the current GCC compiler can't align a buffer in 16 or 32 80 // byte boundaries properly. 81 WebRtc_Word16 channelStored_buf[PART_LEN1 + 8]; 82 WebRtc_Word16 channelAdapt16_buf[PART_LEN1 + 8]; 83 WebRtc_Word32 channelAdapt32_buf[PART_LEN1 + 8]; 84 WebRtc_Word16 xBuf_buf[PART_LEN2 + 16]; // farend 85 WebRtc_Word16 dBufClean_buf[PART_LEN2 + 16]; // nearend 86 WebRtc_Word16 dBufNoisy_buf[PART_LEN2 + 16]; // nearend 87 WebRtc_Word16 outBuf_buf[PART_LEN + 8]; 88 89 // Pointers to the above buffers 90 WebRtc_Word16 *channelStored; 91 WebRtc_Word16 *channelAdapt16; 92 WebRtc_Word32 *channelAdapt32; 93 WebRtc_Word16 *xBuf; 94 WebRtc_Word16 *dBufClean; 95 WebRtc_Word16 *dBufNoisy; 96 WebRtc_Word16 *outBuf; 97 98 WebRtc_Word32 echoFilt[PART_LEN1]; 99 WebRtc_Word16 nearFilt[PART_LEN1]; 100 WebRtc_Word32 noiseEst[PART_LEN1]; 101 int noiseEstTooLowCtr[PART_LEN1]; 102 int noiseEstTooHighCtr[PART_LEN1]; 103 WebRtc_Word16 noiseEstCtr; 104 WebRtc_Word16 cngMode; 105 106 WebRtc_Word32 mseAdaptOld; 107 WebRtc_Word32 mseStoredOld; 108 WebRtc_Word32 mseThreshold; 109 110 WebRtc_Word16 farEnergyMin; 111 WebRtc_Word16 farEnergyMax; 112 WebRtc_Word16 farEnergyMaxMin; 113 WebRtc_Word16 farEnergyVAD; 114 WebRtc_Word16 farEnergyMSE; 115 int currentVADValue; 116 WebRtc_Word16 vadUpdateCount; 117 118 WebRtc_Word16 startupState; 119 WebRtc_Word16 mseChannelCount; 120 WebRtc_Word16 supGain; 121 WebRtc_Word16 supGainOld; 122 123 WebRtc_Word16 supGainErrParamA; 124 WebRtc_Word16 supGainErrParamD; 125 WebRtc_Word16 supGainErrParamDiffAB; 126 WebRtc_Word16 supGainErrParamDiffBD; 127 128 struct RealFFT* real_fft; 129 130#ifdef AEC_DEBUG 131 FILE *farFile; 132 FILE *nearFile; 133 FILE *outFile; 134#endif 135} AecmCore_t; 136 137/////////////////////////////////////////////////////////////////////////////////////////////// 138// WebRtcAecm_CreateCore(...) 139// 140// Allocates the memory needed by the AECM. The memory needs to be 141// initialized separately using the WebRtcAecm_InitCore() function. 142// 143// Input: 144// - aecm : Instance that should be created 145// 146// Output: 147// - aecm : Created instance 148// 149// Return value : 0 - Ok 150// -1 - Error 151// 152int WebRtcAecm_CreateCore(AecmCore_t **aecm); 153 154/////////////////////////////////////////////////////////////////////////////////////////////// 155// WebRtcAecm_InitCore(...) 156// 157// This function initializes the AECM instant created with WebRtcAecm_CreateCore(...) 158// Input: 159// - aecm : Pointer to the AECM instance 160// - samplingFreq : Sampling Frequency 161// 162// Output: 163// - aecm : Initialized instance 164// 165// Return value : 0 - Ok 166// -1 - Error 167// 168int WebRtcAecm_InitCore(AecmCore_t * const aecm, int samplingFreq); 169 170/////////////////////////////////////////////////////////////////////////////////////////////// 171// WebRtcAecm_FreeCore(...) 172// 173// This function releases the memory allocated by WebRtcAecm_CreateCore() 174// Input: 175// - aecm : Pointer to the AECM instance 176// 177// Return value : 0 - Ok 178// -1 - Error 179// 11001-11016: Error 180// 181int WebRtcAecm_FreeCore(AecmCore_t *aecm); 182 183int WebRtcAecm_Control(AecmCore_t *aecm, int delay, int nlpFlag); 184 185/////////////////////////////////////////////////////////////////////////////////////////////// 186// WebRtcAecm_InitEchoPathCore(...) 187// 188// This function resets the echo channel adaptation with the specified channel. 189// Input: 190// - aecm : Pointer to the AECM instance 191// - echo_path : Pointer to the data that should initialize the echo path 192// 193// Output: 194// - aecm : Initialized instance 195// 196void WebRtcAecm_InitEchoPathCore(AecmCore_t* aecm, const WebRtc_Word16* echo_path); 197 198/////////////////////////////////////////////////////////////////////////////////////////////// 199// WebRtcAecm_ProcessFrame(...) 200// 201// This function processes frames and sends blocks to WebRtcAecm_ProcessBlock(...) 202// 203// Inputs: 204// - aecm : Pointer to the AECM instance 205// - farend : In buffer containing one frame of echo signal 206// - nearendNoisy : In buffer containing one frame of nearend+echo signal without NS 207// - nearendClean : In buffer containing one frame of nearend+echo signal with NS 208// 209// Output: 210// - out : Out buffer, one frame of nearend signal : 211// 212// 213int WebRtcAecm_ProcessFrame(AecmCore_t * aecm, const WebRtc_Word16 * farend, 214 const WebRtc_Word16 * nearendNoisy, 215 const WebRtc_Word16 * nearendClean, 216 WebRtc_Word16 * out); 217 218/////////////////////////////////////////////////////////////////////////////////////////////// 219// WebRtcAecm_ProcessBlock(...) 220// 221// This function is called for every block within one frame 222// This function is called by WebRtcAecm_ProcessFrame(...) 223// 224// Inputs: 225// - aecm : Pointer to the AECM instance 226// - farend : In buffer containing one block of echo signal 227// - nearendNoisy : In buffer containing one frame of nearend+echo signal without NS 228// - nearendClean : In buffer containing one frame of nearend+echo signal with NS 229// 230// Output: 231// - out : Out buffer, one block of nearend signal : 232// 233// 234int WebRtcAecm_ProcessBlock(AecmCore_t * aecm, const WebRtc_Word16 * farend, 235 const WebRtc_Word16 * nearendNoisy, 236 const WebRtc_Word16 * noisyClean, 237 WebRtc_Word16 * out); 238 239/////////////////////////////////////////////////////////////////////////////////////////////// 240// WebRtcAecm_BufferFarFrame() 241// 242// Inserts a frame of data into farend buffer. 243// 244// Inputs: 245// - aecm : Pointer to the AECM instance 246// - farend : In buffer containing one frame of farend signal 247// - farLen : Length of frame 248// 249void WebRtcAecm_BufferFarFrame(AecmCore_t * const aecm, const WebRtc_Word16 * const farend, 250 const int farLen); 251 252/////////////////////////////////////////////////////////////////////////////////////////////// 253// WebRtcAecm_FetchFarFrame() 254// 255// Read the farend buffer to account for known delay 256// 257// Inputs: 258// - aecm : Pointer to the AECM instance 259// - farend : In buffer containing one frame of farend signal 260// - farLen : Length of frame 261// - knownDelay : known delay 262// 263void WebRtcAecm_FetchFarFrame(AecmCore_t * const aecm, WebRtc_Word16 * const farend, 264 const int farLen, const int knownDelay); 265 266/////////////////////////////////////////////////////////////////////////////// 267// Some function pointers, for internal functions shared by ARM NEON and 268// generic C code. 269// 270typedef void (*CalcLinearEnergies)( 271 AecmCore_t* aecm, 272 const WebRtc_UWord16* far_spectrum, 273 WebRtc_Word32* echoEst, 274 WebRtc_UWord32* far_energy, 275 WebRtc_UWord32* echo_energy_adapt, 276 WebRtc_UWord32* echo_energy_stored); 277extern CalcLinearEnergies WebRtcAecm_CalcLinearEnergies; 278 279typedef void (*StoreAdaptiveChannel)( 280 AecmCore_t* aecm, 281 const WebRtc_UWord16* far_spectrum, 282 WebRtc_Word32* echo_est); 283extern StoreAdaptiveChannel WebRtcAecm_StoreAdaptiveChannel; 284 285typedef void (*ResetAdaptiveChannel)(AecmCore_t* aecm); 286extern ResetAdaptiveChannel WebRtcAecm_ResetAdaptiveChannel; 287 288typedef void (*WindowAndFFT)( 289 AecmCore_t* aecm, 290 WebRtc_Word16* fft, 291 const WebRtc_Word16* time_signal, 292 complex16_t* freq_signal, 293 int time_signal_scaling); 294extern WindowAndFFT WebRtcAecm_WindowAndFFT; 295 296typedef void (*InverseFFTAndWindow)( 297 AecmCore_t* aecm, 298 WebRtc_Word16* fft, complex16_t* efw, 299 WebRtc_Word16* output, 300 const WebRtc_Word16* nearendClean); 301extern InverseFFTAndWindow WebRtcAecm_InverseFFTAndWindow; 302 303// For the above function pointers, functions for generic platforms are declared 304// and defined as static in file aecm_core.c, while those for ARM Neon platforms 305// are declared below and defined in file aecm_core_neon.s. 306#if (defined WEBRTC_DETECT_ARM_NEON) || defined (WEBRTC_ARCH_ARM_NEON) 307void WebRtcAecm_WindowAndFFTNeon(AecmCore_t* aecm, 308 WebRtc_Word16* fft, 309 const WebRtc_Word16* time_signal, 310 complex16_t* freq_signal, 311 int time_signal_scaling); 312 313void WebRtcAecm_InverseFFTAndWindowNeon(AecmCore_t* aecm, 314 WebRtc_Word16* fft, 315 complex16_t* efw, 316 WebRtc_Word16* output, 317 const WebRtc_Word16* nearendClean); 318 319void WebRtcAecm_CalcLinearEnergiesNeon(AecmCore_t* aecm, 320 const WebRtc_UWord16* far_spectrum, 321 WebRtc_Word32* echo_est, 322 WebRtc_UWord32* far_energy, 323 WebRtc_UWord32* echo_energy_adapt, 324 WebRtc_UWord32* echo_energy_stored); 325 326void WebRtcAecm_StoreAdaptiveChannelNeon(AecmCore_t* aecm, 327 const WebRtc_UWord16* far_spectrum, 328 WebRtc_Word32* echo_est); 329 330void WebRtcAecm_ResetAdaptiveChannelNeon(AecmCore_t* aecm); 331#endif 332 333#endif 334