From 716fd90ff298e08051192ffbd92e9821120ff213 Mon Sep 17 00:00:00 2001 From: "bjornv@webrtc.org" Date: Wed, 20 Feb 2013 16:59:41 +0000 Subject: [PATCH] Moved out buffer handling to ProcessFrame() Tested with audioproc_unittest, trybots and verified bit exactness on recording data base. TEST=none BUG=none Review URL: https://webrtc-codereview.appspot.com/1110006 git-svn-id: http://webrtc.googlecode.com/svn/trunk@3547 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../modules/audio_processing/aec/aec_core.c | 38 ++++++++++++++++--- .../modules/audio_processing/aec/aec_core.h | 8 ++-- .../audio_processing/aec/echo_cancellation.c | 33 ++-------------- 3 files changed, 40 insertions(+), 39 deletions(-) diff --git a/webrtc/modules/audio_processing/aec/aec_core.c b/webrtc/modules/audio_processing/aec/aec_core.c index 19c2be596..757ec3c9c 100644 --- a/webrtc/modules/audio_processing/aec/aec_core.c +++ b/webrtc/modules/audio_processing/aec/aec_core.c @@ -606,22 +606,29 @@ int WebRtcAec_MoveFarReadPtr(aec_t *aec, int elements) { return elements_moved; } -void WebRtcAec_ProcessFrame(aec_t *aec, - const short *nearend, - const short *nearendH, - int knownDelay) -{ +void WebRtcAec_ProcessFrame(aec_t* aec, + const short* nearend, + const short* nearendH, + int knownDelay, + int16_t* out, + int16_t* outH) { + int out_elements = 0; + int16_t* out_ptr = NULL; + int16_t out_tmp[FRAME_LEN]; + // For each frame the process is as follows: // 1) If the system_delay indicates on being too small for processing a // frame we stuff the buffer with enough data for 10 ms. // 2) Adjust the buffer to the system delay, by moving the read pointer. - // 3) If we can't move read pointer due to buffer size limitations we + // 3) TODO(bjornv): Investigate if we need to add this: + // If we can't move read pointer due to buffer size limitations we // flush/stuff the buffer. // 4) Process as many partitions as possible. // 5) Update the |system_delay| with respect to a full frame of FRAME_LEN // samples. Even though we will have data left to process (we work with // partitions) we consider updating a whole frame, since that's the // amount of data we input and output in audio_processing. + // 6) Update the outputs. // TODO(bjornv): Investigate how we should round the delay difference; right // now we know that incoming |knownDelay| is underestimated when it's less @@ -664,6 +671,25 @@ void WebRtcAec_ProcessFrame(aec_t *aec, // 5) Update system delay with respect to the entire frame. aec->system_delay -= FRAME_LEN; + + // 6) Update output frame. + // Stuff the out buffer if we have less than a frame to output. + // This should only happen for the first frame. + out_elements = (int) WebRtc_available_read(aec->outFrBuf); + if (out_elements < FRAME_LEN) { + WebRtc_MoveReadPtr(aec->outFrBuf, out_elements - FRAME_LEN); + if (aec->sampFreq == 32000) { + WebRtc_MoveReadPtr(aec->outFrBufH, out_elements - FRAME_LEN); + } + } + // Obtain an output frame. + WebRtc_ReadBuffer(aec->outFrBuf, (void**) &out_ptr, out_tmp, FRAME_LEN); + memcpy(out, out_ptr, sizeof(int16_t) * FRAME_LEN); + // For H band. + if (aec->sampFreq == 32000) { + WebRtc_ReadBuffer(aec->outFrBufH, (void**) &out_ptr, out_tmp, FRAME_LEN); + memcpy(outH, out_ptr, sizeof(int16_t) * FRAME_LEN); + } } int WebRtcAec_GetDelayMetricsCore(aec_t* self, int* median, int* std) { diff --git a/webrtc/modules/audio_processing/aec/aec_core.h b/webrtc/modules/audio_processing/aec/aec_core.h index 19f99f88d..b23c67696 100644 --- a/webrtc/modules/audio_processing/aec/aec_core.h +++ b/webrtc/modules/audio_processing/aec/aec_core.h @@ -174,9 +174,11 @@ void WebRtcAec_InitAec_SSE2(void); void WebRtcAec_InitMetrics(aec_t *aec); void WebRtcAec_BufferFarendPartition(aec_t *aec, const float* farend); void WebRtcAec_ProcessFrame(aec_t* aec, - const short *nearend, - const short *nearendH, - int knownDelay); + const short* nearend, + const short* nearendH, + int knownDelay, + int16_t* out, + int16_t* outH); // A helper function to call WebRtc_MoveReadPtr() for all far-end buffers. // Returns the number of elements moved, and adjusts |system_delay| by the diff --git a/webrtc/modules/audio_processing/aec/echo_cancellation.c b/webrtc/modules/audio_processing/aec/echo_cancellation.c index 529382aa7..fb0770bfd 100644 --- a/webrtc/modules/audio_processing/aec/echo_cancellation.c +++ b/webrtc/modules/audio_processing/aec/echo_cancellation.c @@ -474,47 +474,20 @@ WebRtc_Word32 WebRtcAec_Process(void *aecInst, const WebRtc_Word16 *nearend, } else { // AEC is enabled. - int out_elements = 0; - EstBufDelay(aecpc); // Note that 1 frame is supported for NB and 2 frames for WB. for (i = 0; i < nFrames; i++) { - int16_t* out_ptr = NULL; - int16_t out_tmp[FRAME_LEN]; - // Call the AEC. WebRtcAec_ProcessFrame(aecpc->aec, &nearend[FRAME_LEN * i], &nearendH[FRAME_LEN * i], - aecpc->knownDelay); + aecpc->knownDelay, + &out[FRAME_LEN * i], + &outH[FRAME_LEN * i]); // TODO(bjornv): Re-structure such that we don't have to pass // |aecpc->knownDelay| as input. Change name to something like // |system_buffer_diff|. - - // Stuff the out buffer if we have less than a frame to output. - // This should only happen for the first frame. - out_elements = (int) WebRtc_available_read(aecpc->aec->outFrBuf); - if (out_elements < FRAME_LEN) { - WebRtc_MoveReadPtr(aecpc->aec->outFrBuf, - out_elements - FRAME_LEN); - if (aecpc->sampFreq == 32000) { - WebRtc_MoveReadPtr(aecpc->aec->outFrBufH, - out_elements - FRAME_LEN); - } - } - - // Obtain an output frame. - WebRtc_ReadBuffer(aecpc->aec->outFrBuf, (void**) &out_ptr, - out_tmp, FRAME_LEN); - memcpy(&out[FRAME_LEN * i], out_ptr, sizeof(int16_t) * FRAME_LEN); - // For H band - if (aecpc->sampFreq == 32000) { - WebRtc_ReadBuffer(aecpc->aec->outFrBufH, (void**) &out_ptr, - out_tmp, FRAME_LEN); - memcpy(&outH[FRAME_LEN * i], out_ptr, - sizeof(int16_t) * FRAME_LEN); - } } }