Delay estimator structural changes.
Improved the way we handle different data types (float vs fixed) and reduced the complexity by nearly 50%. We now have a generic struct for both float and fixed delay estimators and a core struct for the binary spectrum based delay estimator. All wrapper codes (for both fixed and float) are gathered in delay_estimator_wrappers.*. Moved out the far end history buffer to AEC(M). Added a union to handle difference types when create. Review URL: http://webrtc-codereview.appspot.com/277004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@973 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
fa9b016fb5
commit
6a9835d59c
@ -19,7 +19,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "aec_rdft.h"
|
||||
#include "delay_estimator_float.h"
|
||||
#include "delay_estimator_wrapper.h"
|
||||
#include "ring_buffer.h"
|
||||
#include "system_wrappers/interface/cpu_features_wrapper.h"
|
||||
|
||||
@ -176,10 +176,9 @@ int WebRtcAec_CreateAec(aec_t **aecInst)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (WebRtc_CreateDelayEstimatorFloat(&aec->delay_estimator,
|
||||
PART_LEN1,
|
||||
kMaxDelay,
|
||||
0) == -1) {
|
||||
if (WebRtc_CreateDelayEstimator(&aec->delay_estimator,
|
||||
PART_LEN1,
|
||||
kMaxDelay) == -1) {
|
||||
WebRtcAec_FreeAec(aec);
|
||||
aec = NULL;
|
||||
return -1;
|
||||
@ -201,7 +200,7 @@ int WebRtcAec_FreeAec(aec_t *aec)
|
||||
WebRtcApm_FreeBuffer(aec->nearFrBufH);
|
||||
WebRtcApm_FreeBuffer(aec->outFrBufH);
|
||||
|
||||
WebRtc_FreeDelayEstimatorFloat(aec->delay_estimator);
|
||||
WebRtc_FreeDelayEstimator(aec->delay_estimator);
|
||||
|
||||
free(aec);
|
||||
return 0;
|
||||
@ -384,7 +383,7 @@ int WebRtcAec_InitAec(aec_t *aec, int sampFreq)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (WebRtc_InitDelayEstimatorFloat(aec->delay_estimator) != 0) {
|
||||
if (WebRtc_InitDelayEstimator(aec->delay_estimator) != 0) {
|
||||
return -1;
|
||||
}
|
||||
aec->delay_logging_enabled = 0;
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "echo_control_mobile.h"
|
||||
#include "delay_estimator.h"
|
||||
#include "delay_estimator_wrapper.h"
|
||||
#include "ring_buffer.h"
|
||||
#include "typedefs.h"
|
||||
|
||||
@ -112,6 +112,62 @@ static void ComfortNoise(AecmCore_t* aecm,
|
||||
|
||||
static WebRtc_Word16 CalcSuppressionGain(AecmCore_t * const aecm);
|
||||
|
||||
// Moves the pointer to the next entry and inserts |far_spectrum| and
|
||||
// corresponding Q-domain in its buffer.
|
||||
//
|
||||
// Inputs:
|
||||
// - self : Pointer to the delay estimation instance
|
||||
// - far_spectrum : Pointer to the far end spectrum
|
||||
// - far_q : Q-domain of far end spectrum
|
||||
//
|
||||
static void UpdateFarHistory(AecmCore_t* self,
|
||||
uint16_t* far_spectrum,
|
||||
int far_q) {
|
||||
// Get new buffer position
|
||||
self->far_history_pos++;
|
||||
if (self->far_history_pos >= MAX_DELAY) {
|
||||
self->far_history_pos = 0;
|
||||
}
|
||||
// Update Q-domain buffer
|
||||
self->far_q_domains[self->far_history_pos] = far_q;
|
||||
// Update far end spectrum buffer
|
||||
memcpy(&(self->far_history[self->far_history_pos * PART_LEN1]),
|
||||
far_spectrum,
|
||||
sizeof(uint16_t) * PART_LEN1);
|
||||
}
|
||||
|
||||
// Returns a pointer to the far end spectrum aligned to current near end
|
||||
// spectrum. The function WebRtc_DelayEstimatorProcessFix(...) should have been
|
||||
// called before AlignedFarend(...). Otherwise, you get the pointer to the
|
||||
// previous frame. The memory is only valid until the next call of
|
||||
// WebRtc_DelayEstimatorProcessFix(...).
|
||||
//
|
||||
// Inputs:
|
||||
// - self : Pointer to the AECM instance.
|
||||
//
|
||||
// Output:
|
||||
// - far_q : The Q-domain of the aligned far end spectrum
|
||||
//
|
||||
// Return value:
|
||||
// - far_spectrum : Pointer to the aligned far end spectrum
|
||||
// NULL - Error
|
||||
//
|
||||
static const uint16_t* AlignedFarend(AecmCore_t* self, int* far_q) {
|
||||
int buffer_position = 0;
|
||||
assert(self != NULL);
|
||||
buffer_position = self->far_history_pos -
|
||||
WebRtc_last_delay(self->delay_estimator);
|
||||
|
||||
// Check buffer position
|
||||
if (buffer_position < 0) {
|
||||
buffer_position += MAX_DELAY;
|
||||
}
|
||||
// Get Q-domain
|
||||
*far_q = self->far_q_domains[buffer_position];
|
||||
// Return far end spectrum
|
||||
return &(self->far_history[buffer_position * PART_LEN1]);
|
||||
}
|
||||
|
||||
#ifdef ARM_WINM_LOG
|
||||
HANDLE logFile = NULL;
|
||||
#endif
|
||||
@ -155,8 +211,7 @@ int WebRtcAecm_CreateCore(AecmCore_t **aecmInst)
|
||||
|
||||
if (WebRtc_CreateDelayEstimator(&aecm->delay_estimator,
|
||||
PART_LEN1,
|
||||
MAX_DELAY,
|
||||
1) == -1) {
|
||||
MAX_DELAY) == -1) {
|
||||
WebRtcAecm_FreeCore(aecm);
|
||||
aecm = NULL;
|
||||
return -1;
|
||||
@ -247,6 +302,10 @@ int WebRtcAecm_InitCore(AecmCore_t * const aecm, int samplingFreq)
|
||||
if (WebRtc_InitDelayEstimator(aecm->delay_estimator) != 0) {
|
||||
return -1;
|
||||
}
|
||||
// Set far end histories to zero
|
||||
memset(aecm->far_history, 0, sizeof(uint16_t) * PART_LEN1 * MAX_DELAY);
|
||||
memset(aecm->far_q_domains, 0, sizeof(int) * MAX_DELAY);
|
||||
aecm->far_history_pos = MAX_DELAY;
|
||||
|
||||
// Initialize to reasonable values
|
||||
aecm->currentDelay = 8;
|
||||
@ -1245,12 +1304,13 @@ int WebRtcAecm_ProcessBlock(AecmCore_t * aecm,
|
||||
|
||||
// Get the delay
|
||||
// Save far-end history and estimate delay
|
||||
delay = WebRtc_DelayEstimatorProcess(aecm->delay_estimator,
|
||||
xfa,
|
||||
dfaNoisy,
|
||||
PART_LEN1,
|
||||
far_q,
|
||||
aecm->currentVADValue);
|
||||
UpdateFarHistory(aecm, xfa, far_q);
|
||||
delay = WebRtc_DelayEstimatorProcessFix(aecm->delay_estimator,
|
||||
xfa,
|
||||
dfaNoisy,
|
||||
PART_LEN1,
|
||||
far_q,
|
||||
aecm->currentVADValue);
|
||||
if (delay < 0)
|
||||
{
|
||||
return -1;
|
||||
@ -1258,6 +1318,8 @@ int WebRtcAecm_ProcessBlock(AecmCore_t * aecm,
|
||||
|
||||
if (aecm->fixedDelay >= 0)
|
||||
{
|
||||
// TODO(bjornv): Make this work in practice, that is, get proper
|
||||
// aligned farend.
|
||||
// Use fixed delay
|
||||
delay = aecm->fixedDelay;
|
||||
}
|
||||
@ -1274,9 +1336,7 @@ int WebRtcAecm_ProcessBlock(AecmCore_t * aecm,
|
||||
QueryPerformanceCounter((LARGE_INTEGER*)&start);
|
||||
#endif
|
||||
// Get aligned far end spectrum
|
||||
far_spectrum_ptr = WebRtc_AlignedFarend(aecm->delay_estimator,
|
||||
PART_LEN1,
|
||||
&far_q);
|
||||
far_spectrum_ptr = AlignedFarend(aecm, &far_q);
|
||||
zerosXBuf = (WebRtc_Word16) far_q;
|
||||
if (far_spectrum_ptr == NULL)
|
||||
{
|
||||
|
@ -125,6 +125,11 @@ typedef struct
|
||||
// Delay estimation variables
|
||||
void* delay_estimator;
|
||||
WebRtc_UWord16 currentDelay;
|
||||
// Far end history variables
|
||||
// TODO(bjornv): Replace |far_history| with ring_buffer.
|
||||
uint16_t far_history[PART_LEN1 * MAX_DELAY];
|
||||
int far_history_pos;
|
||||
int far_q_domains[MAX_DELAY];
|
||||
|
||||
WebRtc_Word16 nlpFlag;
|
||||
WebRtc_Word16 fixedDelay;
|
||||
|
@ -16,55 +16,6 @@
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
typedef struct {
|
||||
// Pointers to mean values of spectrum and bit counts
|
||||
int32_t* mean_far_spectrum;
|
||||
int32_t* mean_near_spectrum;
|
||||
int32_t* mean_bit_counts;
|
||||
|
||||
// Arrays only used locally in DelayEstimatorProcess() but whose size
|
||||
// is determined at run-time.
|
||||
int32_t* bit_counts;
|
||||
int32_t* far_spectrum_32;
|
||||
int32_t* near_spectrum_32;
|
||||
|
||||
// Binary history variables
|
||||
uint32_t* binary_far_history;
|
||||
|
||||
// Far end history variables
|
||||
uint16_t* far_history;
|
||||
int far_history_pos;
|
||||
int* far_q_domains;
|
||||
|
||||
// Delay histogram variables
|
||||
int* delay_histogram;
|
||||
int vad_counter;
|
||||
|
||||
// Delay memory
|
||||
int last_delay;
|
||||
|
||||
// Used to enable far end alignment. If it is disabled, only delay values are
|
||||
// produced
|
||||
int alignment_enabled;
|
||||
|
||||
// Buffer size parameters
|
||||
int history_size;
|
||||
int spectrum_size;
|
||||
|
||||
} DelayEstimator_t;
|
||||
|
||||
// Only bit |kBandFirst| through bit |kBandLast| are processed
|
||||
// |kBandFirst| - |kBandLast| must be < 32
|
||||
static const int kBandFirst = 12;
|
||||
static const int kBandLast = 43;
|
||||
|
||||
static __inline uint32_t SetBit(uint32_t in, int32_t pos) {
|
||||
uint32_t mask = WEBRTC_SPL_LSHIFT_W32(1, pos);
|
||||
uint32_t out = (in | mask);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// Compares the |binary_vector| with all rows of the |binary_matrix| and counts
|
||||
// per row the number of times they have the same value.
|
||||
//
|
||||
@ -99,42 +50,193 @@ static void BitCountComparison(uint32_t binary_vector,
|
||||
}
|
||||
}
|
||||
|
||||
// Computes the binary spectrum by comparing the input |spectrum| with a
|
||||
// |threshold_spectrum|.
|
||||
//
|
||||
// Inputs:
|
||||
// - spectrum : Spectrum of which the binary spectrum should be
|
||||
// calculated.
|
||||
// - threshold_spectrum : Threshold spectrum with which the input
|
||||
// spectrum is compared.
|
||||
// Return:
|
||||
// - out : Binary spectrum
|
||||
//
|
||||
static uint32_t BinarySpectrum(int32_t* spectrum, int32_t* threshold_spectrum) {
|
||||
int k = kBandFirst;
|
||||
uint32_t out = 0;
|
||||
int WebRtc_FreeBinaryDelayEstimator(BinaryDelayEstimator_t* handle) {
|
||||
assert(handle != NULL);
|
||||
|
||||
for (; k <= kBandLast; k++) {
|
||||
if (spectrum[k] > threshold_spectrum[k]) {
|
||||
out = SetBit(out, k - kBandFirst);
|
||||
}
|
||||
if (handle->mean_bit_counts != NULL) {
|
||||
free(handle->mean_bit_counts);
|
||||
handle->mean_bit_counts = NULL;
|
||||
}
|
||||
if (handle->bit_counts != NULL) {
|
||||
free(handle->bit_counts);
|
||||
handle->bit_counts = NULL;
|
||||
}
|
||||
if (handle->binary_far_history != NULL) {
|
||||
free(handle->binary_far_history);
|
||||
handle->binary_far_history = NULL;
|
||||
}
|
||||
if (handle->delay_histogram != NULL) {
|
||||
free(handle->delay_histogram);
|
||||
handle->delay_histogram = NULL;
|
||||
}
|
||||
|
||||
return out;
|
||||
free(handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Calculates the mean recursively.
|
||||
//
|
||||
// Inputs:
|
||||
// - new_value : new additional value
|
||||
// - factor : factor for smoothing
|
||||
//
|
||||
// Input/Output:
|
||||
// - mean_value : pointer to the mean value that should be updated
|
||||
//
|
||||
static void MeanEstimator(const int32_t new_value,
|
||||
int factor,
|
||||
int32_t* mean_value) {
|
||||
int WebRtc_CreateBinaryDelayEstimator(BinaryDelayEstimator_t** handle,
|
||||
int history_size) {
|
||||
BinaryDelayEstimator_t* self = NULL;
|
||||
|
||||
if (handle == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (history_size < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
self = malloc(sizeof(BinaryDelayEstimator_t));
|
||||
*handle = self;
|
||||
if (self == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
self->mean_bit_counts = NULL;
|
||||
self->bit_counts = NULL;
|
||||
self->binary_far_history = NULL;
|
||||
self->delay_histogram = NULL;
|
||||
|
||||
// Allocate memory for spectrum buffers
|
||||
self->mean_bit_counts = malloc(history_size * sizeof(int32_t));
|
||||
if (self->mean_bit_counts == NULL) {
|
||||
WebRtc_FreeBinaryDelayEstimator(self);
|
||||
self = NULL;
|
||||
return -1;
|
||||
}
|
||||
self->bit_counts = malloc(history_size * sizeof(int32_t));
|
||||
if (self->bit_counts == NULL) {
|
||||
WebRtc_FreeBinaryDelayEstimator(self);
|
||||
self = NULL;
|
||||
return -1;
|
||||
}
|
||||
// Allocate memory for history buffers
|
||||
self->binary_far_history = malloc(history_size * sizeof(uint32_t));
|
||||
if (self->binary_far_history == NULL) {
|
||||
WebRtc_FreeBinaryDelayEstimator(self);
|
||||
self = NULL;
|
||||
return -1;
|
||||
}
|
||||
self->delay_histogram = malloc(history_size * sizeof(int));
|
||||
if (self->delay_histogram == NULL) {
|
||||
WebRtc_FreeBinaryDelayEstimator(self);
|
||||
self = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
self->history_size = history_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WebRtc_InitBinaryDelayEstimator(BinaryDelayEstimator_t* handle) {
|
||||
assert(handle != NULL);
|
||||
// Set averaged bit counts to zero
|
||||
memset(handle->mean_bit_counts, 0, sizeof(int32_t) * handle->history_size);
|
||||
memset(handle->bit_counts, 0, sizeof(int32_t) * handle->history_size);
|
||||
// Set far end histories to zero
|
||||
memset(handle->binary_far_history,
|
||||
0,
|
||||
sizeof(uint32_t) * handle->history_size);
|
||||
// Set delay histogram to zero
|
||||
memset(handle->delay_histogram, 0, sizeof(int) * handle->history_size);
|
||||
// Set VAD counter to zero
|
||||
handle->vad_counter = 0;
|
||||
// Set delay memory to zero
|
||||
handle->last_delay = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WebRtc_ProcessBinarySpectrum(BinaryDelayEstimator_t* handle,
|
||||
uint32_t binary_far_spectrum,
|
||||
uint32_t binary_near_spectrum,
|
||||
int vad_value) {
|
||||
const int kVadCountThreshold = 25;
|
||||
const int kMaxHistogram = 600;
|
||||
|
||||
int histogram_bin = 0;
|
||||
int i = 0;
|
||||
int max_histogram_level = 0;
|
||||
int min_position = -1;
|
||||
|
||||
int32_t bit_counts_tmp = 0;
|
||||
|
||||
assert(handle != NULL);
|
||||
// Shift binary spectrum history
|
||||
memmove(&(handle->binary_far_history[1]), &(handle->binary_far_history[0]),
|
||||
(handle->history_size - 1) * sizeof(uint32_t));
|
||||
// Insert new binary spectrum
|
||||
handle->binary_far_history[0] = binary_far_spectrum;
|
||||
|
||||
// Compare with delayed spectra
|
||||
BitCountComparison(binary_near_spectrum,
|
||||
handle->binary_far_history,
|
||||
handle->history_size,
|
||||
handle->bit_counts);
|
||||
|
||||
// Smooth bit count curve
|
||||
for (i = 0; i < handle->history_size; i++) {
|
||||
// Update sum
|
||||
// |bit_counts| is constrained to [0, 32], meaning we can smooth with a
|
||||
// factor up to 2^26. We use Q9.
|
||||
bit_counts_tmp = WEBRTC_SPL_LSHIFT_W32(handle->bit_counts[i], 9); // Q9
|
||||
WebRtc_MeanEstimatorFix(bit_counts_tmp, 9, &(handle->mean_bit_counts[i]));
|
||||
}
|
||||
|
||||
// Find minimum position of bit count curve
|
||||
min_position = (int) WebRtcSpl_MinIndexW32(handle->mean_bit_counts,
|
||||
(int16_t) handle->history_size);
|
||||
|
||||
// If the far end has been active sufficiently long, begin accumulating a
|
||||
// histogram of the minimum positions. Search for the maximum bin to
|
||||
// determine the delay.
|
||||
if (vad_value == 1) {
|
||||
if (handle->vad_counter >= kVadCountThreshold) {
|
||||
// Increment the histogram at the current minimum position.
|
||||
if (handle->delay_histogram[min_position] < kMaxHistogram) {
|
||||
handle->delay_histogram[min_position] += 3;
|
||||
}
|
||||
|
||||
handle->last_delay = 0;
|
||||
for (i = 0; i < handle->history_size; i++) {
|
||||
histogram_bin = handle->delay_histogram[i];
|
||||
|
||||
// Decrement the histogram bin.
|
||||
if (histogram_bin > 0) {
|
||||
histogram_bin--;
|
||||
handle->delay_histogram[i] = histogram_bin;
|
||||
// Select the histogram index corresponding to the maximum bin as the
|
||||
// delay.
|
||||
if (histogram_bin > max_histogram_level) {
|
||||
max_histogram_level = histogram_bin;
|
||||
handle->last_delay = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
handle->vad_counter++;
|
||||
}
|
||||
} else {
|
||||
handle->vad_counter = 0;
|
||||
}
|
||||
|
||||
return handle->last_delay;
|
||||
}
|
||||
|
||||
int WebRtc_binary_last_delay(BinaryDelayEstimator_t* handle) {
|
||||
assert(handle != NULL);
|
||||
return handle->last_delay;
|
||||
}
|
||||
|
||||
int WebRtc_history_size(BinaryDelayEstimator_t* handle) {
|
||||
assert(handle != NULL);
|
||||
return handle->history_size;
|
||||
}
|
||||
|
||||
void WebRtc_MeanEstimatorFix(int32_t new_value,
|
||||
int factor,
|
||||
int32_t* mean_value) {
|
||||
int32_t mean_new = *mean_value;
|
||||
int32_t diff = new_value - mean_new;
|
||||
|
||||
@ -148,403 +250,3 @@ static void MeanEstimator(const int32_t new_value,
|
||||
|
||||
*mean_value = mean_new;
|
||||
}
|
||||
|
||||
// Moves the pointer to the next entry and inserts |far_spectrum| and
|
||||
// corresponding Q-domain in its buffer.
|
||||
//
|
||||
// Inputs:
|
||||
// - self : Pointer to the delay estimation instance
|
||||
// - far_spectrum : Pointer to the far end spectrum
|
||||
// - far_q : Q-domain of far end spectrum
|
||||
//
|
||||
static void UpdateFarHistory(DelayEstimator_t* self,
|
||||
uint16_t* far_spectrum,
|
||||
int far_q) {
|
||||
// Get new buffer position
|
||||
self->far_history_pos++;
|
||||
if (self->far_history_pos >= self->history_size) {
|
||||
self->far_history_pos = 0;
|
||||
}
|
||||
// Update Q-domain buffer
|
||||
self->far_q_domains[self->far_history_pos] = far_q;
|
||||
// Update far end spectrum buffer
|
||||
memcpy(&(self->far_history[self->far_history_pos * self->spectrum_size]),
|
||||
far_spectrum,
|
||||
sizeof(uint16_t) * self->spectrum_size);
|
||||
}
|
||||
|
||||
int WebRtc_FreeDelayEstimator(void* handle) {
|
||||
DelayEstimator_t* self = (DelayEstimator_t*) handle;
|
||||
|
||||
if (self == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (self->mean_far_spectrum != NULL) {
|
||||
free(self->mean_far_spectrum);
|
||||
self->mean_far_spectrum = NULL;
|
||||
}
|
||||
if (self->mean_near_spectrum != NULL) {
|
||||
free(self->mean_near_spectrum);
|
||||
self->mean_near_spectrum = NULL;
|
||||
}
|
||||
if (self->mean_bit_counts != NULL) {
|
||||
free(self->mean_bit_counts);
|
||||
self->mean_bit_counts = NULL;
|
||||
}
|
||||
if (self->bit_counts != NULL) {
|
||||
free(self->bit_counts);
|
||||
self->bit_counts = NULL;
|
||||
}
|
||||
if (self->far_spectrum_32 != NULL) {
|
||||
free(self->far_spectrum_32);
|
||||
self->far_spectrum_32 = NULL;
|
||||
}
|
||||
if (self->near_spectrum_32 != NULL) {
|
||||
free(self->near_spectrum_32);
|
||||
self->near_spectrum_32 = NULL;
|
||||
}
|
||||
if (self->binary_far_history != NULL) {
|
||||
free(self->binary_far_history);
|
||||
self->binary_far_history = NULL;
|
||||
}
|
||||
if (self->far_history != NULL) {
|
||||
free(self->far_history);
|
||||
self->far_history = NULL;
|
||||
}
|
||||
if (self->far_q_domains != NULL) {
|
||||
free(self->far_q_domains);
|
||||
self->far_q_domains = NULL;
|
||||
}
|
||||
if (self->delay_histogram != NULL) {
|
||||
free(self->delay_histogram);
|
||||
self->delay_histogram = NULL;
|
||||
}
|
||||
|
||||
free(self);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WebRtc_CreateDelayEstimator(void** handle,
|
||||
int spectrum_size,
|
||||
int history_size,
|
||||
int enable_alignment) {
|
||||
DelayEstimator_t *self = NULL;
|
||||
|
||||
// Check if the sub band used in the delay estimation is small enough to
|
||||
// fit the binary spectra in a uint32.
|
||||
assert(kBandLast - kBandFirst < 32);
|
||||
|
||||
if (spectrum_size < kBandLast) {
|
||||
return -1;
|
||||
}
|
||||
if (history_size < 0) {
|
||||
return -1;
|
||||
}
|
||||
if ((enable_alignment != 0) && (enable_alignment != 1)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
self = malloc(sizeof(DelayEstimator_t));
|
||||
*handle = self;
|
||||
if (self == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
self->mean_far_spectrum = NULL;
|
||||
self->mean_near_spectrum = NULL;
|
||||
self->mean_bit_counts = NULL;
|
||||
self->bit_counts = NULL;
|
||||
self->far_spectrum_32 = NULL;
|
||||
self->near_spectrum_32 = NULL;
|
||||
self->binary_far_history = NULL;
|
||||
self->far_history = NULL;
|
||||
self->far_q_domains = NULL;
|
||||
self->delay_histogram = NULL;
|
||||
|
||||
// Allocate memory for spectrum buffers
|
||||
self->mean_far_spectrum = malloc(spectrum_size * sizeof(int32_t));
|
||||
if (self->mean_far_spectrum == NULL) {
|
||||
WebRtc_FreeDelayEstimator(self);
|
||||
self = NULL;
|
||||
return -1;
|
||||
}
|
||||
self->mean_near_spectrum = malloc(spectrum_size * sizeof(int32_t));
|
||||
if (self->mean_near_spectrum == NULL) {
|
||||
WebRtc_FreeDelayEstimator(self);
|
||||
self = NULL;
|
||||
return -1;
|
||||
}
|
||||
self->mean_bit_counts = malloc(history_size * sizeof(int32_t));
|
||||
if (self->mean_bit_counts == NULL) {
|
||||
WebRtc_FreeDelayEstimator(self);
|
||||
self = NULL;
|
||||
return -1;
|
||||
}
|
||||
self->bit_counts = malloc(history_size * sizeof(int32_t));
|
||||
if (self->bit_counts == NULL) {
|
||||
WebRtc_FreeDelayEstimator(self);
|
||||
self = NULL;
|
||||
return -1;
|
||||
}
|
||||
self->far_spectrum_32 = malloc(spectrum_size * sizeof(int32_t));
|
||||
if (self->far_spectrum_32 == NULL) {
|
||||
WebRtc_FreeDelayEstimator(self);
|
||||
self = NULL;
|
||||
return -1;
|
||||
}
|
||||
self->near_spectrum_32 = malloc(spectrum_size * sizeof(int32_t));
|
||||
if (self->near_spectrum_32 == NULL) {
|
||||
WebRtc_FreeDelayEstimator(self);
|
||||
self = NULL;
|
||||
return -1;
|
||||
}
|
||||
// Allocate memory for history buffers
|
||||
self->binary_far_history = malloc(history_size * sizeof(uint32_t));
|
||||
if (self->binary_far_history == NULL) {
|
||||
WebRtc_FreeDelayEstimator(self);
|
||||
self = NULL;
|
||||
return -1;
|
||||
}
|
||||
if (enable_alignment) {
|
||||
self->far_history = malloc(spectrum_size * history_size * sizeof(uint16_t));
|
||||
if (self->far_history == NULL) {
|
||||
WebRtc_FreeDelayEstimator(self);
|
||||
self = NULL;
|
||||
return -1;
|
||||
}
|
||||
self->far_q_domains = malloc(history_size * sizeof(int));
|
||||
if (self->far_q_domains == NULL) {
|
||||
WebRtc_FreeDelayEstimator(self);
|
||||
self = NULL;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
self->delay_histogram = malloc(history_size * sizeof(int));
|
||||
if (self->delay_histogram == NULL) {
|
||||
WebRtc_FreeDelayEstimator(self);
|
||||
self = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
self->spectrum_size = spectrum_size;
|
||||
self->history_size = history_size;
|
||||
self->alignment_enabled = enable_alignment;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WebRtc_InitDelayEstimator(void* handle) {
|
||||
DelayEstimator_t* self = (DelayEstimator_t*) handle;
|
||||
|
||||
if (self == NULL) {
|
||||
return -1;
|
||||
}
|
||||
// Set averaged far and near end spectra to zero
|
||||
memset(self->mean_far_spectrum, 0, sizeof(int32_t) * self->spectrum_size);
|
||||
memset(self->mean_near_spectrum, 0, sizeof(int32_t) * self->spectrum_size);
|
||||
// Set averaged bit counts to zero
|
||||
memset(self->mean_bit_counts, 0, sizeof(int32_t) * self->history_size);
|
||||
memset(self->bit_counts, 0, sizeof(int32_t) * self->history_size);
|
||||
memset(self->far_spectrum_32, 0, sizeof(int32_t) * self->spectrum_size);
|
||||
memset(self->near_spectrum_32, 0, sizeof(int32_t) * self->spectrum_size);
|
||||
// Set far end histories to zero
|
||||
memset(self->binary_far_history, 0, sizeof(uint32_t) * self->history_size);
|
||||
if (self->alignment_enabled) {
|
||||
memset(self->far_history,
|
||||
0,
|
||||
sizeof(uint16_t) * self->spectrum_size * self->history_size);
|
||||
memset(self->far_q_domains, 0, sizeof(int) * self->history_size);
|
||||
self->far_history_pos = self->history_size;
|
||||
}
|
||||
// Set delay histogram to zero
|
||||
memset(self->delay_histogram, 0, sizeof(int) * self->history_size);
|
||||
// Set VAD counter to zero
|
||||
self->vad_counter = 0;
|
||||
// Set delay memory to zero
|
||||
self->last_delay = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WebRtc_DelayEstimatorProcess(void* handle,
|
||||
uint16_t* far_spectrum,
|
||||
uint16_t* near_spectrum,
|
||||
int spectrum_size,
|
||||
int far_q,
|
||||
int vad_value) {
|
||||
DelayEstimator_t* self = (DelayEstimator_t*) handle;
|
||||
|
||||
const int kVadCountThreshold = 25;
|
||||
const int kMaxHistogram = 600;
|
||||
|
||||
int histogram_bin = 0;
|
||||
int i = 0;
|
||||
int max_histogram_level = 0;
|
||||
int min_position = -1;
|
||||
|
||||
uint32_t binary_far_spectrum = 0;
|
||||
uint32_t binary_near_spectrum = 0;
|
||||
|
||||
int32_t bit_counts_tmp = 0;
|
||||
|
||||
if (self == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (spectrum_size != self->spectrum_size) {
|
||||
// Data sizes don't match
|
||||
return -1;
|
||||
}
|
||||
if (far_q > 15) {
|
||||
// If |far_q| is larger than 15 we cannot guarantee no wrap around
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (self->alignment_enabled) {
|
||||
// Update far end history
|
||||
UpdateFarHistory(self, far_spectrum, far_q);
|
||||
} // Update the far and near end means
|
||||
for (i = 0; i < self->spectrum_size; i++) {
|
||||
self->far_spectrum_32[i] = (int32_t) far_spectrum[i];
|
||||
MeanEstimator(self->far_spectrum_32[i], 6, &(self->mean_far_spectrum[i]));
|
||||
|
||||
self->near_spectrum_32[i] = (int32_t) near_spectrum[i];
|
||||
MeanEstimator(self->near_spectrum_32[i], 6, &(self->mean_near_spectrum[i]));
|
||||
}
|
||||
|
||||
// Shift binary spectrum history
|
||||
memmove(&(self->binary_far_history[1]), &(self->binary_far_history[0]),
|
||||
(self->history_size - 1) * sizeof(uint32_t));
|
||||
|
||||
// Get binary spectra
|
||||
binary_far_spectrum = BinarySpectrum(self->far_spectrum_32,
|
||||
self->mean_far_spectrum);
|
||||
binary_near_spectrum = BinarySpectrum(self->near_spectrum_32,
|
||||
self->mean_near_spectrum);
|
||||
// Insert new binary spectrum
|
||||
self->binary_far_history[0] = binary_far_spectrum;
|
||||
|
||||
// Compare with delayed spectra
|
||||
BitCountComparison(binary_near_spectrum,
|
||||
self->binary_far_history,
|
||||
self->history_size,
|
||||
self->bit_counts);
|
||||
|
||||
// Smooth bit count curve
|
||||
for (i = 0; i < self->history_size; i++) {
|
||||
// Update sum
|
||||
// |bit_counts| is constrained to [0, 32], meaning we can smooth with a
|
||||
// factor up to 2^26. We use Q9.
|
||||
bit_counts_tmp = WEBRTC_SPL_LSHIFT_W32(self->bit_counts[i], 9); // Q9
|
||||
MeanEstimator(bit_counts_tmp, 9, &(self->mean_bit_counts[i]));
|
||||
}
|
||||
|
||||
// Find minimum position of bit count curve
|
||||
min_position = (int) WebRtcSpl_MinIndexW32(self->mean_bit_counts,
|
||||
(int16_t) self->history_size);
|
||||
|
||||
// If the far end has been active sufficiently long, begin accumulating a
|
||||
// histogram of the minimum positions. Search for the maximum bin to
|
||||
// determine the delay.
|
||||
if (vad_value == 1) {
|
||||
if (self->vad_counter >= kVadCountThreshold) {
|
||||
// Increment the histogram at the current minimum position.
|
||||
if (self->delay_histogram[min_position] < kMaxHistogram) {
|
||||
self->delay_histogram[min_position] += 3;
|
||||
}
|
||||
|
||||
self->last_delay = 0;
|
||||
for (i = 0; i < self->history_size; i++) {
|
||||
histogram_bin = self->delay_histogram[i];
|
||||
|
||||
// Decrement the histogram bin.
|
||||
if (histogram_bin > 0) {
|
||||
histogram_bin--;
|
||||
self->delay_histogram[i] = histogram_bin;
|
||||
// Select the histogram index corresponding to the maximum bin as the
|
||||
// delay.
|
||||
if (histogram_bin > max_histogram_level) {
|
||||
max_histogram_level = histogram_bin;
|
||||
self->last_delay = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self->vad_counter++;
|
||||
}
|
||||
} else {
|
||||
self->vad_counter = 0;
|
||||
}
|
||||
|
||||
return self->last_delay;
|
||||
}
|
||||
|
||||
const uint16_t* WebRtc_AlignedFarend(void* handle,
|
||||
int far_spectrum_size,
|
||||
int* far_q) {
|
||||
DelayEstimator_t* self = (DelayEstimator_t*) handle;
|
||||
int buffer_position = 0;
|
||||
|
||||
if (self == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (far_spectrum_size != self->spectrum_size) {
|
||||
return NULL;
|
||||
}
|
||||
if (self->alignment_enabled == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get buffer position
|
||||
buffer_position = self->far_history_pos - self->last_delay;
|
||||
if (buffer_position < 0) {
|
||||
buffer_position += self->history_size;
|
||||
}
|
||||
// Get Q-domain
|
||||
*far_q = self->far_q_domains[buffer_position];
|
||||
// Return far end spectrum
|
||||
return (self->far_history + (buffer_position * far_spectrum_size));
|
||||
|
||||
}
|
||||
|
||||
int WebRtc_last_delay(void* handle) {
|
||||
DelayEstimator_t* self = (DelayEstimator_t*) handle;
|
||||
|
||||
if (self == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return self->last_delay;
|
||||
}
|
||||
|
||||
int WebRtc_history_size(void* handle) {
|
||||
DelayEstimator_t* self = (DelayEstimator_t*) handle;
|
||||
|
||||
if (self == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return self->history_size;
|
||||
}
|
||||
|
||||
int WebRtc_spectrum_size(void* handle) {
|
||||
DelayEstimator_t* self = (DelayEstimator_t*) handle;
|
||||
|
||||
if (self == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return self->spectrum_size;
|
||||
}
|
||||
|
||||
int WebRtc_is_alignment_enabled(void* handle) {
|
||||
DelayEstimator_t* self = (DelayEstimator_t*) handle;
|
||||
|
||||
if (self == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return self->alignment_enabled;
|
||||
}
|
||||
|
@ -8,147 +8,126 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
// Performs delay estimation on a block by block basis
|
||||
// Performs delay estimation on binary converted spectra.
|
||||
// The return value is 0 - OK and -1 - Error, unless otherwise stated.
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_DELAY_ESTIMATOR_H_
|
||||
#define WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_DELAY_ESTIMATOR_H_
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
#include "typedefs.h"
|
||||
|
||||
// Releases the memory allocated by WebRtc_CreateDelayEstimator(...)
|
||||
// Input:
|
||||
// - handle : Pointer to the delay estimation instance
|
||||
//
|
||||
int WebRtc_FreeDelayEstimator(void* handle);
|
||||
typedef struct {
|
||||
// Pointer to bit counts
|
||||
int32_t* mean_bit_counts;
|
||||
|
||||
// Allocates the memory needed by the delay estimation. The memory needs to be
|
||||
// initialized separately using the WebRtc_InitDelayEstimator(...)
|
||||
// function.
|
||||
// Array only used locally in ProcessBinarySpectrum() but whose size is
|
||||
// determined at run-time.
|
||||
int32_t* bit_counts;
|
||||
|
||||
// Binary history variables
|
||||
uint32_t* binary_far_history;
|
||||
|
||||
// Delay histogram variables
|
||||
int* delay_histogram;
|
||||
int vad_counter;
|
||||
|
||||
// Delay memory
|
||||
int last_delay;
|
||||
|
||||
// Buffer size parameters
|
||||
int history_size;
|
||||
} BinaryDelayEstimator_t;
|
||||
|
||||
// Releases the memory allocated by WebRtc_CreateBinaryDelayEstimator(...)
|
||||
// Input:
|
||||
// - handle : Pointer to the delay estimation instance
|
||||
//
|
||||
int WebRtc_FreeBinaryDelayEstimator(BinaryDelayEstimator_t* handle);
|
||||
|
||||
// Allocates the memory needed by the binary delay estimation. The memory needs
|
||||
// to be initialized separately using WebRtc_InitBinaryDelayEstimator(...).
|
||||
//
|
||||
// Inputs:
|
||||
// - handle : Instance that should be created
|
||||
// - spectrum_size : Size of the spectrum used both in far end and
|
||||
// near end. Used to allocate memory for spectrum
|
||||
// specific buffers.
|
||||
// - history_size : Size of the far end history used to estimate the
|
||||
// delay from. Used to allocate memory for history
|
||||
// specific buffers.
|
||||
// - enable_alignment : With this mode set to 1, a far end history is
|
||||
// created, so that the user can retrieve aligned
|
||||
// far end spectra using
|
||||
// WebRtc_AlignedFarend(...). Otherwise, only delay
|
||||
// values are calculated.
|
||||
// - handle : Instance that should be created
|
||||
// - history_size : Size of the far end history used to estimate the
|
||||
// delay from. Used to allocate memory for history
|
||||
// specific buffers.
|
||||
//
|
||||
// Output:
|
||||
// - handle : Created instance
|
||||
// - handle : Created instance
|
||||
//
|
||||
int WebRtc_CreateDelayEstimator(void** handle,
|
||||
int spectrum_size,
|
||||
int history_size,
|
||||
int enable_alignment);
|
||||
int WebRtc_CreateBinaryDelayEstimator(BinaryDelayEstimator_t** handle,
|
||||
int history_size);
|
||||
|
||||
// Initializes the delay estimation instance created with
|
||||
// WebRtc_CreateDelayEstimator(...)
|
||||
// WebRtc_CreateBinaryDelayEstimator(...)
|
||||
// Input:
|
||||
// - handle : Pointer to the delay estimation instance
|
||||
// - handle : Pointer to the delay estimation instance
|
||||
//
|
||||
// Output:
|
||||
// - handle : Initialized instance
|
||||
// - handle : Initialized instance
|
||||
//
|
||||
int WebRtc_InitDelayEstimator(void* handle);
|
||||
int WebRtc_InitBinaryDelayEstimator(BinaryDelayEstimator_t* handle);
|
||||
|
||||
// Estimates and returns the delay between the far end and near end blocks.
|
||||
// Estimates and returns the delay between the binary far end and binary near
|
||||
// end spectra.
|
||||
// Inputs:
|
||||
// - handle : Pointer to the delay estimation instance
|
||||
// - far_spectrum : Pointer to the far end spectrum data
|
||||
// - near_spectrum : Pointer to the near end spectrum data of the current
|
||||
// block
|
||||
// - 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
|
||||
// - vad_value : The VAD decision of the current block
|
||||
// - handle : Pointer to the delay estimation instance
|
||||
// - binary_far_spectrum : Far end binary spectrum
|
||||
// - binary_near_spectrum : Near end binary spectrum of the current block
|
||||
// - vad_value : The VAD decision of the current block
|
||||
//
|
||||
// Output:
|
||||
// - handle : Updated instance
|
||||
// - handle : Updated instance
|
||||
//
|
||||
// Return value:
|
||||
// - delay : >= 0 - Calculated delay value
|
||||
// -1 - Error
|
||||
// - delay : >= 0 - Calculated delay value
|
||||
// -1 - Error
|
||||
//
|
||||
int WebRtc_DelayEstimatorProcess(void* handle,
|
||||
uint16_t* far_spectrum,
|
||||
uint16_t* near_spectrum,
|
||||
int spectrum_size,
|
||||
int far_q,
|
||||
int WebRtc_ProcessBinarySpectrum(BinaryDelayEstimator_t* handle,
|
||||
uint32_t binary_far_spectrum,
|
||||
uint32_t binary_near_spectrum,
|
||||
int vad_value);
|
||||
|
||||
// Returns a pointer to the far end spectrum aligned to current near end
|
||||
// spectrum. The function WebRtc_DelayEstimatorProcess(...) should have been
|
||||
// called before WebRtc_AlignedFarend(...). Otherwise, you get the pointer to
|
||||
// the previous frame. The memory is only valid until the next call of
|
||||
// WebRtc_DelayEstimatorProcess(...).
|
||||
//
|
||||
// Inputs:
|
||||
// - handle : Pointer to the delay estimation instance
|
||||
// - far_spectrum_size : Size of far_spectrum allocated by the caller
|
||||
//
|
||||
// Output:
|
||||
// - far_q : The Q-domain of the aligned far end spectrum
|
||||
//
|
||||
// Return value:
|
||||
// - far_spectrum : Pointer to the aligned far end spectrum
|
||||
// NULL - Error
|
||||
//
|
||||
const uint16_t* WebRtc_AlignedFarend(void* handle,
|
||||
int far_spectrum_size,
|
||||
int* far_q);
|
||||
|
||||
// Returns the last calculated delay updated by the function
|
||||
// WebRtc_DelayEstimatorProcess(...)
|
||||
// WebRtc_ProcessBinarySpectrum(...)
|
||||
//
|
||||
// Input:
|
||||
// - handle : Pointer to the delay estimation instance
|
||||
// - handle : Pointer to the delay estimation instance
|
||||
//
|
||||
// Return value:
|
||||
// - delay : >= 0 - Last calculated delay value
|
||||
// -1 - Error
|
||||
// - delay : >= 0 - Last calculated delay value
|
||||
// -1 - Error
|
||||
//
|
||||
int WebRtc_last_delay(void* handle);
|
||||
int WebRtc_binary_last_delay(BinaryDelayEstimator_t* handle);
|
||||
|
||||
// Returns the history size used in the far end buffers to calculate the delay
|
||||
// over.
|
||||
//
|
||||
// Input:
|
||||
// - handle : Pointer to the delay estimation instance
|
||||
// - handle : Pointer to the delay estimation instance
|
||||
//
|
||||
// Return value:
|
||||
// - history_size : > 0 - Far end history size
|
||||
// -1 - Error
|
||||
// - history_size : > 0 - Far end history size
|
||||
// -1 - Error
|
||||
//
|
||||
int WebRtc_history_size(void* handle);
|
||||
int WebRtc_history_size(BinaryDelayEstimator_t* handle);
|
||||
|
||||
// Returns the fixed spectrum size used in the algorithm.
|
||||
// Updates the |mean_value| recursively with a step size of 2^-|factor|. This
|
||||
// function is used internally in the Binary Delay Estimator as well as the
|
||||
// Fixed point wrapper.
|
||||
//
|
||||
// Input:
|
||||
// - handle : Pointer to the delay estimation instance
|
||||
// Inputs:
|
||||
// - new_value : The new value the mean should be updated with.
|
||||
// - factor : The step size, in number of right shifts.
|
||||
//
|
||||
// Return value:
|
||||
// - spectrum_size : > 0 - Spectrum size
|
||||
// -1 - Error
|
||||
// Input/Output:
|
||||
// - mean_value : Pointer to the mean value.
|
||||
//
|
||||
int WebRtc_spectrum_size(void* handle);
|
||||
void WebRtc_MeanEstimatorFix(int32_t new_value,
|
||||
int factor,
|
||||
int32_t* mean_value);
|
||||
|
||||
// Returns 1 if the far end alignment is enabled and 0 otherwise.
|
||||
//
|
||||
// Input:
|
||||
// - handle : Pointer to the delay estimation instance
|
||||
//
|
||||
// Return value:
|
||||
// - alignment_enabled : 1 - Enabled
|
||||
// 0 - Disabled
|
||||
// -1 - Error
|
||||
//
|
||||
int WebRtc_is_alignment_enabled(void* handle);
|
||||
|
||||
#endif // WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_DELAY_ESTIMATOR_H_
|
||||
|
@ -1,288 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "delay_estimator_float.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "delay_estimator.h"
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
typedef struct {
|
||||
// Fixed point spectra
|
||||
uint16_t* far_spectrum_u16;
|
||||
uint16_t* near_spectrum_u16;
|
||||
|
||||
// Far end history variables
|
||||
float* far_history;
|
||||
int far_history_pos;
|
||||
|
||||
// Fixed point delay estimator
|
||||
void* fixed_handle;
|
||||
|
||||
} DelayEstimatorFloat_t;
|
||||
|
||||
// Moves the pointer to the next buffer entry and inserts new far end spectrum.
|
||||
// Only used when alignment is enabled.
|
||||
//
|
||||
// Inputs:
|
||||
// - self : Pointer to the delay estimation instance
|
||||
// - far_spectrum : Pointer to the far end spectrum
|
||||
//
|
||||
static void UpdateFarHistory(DelayEstimatorFloat_t* self, float* far_spectrum) {
|
||||
int spectrum_size = WebRtc_spectrum_size(self->fixed_handle);
|
||||
// Get new buffer position
|
||||
self->far_history_pos++;
|
||||
if (self->far_history_pos >= WebRtc_history_size(self->fixed_handle)) {
|
||||
self->far_history_pos = 0;
|
||||
}
|
||||
// Update far end spectrum buffer
|
||||
memcpy(&(self->far_history[self->far_history_pos * spectrum_size]),
|
||||
far_spectrum,
|
||||
sizeof(float) * spectrum_size);
|
||||
}
|
||||
|
||||
int WebRtc_FreeDelayEstimatorFloat(void* handle) {
|
||||
DelayEstimatorFloat_t* self = (DelayEstimatorFloat_t*) handle;
|
||||
|
||||
if (self == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (self->far_history != NULL) {
|
||||
free(self->far_history);
|
||||
self->far_history = NULL;
|
||||
}
|
||||
if (self->far_spectrum_u16 != NULL) {
|
||||
free(self->far_spectrum_u16);
|
||||
self->far_spectrum_u16 = NULL;
|
||||
}
|
||||
if (self->near_spectrum_u16 != NULL) {
|
||||
free(self->near_spectrum_u16);
|
||||
self->near_spectrum_u16 = NULL;
|
||||
}
|
||||
|
||||
WebRtc_FreeDelayEstimator(self->fixed_handle);
|
||||
free(self);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WebRtc_CreateDelayEstimatorFloat(void** handle,
|
||||
int spectrum_size,
|
||||
int history_size,
|
||||
int enable_alignment) {
|
||||
DelayEstimatorFloat_t *self = NULL;
|
||||
if ((enable_alignment != 0) && (enable_alignment != 1)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
self = malloc(sizeof(DelayEstimatorFloat_t));
|
||||
*handle = self;
|
||||
if (self == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
self->far_history = NULL;
|
||||
self->far_spectrum_u16 = NULL;
|
||||
self->near_spectrum_u16 = NULL;
|
||||
|
||||
// Create fixed point core delay estimator
|
||||
if (WebRtc_CreateDelayEstimator(&self->fixed_handle,
|
||||
spectrum_size,
|
||||
history_size,
|
||||
enable_alignment) != 0) {
|
||||
WebRtc_FreeDelayEstimatorFloat(self);
|
||||
self = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Allocate memory for far history buffer
|
||||
if (enable_alignment) {
|
||||
self->far_history = malloc(spectrum_size * history_size * sizeof(float));
|
||||
if (self->far_history == NULL) {
|
||||
WebRtc_FreeDelayEstimatorFloat(self);
|
||||
self = NULL;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
// Allocate memory for fixed point spectra
|
||||
self->far_spectrum_u16 = malloc(spectrum_size * sizeof(uint16_t));
|
||||
if (self->far_spectrum_u16 == NULL) {
|
||||
WebRtc_FreeDelayEstimatorFloat(self);
|
||||
self = NULL;
|
||||
return -1;
|
||||
}
|
||||
self->near_spectrum_u16 = malloc(spectrum_size * sizeof(uint16_t));
|
||||
if (self->near_spectrum_u16 == NULL) {
|
||||
WebRtc_FreeDelayEstimatorFloat(self);
|
||||
self = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WebRtc_InitDelayEstimatorFloat(void* handle) {
|
||||
DelayEstimatorFloat_t* self = (DelayEstimatorFloat_t*) handle;
|
||||
|
||||
if (self == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (WebRtc_InitDelayEstimator(self->fixed_handle) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
{
|
||||
int history_size = WebRtc_history_size(self->fixed_handle);
|
||||
int spectrum_size = WebRtc_spectrum_size(self->fixed_handle);
|
||||
if (WebRtc_is_alignment_enabled(self->fixed_handle) == 1) {
|
||||
// Set far end histories to zero
|
||||
memset(self->far_history,
|
||||
0,
|
||||
sizeof(float) * spectrum_size * history_size);
|
||||
self->far_history_pos = history_size;
|
||||
}
|
||||
// Set fixed point spectra to zero
|
||||
memset(self->far_spectrum_u16, 0, sizeof(uint16_t) * spectrum_size);
|
||||
memset(self->near_spectrum_u16, 0, sizeof(uint16_t) * spectrum_size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WebRtc_DelayEstimatorProcessFloat(void* handle,
|
||||
float* far_spectrum,
|
||||
float* near_spectrum,
|
||||
int spectrum_size,
|
||||
int vad_value) {
|
||||
DelayEstimatorFloat_t* self = (DelayEstimatorFloat_t*) handle;
|
||||
|
||||
const float kFftSize = (float) (2 * (spectrum_size - 1));
|
||||
const float kLogOf2Inverse = 1.4426950f;
|
||||
float max_value = 0.0f;
|
||||
float scaling = 0;
|
||||
|
||||
int far_q = 0;
|
||||
int scaling_log = 0;
|
||||
int i = 0;
|
||||
|
||||
if (self == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (far_spectrum == NULL) {
|
||||
// Empty far end spectrum
|
||||
return -1;
|
||||
}
|
||||
if (near_spectrum == NULL) {
|
||||
// Empty near end spectrum
|
||||
return -1;
|
||||
}
|
||||
if (spectrum_size != WebRtc_spectrum_size(self->fixed_handle)) {
|
||||
// Data sizes don't match
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Convert floating point spectrum to fixed point
|
||||
// 1) Find largest value
|
||||
// 2) Scale largest value to fit in Word16
|
||||
for (i = 0; i < spectrum_size; ++i) {
|
||||
if (near_spectrum[i] > max_value) {
|
||||
max_value = near_spectrum[i];
|
||||
}
|
||||
}
|
||||
// Find the largest possible scaling that is a multiple of two.
|
||||
// With largest we mean to fit in a Word16.
|
||||
// TODO(bjornv): I've taken the size of FFT into account, since there is a
|
||||
// different scaling in float vs fixed point FFTs. I'm not completely sure
|
||||
// this is necessary.
|
||||
scaling_log = 14 - (int) (log(max_value / kFftSize + 1) * kLogOf2Inverse);
|
||||
scaling = (float) (1 << scaling_log) / kFftSize;
|
||||
for (i = 0; i < spectrum_size; ++i) {
|
||||
self->near_spectrum_u16[i] = (uint16_t) (near_spectrum[i] * scaling);
|
||||
}
|
||||
|
||||
// Same for far end
|
||||
max_value = 0.0f;
|
||||
for (i = 0; i < spectrum_size; ++i) {
|
||||
if (far_spectrum[i] > max_value) {
|
||||
max_value = far_spectrum[i];
|
||||
}
|
||||
}
|
||||
// Find the largest possible scaling that is a multiple of two.
|
||||
// With largest we mean to fit in a Word16.
|
||||
scaling_log = 14 - (int) (log(max_value / kFftSize + 1) * kLogOf2Inverse);
|
||||
scaling = (float) (1 << scaling_log) / kFftSize;
|
||||
for (i = 0; i < spectrum_size; ++i) {
|
||||
self->far_spectrum_u16[i] = (uint16_t) (far_spectrum[i] * scaling);
|
||||
}
|
||||
far_q = (int) scaling_log;
|
||||
assert(far_q < 16); // Catch too large scaling, which should never be able to
|
||||
// occur.
|
||||
|
||||
if (WebRtc_is_alignment_enabled(self->fixed_handle) == 1) {
|
||||
// Update far end history
|
||||
UpdateFarHistory(self, far_spectrum);
|
||||
}
|
||||
|
||||
return WebRtc_DelayEstimatorProcess(self->fixed_handle,
|
||||
self->far_spectrum_u16,
|
||||
self->near_spectrum_u16,
|
||||
spectrum_size,
|
||||
far_q,
|
||||
vad_value);
|
||||
}
|
||||
|
||||
const float* WebRtc_AlignedFarendFloat(void* handle, int far_spectrum_size) {
|
||||
DelayEstimatorFloat_t* self = (DelayEstimatorFloat_t*) handle;
|
||||
int buffer_pos = 0;
|
||||
|
||||
if (self == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (far_spectrum_size != WebRtc_spectrum_size(self->fixed_handle)) {
|
||||
return NULL;
|
||||
}
|
||||
if (WebRtc_is_alignment_enabled(self->fixed_handle) != 1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get buffer position
|
||||
buffer_pos = self->far_history_pos - WebRtc_last_delay(self->fixed_handle);
|
||||
if (buffer_pos < 0) {
|
||||
buffer_pos += WebRtc_history_size(self->fixed_handle);
|
||||
}
|
||||
// Return pointer to far end spectrum
|
||||
return (self->far_history + (buffer_pos * far_spectrum_size));
|
||||
}
|
||||
|
||||
int WebRtc_last_delay_float(void* handle) {
|
||||
DelayEstimatorFloat_t* self = (DelayEstimatorFloat_t*) handle;
|
||||
|
||||
if (self == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return WebRtc_last_delay(self->fixed_handle);
|
||||
}
|
||||
|
||||
int WebRtc_is_alignment_enabled_float(void* handle) {
|
||||
DelayEstimatorFloat_t* self = (DelayEstimatorFloat_t*) handle;
|
||||
|
||||
if (self == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return WebRtc_is_alignment_enabled(self->fixed_handle);
|
||||
}
|
297
src/modules/audio_processing/utility/delay_estimator_wrapper.c
Normal file
297
src/modules/audio_processing/utility/delay_estimator_wrapper.c
Normal file
@ -0,0 +1,297 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "delay_estimator_wrapper.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "delay_estimator.h"
|
||||
#include "signal_processing_library.h"
|
||||
|
||||
typedef union {
|
||||
float float_;
|
||||
int32_t int32_;
|
||||
} SpectrumType_t;
|
||||
|
||||
typedef struct {
|
||||
// Pointers to mean values of spectrum
|
||||
SpectrumType_t* mean_far_spectrum;
|
||||
SpectrumType_t* mean_near_spectrum;
|
||||
|
||||
// Spectrum size
|
||||
int spectrum_size;
|
||||
|
||||
// Binary spectrum based delay estimator
|
||||
BinaryDelayEstimator_t* binary_handle;
|
||||
} DelayEstimator_t;
|
||||
|
||||
// Only bit |kBandFirst| through bit |kBandLast| are processed
|
||||
// |kBandFirst| - |kBandLast| must be < 32
|
||||
static const int kBandFirst = 12;
|
||||
static const int kBandLast = 43;
|
||||
|
||||
static __inline uint32_t SetBit(uint32_t in, int pos) {
|
||||
uint32_t mask = WEBRTC_SPL_LSHIFT_W32(1, pos);
|
||||
uint32_t out = (in | mask);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// Calculates the mean recursively. Same version as WebRtc_MeanEstimatorFix(),
|
||||
// but for float.
|
||||
//
|
||||
// Inputs:
|
||||
// - new_value : new additional value.
|
||||
// - scale : scale for smoothing (should be less than 1.0).
|
||||
//
|
||||
// Input/Output:
|
||||
// - mean_value : pointer to the mean value for updating.
|
||||
//
|
||||
static void MeanEstimatorFloat(float new_value,
|
||||
float scale,
|
||||
float* mean_value) {
|
||||
assert(scale < 1.0f);
|
||||
// mean_new = mean_value + ((new_value - mean_value) * scale);
|
||||
float diff = (new_value - *mean_value) * scale;
|
||||
float mean_new = *mean_value + diff;
|
||||
|
||||
*mean_value = mean_new;
|
||||
}
|
||||
|
||||
// Computes the binary spectrum by comparing the input |spectrum| with a
|
||||
// |threshold_spectrum|. Float and fixed point versions.
|
||||
//
|
||||
// Inputs:
|
||||
// - spectrum : Spectrum of which the binary spectrum should be
|
||||
// calculated.
|
||||
// - threshold_spectrum : Threshold spectrum with which the input
|
||||
// spectrum is compared.
|
||||
// Return:
|
||||
// - out : Binary spectrum
|
||||
//
|
||||
static uint32_t BinarySpectrumFix(uint16_t* spectrum,
|
||||
SpectrumType_t* threshold_spectrum) {
|
||||
int k = kBandFirst;
|
||||
uint32_t out = 0;
|
||||
|
||||
for (; k <= kBandLast; k++) {
|
||||
WebRtc_MeanEstimatorFix((int32_t) spectrum[k],
|
||||
6,
|
||||
&(threshold_spectrum[k].int32_));
|
||||
if (spectrum[k] > threshold_spectrum[k].int32_) {
|
||||
out = SetBit(out, k - kBandFirst);
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
static uint32_t BinarySpectrumFloat(float* spectrum,
|
||||
SpectrumType_t* threshold_spectrum) {
|
||||
int k = kBandFirst;
|
||||
uint32_t out = 0;
|
||||
float scale = 1 / 64.0;
|
||||
|
||||
for (; k <= kBandLast; k++) {
|
||||
MeanEstimatorFloat(spectrum[k], scale, &(threshold_spectrum[k].float_));
|
||||
if (spectrum[k] > threshold_spectrum[k].float_) {
|
||||
out = SetBit(out, k - kBandFirst);
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
int WebRtc_FreeDelayEstimator(void* handle) {
|
||||
DelayEstimator_t* self = (DelayEstimator_t*) handle;
|
||||
|
||||
if (self == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (self->mean_far_spectrum != NULL) {
|
||||
free(self->mean_far_spectrum);
|
||||
self->mean_far_spectrum = NULL;
|
||||
}
|
||||
if (self->mean_near_spectrum != NULL) {
|
||||
free(self->mean_near_spectrum);
|
||||
self->mean_near_spectrum = NULL;
|
||||
}
|
||||
|
||||
WebRtc_FreeBinaryDelayEstimator(self->binary_handle);
|
||||
|
||||
free(self);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WebRtc_CreateDelayEstimator(void** handle,
|
||||
int spectrum_size,
|
||||
int history_size) {
|
||||
DelayEstimator_t *self = NULL;
|
||||
|
||||
// Check if the sub band used in the delay estimation is small enough to
|
||||
// fit the binary spectra in a uint32.
|
||||
assert(kBandLast - kBandFirst < 32);
|
||||
|
||||
if (handle == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (spectrum_size < kBandLast) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
self = malloc(sizeof(DelayEstimator_t));
|
||||
*handle = self;
|
||||
if (self == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
self->mean_far_spectrum = NULL;
|
||||
self->mean_near_spectrum = NULL;
|
||||
|
||||
// Create binary delay estimator.
|
||||
if (WebRtc_CreateBinaryDelayEstimator(&self->binary_handle,
|
||||
history_size) != 0) {
|
||||
WebRtc_FreeDelayEstimator(self);
|
||||
self = NULL;
|
||||
return -1;
|
||||
}
|
||||
// Allocate memory for spectrum buffers
|
||||
self->mean_far_spectrum = malloc(spectrum_size * sizeof(SpectrumType_t));
|
||||
if (self->mean_far_spectrum == NULL) {
|
||||
WebRtc_FreeDelayEstimator(self);
|
||||
self = NULL;
|
||||
return -1;
|
||||
}
|
||||
self->mean_near_spectrum = malloc(spectrum_size * sizeof(SpectrumType_t));
|
||||
if (self->mean_near_spectrum == NULL) {
|
||||
WebRtc_FreeDelayEstimator(self);
|
||||
self = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
self->spectrum_size = spectrum_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WebRtc_InitDelayEstimator(void* handle) {
|
||||
DelayEstimator_t* self = (DelayEstimator_t*) handle;
|
||||
|
||||
if (self == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Initialize binary delay estimator
|
||||
if (WebRtc_InitBinaryDelayEstimator(self->binary_handle) != 0) {
|
||||
return -1;
|
||||
}
|
||||
// Set averaged far and near end spectra to zero
|
||||
memset(self->mean_far_spectrum,
|
||||
0,
|
||||
sizeof(SpectrumType_t) * self->spectrum_size);
|
||||
memset(self->mean_near_spectrum,
|
||||
0,
|
||||
sizeof(SpectrumType_t) * self->spectrum_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WebRtc_DelayEstimatorProcessFix(void* handle,
|
||||
uint16_t* far_spectrum,
|
||||
uint16_t* near_spectrum,
|
||||
int spectrum_size,
|
||||
int far_q,
|
||||
int vad_value) {
|
||||
DelayEstimator_t* self = (DelayEstimator_t*) handle;
|
||||
uint32_t binary_far_spectrum = 0;
|
||||
uint32_t binary_near_spectrum = 0;
|
||||
|
||||
if (self == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (far_spectrum == NULL) {
|
||||
// Empty far end spectrum
|
||||
return -1;
|
||||
}
|
||||
if (near_spectrum == NULL) {
|
||||
// Empty near end spectrum
|
||||
return -1;
|
||||
}
|
||||
if (spectrum_size != self->spectrum_size) {
|
||||
// Data sizes don't match
|
||||
return -1;
|
||||
}
|
||||
if (far_q > 15) {
|
||||
// If |far_q| is larger than 15 we cannot guarantee no wrap around
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Get binary spectra
|
||||
binary_far_spectrum = BinarySpectrumFix(far_spectrum,
|
||||
self->mean_far_spectrum);
|
||||
binary_near_spectrum = BinarySpectrumFix(near_spectrum,
|
||||
self->mean_near_spectrum);
|
||||
|
||||
return WebRtc_ProcessBinarySpectrum(self->binary_handle,
|
||||
binary_far_spectrum,
|
||||
binary_near_spectrum,
|
||||
vad_value);
|
||||
}
|
||||
|
||||
int WebRtc_DelayEstimatorProcessFloat(void* handle,
|
||||
float* far_spectrum,
|
||||
float* near_spectrum,
|
||||
int spectrum_size,
|
||||
int vad_value) {
|
||||
DelayEstimator_t* self = (DelayEstimator_t*) handle;
|
||||
uint32_t binary_far_spectrum = 0;
|
||||
uint32_t binary_near_spectrum = 0;
|
||||
|
||||
if (self == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (far_spectrum == NULL) {
|
||||
// Empty far end spectrum
|
||||
return -1;
|
||||
}
|
||||
if (near_spectrum == NULL) {
|
||||
// Empty near end spectrum
|
||||
return -1;
|
||||
}
|
||||
if (spectrum_size != self->spectrum_size) {
|
||||
// Data sizes don't match
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Get binary spectra
|
||||
binary_far_spectrum = BinarySpectrumFloat(far_spectrum,
|
||||
self->mean_far_spectrum);
|
||||
binary_near_spectrum = BinarySpectrumFloat(near_spectrum,
|
||||
self->mean_near_spectrum);
|
||||
|
||||
return WebRtc_ProcessBinarySpectrum(self->binary_handle,
|
||||
binary_far_spectrum,
|
||||
binary_near_spectrum,
|
||||
vad_value);
|
||||
}
|
||||
|
||||
int WebRtc_last_delay(void* handle) {
|
||||
DelayEstimator_t* self = (DelayEstimator_t*) handle;
|
||||
|
||||
if (self == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return WebRtc_binary_last_delay(self->binary_handle);
|
||||
}
|
@ -11,18 +11,19 @@
|
||||
// Performs delay estimation on a block by block basis
|
||||
// The return value is 0 - OK and -1 - Error, unless otherwise stated.
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_DELAY_ESTIMATOR_FLOAT_H_
|
||||
#define WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_DELAY_ESTIMATOR_FLOAT_H_
|
||||
#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_DELAY_ESTIMATOR_WRAPPER_H_
|
||||
#define WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_DELAY_ESTIMATOR_WRAPPER_H_
|
||||
|
||||
// Releases the memory allocated by WebRtc_CreateDelayEstimatorFloat(...)
|
||||
#include "typedefs.h"
|
||||
|
||||
// Releases the memory allocated by WebRtc_CreateDelayEstimator(...)
|
||||
// Input:
|
||||
// - handle : Pointer to the delay estimation instance
|
||||
//
|
||||
int WebRtc_FreeDelayEstimatorFloat(void* handle);
|
||||
int WebRtc_FreeDelayEstimator(void* handle);
|
||||
|
||||
// Allocates the memory needed by the delay estimation. The memory needs to be
|
||||
// initialized separately using the WebRtc_InitDelayEstimatorFloat(...)
|
||||
// function.
|
||||
// initialized separately through WebRtc_InitDelayEstimator(...).
|
||||
//
|
||||
// Inputs:
|
||||
// - handle : Instance that should be created
|
||||
@ -32,29 +33,23 @@ int WebRtc_FreeDelayEstimatorFloat(void* handle);
|
||||
// - history_size : Size of the far end history used to estimate the
|
||||
// delay from. Used to allocate memory for history
|
||||
// specific buffers.
|
||||
// - enable_alignment : With this mode set to 1, a far end history is
|
||||
// created, so that the user can retrieve aligned
|
||||
// far end spectra using
|
||||
// WebRtc_AlignedFarendFloat(...). Otherwise, only
|
||||
// delay values are calculated.
|
||||
//
|
||||
// Output:
|
||||
// - handle : Created instance
|
||||
//
|
||||
int WebRtc_CreateDelayEstimatorFloat(void** handle,
|
||||
int spectrum_size,
|
||||
int history_size,
|
||||
int enable_alignment);
|
||||
int WebRtc_CreateDelayEstimator(void** handle,
|
||||
int spectrum_size,
|
||||
int history_size);
|
||||
|
||||
// Initializes the delay estimation instance created with
|
||||
// WebRtc_CreateDelayEstimatorFloat(...)
|
||||
// WebRtc_CreateDelayEstimator(...)
|
||||
// Input:
|
||||
// - handle : Pointer to the delay estimation instance
|
||||
//
|
||||
// Output:
|
||||
// - handle : Initialized instance
|
||||
//
|
||||
int WebRtc_InitDelayEstimatorFloat(void* handle);
|
||||
int WebRtc_InitDelayEstimator(void* handle);
|
||||
|
||||
// Estimates and returns the delay between the far end and near end blocks.
|
||||
// Inputs:
|
||||
@ -74,52 +69,30 @@ int WebRtc_InitDelayEstimatorFloat(void* handle);
|
||||
// - delay : >= 0 - Calculated delay value
|
||||
// -1 - Error
|
||||
//
|
||||
int WebRtc_DelayEstimatorProcessFix(void* handle,
|
||||
uint16_t* far_spectrum,
|
||||
uint16_t* near_spectrum,
|
||||
int spectrum_size,
|
||||
int far_q,
|
||||
int vad_value);
|
||||
|
||||
// See WebRtc_DelayEstimatorProcessFix() for description.
|
||||
int WebRtc_DelayEstimatorProcessFloat(void* handle,
|
||||
float* far_spectrum,
|
||||
float* near_spectrum,
|
||||
int spectrum_size,
|
||||
int vad_value);
|
||||
|
||||
// Returns a pointer to the far end spectrum aligned to current near end
|
||||
// spectrum. The function WebRtc_DelayEstimatorProcessFloat(...) should
|
||||
// have been called before WebRtc_AlignedFarendFloat(...). Otherwise, you get
|
||||
// the pointer to the previous frame. The memory is only valid until the
|
||||
// next call of WebRtc_DelayEstimatorProcessFloat(...).
|
||||
//
|
||||
// Inputs:
|
||||
// - handle : Pointer to the delay estimation instance
|
||||
// - far_spectrum_size : Size of far_spectrum allocated by the caller
|
||||
//
|
||||
// Output:
|
||||
//
|
||||
// Return value:
|
||||
// - far_spectrum : Pointer to the aligned far end spectrum
|
||||
// NULL - Error
|
||||
//
|
||||
const float* WebRtc_AlignedFarendFloat(void* handle, int far_spectrum_size);
|
||||
|
||||
// Returns the last calculated delay updated by the function
|
||||
// WebRtcApm_DelayEstimatorProcessFloat(...)
|
||||
// WebRtc_DelayEstimatorProcess(...)
|
||||
//
|
||||
// Inputs:
|
||||
// Input:
|
||||
// - handle : Pointer to the delay estimation instance
|
||||
//
|
||||
// Return value:
|
||||
// - delay : >= 0 - Last calculated delay value
|
||||
// -1 - Error
|
||||
//
|
||||
int WebRtc_last_delay_float(void* handle);
|
||||
int WebRtc_last_delay(void* handle);
|
||||
|
||||
// Returns 1 if the far end alignment is enabled and 0 otherwise.
|
||||
//
|
||||
// Input:
|
||||
// - handle : Pointer to the delay estimation instance
|
||||
//
|
||||
// Return value:
|
||||
// - alignment_enabled : 1 - Enabled
|
||||
// 0 - Disabled
|
||||
// -1 - Error
|
||||
//
|
||||
int WebRtc_is_alignment_enabled_float(void* handle);
|
||||
|
||||
#endif // WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_DELAY_ESTIMATOR_FLOAT_H_
|
||||
#endif // WEBRTC_MODULES_AUDIO_PROCESSING_UTILITY_DELAY_ESTIMATOR_WRAPPER_H_
|
@ -20,10 +20,10 @@
|
||||
],
|
||||
},
|
||||
'sources': [
|
||||
'delay_estimator_float.c',
|
||||
'delay_estimator_float.h',
|
||||
'delay_estimator.c',
|
||||
'delay_estimator.h',
|
||||
'delay_estimator_wrapper.c',
|
||||
'delay_estimator_wrapper.h',
|
||||
'fft4g.c',
|
||||
'fft4g.h',
|
||||
'ring_buffer.c',
|
||||
|
Loading…
x
Reference in New Issue
Block a user