• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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