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 #ifndef MODULES_AUDIO_PROCESSING_AEC_ECHO_CANCELLATION_H_
12 #define MODULES_AUDIO_PROCESSING_AEC_ECHO_CANCELLATION_H_
13 
14 #include <memory>
15 
16 #include <stddef.h>
17 
18 extern "C" {
19 #include "common_audio/ring_buffer.h"
20 }
21 #include "modules/audio_processing/aec/aec_core.h"
22 
23 namespace webrtc {
24 
25 // Errors
26 #define AEC_UNSPECIFIED_ERROR 12000
27 #define AEC_UNSUPPORTED_FUNCTION_ERROR 12001
28 #define AEC_UNINITIALIZED_ERROR 12002
29 #define AEC_NULL_POINTER_ERROR 12003
30 #define AEC_BAD_PARAMETER_ERROR 12004
31 
32 // Warnings
33 #define AEC_BAD_PARAMETER_WARNING 12050
34 
35 enum { kAecNlpConservative = 0, kAecNlpModerate, kAecNlpAggressive };
36 
37 enum { kAecFalse = 0, kAecTrue };
38 
39 typedef struct {
40   int16_t nlpMode;      // default kAecNlpModerate
41   int16_t skewMode;     // default kAecFalse
42   int16_t metricsMode;  // default kAecFalse
43   int delay_logging;    // default kAecFalse
44   // float realSkew;
45 } AecConfig;
46 
47 typedef struct {
48   int instant;
49   int average;
50   int max;
51   int min;
52 } AecLevel;
53 
54 typedef struct {
55   AecLevel rerl;
56   AecLevel erl;
57   AecLevel erle;
58   AecLevel aNlp;
59   float divergent_filter_fraction;
60 } AecMetrics;
61 
62 struct AecCore;
63 
64 class ApmDataDumper;
65 
66 typedef struct Aec {
67   Aec();
68   ~Aec();
69 
70   std::unique_ptr<ApmDataDumper> data_dumper;
71 
72   int delayCtr;
73   int sampFreq;
74   int splitSampFreq;
75   int scSampFreq;
76   float sampFactor;  // scSampRate / sampFreq
77   short skewMode;
78   int bufSizeStart;
79   int knownDelay;
80   int rate_factor;
81 
82   short initFlag;  // indicates if AEC has been initialized
83 
84   // Variables used for averaging far end buffer size
85   short counter;
86   int sum;
87   short firstVal;
88   short checkBufSizeCtr;
89 
90   // Variables used for delay shifts
91   short msInSndCardBuf;
92   short filtDelay;  // Filtered delay estimate.
93   int timeForDelayChange;
94   int startup_phase;
95   int checkBuffSize;
96   short lastDelayDiff;
97 
98   // Structures
99   void* resampler;
100 
101   int skewFrCtr;
102   int resample;  // if the skew is small enough we don't resample
103   int highSkewCtr;
104   float skew;
105 
106   RingBuffer* far_pre_buf;  // Time domain far-end pre-buffer.
107 
108   int farend_started;
109 
110   // Aec instance counter.
111   static int instance_count;
112   AecCore* aec;
113 } Aec;
114 
115 /*
116  * Allocates the memory needed by the AEC. The memory needs to be initialized
117  * separately using the WebRtcAec_Init() function. Returns a pointer to the
118  * object or NULL on error.
119  */
120 void* WebRtcAec_Create();
121 
122 /*
123  * This function releases the memory allocated by WebRtcAec_Create().
124  *
125  * Inputs                       Description
126  * -------------------------------------------------------------------
127  * void*        aecInst         Pointer to the AEC instance
128  */
129 void WebRtcAec_Free(void* aecInst);
130 
131 /*
132  * Initializes an AEC instance.
133  *
134  * Inputs                       Description
135  * -------------------------------------------------------------------
136  * void*          aecInst       Pointer to the AEC instance
137  * int32_t        sampFreq      Sampling frequency of data
138  * int32_t        scSampFreq    Soundcard sampling frequency
139  *
140  * Outputs                      Description
141  * -------------------------------------------------------------------
142  * int32_t        return        0: OK
143  *                             -1: error
144  */
145 int32_t WebRtcAec_Init(void* aecInst, int32_t sampFreq, int32_t scSampFreq);
146 
147 /*
148  * Inserts an 80 or 160 sample block of data into the farend buffer.
149  *
150  * Inputs                       Description
151  * -------------------------------------------------------------------
152  * void*          aecInst       Pointer to the AEC instance
153  * const float*   farend        In buffer containing one frame of
154  *                              farend signal for L band
155  * int16_t        nrOfSamples   Number of samples in farend buffer
156  *
157  * Outputs                      Description
158  * -------------------------------------------------------------------
159  * int32_t        return        0: OK
160  *                              12000-12050: error code
161  */
162 int32_t WebRtcAec_BufferFarend(void* aecInst,
163                                const float* farend,
164                                size_t nrOfSamples);
165 
166 /*
167  * Reports any errors that would arise if buffering a farend buffer
168  *
169  * Inputs                       Description
170  * -------------------------------------------------------------------
171  * void*          aecInst       Pointer to the AEC instance
172  * const float*   farend        In buffer containing one frame of
173  *                              farend signal for L band
174  * int16_t        nrOfSamples   Number of samples in farend buffer
175  *
176  * Outputs                      Description
177  * -------------------------------------------------------------------
178  * int32_t        return        0: OK
179  *                              12000-12050: error code
180  */
181 int32_t WebRtcAec_GetBufferFarendError(void* aecInst,
182                                        const float* farend,
183                                        size_t nrOfSamples);
184 
185 /*
186  * Runs the echo canceller on an 80 or 160 sample blocks of data.
187  *
188  * Inputs                       Description
189  * -------------------------------------------------------------------
190  * void*         aecInst        Pointer to the AEC instance
191  * float* const* nearend        In buffer containing one frame of
192  *                              nearend+echo signal for each band
193  * int           num_bands      Number of bands in nearend buffer
194  * int16_t       nrOfSamples    Number of samples in nearend buffer
195  * int16_t       msInSndCardBuf Delay estimate for sound card and
196  *                              system buffers
197  * int16_t       skew           Difference between number of samples played
198  *                              and recorded at the soundcard (for clock skew
199  *                              compensation)
200  *
201  * Outputs                      Description
202  * -------------------------------------------------------------------
203  * float* const* out            Out buffer, one frame of processed nearend
204  *                              for each band
205  * int32_t       return         0: OK
206  *                              12000-12050: error code
207  */
208 int32_t WebRtcAec_Process(void* aecInst,
209                           const float* const* nearend,
210                           size_t num_bands,
211                           float* const* out,
212                           size_t nrOfSamples,
213                           int16_t msInSndCardBuf,
214                           int32_t skew);
215 
216 /*
217  * This function enables the user to set certain parameters on-the-fly.
218  *
219  * Inputs                       Description
220  * -------------------------------------------------------------------
221  * void*          handle        Pointer to the AEC instance
222  * AecConfig      config        Config instance that contains all
223  *                              properties to be set
224  *
225  * Outputs                      Description
226  * -------------------------------------------------------------------
227  * int            return        0: OK
228  *                              12000-12050: error code
229  */
230 int WebRtcAec_set_config(void* handle, AecConfig config);
231 
232 /*
233  * Gets the current echo status of the nearend signal.
234  *
235  * Inputs                       Description
236  * -------------------------------------------------------------------
237  * void*          handle        Pointer to the AEC instance
238  *
239  * Outputs                      Description
240  * -------------------------------------------------------------------
241  * int*           status        0: Almost certainly nearend single-talk
242  *                              1: Might not be neared single-talk
243  * int            return        0: OK
244  *                              12000-12050: error code
245  */
246 int WebRtcAec_get_echo_status(void* handle, int* status);
247 
248 /*
249  * Gets the current echo metrics for the session.
250  *
251  * Inputs                       Description
252  * -------------------------------------------------------------------
253  * void*          handle        Pointer to the AEC instance
254  *
255  * Outputs                      Description
256  * -------------------------------------------------------------------
257  * AecMetrics*    metrics       Struct which will be filled out with the
258  *                              current echo metrics.
259  * int            return        0: OK
260  *                              12000-12050: error code
261  */
262 int WebRtcAec_GetMetrics(void* handle, AecMetrics* metrics);
263 
264 /*
265  * Gets the current delay metrics for the session.
266  *
267  * Inputs                       Description
268  * -------------------------------------------------------------------
269  * void*   handle               Pointer to the AEC instance
270  *
271  * Outputs                      Description
272  * -------------------------------------------------------------------
273  * int*    median               Delay median value.
274  * int*    std                  Delay standard deviation.
275  * float*  fraction_poor_delays Fraction of the delay estimates that may
276  *                              cause the AEC to perform poorly.
277  *
278  * int            return        0: OK
279  *                              12000-12050: error code
280  */
281 int WebRtcAec_GetDelayMetrics(void* handle,
282                               int* median,
283                               int* std,
284                               float* fraction_poor_delays);
285 
286 // Returns a pointer to the low level AEC handle.
287 //
288 // Input:
289 //  - handle                    : Pointer to the AEC instance.
290 //
291 // Return value:
292 //  - AecCore pointer           : NULL for error.
293 //
294 struct AecCore* WebRtcAec_aec_core(void* handle);
295 
296 }  // namespace webrtc
297 
298 #endif  // MODULES_AUDIO_PROCESSING_AEC_ECHO_CANCELLATION_H_
299