From 69ef9911e4ee0f81502e0f0c85d19eb18ae2bf89 Mon Sep 17 00:00:00 2001 From: "bjornv@webrtc.org" Date: Thu, 3 Jul 2014 14:59:03 +0000 Subject: [PATCH] delay_estimator: Allows dynamically used history sizes Gives the user a possibility to dynamically change the history size. The main advantage is, for example, that you now can start with a wide delay range and over time decrease the search window to lower complexity. Adds - two new APIs. - and updates unit tests. - a history_size member variable to BinaryDelayEstimator. - two help function re-allocating buffer memory. One thing that makes this a little complicated is that you are allowed to have multiple delay estimators with the same reference, so changing the buffer sizes at one place will automatically give you a mismatch at other places. BUG=3532, 3504 TESTED=trybots and manually R=aluebs@webrtc.org, kwiberg@webrtc.org Review URL: https://webrtc-codereview.appspot.com/15879004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@6593 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../utility/delay_estimator.c | 164 ++++++++++++------ .../utility/delay_estimator.h | 29 +++- .../utility/delay_estimator_unittest.cc | 83 ++++++++- .../utility/delay_estimator_wrapper.c | 25 ++- .../utility/delay_estimator_wrapper.h | 76 ++++---- 5 files changed, 271 insertions(+), 106 deletions(-) diff --git a/webrtc/modules/audio_processing/utility/delay_estimator.c b/webrtc/modules/audio_processing/utility/delay_estimator.c index 3b2043267f..60c7a04214 100644 --- a/webrtc/modules/audio_processing/utility/delay_estimator.c +++ b/webrtc/modules/audio_processing/utility/delay_estimator.c @@ -98,6 +98,7 @@ static void UpdateRobustValidationStatistics(BinaryDelayEstimator* self, kMaxHitsWhenPossiblyNonCausal : kMaxHitsWhenPossiblyCausal; int i = 0; + assert(self->history_size == self->farend->history_size); // Reset |candidate_hits| if we have a new candidate. if (candidate_delay != self->last_candidate_delay) { self->candidate_hits = 0; @@ -130,7 +131,7 @@ static void UpdateRobustValidationStatistics(BinaryDelayEstimator* self, // 4. All other bins are decreased with |valley_depth|. // TODO(bjornv): Investigate how to make this loop more efficient. Split up // the loop? Remove parts that doesn't add too much. - for (i = 0; i < self->farend->history_size; ++i) { + for (i = 0; i < self->history_size; ++i) { int is_in_last_set = (i >= self->last_delay - 2) && (i <= self->last_delay + 1) && (i != candidate_delay); int is_in_candidate_set = (i >= candidate_delay - 2) && @@ -277,27 +278,47 @@ BinaryDelayEstimatorFarend* WebRtc_CreateBinaryDelayEstimatorFarend( // Sanity conditions fulfilled. self = malloc(sizeof(BinaryDelayEstimatorFarend)); } - if (self != NULL) { - int malloc_fail = 0; - - self->history_size = history_size; - - // Allocate memory for history buffers. - self->binary_far_history = malloc(history_size * sizeof(uint32_t)); - malloc_fail |= (self->binary_far_history == NULL); - - self->far_bit_counts = malloc(history_size * sizeof(int)); - malloc_fail |= (self->far_bit_counts == NULL); - - if (malloc_fail) { - WebRtc_FreeBinaryDelayEstimatorFarend(self); - self = NULL; - } + if (self == NULL) { + return NULL; } + self->history_size = 0; + self->binary_far_history = NULL; + self->far_bit_counts = NULL; + if (WebRtc_AllocateFarendBufferMemory(self, history_size) == 0) { + WebRtc_FreeBinaryDelayEstimatorFarend(self); + self = NULL; + } return self; } +int WebRtc_AllocateFarendBufferMemory(BinaryDelayEstimatorFarend* self, + int history_size) { + assert(self != NULL); + // (Re-)Allocate memory for history buffers. + self->binary_far_history = + realloc(self->binary_far_history, + history_size * sizeof(*self->binary_far_history)); + self->far_bit_counts = realloc(self->far_bit_counts, + history_size * sizeof(*self->far_bit_counts)); + if ((self->binary_far_history == NULL) || (self->far_bit_counts == NULL)) { + history_size = 0; + } + // Fill with zeros if we have expanded the buffers. + if (history_size > self->history_size) { + int size_diff = history_size - self->history_size; + memset(&self->binary_far_history[self->history_size], + 0, + sizeof(*self->binary_far_history) * size_diff); + memset(&self->far_bit_counts[self->history_size], + 0, + sizeof(*self->far_bit_counts) * size_diff); + } + self->history_size = history_size; + + return self->history_size; +} + void WebRtc_InitBinaryDelayEstimatorFarend(BinaryDelayEstimatorFarend* self) { assert(self != NULL); memset(self->binary_far_history, 0, sizeof(uint32_t) * self->history_size); @@ -385,51 +406,84 @@ BinaryDelayEstimator* WebRtc_CreateBinaryDelayEstimator( // Sanity conditions fulfilled. self = malloc(sizeof(BinaryDelayEstimator)); } + if (self == NULL) { + return NULL; + } - if (self != NULL) { - int malloc_fail = 0; + self->farend = farend; + self->near_history_size = max_lookahead + 1; + self->history_size = 0; + self->robust_validation_enabled = 0; // Disabled by default. + self->allowed_offset = 0; - self->farend = farend; - self->near_history_size = max_lookahead + 1; - self->robust_validation_enabled = 0; // Disabled by default. - self->allowed_offset = 0; + self->lookahead = max_lookahead; - self->lookahead = max_lookahead; - - // Allocate memory for spectrum buffers. The extra array element in - // |mean_bit_counts| and |histogram| is a dummy element only used while - // |last_delay| == -2, i.e., before we have a valid estimate. - self->mean_bit_counts = - malloc((farend->history_size + 1) * sizeof(int32_t)); - malloc_fail |= (self->mean_bit_counts == NULL); - - self->bit_counts = malloc(farend->history_size * sizeof(int32_t)); - malloc_fail |= (self->bit_counts == NULL); - - // Allocate memory for history buffers. - self->binary_near_history = malloc((max_lookahead + 1) * sizeof(uint32_t)); - malloc_fail |= (self->binary_near_history == NULL); - - self->histogram = malloc((farend->history_size + 1) * sizeof(float)); - malloc_fail |= (self->histogram == NULL); - - if (malloc_fail) { - WebRtc_FreeBinaryDelayEstimator(self); - self = NULL; - } + // Allocate memory for spectrum and history buffers. + self->mean_bit_counts = NULL; + self->bit_counts = NULL; + self->histogram = NULL; + self->binary_near_history = + malloc((max_lookahead + 1) * sizeof(*self->binary_near_history)); + if (self->binary_near_history == NULL || + WebRtc_AllocateHistoryBufferMemory(self, farend->history_size) == 0) { + WebRtc_FreeBinaryDelayEstimator(self); + self = NULL; } return self; } +int WebRtc_AllocateHistoryBufferMemory(BinaryDelayEstimator* self, + int history_size) { + BinaryDelayEstimatorFarend* far = self->farend; + // (Re-)Allocate memory for spectrum and history buffers. + if (history_size != far->history_size) { + // Only update far-end buffers if we need. + history_size = WebRtc_AllocateFarendBufferMemory(far, history_size); + } + // The extra array element in |mean_bit_counts| and |histogram| is a dummy + // element only used while |last_delay| == -2, i.e., before we have a valid + // estimate. + self->mean_bit_counts = + realloc(self->mean_bit_counts, + (history_size + 1) * sizeof(*self->mean_bit_counts)); + self->bit_counts = + realloc(self->bit_counts, history_size * sizeof(*self->bit_counts)); + self->histogram = + realloc(self->histogram, (history_size + 1) * sizeof(*self->histogram)); + + if ((self->mean_bit_counts == NULL) || + (self->bit_counts == NULL) || + (self->histogram == NULL)) { + history_size = 0; + } + // Fill with zeros if we have expanded the buffers. + if (history_size > self->history_size) { + int size_diff = history_size - self->history_size; + memset(&self->mean_bit_counts[self->history_size], + 0, + sizeof(*self->mean_bit_counts) * size_diff); + memset(&self->bit_counts[self->history_size], + 0, + sizeof(*self->bit_counts) * size_diff); + memset(&self->histogram[self->history_size], + 0, + sizeof(*self->histogram) * size_diff); + } + self->history_size = history_size; + + return self->history_size; +} + void WebRtc_InitBinaryDelayEstimator(BinaryDelayEstimator* self) { int i = 0; assert(self != NULL); - memset(self->bit_counts, 0, sizeof(int32_t) * self->farend->history_size); - memset(self->binary_near_history, 0, + memset(self->bit_counts, 0, sizeof(int32_t) * self->history_size); + memset(self->binary_near_history, + 0, sizeof(uint32_t) * self->near_history_size); - for (i = 0; i <= self->farend->history_size; ++i) { + for (i = 0; i <= self->history_size; ++i) { self->mean_bit_counts[i] = (20 << 9); // 20 in Q9. self->histogram[i] = 0.f; } @@ -440,7 +494,7 @@ void WebRtc_InitBinaryDelayEstimator(BinaryDelayEstimator* self) { self->last_delay = -2; self->last_candidate_delay = -2; - self->compare_delay = self->farend->history_size; + self->compare_delay = self->history_size; self->candidate_hits = 0; self->last_delay_histogram = 0.f; } @@ -471,6 +525,10 @@ int WebRtc_ProcessBinarySpectrum(BinaryDelayEstimator* self, int32_t valley_depth = 0; assert(self != NULL); + if (self->farend->history_size != self->history_size) { + // Non matching history sizes. + return -1; + } if (self->near_history_size > 1) { // If we apply lookahead, shift near-end binary spectrum history. Insert // current |binary_near_spectrum| and pull out the delayed one. @@ -482,10 +540,10 @@ int WebRtc_ProcessBinarySpectrum(BinaryDelayEstimator* self, // Compare with delayed spectra and store the |bit_counts| for each delay. BitCountComparison(binary_near_spectrum, self->farend->binary_far_history, - self->farend->history_size, self->bit_counts); + self->history_size, self->bit_counts); // Update |mean_bit_counts|, which is the smoothed version of |bit_counts|. - for (i = 0; i < self->farend->history_size; i++) { + for (i = 0; i < self->history_size; i++) { // |bit_counts| is constrained to [0, 32], meaning we can smooth with a // factor up to 2^26. We use Q9. int32_t bit_count = (self->bit_counts[i] << 9); // Q9. @@ -503,7 +561,7 @@ int WebRtc_ProcessBinarySpectrum(BinaryDelayEstimator* self, // Find |candidate_delay|, |value_best_candidate| and |value_worst_candidate| // of |mean_bit_counts|. - for (i = 0; i < self->farend->history_size; i++) { + for (i = 0; i < self->history_size; i++) { if (self->mean_bit_counts[i] < value_best_candidate) { value_best_candidate = self->mean_bit_counts[i]; candidate_delay = i; diff --git a/webrtc/modules/audio_processing/utility/delay_estimator.h b/webrtc/modules/audio_processing/utility/delay_estimator.h index 3d5ffce20e..65c3f034ba 100644 --- a/webrtc/modules/audio_processing/utility/delay_estimator.h +++ b/webrtc/modules/audio_processing/utility/delay_estimator.h @@ -36,6 +36,7 @@ typedef struct { // Binary history variables. uint32_t* binary_near_history; int near_history_size; + int history_size; // Delay estimation variables. int32_t minimum_probability; @@ -85,6 +86,19 @@ void WebRtc_FreeBinaryDelayEstimatorFarend(BinaryDelayEstimatorFarend* self); BinaryDelayEstimatorFarend* WebRtc_CreateBinaryDelayEstimatorFarend( int history_size); +// Re-allocates the buffers. +// +// Inputs: +// - self : Pointer to the binary estimation far-end instance +// which is the return value of +// WebRtc_CreateBinaryDelayEstimatorFarend(). +// - history_size : Size of the far-end binary spectrum history. +// +// Return value: +// - history_size : The history size allocated. +int WebRtc_AllocateFarendBufferMemory(BinaryDelayEstimatorFarend* self, + int history_size); + // Initializes the delay estimation far-end instance created with // WebRtc_CreateBinaryDelayEstimatorFarend(...). // @@ -141,6 +155,20 @@ void WebRtc_FreeBinaryDelayEstimator(BinaryDelayEstimator* self); BinaryDelayEstimator* WebRtc_CreateBinaryDelayEstimator( BinaryDelayEstimatorFarend* farend, int max_lookahead); +// Re-allocates |history_size| dependent buffers. The far-end buffers will be +// updated at the same time if needed. +// +// Input: +// - self : Pointer to the binary estimation instance which is +// the return value of +// WebRtc_CreateBinaryDelayEstimator(). +// - history_size : Size of the history buffers. +// +// Return value: +// - history_size : The history size allocated. +int WebRtc_AllocateHistoryBufferMemory(BinaryDelayEstimator* self, + int history_size); + // Initializes the delay estimation instance created with // WebRtc_CreateBinaryDelayEstimator(...). // @@ -220,5 +248,4 @@ void WebRtc_MeanEstimatorFix(int32_t new_value, int factor, int32_t* mean_value); - #endif // WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_DELAY_ESTIMATOR_H_ diff --git a/webrtc/modules/audio_processing/utility/delay_estimator_unittest.cc b/webrtc/modules/audio_processing/utility/delay_estimator_unittest.cc index ca0901d6db..3b354d0798 100644 --- a/webrtc/modules/audio_processing/utility/delay_estimator_unittest.cc +++ b/webrtc/modules/audio_processing/utility/delay_estimator_unittest.cc @@ -23,9 +23,13 @@ enum { kSpectrumSize = 65 }; // Delay history sizes. enum { kMaxDelay = 100 }; enum { kLookahead = 10 }; +enum { kHistorySize = kMaxDelay + kLookahead }; // Length of binary spectrum sequence. enum { kSequenceLength = 400 }; +const int kDifferentHistorySize = 3; +const int kDifferentLookahead = 1; + const int kEnable[] = { 0, 1 }; const size_t kSizeEnable = sizeof(kEnable) / sizeof(*kEnable); @@ -56,7 +60,7 @@ class DelayEstimatorTest : public ::testing::Test { float near_f_[kSpectrumSize]; uint16_t far_u16_[kSpectrumSize]; uint16_t near_u16_[kSpectrumSize]; - uint32_t binary_spectrum_[kSequenceLength + kMaxDelay + kLookahead]; + uint32_t binary_spectrum_[kSequenceLength + kHistorySize]; }; DelayEstimatorTest::DelayEstimatorTest() @@ -76,21 +80,20 @@ DelayEstimatorTest::DelayEstimatorTest() // |kSequenceLength| has to be long enough for the delay estimation to leave // the initialized state. binary_spectrum_[0] = 1; - for (int i = 1; i < (kSequenceLength + kMaxDelay + kLookahead); i++) { + for (int i = 1; i < (kSequenceLength + kHistorySize); i++) { binary_spectrum_[i] = 3 * binary_spectrum_[i - 1]; } } void DelayEstimatorTest::SetUp() { farend_handle_ = WebRtc_CreateDelayEstimatorFarend(kSpectrumSize, - kMaxDelay + kLookahead); + kHistorySize); ASSERT_TRUE(farend_handle_ != NULL); farend_self_ = reinterpret_cast(farend_handle_); handle_ = WebRtc_CreateDelayEstimator(farend_handle_, kLookahead); ASSERT_TRUE(handle_ != NULL); self_ = reinterpret_cast(handle_); - binary_farend_ = WebRtc_CreateBinaryDelayEstimatorFarend(kMaxDelay + - kLookahead); + binary_farend_ = WebRtc_CreateBinaryDelayEstimatorFarend(kHistorySize); ASSERT_TRUE(binary_farend_ != NULL); binary_ = WebRtc_CreateBinaryDelayEstimator(binary_farend_, kLookahead); ASSERT_TRUE(binary_ != NULL); @@ -226,7 +229,7 @@ TEST_F(DelayEstimatorTest, CorrectErrorReturnsOfWrapper) { // Make sure we have a non-NULL value at start, so we can detect NULL after // create failure. void* handle = farend_handle_; - handle = WebRtc_CreateDelayEstimatorFarend(33, kMaxDelay + kLookahead); + handle = WebRtc_CreateDelayEstimatorFarend(33, kHistorySize); EXPECT_TRUE(handle == NULL); handle = WebRtc_CreateDelayEstimatorFarend(kSpectrumSize, 1); EXPECT_TRUE(handle == NULL); @@ -266,6 +269,28 @@ TEST_F(DelayEstimatorTest, CorrectErrorReturnsOfWrapper) { EXPECT_EQ(-1, WebRtc_AddFarSpectrumFix(farend_handle_, far_u16_, spectrum_size_, 16)); + // WebRtc_set_history_size() should return -1 if: + // 1) |handle| is a NULL. + // 2) |history_size| <= 1. + EXPECT_EQ(-1, WebRtc_set_history_size(NULL, 1)); + EXPECT_EQ(-1, WebRtc_set_history_size(handle_, 1)); + // WebRtc_history_size() should return -1 if: + // 1) NULL pointer input. + EXPECT_EQ(-1, WebRtc_history_size(NULL)); + // 2) there is a mismatch between history size. + void* tmp_handle = WebRtc_CreateDelayEstimator(farend_handle_, kHistorySize); + EXPECT_EQ(0, WebRtc_InitDelayEstimator(tmp_handle)); + EXPECT_EQ(kDifferentHistorySize, + WebRtc_set_history_size(tmp_handle, kDifferentHistorySize)); + EXPECT_EQ(kDifferentHistorySize, WebRtc_history_size(tmp_handle)); + EXPECT_EQ(kHistorySize, WebRtc_set_history_size(handle_, kHistorySize)); + EXPECT_EQ(-1, WebRtc_history_size(tmp_handle)); + + // WebRtc_set_lookahead() should return -1 if we try a value outside the + /// buffer. + EXPECT_EQ(-1, WebRtc_set_lookahead(handle_, kLookahead + 1)); + EXPECT_EQ(-1, WebRtc_set_lookahead(handle_, -1)); + // WebRtc_set_allowed_offset() should return -1 if we have: // 1) NULL pointer as |handle|. // 2) |allowed_offset| < 0. @@ -289,6 +314,8 @@ TEST_F(DelayEstimatorTest, CorrectErrorReturnsOfWrapper) { // 1) NULL pointer as |handle|. // 2) NULL pointer as near-end spectrum. // 3) Incorrect spectrum size. + // 4) Non matching history sizes if multiple delay estimators using the same + // far-end reference. EXPECT_EQ(-1, WebRtc_DelayEstimatorProcessFloat(NULL, near_f_, spectrum_size_)); // Use |handle_| which is properly created at SetUp(). @@ -296,12 +323,18 @@ TEST_F(DelayEstimatorTest, CorrectErrorReturnsOfWrapper) { spectrum_size_)); EXPECT_EQ(-1, WebRtc_DelayEstimatorProcessFloat(handle_, near_f_, spectrum_size_ + 1)); + // |tmp_handle| is already in a non-matching state. + EXPECT_EQ(-1, WebRtc_DelayEstimatorProcessFloat(tmp_handle, + near_f_, + spectrum_size_)); // WebRtc_DelayEstimatorProcessFix() should return -1 if we have: // 1) NULL pointer as |handle|. - // 3) NULL pointer as near-end spectrum. - // 4) Incorrect spectrum size. - // 6) Too high precision in near-end spectrum (Q-domain > 15). + // 2) NULL pointer as near-end spectrum. + // 3) Incorrect spectrum size. + // 4) Too high precision in near-end spectrum (Q-domain > 15). + // 5) Non matching history sizes if multiple delay estimators using the same + // far-end reference. EXPECT_EQ(-1, WebRtc_DelayEstimatorProcessFix(NULL, near_u16_, spectrum_size_, 0)); EXPECT_EQ(-1, WebRtc_DelayEstimatorProcessFix(handle_, NULL, spectrum_size_, @@ -310,6 +343,12 @@ TEST_F(DelayEstimatorTest, CorrectErrorReturnsOfWrapper) { spectrum_size_ + 1, 0)); EXPECT_EQ(-1, WebRtc_DelayEstimatorProcessFix(handle_, near_u16_, spectrum_size_, 16)); + // |tmp_handle| is already in a non-matching state. + EXPECT_EQ(-1, WebRtc_DelayEstimatorProcessFix(tmp_handle, + near_u16_, + spectrum_size_, + 0)); + WebRtc_FreeDelayEstimator(tmp_handle); // WebRtc_last_delay() should return -1 if we have a NULL pointer as |handle|. EXPECT_EQ(-1, WebRtc_last_delay(NULL)); @@ -536,6 +575,32 @@ TEST_F(DelayEstimatorTest, VerifyLookaheadAtCreate) { WebRtc_FreeDelayEstimatorFarend(farend_handle); } +TEST_F(DelayEstimatorTest, VerifyLookaheadIsSetAndKeptAfterInit) { + EXPECT_EQ(kLookahead, WebRtc_lookahead(handle_)); + EXPECT_EQ(kDifferentLookahead, + WebRtc_set_lookahead(handle_, kDifferentLookahead)); + EXPECT_EQ(kDifferentLookahead, WebRtc_lookahead(handle_)); + EXPECT_EQ(0, WebRtc_InitDelayEstimatorFarend(farend_handle_)); + EXPECT_EQ(kDifferentLookahead, WebRtc_lookahead(handle_)); + EXPECT_EQ(0, WebRtc_InitDelayEstimator(handle_)); + EXPECT_EQ(kDifferentLookahead, WebRtc_lookahead(handle_)); +} + +TEST_F(DelayEstimatorTest, VerifyHistorySizeAtCreate) { + EXPECT_EQ(kHistorySize, WebRtc_history_size(handle_)); +} + +TEST_F(DelayEstimatorTest, VerifyHistorySizeIsSetAndKeptAfterInit) { + EXPECT_EQ(kHistorySize, WebRtc_history_size(handle_)); + EXPECT_EQ(kDifferentHistorySize, + WebRtc_set_history_size(handle_, kDifferentHistorySize)); + EXPECT_EQ(kDifferentHistorySize, WebRtc_history_size(handle_)); + EXPECT_EQ(0, WebRtc_InitDelayEstimator(handle_)); + EXPECT_EQ(kDifferentHistorySize, WebRtc_history_size(handle_)); + EXPECT_EQ(0, WebRtc_InitDelayEstimatorFarend(farend_handle_)); + EXPECT_EQ(kDifferentHistorySize, WebRtc_history_size(handle_)); +} + // TODO(bjornv): Add tests for SoftReset...(...). } // namespace diff --git a/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.c b/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.c index 6ec894e65e..5c8be67bf2 100644 --- a/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.c +++ b/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.c @@ -147,7 +147,7 @@ void* WebRtc_CreateDelayEstimatorFarend(int spectrum_size, int history_size) { COMPILE_ASSERT(kBandLast - kBandFirst < 32); if (spectrum_size >= kBandLast) { - self = malloc(sizeof(DelayEstimator)); + self = malloc(sizeof(DelayEstimatorFarend)); } if (self != NULL) { @@ -324,6 +324,29 @@ int WebRtc_SoftResetDelayEstimator(void* handle, int delay_shift) { return WebRtc_SoftResetBinaryDelayEstimator(self->binary_handle, delay_shift); } +int WebRtc_set_history_size(void* handle, int history_size) { + DelayEstimator* self = handle; + + if ((self == NULL) || (history_size <= 1)) { + return -1; + } + return WebRtc_AllocateHistoryBufferMemory(self->binary_handle, history_size); +} + +int WebRtc_history_size(const void* handle) { + const DelayEstimator* self = handle; + + if (self == NULL) { + return -1; + } + if (self->binary_handle->farend->history_size != + self->binary_handle->history_size) { + // Non matching history sizes. + return -1; + } + return self->binary_handle->history_size; +} + int WebRtc_set_lookahead(void* handle, int lookahead) { DelayEstimator* self = (DelayEstimator*) handle; assert(self != NULL); diff --git a/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h b/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h index 13e86bdd43..68463d29d7 100644 --- a/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h +++ b/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h @@ -17,9 +17,6 @@ #include "webrtc/typedefs.h" // Releases the memory allocated by WebRtc_CreateDelayEstimatorFarend(...) -// Input: -// - handle : Pointer to the delay estimation far-end instance. -// void WebRtc_FreeDelayEstimatorFarend(void* handle); // Allocates the memory needed by the far-end part of the delay estimation. The @@ -27,36 +24,28 @@ void WebRtc_FreeDelayEstimatorFarend(void* handle); // WebRtc_InitDelayEstimatorFarend(...). // // Inputs: -// - spectrum_size : Size of the spectrum used both in far-end and +// - spectrum_size : Size of the spectrum used both in far-end and // near-end. Used to allocate memory for spectrum // specific buffers. -// - history_size : The far-end history buffer size. Note that the maximum -// delay which can be estimated is controlled together -// with |lookahead| through -// WebRtc_CreateDelayEstimator(). +// - history_size : The far-end history buffer size. A change in buffer +// size can be forced with WebRtc_set_history_size(). +// Note that the maximum delay which can be estimated is +// determined together with WebRtc_set_lookahead(). // // 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 // returned. -// void* WebRtc_CreateDelayEstimatorFarend(int spectrum_size, int history_size); // Initializes the far-end part of the delay estimation instance returned by // WebRtc_CreateDelayEstimatorFarend(...) -// Input: -// - handle : Pointer to the delay estimation far-end instance. -// -// Output: -// - handle : Initialized instance. -// int WebRtc_InitDelayEstimatorFarend(void* handle); // Soft resets the far-end part of the delay estimation instance returned by // WebRtc_CreateDelayEstimatorFarend(...). // Input: // - delay_shift : The amount of blocks to shift history buffers. -// void WebRtc_SoftResetDelayEstimatorFarend(void* handle, int delay_shift); // Adds the far-end spectrum to the far-end history buffer. This spectrum is @@ -64,15 +53,10 @@ void WebRtc_SoftResetDelayEstimatorFarend(void* handle, int delay_shift); // WebRtc_ProcessSpectrum(). // // Inputs: -// - handle : Pointer to the delay estimation far-end instance. // - far_spectrum : Far-end spectrum. // - spectrum_size : The size of the data arrays (same for both far- and // near-end). // - far_q : The Q-domain of the far-end data. -// -// Output: -// - handle : Updated far-end instance. -// int WebRtc_AddFarSpectrumFix(void* handle, uint16_t* far_spectrum, int spectrum_size, int far_q); @@ -81,9 +65,6 @@ int WebRtc_AddFarSpectrumFloat(void* handle, float* far_spectrum, int spectrum_size); // Releases the memory allocated by WebRtc_CreateDelayEstimator(...) -// Input: -// - handle : Pointer to the delay estimation instance. -// void WebRtc_FreeDelayEstimator(void* handle); // Allocates the memory needed by the delay estimation. The memory needs to be @@ -117,24 +98,17 @@ void WebRtc_FreeDelayEstimator(void* handle); // // 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. +// where |history_size| is set through +// WebRtc_set_history_size(). // // Return value: // - void* : Created |handle|. If the memory can't be allocated or // if any of the input parameters are invalid NULL is // returned. -// void* WebRtc_CreateDelayEstimator(void* farend_handle, int max_lookahead); // Initializes the delay estimation instance returned by // WebRtc_CreateDelayEstimator(...) -// Input: -// - handle : Pointer to the delay estimation instance. -// -// Output: -// - handle : Initialized instance. -// int WebRtc_InitDelayEstimator(void* handle); // Soft resets the delay estimation instance returned by @@ -144,22 +118,44 @@ int WebRtc_InitDelayEstimator(void* handle); // // Return value: // - actual_shifts : The actual number of shifts performed. -// int WebRtc_SoftResetDelayEstimator(void* handle, int delay_shift); +// Sets the effective |history_size| used. Valid values from 2. We simply need +// at least two delays to compare to perform an estimate. If |history_size| is +// changed, buffers are reallocated filling in with zeros if necessary. +// Note that changing the |history_size| affects both buffers in far-end and +// near-end. Hence it is important to change all DelayEstimators that use the +// same reference far-end, to the same |history_size| value. +// Inputs: +// - handle : Pointer to the delay estimation instance. +// - history_size : Effective history size to be used. +// Return value: +// - new_history_size : The new history size used. If the memory was not able +// to be allocated 0 is returned. +int WebRtc_set_history_size(void* handle, int history_size); + +// Returns the history_size currently used. +// Input: +// - handle : Pointer to the delay estimation instance. +int WebRtc_history_size(const void* handle); + // 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. +// - handle : Pointer to the delay estimation instance. +// - lookahead : The amount of lookahead to be used. // // Return value: -// - new_lookahead : The actual number of shifts performed. -// +// - new_lookahead : The actual amount of lookahead set, unless |handle| is +// a NULL pointer or |lookahead| is invalid, for which an +// error is returned. int WebRtc_set_lookahead(void* handle, int lookahead); // Returns the amount of lookahead we currently use. +// Input: +// - handle : Pointer to the delay estimation instance. int WebRtc_lookahead(void* handle); // Sets the |allowed_offset| used in the robust validation scheme. If the @@ -178,8 +174,6 @@ int WebRtc_set_allowed_offset(void* handle, int allowed_offset); // Returns the |allowed_offset| in number of partitions. int WebRtc_get_allowed_offset(const void* handle); -// TODO(bjornv): Implement this functionality. Currently, enabling it has no -// impact, hence this is an empty API. // Enables/Disables a robust validation functionality in the delay estimation. // This is by default set to disabled at create time. The state is preserved // over a reset. @@ -209,7 +203,6 @@ int WebRtc_is_robust_validation_enabled(const void* handle); // - delay : >= 0 - Calculated delay value. // -1 - Error. // -2 - Insufficient data for estimation. -// int WebRtc_DelayEstimatorProcessFix(void* handle, uint16_t* near_spectrum, int spectrum_size, @@ -230,7 +223,6 @@ int WebRtc_DelayEstimatorProcessFloat(void* handle, // - delay : >= 0 - Last calculated delay value. // -1 - Error. // -2 - Insufficient data for estimation. -// int WebRtc_last_delay(void* handle); // Returns the estimation quality/probability of the last calculated delay