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