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