From a919d3a643c51adc42df39cdafda32559294b460 Mon Sep 17 00:00:00 2001 From: "andrew@webrtc.org" Date: Sun, 27 Nov 2011 23:40:58 +0000 Subject: [PATCH] Don't return a zero delay with insufficient data. For estimating a delay over a long segment (e.g. a file) this can throw off the estimate. Better not to add values to the AEC's histogram until they're reliable. BUG= TEST=audiproc, audioproc_unittest Review URL: http://webrtc-codereview.appspot.com/292004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@1035 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../audio_processing/aec/echo_cancellation.c | 5 +++- src/modules/audio_processing/aecm/aecm_core.c | 25 +++++++++--------- .../utility/delay_estimator.c | 5 ++-- .../utility/delay_estimator.h | 2 ++ .../utility/delay_estimator_wrapper.h | 2 ++ .../audio_processing/output_data_float.pb | Bin 1340 -> 1412 bytes 6 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/modules/audio_processing/aec/echo_cancellation.c b/src/modules/audio_processing/aec/echo_cancellation.c index 91e968df1..2e1f8bb7c 100644 --- a/src/modules/audio_processing/aec/echo_cancellation.c +++ b/src/modules/audio_processing/aec/echo_cancellation.c @@ -367,6 +367,7 @@ WebRtc_Word32 WebRtcAec_Process(void *aecInst, const WebRtc_Word16 *nearend, aecpc->lastError = AEC_BAD_PARAMETER_WARNING; retVal = -1; } + // TODO(andrew): we need to investigate if this +10 is really wanted. msInSndCardBuf += 10; aecpc->msInSndCardBuf = msInSndCardBuf; @@ -752,7 +753,9 @@ int WebRtcAec_GetDelayMetrics(void* handle, int* median, int* std) { num_delay_values += self->aec->delay_histogram[i]; } if (num_delay_values == 0) { - // We have no new delay value data + // We have no new delay value data. Even though -1 is a valid estimate, it + // will practically never be used since multiples of |kMsPerBlock| will + // always be returned. *median = -1; *std = -1; return 0; diff --git a/src/modules/audio_processing/aecm/aecm_core.c b/src/modules/audio_processing/aecm/aecm_core.c index 546ad34f9..b80147b73 100644 --- a/src/modules/audio_processing/aecm/aecm_core.c +++ b/src/modules/audio_processing/aecm/aecm_core.c @@ -144,6 +144,7 @@ static void UpdateFarHistory(AecmCore_t* self, // // Inputs: // - self : Pointer to the AECM instance. +// - delay : Current delay estimate. // // Output: // - far_q : The Q-domain of the aligned far end spectrum @@ -152,11 +153,10 @@ static void UpdateFarHistory(AecmCore_t* self, // - far_spectrum : Pointer to the aligned far end spectrum // NULL - Error // -static const uint16_t* AlignedFarend(AecmCore_t* self, int* far_q) { +static const uint16_t* AlignedFarend(AecmCore_t* self, int* far_q, int delay) { int buffer_position = 0; assert(self != NULL); - buffer_position = self->far_history_pos - - WebRtc_last_delay(self->delay_estimator); + buffer_position = self->far_history_pos - delay; // Check buffer position if (buffer_position < 0) { @@ -308,9 +308,6 @@ int WebRtcAecm_InitCore(AecmCore_t * const aecm, int samplingFreq) memset(aecm->far_q_domains, 0, sizeof(int) * MAX_DELAY); aecm->far_history_pos = MAX_DELAY; - // Initialize to reasonable values - aecm->currentDelay = 8; - aecm->nlpFlag = 1; aecm->fixedDelay = -1; @@ -1215,7 +1212,7 @@ int WebRtcAecm_ProcessBlock(AecmCore_t * aecm, WebRtc_Word16 hnl[PART_LEN1]; WebRtc_Word16 numPosCoef = 0; WebRtc_Word16 nlpGain = ONE_Q14; - WebRtc_Word16 delay; + int delay; WebRtc_Word16 tmp16no1; WebRtc_Word16 tmp16no2; WebRtc_Word16 mu; @@ -1312,21 +1309,23 @@ int WebRtcAecm_ProcessBlock(AecmCore_t * aecm, PART_LEN1, far_q, aecm->currentVADValue); - if (delay < 0) + if (delay == -1) { return -1; } + else if (delay == -2) + { + // If the delay is unknown, we assume zero. + // NOTE: this will have to be adjusted if we ever add lookahead. + delay = 0; + } if (aecm->fixedDelay >= 0) { - // TODO(bjornv): Make this work in practice, that is, get proper - // aligned farend. // Use fixed delay delay = aecm->fixedDelay; } - aecm->currentDelay = delay; - #ifdef ARM_WINM_LOG_ // measure tick end QueryPerformanceCounter((LARGE_INTEGER*)&end); @@ -1337,7 +1336,7 @@ int WebRtcAecm_ProcessBlock(AecmCore_t * aecm, QueryPerformanceCounter((LARGE_INTEGER*)&start); #endif // Get aligned far end spectrum - far_spectrum_ptr = AlignedFarend(aecm, &far_q); + far_spectrum_ptr = AlignedFarend(aecm, &far_q, delay); zerosXBuf = (WebRtc_Word16) far_q; if (far_spectrum_ptr == NULL) { diff --git a/src/modules/audio_processing/utility/delay_estimator.c b/src/modules/audio_processing/utility/delay_estimator.c index d06cccc46..af1d2e331 100644 --- a/src/modules/audio_processing/utility/delay_estimator.c +++ b/src/modules/audio_processing/utility/delay_estimator.c @@ -163,8 +163,9 @@ int WebRtc_InitBinaryDelayEstimator(BinaryDelayEstimator_t* handle) { handle->vad_counter = 0; - // Set to zero delay after compensating for lookahead. - handle->last_delay = handle->near_history_size - 1; + // Default value to return if we're unable to estimate. -1 is used for + // errors. + handle->last_delay = -2; return 0; } diff --git a/src/modules/audio_processing/utility/delay_estimator.h b/src/modules/audio_processing/utility/delay_estimator.h index 242124ee8..8ff65cb83 100644 --- a/src/modules/audio_processing/utility/delay_estimator.h +++ b/src/modules/audio_processing/utility/delay_estimator.h @@ -79,6 +79,7 @@ int WebRtc_InitBinaryDelayEstimator(BinaryDelayEstimator_t* handle); // Return value: // - delay : >= 0 - Calculated delay value // -1 - Error +// -2 - Insufficient data for estimation. // int WebRtc_ProcessBinarySpectrum(BinaryDelayEstimator_t* handle, uint32_t binary_far_spectrum, @@ -94,6 +95,7 @@ int WebRtc_ProcessBinarySpectrum(BinaryDelayEstimator_t* handle, // Return value: // - delay : >= 0 - Last calculated delay value // -1 - Error +// -2 - Insufficient data for estimation. // int WebRtc_binary_last_delay(BinaryDelayEstimator_t* handle); diff --git a/src/modules/audio_processing/utility/delay_estimator_wrapper.h b/src/modules/audio_processing/utility/delay_estimator_wrapper.h index 31e1dde71..c1f5cc12c 100644 --- a/src/modules/audio_processing/utility/delay_estimator_wrapper.h +++ b/src/modules/audio_processing/utility/delay_estimator_wrapper.h @@ -79,6 +79,7 @@ int WebRtc_InitDelayEstimator(void* handle); // Return value: // - delay : >= 0 - Calculated delay value // -1 - Error +// -2 - Insufficient data for estimation. // int WebRtc_DelayEstimatorProcessFix(void* handle, uint16_t* far_spectrum, @@ -103,6 +104,7 @@ int WebRtc_DelayEstimatorProcessFloat(void* handle, // Return value: // - delay : >= 0 - Last calculated delay value // -1 - Error +// -2 - Insufficient data for estimation. // int WebRtc_last_delay(void* handle); diff --git a/test/data/audio_processing/output_data_float.pb b/test/data/audio_processing/output_data_float.pb index fcbc3e476f9176f8bc17dad9e4064e16df9477d5..b755c0e870cd2457fc0bcb07de63431dd807a7a8 100644 GIT binary patch delta 191 zcmdnP)xyo#Fp;sCv20>#nh-C?pZ`$6D8P^*&s9G0NjeX*=wv^}62`L0hZ(Uco@~T~ krg{z&NVOm{R@Dv6XsTZ^gH*?}U{!sNC0zj7B_Q_!0HF6{PXGV_ delta 119 zcmZqS-owRcF_E#DF?V8V8Yc?}g8)N@JXhYtx9QA4&g2Bf62{!gR~eC{Ci^l$Go