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