1 /* 2 * Copyright (c) 2011 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_MAIN_SOURCE_AECM_CORE_H_ 14 #define WEBRTC_MODULES_AUDIO_PROCESSING_AECM_MAIN_SOURCE_AECM_CORE_H_ 15 16 #define AECM_DYNAMIC_Q // turn on/off dynamic Q-domain 17 //#define AECM_WITH_ABS_APPROX 18 //#define AECM_SHORT // for 32 sample partition length (otherwise 64) 19 20 // TODO(bjornv): These defines will be removed in final version. 21 //#define STORE_CHANNEL_DATA 22 //#define VAD_DATA 23 24 #include "typedefs.h" 25 #include "signal_processing_library.h" 26 // TODO(bjornv): Will be removed in final version. 27 //#include <stdio.h> 28 29 // Algorithm parameters 30 31 #define FRAME_LEN 80 // Total frame length, 10 ms 32 #ifdef AECM_SHORT 33 34 #define PART_LEN 32 // Length of partition 35 #define PART_LEN_SHIFT 6 // Length of (PART_LEN * 2) in base 2 36 37 #else 38 39 #define PART_LEN 64 // Length of partition 40 #define PART_LEN_SHIFT 7 // Length of (PART_LEN * 2) in base 2 41 42 #endif 43 44 #define PART_LEN1 (PART_LEN + 1) // Unique fft coefficients 45 #define PART_LEN2 (PART_LEN << 1) // Length of partition * 2 46 #define PART_LEN4 (PART_LEN << 2) // Length of partition * 4 47 #define FAR_BUF_LEN PART_LEN4 // Length of buffers 48 #define MAX_DELAY 100 49 50 // Counter parameters 51 #ifdef AECM_SHORT 52 53 #define CONV_LEN 1024 // Convergence length used at startup 54 #else 55 56 #define CONV_LEN 512 // Convergence length used at startup 57 #endif 58 59 #define CONV_LEN2 (CONV_LEN << 1) // Convergence length * 2 used at startup 60 // Energy parameters 61 #define MAX_BUF_LEN 64 // History length of energy signals 62 63 #define FAR_ENERGY_MIN 1025 // Lowest Far energy level: At least 2 in energy 64 #define FAR_ENERGY_DIFF 929 // Allowed difference between max and min 65 66 #define ENERGY_DEV_OFFSET 0 // The energy error offset in Q8 67 #define ENERGY_DEV_TOL 400 // The energy estimation tolerance in Q8 68 #define FAR_ENERGY_VAD_REGION 230 // Far VAD tolerance region 69 // Stepsize parameters 70 #define MU_MIN 10 // Min stepsize 2^-MU_MIN (far end energy dependent) 71 #define MU_MAX 1 // Max stepsize 2^-MU_MAX (far end energy dependent) 72 #define MU_DIFF 9 // MU_MIN - MU_MAX 73 // Channel parameters 74 #define MIN_MSE_COUNT 20 // Min number of consecutive blocks with enough far end 75 // energy to compare channel estimates 76 #define MIN_MSE_DIFF 29 // The ratio between adapted and stored channel to 77 // accept a new storage (0.8 in Q-MSE_RESOLUTION) 78 #define MSE_RESOLUTION 5 // MSE parameter resolution 79 #define RESOLUTION_CHANNEL16 12 // W16 Channel in Q-RESOLUTION_CHANNEL16 80 #define RESOLUTION_CHANNEL32 28 // W32 Channel in Q-RESOLUTION_CHANNEL 81 #define CHANNEL_VAD 16 // Minimum energy in frequency band to update channel 82 // Suppression gain parameters: SUPGAIN_ parameters in Q-(RESOLUTION_SUPGAIN) 83 #define RESOLUTION_SUPGAIN 8 // Channel in Q-(RESOLUTION_SUPGAIN) 84 #define SUPGAIN_DEFAULT (1 << RESOLUTION_SUPGAIN) // Default suppression gain 85 #define SUPGAIN_ERROR_PARAM_A 3072 // Estimation error parameter (Maximum gain) (8 in Q8) 86 #define SUPGAIN_ERROR_PARAM_B 1536 // Estimation error parameter (Gain before going down) 87 #define SUPGAIN_ERROR_PARAM_D SUPGAIN_DEFAULT // Estimation error parameter 88 // (Should be the same as Default) (1 in Q8) 89 #define SUPGAIN_EPC_DT 200 // = SUPGAIN_ERROR_PARAM_C * ENERGY_DEV_TOL 90 // Defines for "check delay estimation" 91 #define CORR_WIDTH 31 // Number of samples to correlate over. 92 #define CORR_MAX 16 // Maximum correlation offset 93 #define CORR_MAX_BUF 63 94 #define CORR_DEV 4 95 #define CORR_MAX_LEVEL 20 96 #define CORR_MAX_LOW 4 97 #define CORR_BUF_LEN (CORR_MAX << 1) + 1 98 // Note that CORR_WIDTH + 2*CORR_MAX <= MAX_BUF_LEN 99 100 #define ONE_Q14 (1 << 14) 101 102 // NLP defines 103 #define NLP_COMP_LOW 3277 // 0.2 in Q14 104 #define NLP_COMP_HIGH ONE_Q14 // 1 in Q14 105 106 typedef struct 107 { 108 int farBufWritePos; 109 int farBufReadPos; 110 int knownDelay; 111 int lastKnownDelay; 112 int firstVAD; // Parameter to control poorly initialized channels 113 114 void *farFrameBuf; 115 void *nearNoisyFrameBuf; 116 void *nearCleanFrameBuf; 117 void *outFrameBuf; 118 119 WebRtc_Word16 xBuf[PART_LEN2]; // farend 120 WebRtc_Word16 dBufClean[PART_LEN2]; // nearend 121 WebRtc_Word16 dBufNoisy[PART_LEN2]; // nearend 122 WebRtc_Word16 outBuf[PART_LEN]; 123 124 WebRtc_Word16 farBuf[FAR_BUF_LEN]; 125 126 WebRtc_Word16 mult; 127 WebRtc_UWord32 seed; 128 129 // Delay estimation variables 130 WebRtc_UWord16 medianYlogspec[PART_LEN1]; 131 WebRtc_UWord16 medianXlogspec[PART_LEN1]; 132 WebRtc_UWord16 medianBCount[MAX_DELAY]; 133 WebRtc_UWord16 xfaHistory[PART_LEN1][MAX_DELAY]; 134 WebRtc_Word16 delHistoryPos; 135 WebRtc_UWord32 bxHistory[MAX_DELAY]; 136 WebRtc_UWord16 currentDelay; 137 WebRtc_UWord16 previousDelay; 138 WebRtc_Word16 delayAdjust; 139 140 WebRtc_Word16 nlpFlag; 141 WebRtc_Word16 fixedDelay; 142 143 WebRtc_UWord32 totCount; 144 145 WebRtc_Word16 xfaQDomainBuf[MAX_DELAY]; 146 WebRtc_Word16 dfaCleanQDomain; 147 WebRtc_Word16 dfaCleanQDomainOld; 148 WebRtc_Word16 dfaNoisyQDomain; 149 WebRtc_Word16 dfaNoisyQDomainOld; 150 151 WebRtc_Word16 nearLogEnergy[MAX_BUF_LEN]; 152 WebRtc_Word16 farLogEnergy[MAX_BUF_LEN]; 153 WebRtc_Word16 echoAdaptLogEnergy[MAX_BUF_LEN]; 154 WebRtc_Word16 echoStoredLogEnergy[MAX_BUF_LEN]; 155 156 WebRtc_Word16 channelAdapt16[PART_LEN1]; 157 WebRtc_Word32 channelAdapt32[PART_LEN1]; 158 WebRtc_Word16 channelStored[PART_LEN1]; 159 WebRtc_Word32 echoFilt[PART_LEN1]; 160 WebRtc_Word16 nearFilt[PART_LEN1]; 161 WebRtc_Word32 noiseEst[PART_LEN1]; 162 WebRtc_Word16 noiseEstQDomain[PART_LEN1]; 163 WebRtc_Word16 noiseEstCtr; 164 WebRtc_Word16 cngMode; 165 166 WebRtc_Word32 mseAdaptOld; 167 WebRtc_Word32 mseStoredOld; 168 WebRtc_Word32 mseThreshold; 169 170 WebRtc_Word16 farEnergyMin; 171 WebRtc_Word16 farEnergyMax; 172 WebRtc_Word16 farEnergyMaxMin; 173 WebRtc_Word16 farEnergyVAD; 174 WebRtc_Word16 farEnergyMSE; 175 WebRtc_Word16 currentVADValue; 176 WebRtc_Word16 vadUpdateCount; 177 178 WebRtc_Word16 delayHistogram[MAX_DELAY]; 179 WebRtc_Word16 delayVadCount; 180 WebRtc_Word16 maxDelayHistIdx; 181 WebRtc_Word16 lastMinPos; 182 183 WebRtc_Word16 startupState; 184 WebRtc_Word16 mseChannelCount; 185 WebRtc_Word16 delayCount; 186 WebRtc_Word16 newDelayCorrData; 187 WebRtc_Word16 lastDelayUpdateCount; 188 WebRtc_Word16 delayCorrelation[CORR_BUF_LEN]; 189 WebRtc_Word16 supGain; 190 WebRtc_Word16 supGainOld; 191 WebRtc_Word16 delayOffsetFlag; 192 193 WebRtc_Word16 supGainErrParamA; 194 WebRtc_Word16 supGainErrParamD; 195 WebRtc_Word16 supGainErrParamDiffAB; 196 WebRtc_Word16 supGainErrParamDiffBD; 197 198 // TODO(bjornv): Will be removed after final version has been committed. 199 #ifdef VAD_DATA 200 FILE *vad_file; 201 FILE *delay_file; 202 FILE *far_file; 203 FILE *far_cur_file; 204 FILE *far_min_file; 205 FILE *far_max_file; 206 FILE *far_vad_file; 207 #endif 208 209 // TODO(bjornv): Will be removed after final version has been committed. 210 #ifdef STORE_CHANNEL_DATA 211 FILE *channel_file; 212 FILE *channel_file_init; 213 #endif 214 215 #ifdef AEC_DEBUG 216 FILE *farFile; 217 FILE *nearFile; 218 FILE *outFile; 219 #endif 220 } AecmCore_t; 221 222 /////////////////////////////////////////////////////////////////////////////////////////////// 223 // WebRtcAecm_CreateCore(...) 224 // 225 // Allocates the memory needed by the AECM. The memory needs to be 226 // initialized separately using the WebRtcAecm_InitCore() function. 227 // 228 // Input: 229 // - aecm : Instance that should be created 230 // 231 // Output: 232 // - aecm : Created instance 233 // 234 // Return value : 0 - Ok 235 // -1 - Error 236 // 237 int WebRtcAecm_CreateCore(AecmCore_t **aecm); 238 239 /////////////////////////////////////////////////////////////////////////////////////////////// 240 // WebRtcAecm_InitCore(...) 241 // 242 // This function initializes the AECM instant created with WebRtcAecm_CreateCore(...) 243 // Input: 244 // - aecm : Pointer to the AECM instance 245 // - samplingFreq : Sampling Frequency 246 // 247 // Output: 248 // - aecm : Initialized instance 249 // 250 // Return value : 0 - Ok 251 // -1 - Error 252 // 253 int WebRtcAecm_InitCore(AecmCore_t * const aecm, int samplingFreq); 254 255 /////////////////////////////////////////////////////////////////////////////////////////////// 256 // WebRtcAecm_FreeCore(...) 257 // 258 // This function releases the memory allocated by WebRtcAecm_CreateCore() 259 // Input: 260 // - aecm : Pointer to the AECM instance 261 // 262 // Return value : 0 - Ok 263 // -1 - Error 264 // 11001-11016: Error 265 // 266 int WebRtcAecm_FreeCore(AecmCore_t *aecm); 267 268 int WebRtcAecm_Control(AecmCore_t *aecm, int delay, int nlpFlag, int delayOffsetFlag); 269 270 /////////////////////////////////////////////////////////////////////////////////////////////// 271 // WebRtcAecm_ProcessFrame(...) 272 // 273 // This function processes frames and sends blocks to WebRtcAecm_ProcessBlock(...) 274 // 275 // Inputs: 276 // - aecm : Pointer to the AECM instance 277 // - farend : In buffer containing one frame of echo signal 278 // - nearendNoisy : In buffer containing one frame of nearend+echo signal without NS 279 // - nearendClean : In buffer containing one frame of nearend+echo signal with NS 280 // 281 // Output: 282 // - out : Out buffer, one frame of nearend signal : 283 // 284 // 285 void WebRtcAecm_ProcessFrame(AecmCore_t * const aecm, const WebRtc_Word16 * const farend, 286 const WebRtc_Word16 * const nearendNoisy, 287 const WebRtc_Word16 * const nearendClean, 288 WebRtc_Word16 * const out); 289 290 /////////////////////////////////////////////////////////////////////////////////////////////// 291 // WebRtcAecm_ProcessBlock(...) 292 // 293 // This function is called for every block within one frame 294 // This function is called by WebRtcAecm_ProcessFrame(...) 295 // 296 // Inputs: 297 // - aecm : Pointer to the AECM instance 298 // - farend : In buffer containing one block of echo signal 299 // - nearendNoisy : In buffer containing one frame of nearend+echo signal without NS 300 // - nearendClean : In buffer containing one frame of nearend+echo signal with NS 301 // 302 // Output: 303 // - out : Out buffer, one block of nearend signal : 304 // 305 // 306 void WebRtcAecm_ProcessBlock(AecmCore_t * const aecm, const WebRtc_Word16 * const farend, 307 const WebRtc_Word16 * const nearendNoisy, 308 const WebRtc_Word16 * const noisyClean, 309 WebRtc_Word16 * const out); 310 311 /////////////////////////////////////////////////////////////////////////////////////////////// 312 // WebRtcAecm_BufferFarFrame() 313 // 314 // Inserts a frame of data into farend buffer. 315 // 316 // Inputs: 317 // - aecm : Pointer to the AECM instance 318 // - farend : In buffer containing one frame of farend signal 319 // - farLen : Length of frame 320 // 321 void WebRtcAecm_BufferFarFrame(AecmCore_t * const aecm, const WebRtc_Word16 * const farend, 322 const int farLen); 323 324 /////////////////////////////////////////////////////////////////////////////////////////////// 325 // WebRtcAecm_FetchFarFrame() 326 // 327 // Read the farend buffer to account for known delay 328 // 329 // Inputs: 330 // - aecm : Pointer to the AECM instance 331 // - farend : In buffer containing one frame of farend signal 332 // - farLen : Length of frame 333 // - knownDelay : known delay 334 // 335 void WebRtcAecm_FetchFarFrame(AecmCore_t * const aecm, WebRtc_Word16 * const farend, 336 const int farLen, const int knownDelay); 337 338 #endif 339