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