From 61bf8e33c451a64aeffc3d0b4300e8b2792c7346 Mon Sep 17 00:00:00 2001 From: "andrew@webrtc.org" Date: Thu, 15 Mar 2012 19:04:55 +0000 Subject: [PATCH] Flush far-end buffers when larger than system delay. Add a helper function to manage far-end buffer moves. BUG=issue362 TEST=manually with audioproc Review URL: https://webrtc-codereview.appspot.com/447007 git-svn-id: http://webrtc.googlecode.com/svn/trunk@1899 4adac7df-926f-26a2-2b94-8c16560cd09d --- src/modules/audio_processing/aec/aec_core.c | 28 ++++++++---------- src/modules/audio_processing/aec/aec_core.h | 7 ++++- .../audio_processing/aec/echo_cancellation.c | 12 ++++---- .../audio_processing/output_data_float.pb | Bin 1996 -> 1996 bytes 4 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/modules/audio_processing/aec/aec_core.c b/src/modules/audio_processing/aec/aec_core.c index 1637e6fdbc..93ec26b0d0 100644 --- a/src/modules/audio_processing/aec/aec_core.c +++ b/src/modules/audio_processing/aec/aec_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source @@ -543,19 +543,13 @@ void WebRtcAec_InitMetrics(aec_t *aec) WebRtcAec_InitStats(&aec->rerl); } - void WebRtcAec_BufferFarendPartition(aec_t *aec, const float* farend) { float fft[PART_LEN2]; float xf[2][PART_LEN1]; // Check if the buffer is full, and in that case flush the oldest data. if (WebRtc_available_write(aec->far_buf) < 1) { - WebRtc_MoveReadPtr(aec->far_buf, 1); - WebRtc_MoveReadPtr(aec->far_buf_windowed, 1); - aec->system_delay -= PART_LEN; -#ifdef WEBRTC_AEC_DEBUG_DUMP - WebRtc_MoveReadPtr(aec->far_time_buf, 1); -#endif + WebRtcAec_MoveFarReadPtr(aec, 1); } // Convert far-end partition to the frequency domain without windowing. memcpy(fft, farend, sizeof(float) * PART_LEN2); @@ -568,6 +562,16 @@ void WebRtcAec_BufferFarendPartition(aec_t *aec, const float* farend) { WebRtc_WriteBuffer(aec->far_buf_windowed, &xf[0][0], 1); } +int WebRtcAec_MoveFarReadPtr(aec_t *aec, int elements) { + int elements_moved = WebRtc_MoveReadPtr(aec->far_buf_windowed, elements); + WebRtc_MoveReadPtr(aec->far_buf, elements); +#ifdef WEBRTC_AEC_DEBUG_DUMP + WebRtc_MoveReadPtr(aec->far_time_buf, elements); +#endif + aec->system_delay -= elements_moved * PART_LEN; + return elements_moved; +} + void WebRtcAec_ProcessFrame(aec_t *aec, const short *nearend, const short *nearendH, @@ -608,16 +612,10 @@ void WebRtcAec_ProcessFrame(aec_t *aec, // |system_delay| indicates others. if (aec->system_delay < FRAME_LEN) { // We don't have enough data so we rewind 10 ms. - WebRtc_MoveReadPtr(aec->far_buf_windowed, -(aec->mult + 1)); - aec->system_delay -= WebRtc_MoveReadPtr(aec->far_buf, -(aec->mult + 1)) * - PART_LEN; -#ifdef WEBRTC_AEC_DEBUG_DUMP - WebRtc_MoveReadPtr(aec->far_time_buf, -(aec->mult + 1)); -#endif + WebRtcAec_MoveFarReadPtr(aec, -(aec->mult + 1)); } // 2) Compensate for a possible change in the system delay. - WebRtc_MoveReadPtr(aec->far_buf_windowed, move_elements); moved_elements = WebRtc_MoveReadPtr(aec->far_buf, move_elements); aec->knownDelay -= moved_elements * PART_LEN; diff --git a/src/modules/audio_processing/aec/aec_core.h b/src/modules/audio_processing/aec/aec_core.h index d326a6842d..c07528d644 100644 --- a/src/modules/audio_processing/aec/aec_core.h +++ b/src/modules/audio_processing/aec/aec_core.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source @@ -177,4 +177,9 @@ void WebRtcAec_ProcessFrame(aec_t* aec, const short *nearendH, int knownDelay); +// A helper function to call WebRtc_MoveReadPtr() for all far-end buffers. +// Returns the number of elements moved, and adjusts |system_delay| by the +// corresponding amount in ms. +int WebRtcAec_MoveFarReadPtr(aec_t* aec, int elements); + #endif // WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_SOURCE_AEC_CORE_H_ diff --git a/src/modules/audio_processing/aec/echo_cancellation.c b/src/modules/audio_processing/aec/echo_cancellation.c index bde9c87c5b..5d690b9e62 100644 --- a/src/modules/audio_processing/aec/echo_cancellation.c +++ b/src/modules/audio_processing/aec/echo_cancellation.c @@ -526,18 +526,12 @@ WebRtc_Word32 WebRtcAec_Process(void *aecInst, const WebRtc_Word16 *nearend, // Enable the AEC aecpc->ECstartup = 0; } else if (overhead_elements > 0) { - WebRtc_MoveReadPtr(aecpc->aec->far_buf_windowed, - overhead_elements); - WebRtc_MoveReadPtr(aecpc->aec->far_buf, overhead_elements); -#ifdef WEBRTC_AEC_DEBUG_DUMP - WebRtc_MoveReadPtr(aecpc->aec->far_time_buf, overhead_elements); -#endif // TODO(bjornv): Do we need a check on how much we actually // moved the read pointer? It should always be possible to move // the pointer |overhead_elements| since we have only added data // to the buffer and no delay compensation nor AEC processing // has been done. - aecpc->aec->system_delay -= overhead_elements * PART_LEN; + WebRtcAec_MoveFarReadPtr(aecpc->aec, overhead_elements); // Enable the AEC aecpc->ECstartup = 0; @@ -895,6 +889,10 @@ static int EstBufDelay(aecpc_t* aecpc) { current_delay -= kResamplingDelay; } + if (current_delay < PART_LEN) { + current_delay += WebRtcAec_MoveFarReadPtr(aecpc->aec, 1) * PART_LEN; + } + aecpc->filtDelay = WEBRTC_SPL_MAX(0, (short) (0.8 * aecpc->filtDelay + 0.2 * current_delay)); diff --git a/test/data/audio_processing/output_data_float.pb b/test/data/audio_processing/output_data_float.pb index d9a51bbabfb46f37b85314cc96303518aa508aa1..b2b934dd86c1389b802834209c177aec3c94460e 100644 GIT binary patch delta 286 zcmX@Ze};d82**WUhmTAi+nFcNV>6xH%gQ@3PFRXlfl*12gF#@{xA>Y|ea{eG;$32PThwlLcAA@Hk|0Bg=VW kl^$n3&wft;Wa_TTf-Gi}FS9AgV0Qq>ivkRj`PugZ0IEZ1CjbBd delta 275 zcmX@Ze};d82zv*w!$&5M`;!G(oF~Q!ONl8kDhYBh3e5Qr1&k703XDlC92^t79}=&4 z@?*w_>^lTNMjx9j$YM5`ky$}Z0;}1R&6zJl4c<0ckR?n?6st0j6DBvZoF`W4an|$f cC&3Qb2zJ0_HU$~%4oG6*U=ZM#%+J0T09Ns2UH||9