• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h"
12 
13 #include <assert.h>
14 #include <stdlib.h>
15 #include <string.h>
16 
17 #include "webrtc/modules/audio_processing/utility/delay_estimator.h"
18 #include "webrtc/modules/audio_processing/utility/delay_estimator_internal.h"
19 #include "webrtc/system_wrappers/include/compile_assert_c.h"
20 
21 // Only bit |kBandFirst| through bit |kBandLast| are processed and
22 // |kBandFirst| - |kBandLast| must be < 32.
23 enum { kBandFirst = 12 };
24 enum { kBandLast = 43 };
25 
SetBit(uint32_t in,int pos)26 static __inline uint32_t SetBit(uint32_t in, int pos) {
27   uint32_t mask = (1 << pos);
28   uint32_t out = (in | mask);
29 
30   return out;
31 }
32 
33 // Calculates the mean recursively. Same version as WebRtc_MeanEstimatorFix(),
34 // but for float.
35 //
36 // Inputs:
37 //    - new_value             : New additional value.
38 //    - scale                 : Scale for smoothing (should be less than 1.0).
39 //
40 // Input/Output:
41 //    - mean_value            : Pointer to the mean value for updating.
42 //
MeanEstimatorFloat(float new_value,float scale,float * mean_value)43 static void MeanEstimatorFloat(float new_value,
44                                float scale,
45                                float* mean_value) {
46   assert(scale < 1.0f);
47   *mean_value += (new_value - *mean_value) * scale;
48 }
49 
50 // Computes the binary spectrum by comparing the input |spectrum| with a
51 // |threshold_spectrum|. Float and fixed point versions.
52 //
53 // Inputs:
54 //      - spectrum            : Spectrum of which the binary spectrum should be
55 //                              calculated.
56 //      - threshold_spectrum  : Threshold spectrum with which the input
57 //                              spectrum is compared.
58 // Return:
59 //      - out                 : Binary spectrum.
60 //
BinarySpectrumFix(const uint16_t * spectrum,SpectrumType * threshold_spectrum,int q_domain,int * threshold_initialized)61 static uint32_t BinarySpectrumFix(const uint16_t* spectrum,
62                                   SpectrumType* threshold_spectrum,
63                                   int q_domain,
64                                   int* threshold_initialized) {
65   int i = kBandFirst;
66   uint32_t out = 0;
67 
68   assert(q_domain < 16);
69 
70   if (!(*threshold_initialized)) {
71     // Set the |threshold_spectrum| to half the input |spectrum| as starting
72     // value. This speeds up the convergence.
73     for (i = kBandFirst; i <= kBandLast; i++) {
74       if (spectrum[i] > 0) {
75         // Convert input spectrum from Q(|q_domain|) to Q15.
76         int32_t spectrum_q15 = ((int32_t) spectrum[i]) << (15 - q_domain);
77         threshold_spectrum[i].int32_ = (spectrum_q15 >> 1);
78         *threshold_initialized = 1;
79       }
80     }
81   }
82   for (i = kBandFirst; i <= kBandLast; i++) {
83     // Convert input spectrum from Q(|q_domain|) to Q15.
84     int32_t spectrum_q15 = ((int32_t) spectrum[i]) << (15 - q_domain);
85     // Update the |threshold_spectrum|.
86     WebRtc_MeanEstimatorFix(spectrum_q15, 6, &(threshold_spectrum[i].int32_));
87     // Convert |spectrum| at current frequency bin to a binary value.
88     if (spectrum_q15 > threshold_spectrum[i].int32_) {
89       out = SetBit(out, i - kBandFirst);
90     }
91   }
92 
93   return out;
94 }
95 
BinarySpectrumFloat(const float * spectrum,SpectrumType * threshold_spectrum,int * threshold_initialized)96 static uint32_t BinarySpectrumFloat(const float* spectrum,
97                                     SpectrumType* threshold_spectrum,
98                                     int* threshold_initialized) {
99   int i = kBandFirst;
100   uint32_t out = 0;
101   const float kScale = 1 / 64.0;
102 
103   if (!(*threshold_initialized)) {
104     // Set the |threshold_spectrum| to half the input |spectrum| as starting
105     // value. This speeds up the convergence.
106     for (i = kBandFirst; i <= kBandLast; i++) {
107       if (spectrum[i] > 0.0f) {
108         threshold_spectrum[i].float_ = (spectrum[i] / 2);
109         *threshold_initialized = 1;
110       }
111     }
112   }
113 
114   for (i = kBandFirst; i <= kBandLast; i++) {
115     // Update the |threshold_spectrum|.
116     MeanEstimatorFloat(spectrum[i], kScale, &(threshold_spectrum[i].float_));
117     // Convert |spectrum| at current frequency bin to a binary value.
118     if (spectrum[i] > threshold_spectrum[i].float_) {
119       out = SetBit(out, i - kBandFirst);
120     }
121   }
122 
123   return out;
124 }
125 
WebRtc_FreeDelayEstimatorFarend(void * handle)126 void WebRtc_FreeDelayEstimatorFarend(void* handle) {
127   DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
128 
129   if (handle == NULL) {
130     return;
131   }
132 
133   free(self->mean_far_spectrum);
134   self->mean_far_spectrum = NULL;
135 
136   WebRtc_FreeBinaryDelayEstimatorFarend(self->binary_farend);
137   self->binary_farend = NULL;
138 
139   free(self);
140 }
141 
WebRtc_CreateDelayEstimatorFarend(int spectrum_size,int history_size)142 void* WebRtc_CreateDelayEstimatorFarend(int spectrum_size, int history_size) {
143   DelayEstimatorFarend* self = NULL;
144 
145   // Check if the sub band used in the delay estimation is small enough to fit
146   // the binary spectra in a uint32_t.
147   COMPILE_ASSERT(kBandLast - kBandFirst < 32);
148 
149   if (spectrum_size >= kBandLast) {
150     self = malloc(sizeof(DelayEstimatorFarend));
151   }
152 
153   if (self != NULL) {
154     int memory_fail = 0;
155 
156     // Allocate memory for the binary far-end spectrum handling.
157     self->binary_farend = WebRtc_CreateBinaryDelayEstimatorFarend(history_size);
158     memory_fail |= (self->binary_farend == NULL);
159 
160     // Allocate memory for spectrum buffers.
161     self->mean_far_spectrum = malloc(spectrum_size * sizeof(SpectrumType));
162     memory_fail |= (self->mean_far_spectrum == NULL);
163 
164     self->spectrum_size = spectrum_size;
165 
166     if (memory_fail) {
167       WebRtc_FreeDelayEstimatorFarend(self);
168       self = NULL;
169     }
170   }
171 
172   return self;
173 }
174 
WebRtc_InitDelayEstimatorFarend(void * handle)175 int WebRtc_InitDelayEstimatorFarend(void* handle) {
176   DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
177 
178   if (self == NULL) {
179     return -1;
180   }
181 
182   // Initialize far-end part of binary delay estimator.
183   WebRtc_InitBinaryDelayEstimatorFarend(self->binary_farend);
184 
185   // Set averaged far and near end spectra to zero.
186   memset(self->mean_far_spectrum, 0,
187          sizeof(SpectrumType) * self->spectrum_size);
188   // Reset initialization indicators.
189   self->far_spectrum_initialized = 0;
190 
191   return 0;
192 }
193 
WebRtc_SoftResetDelayEstimatorFarend(void * handle,int delay_shift)194 void WebRtc_SoftResetDelayEstimatorFarend(void* handle, int delay_shift) {
195   DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
196   assert(self != NULL);
197   WebRtc_SoftResetBinaryDelayEstimatorFarend(self->binary_farend, delay_shift);
198 }
199 
WebRtc_AddFarSpectrumFix(void * handle,const uint16_t * far_spectrum,int spectrum_size,int far_q)200 int WebRtc_AddFarSpectrumFix(void* handle,
201                              const uint16_t* far_spectrum,
202                              int spectrum_size,
203                              int far_q) {
204   DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
205   uint32_t binary_spectrum = 0;
206 
207   if (self == NULL) {
208     return -1;
209   }
210   if (far_spectrum == NULL) {
211     // Empty far end spectrum.
212     return -1;
213   }
214   if (spectrum_size != self->spectrum_size) {
215     // Data sizes don't match.
216     return -1;
217   }
218   if (far_q > 15) {
219     // If |far_q| is larger than 15 we cannot guarantee no wrap around.
220     return -1;
221   }
222 
223   // Get binary spectrum.
224   binary_spectrum = BinarySpectrumFix(far_spectrum, self->mean_far_spectrum,
225                                       far_q, &(self->far_spectrum_initialized));
226   WebRtc_AddBinaryFarSpectrum(self->binary_farend, binary_spectrum);
227 
228   return 0;
229 }
230 
WebRtc_AddFarSpectrumFloat(void * handle,const float * far_spectrum,int spectrum_size)231 int WebRtc_AddFarSpectrumFloat(void* handle,
232                                const float* far_spectrum,
233                                int spectrum_size) {
234   DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
235   uint32_t binary_spectrum = 0;
236 
237   if (self == NULL) {
238     return -1;
239   }
240   if (far_spectrum == NULL) {
241     // Empty far end spectrum.
242     return -1;
243   }
244   if (spectrum_size != self->spectrum_size) {
245     // Data sizes don't match.
246     return -1;
247   }
248 
249   // Get binary spectrum.
250   binary_spectrum = BinarySpectrumFloat(far_spectrum, self->mean_far_spectrum,
251                                         &(self->far_spectrum_initialized));
252   WebRtc_AddBinaryFarSpectrum(self->binary_farend, binary_spectrum);
253 
254   return 0;
255 }
256 
WebRtc_FreeDelayEstimator(void * handle)257 void WebRtc_FreeDelayEstimator(void* handle) {
258   DelayEstimator* self = (DelayEstimator*) handle;
259 
260   if (handle == NULL) {
261     return;
262   }
263 
264   free(self->mean_near_spectrum);
265   self->mean_near_spectrum = NULL;
266 
267   WebRtc_FreeBinaryDelayEstimator(self->binary_handle);
268   self->binary_handle = NULL;
269 
270   free(self);
271 }
272 
WebRtc_CreateDelayEstimator(void * farend_handle,int max_lookahead)273 void* WebRtc_CreateDelayEstimator(void* farend_handle, int max_lookahead) {
274   DelayEstimator* self = NULL;
275   DelayEstimatorFarend* farend = (DelayEstimatorFarend*) farend_handle;
276 
277   if (farend_handle != NULL) {
278     self = malloc(sizeof(DelayEstimator));
279   }
280 
281   if (self != NULL) {
282     int memory_fail = 0;
283 
284     // Allocate memory for the farend spectrum handling.
285     self->binary_handle =
286         WebRtc_CreateBinaryDelayEstimator(farend->binary_farend, max_lookahead);
287     memory_fail |= (self->binary_handle == NULL);
288 
289     // Allocate memory for spectrum buffers.
290     self->mean_near_spectrum = malloc(farend->spectrum_size *
291                                       sizeof(SpectrumType));
292     memory_fail |= (self->mean_near_spectrum == NULL);
293 
294     self->spectrum_size = farend->spectrum_size;
295 
296     if (memory_fail) {
297       WebRtc_FreeDelayEstimator(self);
298       self = NULL;
299     }
300   }
301 
302   return self;
303 }
304 
WebRtc_InitDelayEstimator(void * handle)305 int WebRtc_InitDelayEstimator(void* handle) {
306   DelayEstimator* self = (DelayEstimator*) handle;
307 
308   if (self == NULL) {
309     return -1;
310   }
311 
312   // Initialize binary delay estimator.
313   WebRtc_InitBinaryDelayEstimator(self->binary_handle);
314 
315   // Set averaged far and near end spectra to zero.
316   memset(self->mean_near_spectrum, 0,
317          sizeof(SpectrumType) * self->spectrum_size);
318   // Reset initialization indicators.
319   self->near_spectrum_initialized = 0;
320 
321   return 0;
322 }
323 
WebRtc_SoftResetDelayEstimator(void * handle,int delay_shift)324 int WebRtc_SoftResetDelayEstimator(void* handle, int delay_shift) {
325   DelayEstimator* self = (DelayEstimator*) handle;
326   assert(self != NULL);
327   return WebRtc_SoftResetBinaryDelayEstimator(self->binary_handle, delay_shift);
328 }
329 
WebRtc_set_history_size(void * handle,int history_size)330 int WebRtc_set_history_size(void* handle, int history_size) {
331   DelayEstimator* self = handle;
332 
333   if ((self == NULL) || (history_size <= 1)) {
334     return -1;
335   }
336   return WebRtc_AllocateHistoryBufferMemory(self->binary_handle, history_size);
337 }
338 
WebRtc_history_size(const void * handle)339 int WebRtc_history_size(const void* handle) {
340   const DelayEstimator* self = handle;
341 
342   if (self == NULL) {
343     return -1;
344   }
345   if (self->binary_handle->farend->history_size !=
346       self->binary_handle->history_size) {
347     // Non matching history sizes.
348     return -1;
349   }
350   return self->binary_handle->history_size;
351 }
352 
WebRtc_set_lookahead(void * handle,int lookahead)353 int WebRtc_set_lookahead(void* handle, int lookahead) {
354   DelayEstimator* self = (DelayEstimator*) handle;
355   assert(self != NULL);
356   assert(self->binary_handle != NULL);
357   if ((lookahead > self->binary_handle->near_history_size - 1) ||
358       (lookahead < 0)) {
359     return -1;
360   }
361   self->binary_handle->lookahead = lookahead;
362   return self->binary_handle->lookahead;
363 }
364 
WebRtc_lookahead(void * handle)365 int WebRtc_lookahead(void* handle) {
366   DelayEstimator* self = (DelayEstimator*) handle;
367   assert(self != NULL);
368   assert(self->binary_handle != NULL);
369   return self->binary_handle->lookahead;
370 }
371 
WebRtc_set_allowed_offset(void * handle,int allowed_offset)372 int WebRtc_set_allowed_offset(void* handle, int allowed_offset) {
373   DelayEstimator* self = (DelayEstimator*) handle;
374 
375   if ((self == NULL) || (allowed_offset < 0)) {
376     return -1;
377   }
378   self->binary_handle->allowed_offset = allowed_offset;
379   return 0;
380 }
381 
WebRtc_get_allowed_offset(const void * handle)382 int WebRtc_get_allowed_offset(const void* handle) {
383   const DelayEstimator* self = (const DelayEstimator*) handle;
384 
385   if (self == NULL) {
386     return -1;
387   }
388   return self->binary_handle->allowed_offset;
389 }
390 
WebRtc_enable_robust_validation(void * handle,int enable)391 int WebRtc_enable_robust_validation(void* handle, int enable) {
392   DelayEstimator* self = (DelayEstimator*) handle;
393 
394   if (self == NULL) {
395     return -1;
396   }
397   if ((enable < 0) || (enable > 1)) {
398     return -1;
399   }
400   assert(self->binary_handle != NULL);
401   self->binary_handle->robust_validation_enabled = enable;
402   return 0;
403 }
404 
WebRtc_is_robust_validation_enabled(const void * handle)405 int WebRtc_is_robust_validation_enabled(const void* handle) {
406   const DelayEstimator* self = (const DelayEstimator*) handle;
407 
408   if (self == NULL) {
409     return -1;
410   }
411   return self->binary_handle->robust_validation_enabled;
412 }
413 
WebRtc_DelayEstimatorProcessFix(void * handle,const uint16_t * near_spectrum,int spectrum_size,int near_q)414 int WebRtc_DelayEstimatorProcessFix(void* handle,
415                                     const uint16_t* near_spectrum,
416                                     int spectrum_size,
417                                     int near_q) {
418   DelayEstimator* self = (DelayEstimator*) handle;
419   uint32_t binary_spectrum = 0;
420 
421   if (self == NULL) {
422     return -1;
423   }
424   if (near_spectrum == NULL) {
425     // Empty near end spectrum.
426     return -1;
427   }
428   if (spectrum_size != self->spectrum_size) {
429     // Data sizes don't match.
430     return -1;
431   }
432   if (near_q > 15) {
433     // If |near_q| is larger than 15 we cannot guarantee no wrap around.
434     return -1;
435   }
436 
437   // Get binary spectra.
438   binary_spectrum = BinarySpectrumFix(near_spectrum,
439                                       self->mean_near_spectrum,
440                                       near_q,
441                                       &(self->near_spectrum_initialized));
442 
443   return WebRtc_ProcessBinarySpectrum(self->binary_handle, binary_spectrum);
444 }
445 
WebRtc_DelayEstimatorProcessFloat(void * handle,const float * near_spectrum,int spectrum_size)446 int WebRtc_DelayEstimatorProcessFloat(void* handle,
447                                       const float* near_spectrum,
448                                       int spectrum_size) {
449   DelayEstimator* self = (DelayEstimator*) handle;
450   uint32_t binary_spectrum = 0;
451 
452   if (self == NULL) {
453     return -1;
454   }
455   if (near_spectrum == NULL) {
456     // Empty near end spectrum.
457     return -1;
458   }
459   if (spectrum_size != self->spectrum_size) {
460     // Data sizes don't match.
461     return -1;
462   }
463 
464   // Get binary spectrum.
465   binary_spectrum = BinarySpectrumFloat(near_spectrum, self->mean_near_spectrum,
466                                         &(self->near_spectrum_initialized));
467 
468   return WebRtc_ProcessBinarySpectrum(self->binary_handle, binary_spectrum);
469 }
470 
WebRtc_last_delay(void * handle)471 int WebRtc_last_delay(void* handle) {
472   DelayEstimator* self = (DelayEstimator*) handle;
473 
474   if (self == NULL) {
475     return -1;
476   }
477 
478   return WebRtc_binary_last_delay(self->binary_handle);
479 }
480 
WebRtc_last_delay_quality(void * handle)481 float WebRtc_last_delay_quality(void* handle) {
482   DelayEstimator* self = (DelayEstimator*) handle;
483   assert(self != NULL);
484   return WebRtc_binary_last_delay_quality(self->binary_handle);
485 }
486