• 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/interface/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(uint16_t * spectrum,SpectrumType * threshold_spectrum,int q_domain,int * threshold_initialized)61 static uint32_t BinarySpectrumFix(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(float * spectrum,SpectrumType * threshold_spectrum,int * threshold_initialized)96 static uint32_t BinarySpectrumFloat(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(DelayEstimator));
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,uint16_t * far_spectrum,int spectrum_size,int far_q)200 int WebRtc_AddFarSpectrumFix(void* handle, uint16_t* far_spectrum,
201                              int spectrum_size, int far_q) {
202   DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
203   uint32_t binary_spectrum = 0;
204 
205   if (self == NULL) {
206     return -1;
207   }
208   if (far_spectrum == NULL) {
209     // Empty far end spectrum.
210     return -1;
211   }
212   if (spectrum_size != self->spectrum_size) {
213     // Data sizes don't match.
214     return -1;
215   }
216   if (far_q > 15) {
217     // If |far_q| is larger than 15 we cannot guarantee no wrap around.
218     return -1;
219   }
220 
221   // Get binary spectrum.
222   binary_spectrum = BinarySpectrumFix(far_spectrum, self->mean_far_spectrum,
223                                       far_q, &(self->far_spectrum_initialized));
224   WebRtc_AddBinaryFarSpectrum(self->binary_farend, binary_spectrum);
225 
226   return 0;
227 }
228 
WebRtc_AddFarSpectrumFloat(void * handle,float * far_spectrum,int spectrum_size)229 int WebRtc_AddFarSpectrumFloat(void* handle, float* far_spectrum,
230                                int spectrum_size) {
231   DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
232   uint32_t binary_spectrum = 0;
233 
234   if (self == NULL) {
235     return -1;
236   }
237   if (far_spectrum == NULL) {
238     // Empty far end spectrum.
239     return -1;
240   }
241   if (spectrum_size != self->spectrum_size) {
242     // Data sizes don't match.
243     return -1;
244   }
245 
246   // Get binary spectrum.
247   binary_spectrum = BinarySpectrumFloat(far_spectrum, self->mean_far_spectrum,
248                                         &(self->far_spectrum_initialized));
249   WebRtc_AddBinaryFarSpectrum(self->binary_farend, binary_spectrum);
250 
251   return 0;
252 }
253 
WebRtc_FreeDelayEstimator(void * handle)254 void WebRtc_FreeDelayEstimator(void* handle) {
255   DelayEstimator* self = (DelayEstimator*) handle;
256 
257   if (handle == NULL) {
258     return;
259   }
260 
261   free(self->mean_near_spectrum);
262   self->mean_near_spectrum = NULL;
263 
264   WebRtc_FreeBinaryDelayEstimator(self->binary_handle);
265   self->binary_handle = NULL;
266 
267   free(self);
268 }
269 
WebRtc_CreateDelayEstimator(void * farend_handle,int max_lookahead)270 void* WebRtc_CreateDelayEstimator(void* farend_handle, int max_lookahead) {
271   DelayEstimator* self = NULL;
272   DelayEstimatorFarend* farend = (DelayEstimatorFarend*) farend_handle;
273 
274   if (farend_handle != NULL) {
275     self = malloc(sizeof(DelayEstimator));
276   }
277 
278   if (self != NULL) {
279     int memory_fail = 0;
280 
281     // Allocate memory for the farend spectrum handling.
282     self->binary_handle =
283         WebRtc_CreateBinaryDelayEstimator(farend->binary_farend, max_lookahead);
284     memory_fail |= (self->binary_handle == NULL);
285 
286     // Allocate memory for spectrum buffers.
287     self->mean_near_spectrum = malloc(farend->spectrum_size *
288                                       sizeof(SpectrumType));
289     memory_fail |= (self->mean_near_spectrum == NULL);
290 
291     self->spectrum_size = farend->spectrum_size;
292 
293     if (memory_fail) {
294       WebRtc_FreeDelayEstimator(self);
295       self = NULL;
296     }
297   }
298 
299   return self;
300 }
301 
WebRtc_InitDelayEstimator(void * handle)302 int WebRtc_InitDelayEstimator(void* handle) {
303   DelayEstimator* self = (DelayEstimator*) handle;
304 
305   if (self == NULL) {
306     return -1;
307   }
308 
309   // Initialize binary delay estimator.
310   WebRtc_InitBinaryDelayEstimator(self->binary_handle);
311 
312   // Set averaged far and near end spectra to zero.
313   memset(self->mean_near_spectrum, 0,
314          sizeof(SpectrumType) * self->spectrum_size);
315   // Reset initialization indicators.
316   self->near_spectrum_initialized = 0;
317 
318   return 0;
319 }
320 
WebRtc_SoftResetDelayEstimator(void * handle,int delay_shift)321 int WebRtc_SoftResetDelayEstimator(void* handle, int delay_shift) {
322   DelayEstimator* self = (DelayEstimator*) handle;
323   assert(self != NULL);
324   return WebRtc_SoftResetBinaryDelayEstimator(self->binary_handle, delay_shift);
325 }
326 
WebRtc_set_lookahead(void * handle,int lookahead)327 int WebRtc_set_lookahead(void* handle, int lookahead) {
328   DelayEstimator* self = (DelayEstimator*) handle;
329   assert(self != NULL);
330   assert(self->binary_handle != NULL);
331   if ((lookahead > self->binary_handle->near_history_size - 1) ||
332       (lookahead < 0)) {
333     return -1;
334   }
335   self->binary_handle->lookahead = lookahead;
336   return self->binary_handle->lookahead;
337 }
338 
WebRtc_lookahead(void * handle)339 int WebRtc_lookahead(void* handle) {
340   DelayEstimator* self = (DelayEstimator*) handle;
341   assert(self != NULL);
342   assert(self->binary_handle != NULL);
343   return self->binary_handle->lookahead;
344 }
345 
WebRtc_set_allowed_offset(void * handle,int allowed_offset)346 int WebRtc_set_allowed_offset(void* handle, int allowed_offset) {
347   DelayEstimator* self = (DelayEstimator*) handle;
348 
349   if ((self == NULL) || (allowed_offset < 0)) {
350     return -1;
351   }
352   self->binary_handle->allowed_offset = allowed_offset;
353   return 0;
354 }
355 
WebRtc_get_allowed_offset(const void * handle)356 int WebRtc_get_allowed_offset(const void* handle) {
357   const DelayEstimator* self = (const DelayEstimator*) handle;
358 
359   if (self == NULL) {
360     return -1;
361   }
362   return self->binary_handle->allowed_offset;
363 }
364 
WebRtc_enable_robust_validation(void * handle,int enable)365 int WebRtc_enable_robust_validation(void* handle, int enable) {
366   DelayEstimator* self = (DelayEstimator*) handle;
367 
368   if (self == NULL) {
369     return -1;
370   }
371   if ((enable < 0) || (enable > 1)) {
372     return -1;
373   }
374   assert(self->binary_handle != NULL);
375   self->binary_handle->robust_validation_enabled = enable;
376   return 0;
377 }
378 
WebRtc_is_robust_validation_enabled(const void * handle)379 int WebRtc_is_robust_validation_enabled(const void* handle) {
380   const DelayEstimator* self = (const DelayEstimator*) handle;
381 
382   if (self == NULL) {
383     return -1;
384   }
385   return self->binary_handle->robust_validation_enabled;
386 }
387 
WebRtc_DelayEstimatorProcessFix(void * handle,uint16_t * near_spectrum,int spectrum_size,int near_q)388 int WebRtc_DelayEstimatorProcessFix(void* handle,
389                                     uint16_t* near_spectrum,
390                                     int spectrum_size,
391                                     int near_q) {
392   DelayEstimator* self = (DelayEstimator*) handle;
393   uint32_t binary_spectrum = 0;
394 
395   if (self == NULL) {
396     return -1;
397   }
398   if (near_spectrum == NULL) {
399     // Empty near end spectrum.
400     return -1;
401   }
402   if (spectrum_size != self->spectrum_size) {
403     // Data sizes don't match.
404     return -1;
405   }
406   if (near_q > 15) {
407     // If |near_q| is larger than 15 we cannot guarantee no wrap around.
408     return -1;
409   }
410 
411   // Get binary spectra.
412   binary_spectrum = BinarySpectrumFix(near_spectrum,
413                                       self->mean_near_spectrum,
414                                       near_q,
415                                       &(self->near_spectrum_initialized));
416 
417   return WebRtc_ProcessBinarySpectrum(self->binary_handle, binary_spectrum);
418 }
419 
WebRtc_DelayEstimatorProcessFloat(void * handle,float * near_spectrum,int spectrum_size)420 int WebRtc_DelayEstimatorProcessFloat(void* handle,
421                                       float* near_spectrum,
422                                       int spectrum_size) {
423   DelayEstimator* self = (DelayEstimator*) handle;
424   uint32_t binary_spectrum = 0;
425 
426   if (self == NULL) {
427     return -1;
428   }
429   if (near_spectrum == NULL) {
430     // Empty near end spectrum.
431     return -1;
432   }
433   if (spectrum_size != self->spectrum_size) {
434     // Data sizes don't match.
435     return -1;
436   }
437 
438   // Get binary spectrum.
439   binary_spectrum = BinarySpectrumFloat(near_spectrum, self->mean_near_spectrum,
440                                         &(self->near_spectrum_initialized));
441 
442   return WebRtc_ProcessBinarySpectrum(self->binary_handle, binary_spectrum);
443 }
444 
WebRtc_last_delay(void * handle)445 int WebRtc_last_delay(void* handle) {
446   DelayEstimator* self = (DelayEstimator*) handle;
447 
448   if (self == NULL) {
449     return -1;
450   }
451 
452   return WebRtc_binary_last_delay(self->binary_handle);
453 }
454 
WebRtc_last_delay_quality(void * handle)455 float WebRtc_last_delay_quality(void* handle) {
456   DelayEstimator* self = (DelayEstimator*) handle;
457   assert(self != NULL);
458   return WebRtc_binary_last_delay_quality(self->binary_handle);
459 }
460