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. 23enum { kBandFirst = 12 }; 24enum { kBandLast = 43 }; 25 26static __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// 43static 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// 61static 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 96static 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 126void 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 142void* 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 175int 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 194void 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 200int 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 229int 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 254void 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 270void* 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 302int 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 321int 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 327int 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 339int 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 346int 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 356int 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 365int 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 379int 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 388int 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 420int 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 445int 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 455float 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