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 |