| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 | 180 |
| 181 WebRtcAec_FreeAec(aecpc->aec); | 181 WebRtcAec_FreeAec(aecpc->aec); |
| 182 WebRtcAec_FreeResampler(aecpc->resampler); | 182 WebRtcAec_FreeResampler(aecpc->resampler); |
| 183 free(aecpc); | 183 free(aecpc); |
| 184 } | 184 } |
| 185 | 185 |
| 186 int32_t WebRtcAec_Init(void* aecInst, int32_t sampFreq, int32_t scSampFreq) { | 186 int32_t WebRtcAec_Init(void* aecInst, int32_t sampFreq, int32_t scSampFreq) { |
| 187 Aec* aecpc = aecInst; | 187 Aec* aecpc = aecInst; |
| 188 AecConfig aecConfig; | 188 AecConfig aecConfig; |
| 189 | 189 |
| 190 if (sampFreq != 8000 && | 190 if (sampFreq != 8000 && sampFreq != 16000 && sampFreq != 32000 && |
| 191 sampFreq != 16000 && | |
| 192 sampFreq != 32000 && | |
| 193 sampFreq != 48000) { | 191 sampFreq != 48000) { |
| 194 return AEC_BAD_PARAMETER_ERROR; | 192 return AEC_BAD_PARAMETER_ERROR; |
| 195 } | 193 } |
| 196 aecpc->sampFreq = sampFreq; | 194 aecpc->sampFreq = sampFreq; |
| 197 | 195 |
| 198 if (scSampFreq < 1 || scSampFreq > 96000) { | 196 if (scSampFreq < 1 || scSampFreq > 96000) { |
| 199 return AEC_BAD_PARAMETER_ERROR; | 197 return AEC_BAD_PARAMETER_ERROR; |
| 200 } | 198 } |
| 201 aecpc->scSampFreq = scSampFreq; | 199 aecpc->scSampFreq = scSampFreq; |
| 202 | 200 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 226 aecpc->rate_factor = aecpc->splitSampFreq / 8000; | 224 aecpc->rate_factor = aecpc->splitSampFreq / 8000; |
| 227 | 225 |
| 228 aecpc->sum = 0; | 226 aecpc->sum = 0; |
| 229 aecpc->counter = 0; | 227 aecpc->counter = 0; |
| 230 aecpc->checkBuffSize = 1; | 228 aecpc->checkBuffSize = 1; |
| 231 aecpc->firstVal = 0; | 229 aecpc->firstVal = 0; |
| 232 | 230 |
| 233 // We skip the startup_phase completely (setting to 0) if DA-AEC is enabled, | 231 // We skip the startup_phase completely (setting to 0) if DA-AEC is enabled, |
| 234 // but not extended_filter mode. | 232 // but not extended_filter mode. |
| 235 aecpc->startup_phase = WebRtcAec_extended_filter_enabled(aecpc->aec) || | 233 aecpc->startup_phase = WebRtcAec_extended_filter_enabled(aecpc->aec) || |
| 236 !WebRtcAec_delay_agnostic_enabled(aecpc->aec); | 234 !WebRtcAec_delay_agnostic_enabled(aecpc->aec); |
| 237 aecpc->bufSizeStart = 0; | 235 aecpc->bufSizeStart = 0; |
| 238 aecpc->checkBufSizeCtr = 0; | 236 aecpc->checkBufSizeCtr = 0; |
| 239 aecpc->msInSndCardBuf = 0; | 237 aecpc->msInSndCardBuf = 0; |
| 240 aecpc->filtDelay = -1; // -1 indicates an initialized state. | 238 aecpc->filtDelay = -1; // -1 indicates an initialized state. |
| 241 aecpc->timeForDelayChange = 0; | 239 aecpc->timeForDelayChange = 0; |
| 242 aecpc->knownDelay = 0; | 240 aecpc->knownDelay = 0; |
| 243 aecpc->lastDelayDiff = 0; | 241 aecpc->lastDelayDiff = 0; |
| 244 | 242 |
| 245 aecpc->skewFrCtr = 0; | 243 aecpc->skewFrCtr = 0; |
| 246 aecpc->resample = kAecFalse; | 244 aecpc->resample = kAecFalse; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 // only buffer L band for farend | 283 // only buffer L band for farend |
| 286 int32_t WebRtcAec_BufferFarend(void* aecInst, | 284 int32_t WebRtcAec_BufferFarend(void* aecInst, |
| 287 const float* farend, | 285 const float* farend, |
| 288 size_t nrOfSamples) { | 286 size_t nrOfSamples) { |
| 289 Aec* aecpc = aecInst; | 287 Aec* aecpc = aecInst; |
| 290 size_t newNrOfSamples = nrOfSamples; | 288 size_t newNrOfSamples = nrOfSamples; |
| 291 float new_farend[MAX_RESAMP_LEN]; | 289 float new_farend[MAX_RESAMP_LEN]; |
| 292 const float* farend_ptr = farend; | 290 const float* farend_ptr = farend; |
| 293 | 291 |
| 294 // Get any error caused by buffering the farend signal. | 292 // Get any error caused by buffering the farend signal. |
| 295 int32_t error_code = WebRtcAec_GetBufferFarendError(aecInst, farend, | 293 int32_t error_code = |
| 296 nrOfSamples); | 294 WebRtcAec_GetBufferFarendError(aecInst, farend, nrOfSamples); |
| 297 | 295 |
| 298 if (error_code != 0) | 296 if (error_code != 0) |
| 299 return error_code; | 297 return error_code; |
| 300 | 298 |
| 301 | |
| 302 if (aecpc->skewMode == kAecTrue && aecpc->resample == kAecTrue) { | 299 if (aecpc->skewMode == kAecTrue && aecpc->resample == kAecTrue) { |
| 303 // Resample and get a new number of samples | 300 // Resample and get a new number of samples |
| 304 WebRtcAec_ResampleLinear(aecpc->resampler, | 301 WebRtcAec_ResampleLinear(aecpc->resampler, farend, nrOfSamples, aecpc->skew, |
| 305 farend, | 302 new_farend, &newNrOfSamples); |
| 306 nrOfSamples, | |
| 307 aecpc->skew, | |
| 308 new_farend, | |
| 309 &newNrOfSamples); | |
| 310 farend_ptr = new_farend; | 303 farend_ptr = new_farend; |
| 311 } | 304 } |
| 312 | 305 |
| 313 aecpc->farend_started = 1; | 306 aecpc->farend_started = 1; |
| 314 WebRtcAec_SetSystemDelay( | 307 WebRtcAec_SetSystemDelay( |
| 315 aecpc->aec, WebRtcAec_system_delay(aecpc->aec) + (int)newNrOfSamples); | 308 aecpc->aec, WebRtcAec_system_delay(aecpc->aec) + (int)newNrOfSamples); |
| 316 | 309 |
| 317 // Write the time-domain data to |far_pre_buf|. | 310 // Write the time-domain data to |far_pre_buf|. |
| 318 WebRtc_WriteBuffer(aecpc->far_pre_buf, farend_ptr, newNrOfSamples); | 311 WebRtc_WriteBuffer(aecpc->far_pre_buf, farend_ptr, newNrOfSamples); |
| 319 | 312 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 if (msInSndCardBuf < 0) { | 354 if (msInSndCardBuf < 0) { |
| 362 msInSndCardBuf = 0; | 355 msInSndCardBuf = 0; |
| 363 retVal = AEC_BAD_PARAMETER_WARNING; | 356 retVal = AEC_BAD_PARAMETER_WARNING; |
| 364 } else if (msInSndCardBuf > kMaxTrustedDelayMs) { | 357 } else if (msInSndCardBuf > kMaxTrustedDelayMs) { |
| 365 // The clamping is now done in ProcessExtended/Normal(). | 358 // The clamping is now done in ProcessExtended/Normal(). |
| 366 retVal = AEC_BAD_PARAMETER_WARNING; | 359 retVal = AEC_BAD_PARAMETER_WARNING; |
| 367 } | 360 } |
| 368 | 361 |
| 369 // This returns the value of aec->extended_filter_enabled. | 362 // This returns the value of aec->extended_filter_enabled. |
| 370 if (WebRtcAec_extended_filter_enabled(aecpc->aec)) { | 363 if (WebRtcAec_extended_filter_enabled(aecpc->aec)) { |
| 371 ProcessExtended(aecpc, | 364 ProcessExtended(aecpc, nearend, num_bands, out, nrOfSamples, msInSndCardBuf, |
| 372 nearend, | |
| 373 num_bands, | |
| 374 out, | |
| 375 nrOfSamples, | |
| 376 msInSndCardBuf, | |
| 377 skew); | 365 skew); |
| 378 } else { | 366 } else { |
| 379 retVal = ProcessNormal(aecpc, | 367 retVal = ProcessNormal(aecpc, nearend, num_bands, out, nrOfSamples, |
| 380 nearend, | 368 msInSndCardBuf, skew); |
| 381 num_bands, | |
| 382 out, | |
| 383 nrOfSamples, | |
| 384 msInSndCardBuf, | |
| 385 skew); | |
| 386 } | 369 } |
| 387 | 370 |
| 388 #ifdef WEBRTC_AEC_DEBUG_DUMP | 371 #ifdef WEBRTC_AEC_DEBUG_DUMP |
| 389 { | 372 { |
| 390 int16_t far_buf_size_ms = (int16_t)(WebRtcAec_system_delay(aecpc->aec) / | 373 int16_t far_buf_size_ms = (int16_t)(WebRtcAec_system_delay(aecpc->aec) / |
| 391 (sampMsNb * aecpc->rate_factor)); | 374 (sampMsNb * aecpc->rate_factor)); |
| 392 (void)fwrite(&far_buf_size_ms, 2, 1, aecpc->bufFile); | 375 (void)fwrite(&far_buf_size_ms, 2, 1, aecpc->bufFile); |
| 393 (void)fwrite( | 376 (void)fwrite(&aecpc->knownDelay, sizeof(aecpc->knownDelay), 1, |
| 394 &aecpc->knownDelay, sizeof(aecpc->knownDelay), 1, aecpc->delayFile); | 377 aecpc->delayFile); |
| 395 } | 378 } |
| 396 #endif | 379 #endif |
| 397 | 380 |
| 398 return retVal; | 381 return retVal; |
| 399 } | 382 } |
| 400 | 383 |
| 401 int WebRtcAec_set_config(void* handle, AecConfig config) { | 384 int WebRtcAec_set_config(void* handle, AecConfig config) { |
| 402 Aec* self = (Aec*)handle; | 385 Aec* self = (Aec*)handle; |
| 403 if (self->initFlag != initCheck) { | 386 if (self->initFlag != initCheck) { |
| 404 return AEC_UNINITIALIZED_ERROR; | 387 return AEC_UNINITIALIZED_ERROR; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 416 } | 399 } |
| 417 | 400 |
| 418 if (config.metricsMode != kAecFalse && config.metricsMode != kAecTrue) { | 401 if (config.metricsMode != kAecFalse && config.metricsMode != kAecTrue) { |
| 419 return AEC_BAD_PARAMETER_ERROR; | 402 return AEC_BAD_PARAMETER_ERROR; |
| 420 } | 403 } |
| 421 | 404 |
| 422 if (config.delay_logging != kAecFalse && config.delay_logging != kAecTrue) { | 405 if (config.delay_logging != kAecFalse && config.delay_logging != kAecTrue) { |
| 423 return AEC_BAD_PARAMETER_ERROR; | 406 return AEC_BAD_PARAMETER_ERROR; |
| 424 } | 407 } |
| 425 | 408 |
| 426 WebRtcAec_SetConfigCore( | 409 WebRtcAec_SetConfigCore(self->aec, config.nlpMode, config.metricsMode, |
| 427 self->aec, config.nlpMode, config.metricsMode, config.delay_logging); | 410 config.delay_logging); |
| 428 return 0; | 411 return 0; |
| 429 } | 412 } |
| 430 | 413 |
| 431 int WebRtcAec_get_echo_status(void* handle, int* status) { | 414 int WebRtcAec_get_echo_status(void* handle, int* status) { |
| 432 Aec* self = (Aec*)handle; | 415 Aec* self = (Aec*)handle; |
| 433 if (status == NULL) { | 416 if (status == NULL) { |
| 434 return AEC_NULL_POINTER_ERROR; | 417 return AEC_NULL_POINTER_ERROR; |
| 435 } | 418 } |
| 436 if (self->initFlag != initCheck) { | 419 if (self->initFlag != initCheck) { |
| 437 return AEC_UNINITIALIZED_ERROR; | 420 return AEC_UNINITIALIZED_ERROR; |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 545 if (median == NULL) { | 528 if (median == NULL) { |
| 546 return AEC_NULL_POINTER_ERROR; | 529 return AEC_NULL_POINTER_ERROR; |
| 547 } | 530 } |
| 548 if (std == NULL) { | 531 if (std == NULL) { |
| 549 return AEC_NULL_POINTER_ERROR; | 532 return AEC_NULL_POINTER_ERROR; |
| 550 } | 533 } |
| 551 if (self->initFlag != initCheck) { | 534 if (self->initFlag != initCheck) { |
| 552 return AEC_UNINITIALIZED_ERROR; | 535 return AEC_UNINITIALIZED_ERROR; |
| 553 } | 536 } |
| 554 if (WebRtcAec_GetDelayMetricsCore(self->aec, median, std, | 537 if (WebRtcAec_GetDelayMetricsCore(self->aec, median, std, |
| 555 fraction_poor_delays) == | 538 fraction_poor_delays) == -1) { |
| 556 -1) { | |
| 557 // Logging disabled. | 539 // Logging disabled. |
| 558 return AEC_UNSUPPORTED_FUNCTION_ERROR; | 540 return AEC_UNSUPPORTED_FUNCTION_ERROR; |
| 559 } | 541 } |
| 560 | 542 |
| 561 return 0; | 543 return 0; |
| 562 } | 544 } |
| 563 | 545 |
| 564 | |
| 565 AecCore* WebRtcAec_aec_core(void* handle) { | 546 AecCore* WebRtcAec_aec_core(void* handle) { |
| 566 if (!handle) { | 547 if (!handle) { |
| 567 return NULL; | 548 return NULL; |
| 568 } | 549 } |
| 569 return ((Aec*)handle)->aec; | 550 return ((Aec*)handle)->aec; |
| 570 } | 551 } |
| 571 | 552 |
| 572 static int ProcessNormal(Aec* aecpc, | 553 static int ProcessNormal(Aec* aecpc, |
| 573 const float* const* nearend, | 554 const float* const* nearend, |
| 574 size_t num_bands, | 555 size_t num_bands, |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 699 } | 680 } |
| 700 } | 681 } |
| 701 } else { | 682 } else { |
| 702 // AEC is enabled. | 683 // AEC is enabled. |
| 703 EstBufDelayNormal(aecpc); | 684 EstBufDelayNormal(aecpc); |
| 704 | 685 |
| 705 // Call the AEC. | 686 // Call the AEC. |
| 706 // TODO(bjornv): Re-structure such that we don't have to pass | 687 // TODO(bjornv): Re-structure such that we don't have to pass |
| 707 // |aecpc->knownDelay| as input. Change name to something like | 688 // |aecpc->knownDelay| as input. Change name to something like |
| 708 // |system_buffer_diff|. | 689 // |system_buffer_diff|. |
| 709 WebRtcAec_ProcessFrames(aecpc->aec, | 690 WebRtcAec_ProcessFrames(aecpc->aec, nearend, num_bands, nrOfSamples, |
| 710 nearend, | 691 aecpc->knownDelay, out); |
| 711 num_bands, | |
| 712 nrOfSamples, | |
| 713 aecpc->knownDelay, | |
| 714 out); | |
| 715 } | 692 } |
| 716 | 693 |
| 717 return retVal; | 694 return retVal; |
| 718 } | 695 } |
| 719 | 696 |
| 720 static void ProcessExtended(Aec* self, | 697 static void ProcessExtended(Aec* self, |
| 721 const float* const* near, | 698 const float* const* near, |
| 722 size_t num_bands, | 699 size_t num_bands, |
| 723 float* const* out, | 700 float* const* out, |
| 724 size_t num_samples, | 701 size_t num_samples, |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 778 | 755 |
| 779 EstBufDelayExtended(self); | 756 EstBufDelayExtended(self); |
| 780 | 757 |
| 781 { | 758 { |
| 782 // |delay_diff_offset| gives us the option to manually rewind the delay on | 759 // |delay_diff_offset| gives us the option to manually rewind the delay on |
| 783 // very low delay platforms which can't be expressed purely through | 760 // very low delay platforms which can't be expressed purely through |
| 784 // |reported_delay_ms|. | 761 // |reported_delay_ms|. |
| 785 const int adjusted_known_delay = | 762 const int adjusted_known_delay = |
| 786 WEBRTC_SPL_MAX(0, self->knownDelay + delay_diff_offset); | 763 WEBRTC_SPL_MAX(0, self->knownDelay + delay_diff_offset); |
| 787 | 764 |
| 788 WebRtcAec_ProcessFrames(self->aec, | 765 WebRtcAec_ProcessFrames(self->aec, near, num_bands, num_samples, |
| 789 near, | 766 adjusted_known_delay, out); |
| 790 num_bands, | |
| 791 num_samples, | |
| 792 adjusted_known_delay, | |
| 793 out); | |
| 794 } | 767 } |
| 795 } | 768 } |
| 796 | 769 |
| 797 static void EstBufDelayNormal(Aec* aecpc) { | 770 static void EstBufDelayNormal(Aec* aecpc) { |
| 798 int nSampSndCard = aecpc->msInSndCardBuf * sampMsNb * aecpc->rate_factor; | 771 int nSampSndCard = aecpc->msInSndCardBuf * sampMsNb * aecpc->rate_factor; |
| 799 int current_delay = nSampSndCard - WebRtcAec_system_delay(aecpc->aec); | 772 int current_delay = nSampSndCard - WebRtcAec_system_delay(aecpc->aec); |
| 800 int delay_difference = 0; | 773 int delay_difference = 0; |
| 801 | 774 |
| 802 // Before we proceed with the delay estimate filtering we: | 775 // Before we proceed with the delay estimate filtering we: |
| 803 // 1) Compensate for the frame that will be read. | 776 // 1) Compensate for the frame that will be read. |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 893 } | 866 } |
| 894 } else { | 867 } else { |
| 895 self->timeForDelayChange = 0; | 868 self->timeForDelayChange = 0; |
| 896 } | 869 } |
| 897 self->lastDelayDiff = delay_difference; | 870 self->lastDelayDiff = delay_difference; |
| 898 | 871 |
| 899 if (self->timeForDelayChange > 25) { | 872 if (self->timeForDelayChange > 25) { |
| 900 self->knownDelay = WEBRTC_SPL_MAX((int)self->filtDelay - 256, 0); | 873 self->knownDelay = WEBRTC_SPL_MAX((int)self->filtDelay - 256, 0); |
| 901 } | 874 } |
| 902 } | 875 } |
| OLD | NEW |