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