Separated far-end handling in BinaryDelayEstimator.

This CL is one step in a larger change of the DelayEstimator where we will open up for multiple near-end signals.

This particular CL separates the low level far-end parts without affecting the usage externally. This is a first step towards separating the far-end and near-end parts giving the user the control.

BUG=None
TEST=audioproc_unittests, trybots

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@3415 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
bjornv@webrtc.org
2013-01-25 15:53:41 +00:00
parent 59d209562f
commit 94c213af1a
5 changed files with 222 additions and 100 deletions

View File

@ -59,6 +59,68 @@ static void BitCountComparison(uint32_t binary_vector,
}
}
void WebRtc_FreeBinaryDelayEstimatorFarend(BinaryDelayEstimatorFarend* self) {
if (self == NULL) {
return;
}
free(self->binary_far_history);
self->binary_far_history = NULL;
free(self->far_bit_counts);
self->far_bit_counts = NULL;
free(self);
}
BinaryDelayEstimatorFarend* WebRtc_CreateBinaryDelayEstimatorFarend(
int history_size) {
BinaryDelayEstimatorFarend* self = malloc(sizeof(BinaryDelayEstimatorFarend));
assert(history_size > 1);
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;
}
}
return self;
}
void WebRtc_InitBinaryDelayEstimatorFarend(BinaryDelayEstimatorFarend* self) {
assert(self != NULL);
memset(self->binary_far_history, 0, sizeof(uint32_t) * self->history_size);
memset(self->far_bit_counts, 0, sizeof(int) * self->history_size);
}
void WebRtc_AddBinaryFarSpectrum(BinaryDelayEstimatorFarend* handle,
uint32_t binary_far_spectrum) {
assert(handle != NULL);
// Shift binary spectrum history and insert current |binary_far_spectrum|.
memmove(&(handle->binary_far_history[1]), &(handle->binary_far_history[0]),
(handle->history_size - 1) * sizeof(uint32_t));
handle->binary_far_history[0] = binary_far_spectrum;
// Shift history of far-end binary spectrum bit counts and insert bit count
// of current |binary_far_spectrum|.
memmove(&(handle->far_bit_counts[1]), &(handle->far_bit_counts[0]),
(handle->history_size - 1) * sizeof(int));
handle->far_bit_counts[0] = BitCount(binary_far_spectrum);
}
void WebRtc_FreeBinaryDelayEstimator(BinaryDelayEstimator* handle) {
if (handle == NULL) {
@ -71,24 +133,21 @@ void WebRtc_FreeBinaryDelayEstimator(BinaryDelayEstimator* handle) {
free(handle->bit_counts);
handle->bit_counts = NULL;
free(handle->binary_far_history);
handle->binary_far_history = NULL;
free(handle->binary_near_history);
handle->binary_near_history = NULL;
free(handle->far_bit_counts);
handle->far_bit_counts = NULL;
// BinaryDelayEstimator does not have ownership of |farend|, hence we do not
// free the memory here. That should be handled separately by the user.
handle->farend = NULL;
free(handle);
}
BinaryDelayEstimator* WebRtc_CreateBinaryDelayEstimator(int max_delay,
int lookahead) {
BinaryDelayEstimator* WebRtc_CreateBinaryDelayEstimator(
BinaryDelayEstimatorFarend* farend, int lookahead) {
BinaryDelayEstimator* self = NULL;
int history_size = max_delay + lookahead; // Must be > 1 for buffer shifting.
if ((max_delay >= 0) && (lookahead >= 0) && (history_size > 1)) {
if ((farend != NULL) && (lookahead >= 0)) {
// Sanity conditions fulfilled.
self = malloc(sizeof(BinaryDelayEstimator));
}
@ -96,32 +155,20 @@ BinaryDelayEstimator* WebRtc_CreateBinaryDelayEstimator(int max_delay,
if (self != NULL) {
int malloc_fail = 0;
self->mean_bit_counts = NULL;
self->bit_counts = NULL;
self->binary_far_history = NULL;
self->far_bit_counts = NULL;
self->binary_near_history = NULL;
self->history_size = history_size;
self->farend = farend;
self->near_history_size = lookahead + 1;
// Allocate memory for spectrum buffers.
self->mean_bit_counts = malloc(history_size * sizeof(int32_t));
self->mean_bit_counts = malloc(farend->history_size * sizeof(int32_t));
malloc_fail |= (self->mean_bit_counts == NULL);
self->bit_counts = malloc(history_size * sizeof(int32_t));
self->bit_counts = malloc(farend->history_size * sizeof(int32_t));
malloc_fail |= (self->bit_counts == NULL);
// Allocate memory for history buffers.
self->binary_far_history = malloc(history_size * sizeof(uint32_t));
malloc_fail |= (self->binary_far_history == NULL);
self->binary_near_history = malloc((lookahead + 1) * sizeof(uint32_t));
malloc_fail |= (self->binary_near_history == NULL);
self->far_bit_counts = malloc(history_size * sizeof(int));
malloc_fail |= (self->far_bit_counts == NULL);
if (malloc_fail) {
WebRtc_FreeBinaryDelayEstimator(self);
self = NULL;
@ -135,13 +182,10 @@ void WebRtc_InitBinaryDelayEstimator(BinaryDelayEstimator* handle) {
int i = 0;
assert(handle != NULL);
memset(handle->bit_counts, 0, sizeof(int32_t) * handle->history_size);
memset(handle->binary_far_history, 0,
sizeof(uint32_t) * handle->history_size);
memset(handle->bit_counts, 0, sizeof(int32_t) * handle->farend->history_size);
memset(handle->binary_near_history, 0,
sizeof(uint32_t) * handle->near_history_size);
memset(handle->far_bit_counts, 0, sizeof(int) * handle->history_size);
for (i = 0; i < handle->history_size; ++i) {
for (i = 0; i < handle->farend->history_size; ++i) {
handle->mean_bit_counts[i] = (20 << 9); // 20 in Q9.
}
handle->minimum_probability = (32 << 9); // 32 in Q9.
@ -151,21 +195,6 @@ void WebRtc_InitBinaryDelayEstimator(BinaryDelayEstimator* handle) {
handle->last_delay = -2;
}
void WebRtc_AddBinaryFarSpectrum(BinaryDelayEstimator* handle,
uint32_t binary_far_spectrum) {
assert(handle != NULL);
// Shift binary spectrum history and insert current |binary_far_spectrum|.
memmove(&(handle->binary_far_history[1]), &(handle->binary_far_history[0]),
(handle->history_size - 1) * sizeof(uint32_t));
handle->binary_far_history[0] = binary_far_spectrum;
// Shift history of far-end binary spectrum bit counts and insert bit count
// of current |binary_far_spectrum|.
memmove(&(handle->far_bit_counts[1]), &(handle->far_bit_counts[0]),
(handle->history_size - 1) * sizeof(int));
handle->far_bit_counts[0] = BitCount(binary_far_spectrum);
}
int WebRtc_ProcessBinarySpectrum(BinaryDelayEstimator* handle,
uint32_t binary_near_spectrum) {
int i = 0;
@ -188,12 +217,12 @@ int WebRtc_ProcessBinarySpectrum(BinaryDelayEstimator* handle,
// Compare with delayed spectra and store the |bit_counts| for each delay.
BitCountComparison(binary_near_spectrum,
handle->binary_far_history,
handle->history_size,
handle->farend->binary_far_history,
handle->farend->history_size,
handle->bit_counts);
// Update |mean_bit_counts|, which is the smoothed version of |bit_counts|.
for (i = 0; i < handle->history_size; i++) {
for (i = 0; i < handle->farend->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 = (handle->bit_counts[i] << 9); // Q9.
@ -201,17 +230,17 @@ int WebRtc_ProcessBinarySpectrum(BinaryDelayEstimator* handle,
// Update |mean_bit_counts| only when far-end signal has something to
// contribute. If |far_bit_counts| is zero the far-end signal is weak and
// we likely have a poor echo condition, hence don't update.
if (handle->far_bit_counts[i] > 0) {
if (handle->farend->far_bit_counts[i] > 0) {
// Make number of right shifts piecewise linear w.r.t. |far_bit_counts|.
int shifts = kShiftsAtZero;
shifts -= (kShiftsLinearSlope * handle->far_bit_counts[i]) >> 4;
shifts -= (kShiftsLinearSlope * handle->farend->far_bit_counts[i]) >> 4;
WebRtc_MeanEstimatorFix(bit_count, shifts, &(handle->mean_bit_counts[i]));
}
}
// Find |candidate_delay|, |value_best_candidate| and |value_worst_candidate|
// of |mean_bit_counts|.
for (i = 0; i < handle->history_size; i++) {
for (i = 0; i < handle->farend->history_size; i++) {
if (handle->mean_bit_counts[i] < value_best_candidate) {
value_best_candidate = handle->mean_bit_counts[i];
candidate_delay = i;