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:
parent
3053702698
commit
61bf8e33c4
@ -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
|
* 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
|
* 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);
|
WebRtcAec_InitStats(&aec->rerl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WebRtcAec_BufferFarendPartition(aec_t *aec, const float* farend) {
|
void WebRtcAec_BufferFarendPartition(aec_t *aec, const float* farend) {
|
||||||
float fft[PART_LEN2];
|
float fft[PART_LEN2];
|
||||||
float xf[2][PART_LEN1];
|
float xf[2][PART_LEN1];
|
||||||
|
|
||||||
// Check if the buffer is full, and in that case flush the oldest data.
|
// Check if the buffer is full, and in that case flush the oldest data.
|
||||||
if (WebRtc_available_write(aec->far_buf) < 1) {
|
if (WebRtc_available_write(aec->far_buf) < 1) {
|
||||||
WebRtc_MoveReadPtr(aec->far_buf, 1);
|
WebRtcAec_MoveFarReadPtr(aec, 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
|
|
||||||
}
|
}
|
||||||
// Convert far-end partition to the frequency domain without windowing.
|
// Convert far-end partition to the frequency domain without windowing.
|
||||||
memcpy(fft, farend, sizeof(float) * PART_LEN2);
|
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);
|
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,
|
void WebRtcAec_ProcessFrame(aec_t *aec,
|
||||||
const short *nearend,
|
const short *nearend,
|
||||||
const short *nearendH,
|
const short *nearendH,
|
||||||
@ -608,16 +612,10 @@ void WebRtcAec_ProcessFrame(aec_t *aec,
|
|||||||
// |system_delay| indicates others.
|
// |system_delay| indicates others.
|
||||||
if (aec->system_delay < FRAME_LEN) {
|
if (aec->system_delay < FRAME_LEN) {
|
||||||
// We don't have enough data so we rewind 10 ms.
|
// We don't have enough data so we rewind 10 ms.
|
||||||
WebRtc_MoveReadPtr(aec->far_buf_windowed, -(aec->mult + 1));
|
WebRtcAec_MoveFarReadPtr(aec, -(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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2) Compensate for a possible change in the system delay.
|
// 2) Compensate for a possible change in the system delay.
|
||||||
|
|
||||||
WebRtc_MoveReadPtr(aec->far_buf_windowed, move_elements);
|
WebRtc_MoveReadPtr(aec->far_buf_windowed, move_elements);
|
||||||
moved_elements = WebRtc_MoveReadPtr(aec->far_buf, move_elements);
|
moved_elements = WebRtc_MoveReadPtr(aec->far_buf, move_elements);
|
||||||
aec->knownDelay -= moved_elements * PART_LEN;
|
aec->knownDelay -= moved_elements * PART_LEN;
|
||||||
|
@ -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
|
* 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
|
* 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,
|
const short *nearendH,
|
||||||
int knownDelay);
|
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_
|
#endif // WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_SOURCE_AEC_CORE_H_
|
||||||
|
@ -526,18 +526,12 @@ WebRtc_Word32 WebRtcAec_Process(void *aecInst, const WebRtc_Word16 *nearend,
|
|||||||
// Enable the AEC
|
// Enable the AEC
|
||||||
aecpc->ECstartup = 0;
|
aecpc->ECstartup = 0;
|
||||||
} else if (overhead_elements > 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
|
// TODO(bjornv): Do we need a check on how much we actually
|
||||||
// moved the read pointer? It should always be possible to move
|
// moved the read pointer? It should always be possible to move
|
||||||
// the pointer |overhead_elements| since we have only added data
|
// the pointer |overhead_elements| since we have only added data
|
||||||
// to the buffer and no delay compensation nor AEC processing
|
// to the buffer and no delay compensation nor AEC processing
|
||||||
// has been done.
|
// has been done.
|
||||||
aecpc->aec->system_delay -= overhead_elements * PART_LEN;
|
WebRtcAec_MoveFarReadPtr(aecpc->aec, overhead_elements);
|
||||||
|
|
||||||
// Enable the AEC
|
// Enable the AEC
|
||||||
aecpc->ECstartup = 0;
|
aecpc->ECstartup = 0;
|
||||||
@ -895,6 +889,10 @@ static int EstBufDelay(aecpc_t* aecpc) {
|
|||||||
current_delay -= kResamplingDelay;
|
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 +
|
aecpc->filtDelay = WEBRTC_SPL_MAX(0, (short) (0.8 * aecpc->filtDelay +
|
||||||
0.2 * current_delay));
|
0.2 * current_delay));
|
||||||
|
|
||||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user