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
This commit is contained in:
andrew@webrtc.org 2012-03-15 19:04:55 +00:00
parent 3053702698
commit 61bf8e33c4
4 changed files with 24 additions and 23 deletions

View File

@ -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;

View File

@ -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_

View File

@ -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));