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