Added a pointer getter to the system_delay variable.

Tested with audioproc_unittest, trybots

TEST=None
BUG=None

Review URL: https://webrtc-codereview.appspot.com/1101015

git-svn-id: http://webrtc.googlecode.com/svn/trunk@3549 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
bjornv@webrtc.org 2013-02-20 17:31:38 +00:00
parent 47b274de44
commit 4d1cfae622
4 changed files with 62 additions and 37 deletions

View File

@ -748,6 +748,7 @@ void WebRtcAec_GetEchoStats(aec_t* self, Stats* erl, Stats* erle,
*erle = self->erle;
*a_nlp = self->aNlp;
}
#ifdef WEBRTC_AEC_DEBUG_DUMP
void* WebRtcAec_far_time_buf(aec_t* self) {
assert(self != NULL);
@ -770,6 +771,17 @@ void WebRtcAec_SetConfigCore(aec_t* self, int nlp_mode, int metrics_mode,
}
}
int WebRtcAec_system_delay(aec_t* self) {
assert(self != NULL);
return self->system_delay;
}
void WebRtcAec_SetSystemDelay(aec_t* self, int delay) {
assert(self != NULL);
assert(delay >= 0);
self->system_delay = delay;
}
static void ProcessBlock(aec_t* aec) {
int i;
float d[PART_LEN], y[PART_LEN], e[PART_LEN], dH[PART_LEN];

View File

@ -12,8 +12,8 @@
* Specifies the interface for the AEC core.
*/
#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_SOURCE_AEC_CORE_H_
#define WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_SOURCE_AEC_CORE_H_
#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AEC_AEC_CORE_H_
#define WEBRTC_MODULES_AUDIO_PROCESSING_AEC_AEC_CORE_H_
#ifdef WEBRTC_AEC_DEBUG_DUMP
#include <stdio.h>
@ -196,5 +196,12 @@ void* WebRtcAec_far_time_buf(aec_t* self);
// Sets local configuration modes.
void WebRtcAec_SetConfigCore(aec_t* self, int nlp_mode, int metrics_mode,
int delay_logging);
// Returns the current |system_delay|, i.e., the buffered difference between
// far-end and near-end.
int WebRtcAec_system_delay(aec_t* self);
// Sets the |system_delay| to |value|. Note that if the value is changed
// improperly, there can be a performance regression. So it should be used with
// care.
void WebRtcAec_SetSystemDelay(aec_t* self, int delay);
#endif // WEBRTC_MODULES_AUDIO_PROCESSING_AEC_MAIN_SOURCE_AEC_CORE_H_
#endif // WEBRTC_MODULES_AUDIO_PROCESSING_AEC_AEC_CORE_H_

View File

@ -268,7 +268,8 @@ WebRtc_Word32 WebRtcAec_BufferFarend(void *aecInst, const WebRtc_Word16 *farend,
farend_ptr = (const int16_t*) newFarend;
}
aecpc->aec->system_delay += newNrOfSamples;
WebRtcAec_SetSystemDelay(aecpc->aec, WebRtcAec_system_delay(aecpc->aec) +
newNrOfSamples);
#ifdef WEBRTC_AEC_DEBUG_DUMP
WebRtc_WriteBuffer(aecpc->far_pre_buf_s16, farend_ptr,
@ -454,7 +455,8 @@ WebRtc_Word32 WebRtcAec_Process(void *aecInst, const WebRtc_Word16 *nearend,
// for too long). When the far-end buffer is filled with
// approximately the same amount of data as reported by the system
// we end the startup phase.
int overhead_elements = aecpc->aec->system_delay / PART_LEN -
int overhead_elements =
WebRtcAec_system_delay(aecpc->aec) / PART_LEN -
aecpc->bufSizeStart;
if (overhead_elements == 0) {
// Enable the AEC
@ -493,7 +495,7 @@ WebRtc_Word32 WebRtcAec_Process(void *aecInst, const WebRtc_Word16 *nearend,
#ifdef WEBRTC_AEC_DEBUG_DUMP
{
int16_t far_buf_size_ms = (int16_t)(aecpc->aec->system_delay /
int16_t far_buf_size_ms = (int16_t)(WebRtcAec_system_delay(aecpc->aec) /
(sampMsNb * aecpc->rate_factor));
(void)fwrite(&far_buf_size_ms, 2, 1, aecpc->bufFile);
(void)fwrite(&aecpc->knownDelay, sizeof(aecpc->knownDelay), 1,
@ -700,7 +702,7 @@ WebRtc_Word32 WebRtcAec_get_error_code(void *aecInst)
static int EstBufDelay(aecpc_t* aecpc) {
int nSampSndCard = aecpc->msInSndCardBuf * sampMsNb * aecpc->rate_factor;
int current_delay = nSampSndCard - aecpc->aec->system_delay;
int current_delay = nSampSndCard - WebRtcAec_system_delay(aecpc->aec);
int delay_difference = 0;
// Before we proceed with the delay estimate filtering we:

View File

@ -8,11 +8,14 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include "gtest/gtest.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "modules/audio_processing/aec/include/echo_cancellation.h"
#include "modules/audio_processing/aec/echo_cancellation_internal.h"
#include "typedefs.h"
extern "C" {
#include "webrtc/modules/audio_processing/aec/aec_core.h"
}
#include "webrtc/modules/audio_processing/aec/echo_cancellation_internal.h"
#include "webrtc/modules/audio_processing/aec/include/echo_cancellation.h"
#include "webrtc/typedefs.h"
namespace {
@ -109,7 +112,7 @@ int SystemDelayTest::BufferFillUp() {
for (int i = 0; i < kDeviceBufMs / 10; i++) {
EXPECT_EQ(0, WebRtcAec_BufferFarend(handle_, far_, samples_per_frame_));
buffer_size += samples_per_frame_;
EXPECT_EQ(buffer_size, self_->aec->system_delay);
EXPECT_EQ(buffer_size, WebRtcAec_system_delay(self_->aec));
}
return buffer_size;
}
@ -133,7 +136,7 @@ void SystemDelayTest::RunStableStartup() {
// Verify convergence time.
EXPECT_GT(kStableConvergenceMs, process_time_ms);
// Verify that the buffer has been flushed.
EXPECT_GE(buffer_size, self_->aec->system_delay);
EXPECT_GE(buffer_size, WebRtcAec_system_delay(self_->aec));
}
int SystemDelayTest::MapBufferSizeToSamples(int size_in_ms) {
@ -172,7 +175,7 @@ TEST_F(SystemDelayTest, CorrectIncreaseWhenBufferFarend) {
// correctly.
for (int j = 1; j <= 5; j++) {
EXPECT_EQ(0, WebRtcAec_BufferFarend(handle_, far_, samples_per_frame_));
EXPECT_EQ(j * samples_per_frame_, self_->aec->system_delay);
EXPECT_EQ(j * samples_per_frame_, WebRtcAec_system_delay(self_->aec));
}
}
}
@ -191,8 +194,9 @@ TEST_F(SystemDelayTest, CorrectDelayAfterStableStartup) {
// |system_delay| is in the interval [75%, 100%] of what's reported on the
// average.
int average_reported_delay = kDeviceBufMs * samples_per_frame_ / 10;
EXPECT_GE(average_reported_delay, self_->aec->system_delay);
EXPECT_LE(average_reported_delay * 3 / 4, self_->aec->system_delay);
EXPECT_GE(average_reported_delay, WebRtcAec_system_delay(self_->aec));
EXPECT_LE(average_reported_delay * 3 / 4,
WebRtcAec_system_delay(self_->aec));
}
}
@ -226,14 +230,14 @@ TEST_F(SystemDelayTest, CorrectDelayAfterUnstableStartup) {
// Verify convergence time.
EXPECT_GE(kMaxConvergenceMs, process_time_ms);
// Verify that the buffer has been flushed.
EXPECT_GE(buffer_size, self_->aec->system_delay);
EXPECT_GE(buffer_size, WebRtcAec_system_delay(self_->aec));
// Verify system delay with respect to requirements, i.e., the
// |system_delay| is in the interval [60%, 100%] of what's last reported.
EXPECT_GE(reported_delay_ms * samples_per_frame_ / 10,
self_->aec->system_delay);
WebRtcAec_system_delay(self_->aec));
EXPECT_LE(reported_delay_ms * samples_per_frame_ / 10 * 3 / 5,
self_->aec->system_delay);
WebRtcAec_system_delay(self_->aec));
}
}
@ -272,14 +276,14 @@ TEST_F(SystemDelayTest, CorrectDelayAfterStableBufferBuildUp) {
// Verify convergence time.
EXPECT_GT(kMaxConvergenceMs, process_time_ms);
// Verify that the buffer has reached the desired size.
EXPECT_LE(target_buffer_size, self_->aec->system_delay);
EXPECT_LE(target_buffer_size, WebRtcAec_system_delay(self_->aec));
// Verify normal behavior (system delay is kept constant) after startup by
// running a couple of calls to BufferFarend() and Process().
for (int j = 0; j < 6; j++) {
int system_delay_before_calls = self_->aec->system_delay;
int system_delay_before_calls = WebRtcAec_system_delay(self_->aec);
RenderAndCapture(kDeviceBufMs);
EXPECT_EQ(system_delay_before_calls, self_->aec->system_delay);
EXPECT_EQ(system_delay_before_calls, WebRtcAec_system_delay(self_->aec));
}
}
}
@ -299,7 +303,7 @@ TEST_F(SystemDelayTest, CorrectDelayWhenBufferUnderrun) {
for (int j = 0; j <= kStableConvergenceMs; j += 10) {
EXPECT_EQ(0, WebRtcAec_Process(handle_, near_, NULL, out_, NULL,
samples_per_frame_, kDeviceBufMs, 0));
EXPECT_LE(0, self_->aec->system_delay);
EXPECT_LE(0, WebRtcAec_system_delay(self_->aec));
}
}
}
@ -327,10 +331,10 @@ TEST_F(SystemDelayTest, CorrectDelayDuringDrift) {
RenderAndCapture(device_buf_ms);
// Verify that the system delay does not exceed the device buffer.
EXPECT_GE(device_buf, self_->aec->system_delay);
EXPECT_GE(device_buf, WebRtcAec_system_delay(self_->aec));
// Verify that the system delay is non-negative.
EXPECT_LE(0, self_->aec->system_delay);
EXPECT_LE(0, WebRtcAec_system_delay(self_->aec));
}
}
}
@ -353,15 +357,15 @@ TEST_F(SystemDelayTest, ShouldRecoverAfterGlitch) {
}
// Verify that we are in a non-causal state, i.e.,
// |system_delay| > |device_buf|.
EXPECT_LT(device_buf, self_->aec->system_delay);
EXPECT_LT(device_buf, WebRtcAec_system_delay(self_->aec));
// Recover state. Should recover at least 4 ms of data per 10 ms, hence a
// glitch of 200 ms will take at most 200 * 10 / 4 = 500 ms to recover from.
bool non_causal = true; // We are currently in a non-causal state.
for (int j = 0; j < 50; j++) {
int system_delay_before = self_->aec->system_delay;
int system_delay_before = WebRtcAec_system_delay(self_->aec);
RenderAndCapture(kDeviceBufMs);
int system_delay_after = self_->aec->system_delay;
int system_delay_after = WebRtcAec_system_delay(self_->aec);
// We have recovered if |device_buf| - |system_delay_after| >= 64 (one
// block). During recovery |system_delay_after| < |system_delay_before|,
@ -375,7 +379,7 @@ TEST_F(SystemDelayTest, ShouldRecoverAfterGlitch) {
EXPECT_EQ(system_delay_before, system_delay_after);
}
// Verify that the system delay is non-negative.
EXPECT_LE(0, self_->aec->system_delay);
EXPECT_LE(0, WebRtcAec_system_delay(self_->aec));
}
// Check that we have recovered.
EXPECT_FALSE(non_causal);
@ -397,7 +401,7 @@ TEST_F(SystemDelayTest, UnaffectedWhenSpuriousDeviceBufferValues) {
// Run 1 s and replace device buffer size with 500 ms every 100 ms.
for (int j = 0; j < 100; j++) {
int system_delay_before_calls = self_->aec->system_delay;
int system_delay_before_calls = WebRtcAec_system_delay(self_->aec);
int device_buf_ms = kDeviceBufMs;
if (j % 10 == 0) {
device_buf_ms = 500;
@ -405,14 +409,14 @@ TEST_F(SystemDelayTest, UnaffectedWhenSpuriousDeviceBufferValues) {
RenderAndCapture(device_buf_ms);
// Check for non-causality.
if (device_buf - self_->aec->system_delay < 64) {
if (device_buf - WebRtcAec_system_delay(self_->aec) < 64) {
non_causal = true;
}
EXPECT_FALSE(non_causal);
EXPECT_EQ(system_delay_before_calls, self_->aec->system_delay);
EXPECT_EQ(system_delay_before_calls, WebRtcAec_system_delay(self_->aec));
// Verify that the system delay is non-negative.
EXPECT_LE(0, self_->aec->system_delay);
EXPECT_LE(0, WebRtcAec_system_delay(self_->aec));
}
}
}
@ -440,16 +444,16 @@ TEST_F(SystemDelayTest, CorrectImpactWhenTogglingDeviceBufferValues) {
// data. Every odd frame we set the device buffer size to 2 * |kDeviceBufMs|
// and even frames we set the device buffer size to zero.
for (int j = 0; j < 100; j++) {
int system_delay_before_calls = self_->aec->system_delay;
int system_delay_before_calls = WebRtcAec_system_delay(self_->aec);
int device_buf_ms = 2 * (j % 2) * kDeviceBufMs;
RenderAndCapture(device_buf_ms);
// Check for non-causality, compared with the average device buffer size.
non_causal |= (device_buf - self_->aec->system_delay < 64);
EXPECT_GE(system_delay_before_calls, self_->aec->system_delay);
non_causal |= (device_buf - WebRtcAec_system_delay(self_->aec) < 64);
EXPECT_GE(system_delay_before_calls, WebRtcAec_system_delay(self_->aec));
// Verify that the system delay is non-negative.
EXPECT_LE(0, self_->aec->system_delay);
EXPECT_LE(0, WebRtcAec_system_delay(self_->aec));
}
// Verify we are not in a non-causal state.
EXPECT_FALSE(non_causal);