Delay Estimator: Minor refactoring and added a setter function.

* Replaced the lookahead input parameter at Create() with a setter. This makes it slightly more user friendly.
* Changed the buffer shifting in SoftReset... to become more readable.

TESTED=trybots, modules_unittests
R=aluebs@webrtc.org, andrew@webrtc.org

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@5836 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
bjornv@webrtc.org 2014-04-03 08:11:47 +00:00
parent 148149138d
commit 240eec3cd4
7 changed files with 82 additions and 97 deletions

View File

@ -231,7 +231,7 @@ int WebRtcAec_CreateAec(AecCore** aecInst) {
return -1; return -1;
} }
aec->delay_estimator = WebRtc_CreateDelayEstimator( aec->delay_estimator = WebRtc_CreateDelayEstimator(
aec->delay_estimator_farend, kLookaheadBlocks, kLookaheadBlocks); aec->delay_estimator_farend, kLookaheadBlocks);
if (aec->delay_estimator == NULL) { if (aec->delay_estimator == NULL) {
WebRtcAec_FreeAec(aec); WebRtcAec_FreeAec(aec);
aec = NULL; aec = NULL;

View File

@ -260,7 +260,7 @@ int WebRtcAecm_CreateCore(AecmCore_t **aecmInst)
return -1; return -1;
} }
aecm->delay_estimator = aecm->delay_estimator =
WebRtc_CreateDelayEstimator(aecm->delay_estimator_farend, 0, 0); WebRtc_CreateDelayEstimator(aecm->delay_estimator_farend, 0);
if (aecm->delay_estimator == NULL) { if (aecm->delay_estimator == NULL) {
WebRtcAecm_FreeCore(aecm); WebRtcAecm_FreeCore(aecm);
aecm = NULL; aecm = NULL;

View File

@ -308,31 +308,33 @@ void WebRtc_SoftResetBinaryDelayEstimatorFarend(
BinaryDelayEstimatorFarend* self, int delay_shift) { BinaryDelayEstimatorFarend* self, int delay_shift) {
int abs_shift = abs(delay_shift); int abs_shift = abs(delay_shift);
int shift_size = 0; int shift_size = 0;
assert(self != NULL); int dest_index = 0;
int src_index = 0;
int padding_index = 0;
assert(self != NULL);
shift_size = self->history_size - abs_shift; shift_size = self->history_size - abs_shift;
if (delay_shift > 0) { assert(shift_size > 0);
memmove(&self->binary_far_history[abs_shift], if (delay_shift == 0) {
self->binary_far_history, return;
sizeof(*self->binary_far_history) * shift_size); } else if (delay_shift > 0) {
memmove(&self->far_bit_counts[abs_shift], dest_index = abs_shift;
self->far_bit_counts,
sizeof(*self->far_bit_counts) * shift_size);
memset(self->binary_far_history, 0,
sizeof(*self->binary_far_history) * abs_shift);
memset(self->far_bit_counts, 0, sizeof(*self->far_bit_counts) * abs_shift);
} else if (delay_shift < 0) { } else if (delay_shift < 0) {
memmove(self->binary_far_history, src_index = abs_shift;
&self->binary_far_history[abs_shift], padding_index = shift_size;
sizeof(*self->binary_far_history) * shift_size);
memmove(self->far_bit_counts,
&self->far_bit_counts[abs_shift],
sizeof(*self->far_bit_counts) * shift_size);
memset(&self->binary_far_history[shift_size], 0,
sizeof(*self->binary_far_history) * abs_shift);
memset(&self->far_bit_counts[shift_size], 0,
sizeof(*self->far_bit_counts) * abs_shift);
} }
// Shift and zero pad buffers.
memmove(&self->binary_far_history[dest_index],
&self->binary_far_history[src_index],
sizeof(*self->binary_far_history) * shift_size);
memset(&self->binary_far_history[padding_index], 0,
sizeof(*self->binary_far_history) * abs_shift);
memmove(&self->far_bit_counts[dest_index],
&self->far_bit_counts[src_index],
sizeof(*self->far_bit_counts) * shift_size);
memset(&self->far_bit_counts[padding_index], 0,
sizeof(*self->far_bit_counts) * abs_shift);
} }
void WebRtc_AddBinaryFarSpectrum(BinaryDelayEstimatorFarend* handle, void WebRtc_AddBinaryFarSpectrum(BinaryDelayEstimatorFarend* handle,
@ -376,10 +378,10 @@ void WebRtc_FreeBinaryDelayEstimator(BinaryDelayEstimator* self) {
} }
BinaryDelayEstimator* WebRtc_CreateBinaryDelayEstimator( BinaryDelayEstimator* WebRtc_CreateBinaryDelayEstimator(
BinaryDelayEstimatorFarend* farend, int max_lookahead, int lookahead) { BinaryDelayEstimatorFarend* farend, int max_lookahead) {
BinaryDelayEstimator* self = NULL; BinaryDelayEstimator* self = NULL;
if ((farend != NULL) && (lookahead >= 0) && (max_lookahead >= lookahead)) { if ((farend != NULL) && (max_lookahead >= 0)) {
// Sanity conditions fulfilled. // Sanity conditions fulfilled.
self = malloc(sizeof(BinaryDelayEstimator)); self = malloc(sizeof(BinaryDelayEstimator));
} }
@ -392,7 +394,7 @@ BinaryDelayEstimator* WebRtc_CreateBinaryDelayEstimator(
self->robust_validation_enabled = 0; // Disabled by default. self->robust_validation_enabled = 0; // Disabled by default.
self->allowed_offset = 0; self->allowed_offset = 0;
self->lookahead = lookahead; self->lookahead = max_lookahead;
// Allocate memory for spectrum buffers. The extra array element in // Allocate memory for spectrum buffers. The extra array element in
// |mean_bit_counts| and |histogram| is a dummy element only used while // |mean_bit_counts| and |histogram| is a dummy element only used while
@ -405,7 +407,7 @@ BinaryDelayEstimator* WebRtc_CreateBinaryDelayEstimator(
malloc_fail |= (self->bit_counts == NULL); malloc_fail |= (self->bit_counts == NULL);
// Allocate memory for history buffers. // Allocate memory for history buffers.
self->binary_near_history = malloc((lookahead + 1) * sizeof(uint32_t)); self->binary_near_history = malloc((max_lookahead + 1) * sizeof(uint32_t));
malloc_fail |= (self->binary_near_history == NULL); malloc_fail |= (self->binary_near_history == NULL);
self->histogram = malloc((farend->history_size + 1) * sizeof(float)); self->histogram = malloc((farend->history_size + 1) * sizeof(float));

View File

@ -136,42 +136,10 @@ void WebRtc_FreeBinaryDelayEstimator(BinaryDelayEstimator* self);
// Allocates the memory needed by the binary delay estimation. The memory needs // Allocates the memory needed by the binary delay estimation. The memory needs
// to be initialized separately through WebRtc_InitBinaryDelayEstimator(...). // to be initialized separately through WebRtc_InitBinaryDelayEstimator(...).
// //
// Inputs: // See WebRtc_CreateDelayEstimator(..) in delay_estimator_wrapper.c for detailed
// - farend : Pointer to the far-end part of the Binary Delay // description.
// Estimator. This memory has to be created separately
// prior to this call using
// WebRtc_CreateBinaryDelayEstimatorFarend().
//
// Note that BinaryDelayEstimator does not take
// ownership of |farend|.
//
// - lookahead : Amount of non-causal lookahead to use. This can
// detect cases in which a near-end signal occurs before
// the corresponding far-end signal. It will delay the
// estimate for the current block by an equal amount,
// and the returned values will be offset by it.
//
// A value of zero is the typical no-lookahead case.
// This also represents the minimum delay which can be
// estimated.
//
// Note that the effective range of delay estimates is
// [-|lookahead|,... ,|history_size|-|lookahead|)
// where |history_size| was set upon creating the far-end
// history buffer size.
//
// - max_lookahead : Maximum amount of non-causal lookahead allowed. This
// is to allow for dynamically changing the lookahead on
// the fly.
//
// Return value:
// - BinaryDelayEstimator*
// : Created |handle|. If the memory can't be allocated
// or if any of the input parameters are invalid NULL
// is returned.
//
BinaryDelayEstimator* WebRtc_CreateBinaryDelayEstimator( BinaryDelayEstimator* WebRtc_CreateBinaryDelayEstimator(
BinaryDelayEstimatorFarend* farend, int max_lookahead, int lookahead); BinaryDelayEstimatorFarend* farend, int max_lookahead);
// Initializes the delay estimation instance created with // Initializes the delay estimation instance created with
// WebRtc_CreateBinaryDelayEstimator(...). // WebRtc_CreateBinaryDelayEstimator(...).
@ -230,7 +198,7 @@ int WebRtc_binary_last_delay(BinaryDelayEstimator* self);
// Returns the estimation quality of the last calculated delay updated by the // Returns the estimation quality of the last calculated delay updated by the
// function WebRtc_ProcessBinarySpectrum(...). The estimation quality is a value // function WebRtc_ProcessBinarySpectrum(...). The estimation quality is a value
// in the interval [0, 1]. The higher the value, the better quality. // in the interval [0, 1]. The higher the value, the better the quality.
// //
// Return value: // Return value:
// - delay_quality : >= 0 - Estimation quality of last calculated // - delay_quality : >= 0 - Estimation quality of last calculated

View File

@ -86,14 +86,13 @@ void DelayEstimatorTest::SetUp() {
kMaxDelay + kLookahead); kMaxDelay + kLookahead);
ASSERT_TRUE(farend_handle_ != NULL); ASSERT_TRUE(farend_handle_ != NULL);
farend_self_ = reinterpret_cast<DelayEstimatorFarend*>(farend_handle_); farend_self_ = reinterpret_cast<DelayEstimatorFarend*>(farend_handle_);
handle_ = WebRtc_CreateDelayEstimator(farend_handle_, kLookahead, kLookahead); handle_ = WebRtc_CreateDelayEstimator(farend_handle_, kLookahead);
ASSERT_TRUE(handle_ != NULL); ASSERT_TRUE(handle_ != NULL);
self_ = reinterpret_cast<DelayEstimator*>(handle_); self_ = reinterpret_cast<DelayEstimator*>(handle_);
binary_farend_ = WebRtc_CreateBinaryDelayEstimatorFarend(kMaxDelay + binary_farend_ = WebRtc_CreateBinaryDelayEstimatorFarend(kMaxDelay +
kLookahead); kLookahead);
ASSERT_TRUE(binary_farend_ != NULL); ASSERT_TRUE(binary_farend_ != NULL);
binary_ = WebRtc_CreateBinaryDelayEstimator(binary_farend_, kLookahead, binary_ = WebRtc_CreateBinaryDelayEstimator(binary_farend_, kLookahead);
kLookahead);
ASSERT_TRUE(binary_ != NULL); ASSERT_TRUE(binary_ != NULL);
} }
@ -202,7 +201,6 @@ void DelayEstimatorTest::RunBinarySpectraTest(int near_offset,
int robust_validation) { int robust_validation) {
BinaryDelayEstimator* binary2 = BinaryDelayEstimator* binary2 =
WebRtc_CreateBinaryDelayEstimator(binary_farend_, WebRtc_CreateBinaryDelayEstimator(binary_farend_,
kLookahead + lookahead_offset,
kLookahead + lookahead_offset); kLookahead + lookahead_offset);
// Verify the delay for both causal and non-causal systems. For causal systems // Verify the delay for both causal and non-causal systems. For causal systems
// the delay is equivalent with a positive |offset| of the far-end sequence. // the delay is equivalent with a positive |offset| of the far-end sequence.
@ -234,12 +232,9 @@ TEST_F(DelayEstimatorTest, CorrectErrorReturnsOfWrapper) {
EXPECT_TRUE(handle == NULL); EXPECT_TRUE(handle == NULL);
handle = handle_; handle = handle_;
handle = WebRtc_CreateDelayEstimator(NULL, kLookahead, kLookahead); handle = WebRtc_CreateDelayEstimator(NULL, kLookahead);
EXPECT_TRUE(handle == NULL); EXPECT_TRUE(handle == NULL);
handle = WebRtc_CreateDelayEstimator(farend_handle_, kLookahead, -1); handle = WebRtc_CreateDelayEstimator(farend_handle_, -1);
EXPECT_TRUE(handle == NULL);
handle = WebRtc_CreateDelayEstimator(farend_handle_, kLookahead - 1,
kLookahead);
EXPECT_TRUE(handle == NULL); EXPECT_TRUE(handle == NULL);
// WebRtc_InitDelayEstimatorFarend() and WebRtc_InitDelayEstimator() should // WebRtc_InitDelayEstimatorFarend() and WebRtc_InitDelayEstimator() should
@ -445,14 +440,9 @@ TEST_F(DelayEstimatorTest, CorrectErrorReturnsOfBinaryEstimator) {
// |binary_handle| should be NULL. // |binary_handle| should be NULL.
// Make sure we have a non-NULL value at start, so we can detect NULL after // Make sure we have a non-NULL value at start, so we can detect NULL after
// create failure. // create failure.
binary_handle = WebRtc_CreateBinaryDelayEstimator(NULL, kLookahead, binary_handle = WebRtc_CreateBinaryDelayEstimator(NULL, kLookahead);
kLookahead);
EXPECT_TRUE(binary_handle == NULL); EXPECT_TRUE(binary_handle == NULL);
binary_handle = WebRtc_CreateBinaryDelayEstimator(binary_farend_, kLookahead, binary_handle = WebRtc_CreateBinaryDelayEstimator(binary_farend_, -1);
-1);
EXPECT_TRUE(binary_handle == NULL);
binary_handle = WebRtc_CreateBinaryDelayEstimator(binary_farend_,
kLookahead - 1, kLookahead);
EXPECT_TRUE(binary_handle == NULL); EXPECT_TRUE(binary_handle == NULL);
} }
@ -539,8 +529,7 @@ TEST_F(DelayEstimatorTest, VerifyLookaheadAtCreate) {
void* farend_handle = WebRtc_CreateDelayEstimatorFarend(kSpectrumSize, void* farend_handle = WebRtc_CreateDelayEstimatorFarend(kSpectrumSize,
kMaxDelay); kMaxDelay);
ASSERT_TRUE(farend_handle != NULL); ASSERT_TRUE(farend_handle != NULL);
void* handle = WebRtc_CreateDelayEstimator(farend_handle, kLookahead, void* handle = WebRtc_CreateDelayEstimator(farend_handle, kLookahead);
kLookahead);
ASSERT_TRUE(handle != NULL); ASSERT_TRUE(handle != NULL);
EXPECT_EQ(kLookahead, WebRtc_lookahead(handle)); EXPECT_EQ(kLookahead, WebRtc_lookahead(handle));
WebRtc_FreeDelayEstimator(handle); WebRtc_FreeDelayEstimator(handle);

View File

@ -267,8 +267,7 @@ void WebRtc_FreeDelayEstimator(void* handle) {
free(self); free(self);
} }
void* WebRtc_CreateDelayEstimator(void* farend_handle, int max_lookahead, void* WebRtc_CreateDelayEstimator(void* farend_handle, int max_lookahead) {
int lookahead) {
DelayEstimator* self = NULL; DelayEstimator* self = NULL;
DelayEstimatorFarend* farend = (DelayEstimatorFarend*) farend_handle; DelayEstimatorFarend* farend = (DelayEstimatorFarend*) farend_handle;
@ -281,8 +280,7 @@ void* WebRtc_CreateDelayEstimator(void* farend_handle, int max_lookahead,
// Allocate memory for the farend spectrum handling. // Allocate memory for the farend spectrum handling.
self->binary_handle = self->binary_handle =
WebRtc_CreateBinaryDelayEstimator(farend->binary_farend, max_lookahead, WebRtc_CreateBinaryDelayEstimator(farend->binary_farend, max_lookahead);
lookahead);
memory_fail |= (self->binary_handle == NULL); memory_fail |= (self->binary_handle == NULL);
// Allocate memory for spectrum buffers. // Allocate memory for spectrum buffers.
@ -326,9 +324,22 @@ int WebRtc_SoftResetDelayEstimator(void* handle, int delay_shift) {
return WebRtc_SoftResetBinaryDelayEstimator(self->binary_handle, delay_shift); return WebRtc_SoftResetBinaryDelayEstimator(self->binary_handle, delay_shift);
} }
int WebRtc_set_lookahead(void* handle, int lookahead) {
DelayEstimator* self = (DelayEstimator*) handle;
assert(self != NULL);
assert(self->binary_handle != NULL);
if ((lookahead > self->binary_handle->near_history_size - 1) ||
(lookahead < 0)) {
return -1;
}
self->binary_handle->lookahead = lookahead;
return self->binary_handle->lookahead;
}
int WebRtc_lookahead(void* handle) { int WebRtc_lookahead(void* handle) {
DelayEstimator* self = (DelayEstimator*) handle; DelayEstimator* self = (DelayEstimator*) handle;
assert(self != NULL); assert(self != NULL);
assert(self->binary_handle != NULL);
return self->binary_handle->lookahead; return self->binary_handle->lookahead;
} }
@ -360,6 +371,7 @@ int WebRtc_enable_robust_validation(void* handle, int enable) {
if ((enable < 0) || (enable > 1)) { if ((enable < 0) || (enable > 1)) {
return -1; return -1;
} }
assert(self->binary_handle != NULL);
self->binary_handle->robust_validation_enabled = enable; self->binary_handle->robust_validation_enabled = enable;
return 0; return 0;
} }

View File

@ -98,11 +98,18 @@ void WebRtc_FreeDelayEstimator(void* handle);
// ownership of |farend_handle|, which has to be torn // ownership of |farend_handle|, which has to be torn
// down properly after this instance. // down properly after this instance.
// //
// - lookahead : Amount of non-causal lookahead to use. This can // - max_lookahead : Maximum amount of non-causal lookahead allowed. The
// detect cases in which a near-end signal occurs before // actual amount of lookahead used can be controlled by
// the corresponding far-end signal. It will delay the // WebRtc_set_lookahead(...). The default |lookahead| is
// estimate for the current block by an equal amount, // set to |max_lookahead| at create time. Use
// and the returned values will be offset by it. // WebRtc_set_lookahead(...) before start if a different
// value is desired.
//
// Using lookahead can detect cases in which a near-end
// signal occurs before the corresponding far-end signal.
// It will delay the estimate for the current block by an
// equal amount, and the returned values will be offset
// by it.
// //
// A value of zero is the typical no-lookahead case. // A value of zero is the typical no-lookahead case.
// This also represents the minimum delay which can be // This also represents the minimum delay which can be
@ -113,17 +120,12 @@ void WebRtc_FreeDelayEstimator(void* handle);
// where |history_size| was set upon creating the far-end // where |history_size| was set upon creating the far-end
// history buffer size. // history buffer size.
// //
// - max_lookahead : Maximum amount of non-causal lookahead allowed. This
// is to allow for dynamically changing the lookahead on
// the fly.
//
// Return value: // Return value:
// - void* : Created |handle|. If the memory can't be allocated or // - void* : Created |handle|. If the memory can't be allocated or
// if any of the input parameters are invalid NULL is // if any of the input parameters are invalid NULL is
// returned. // returned.
// //
void* WebRtc_CreateDelayEstimator(void* farend_handle, int max_lookahead, void* WebRtc_CreateDelayEstimator(void* farend_handle, int max_lookahead);
int lookahead);
// Initializes the delay estimation instance returned by // Initializes the delay estimation instance returned by
// WebRtc_CreateDelayEstimator(...) // WebRtc_CreateDelayEstimator(...)
@ -145,6 +147,18 @@ int WebRtc_InitDelayEstimator(void* handle);
// //
int WebRtc_SoftResetDelayEstimator(void* handle, int delay_shift); int WebRtc_SoftResetDelayEstimator(void* handle, int delay_shift);
// Sets the amount of |lookahead| to use. Valid values are [0, max_lookahead]
// where |max_lookahead| was set at create time through
// WebRtc_CreateDelayEstimator(...).
//
// Input:
// - lookahead : The amount of blocks to shift history buffers.
//
// Return value:
// - new_lookahead : The actual number of shifts performed.
//
int WebRtc_set_lookahead(void* handle, int lookahead);
// Returns the amount of lookahead we currently use. // Returns the amount of lookahead we currently use.
int WebRtc_lookahead(void* handle); int WebRtc_lookahead(void* handle);
@ -222,7 +236,7 @@ int WebRtc_last_delay(void* handle);
// Returns the estimation quality/probability of the last calculated delay // Returns the estimation quality/probability of the last calculated delay
// updated by the function WebRtc_DelayEstimatorProcess(...). The estimation // updated by the function WebRtc_DelayEstimatorProcess(...). The estimation
// quality is a value in the interval [0, 1]. The higher the value, the better // quality is a value in the interval [0, 1]. The higher the value, the better
// quality. // the quality.
// //
// Return value: // Return value:
// - delay_quality : >= 0 - Estimation quality of last calculated delay. // - delay_quality : >= 0 - Estimation quality of last calculated delay.