OLD | NEW |
| (Empty) |
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 | |
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 // | |
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 // | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 } | |
OLD | NEW |