Adds possibility to log delay estimates in AEC.
Review URL: http://webrtc-codereview.appspot.com/178001 git-svn-id: http://webrtc.googlecode.com/svn/trunk@674 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
f72c36763f
commit
1ba3dbecbb
@ -38,6 +38,7 @@ typedef struct {
|
||||
WebRtc_Word16 nlpMode; // default kAecNlpModerate
|
||||
WebRtc_Word16 skewMode; // default kAecFalse
|
||||
WebRtc_Word16 metricsMode; // default kAecFalse
|
||||
int delay_logging; // default kAecFalse
|
||||
//float realSkew;
|
||||
} AecConfig;
|
||||
|
||||
@ -66,7 +67,7 @@ extern "C" {
|
||||
* Inputs Description
|
||||
* -------------------------------------------------------------------
|
||||
* void **aecInst Pointer to the AEC instance to be created
|
||||
* and initilized
|
||||
* and initialized
|
||||
*
|
||||
* Outputs Description
|
||||
* -------------------------------------------------------------------
|
||||
@ -225,6 +226,23 @@ WebRtc_Word32 WebRtcAec_get_echo_status(void *aecInst, WebRtc_Word16 *status);
|
||||
*/
|
||||
WebRtc_Word32 WebRtcAec_GetMetrics(void *aecInst, AecMetrics *metrics);
|
||||
|
||||
/*
|
||||
* Gets the current delay metrics for the session.
|
||||
*
|
||||
* Inputs Description
|
||||
* -------------------------------------------------------------------
|
||||
* void* handle Pointer to the AEC instance
|
||||
*
|
||||
* Outputs Description
|
||||
* -------------------------------------------------------------------
|
||||
* int* median Delay median value.
|
||||
* int* std Delay standard deviation.
|
||||
*
|
||||
* int return 0: OK
|
||||
* -1: error
|
||||
*/
|
||||
int WebRtcAec_GetDelayMetrics(void* handle, int* median, int* std);
|
||||
|
||||
/*
|
||||
* Gets the last error code.
|
||||
*
|
||||
|
@ -12,12 +12,14 @@
|
||||
* The core AEC algorithm, which is presented with time-aligned signals.
|
||||
*/
|
||||
|
||||
#include "aec_core.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "aec_core.h"
|
||||
#include "aec_rdft.h"
|
||||
#include "delay_estimator_float.h"
|
||||
#include "ring_buffer.h"
|
||||
#include "system_wrappers/interface/cpu_features_wrapper.h"
|
||||
|
||||
@ -174,6 +176,15 @@ int WebRtcAec_CreateAec(aec_t **aecInst)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (WebRtc_CreateDelayEstimatorFloat(&aec->delay_estimator,
|
||||
PART_LEN1,
|
||||
kMaxDelay,
|
||||
0) == -1) {
|
||||
WebRtcAec_FreeAec(aec);
|
||||
aec = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -190,6 +201,8 @@ int WebRtcAec_FreeAec(aec_t *aec)
|
||||
WebRtcApm_FreeBuffer(aec->nearFrBufH);
|
||||
WebRtcApm_FreeBuffer(aec->outFrBufH);
|
||||
|
||||
WebRtc_FreeDelayEstimatorFloat(aec->delay_estimator);
|
||||
|
||||
free(aec);
|
||||
return 0;
|
||||
}
|
||||
@ -371,6 +384,12 @@ int WebRtcAec_InitAec(aec_t *aec, int sampFreq)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (WebRtc_InitDelayEstimatorFloat(aec->delay_estimator) != 0) {
|
||||
return -1;
|
||||
}
|
||||
aec->delay_logging_enabled = 0;
|
||||
memset(aec->delay_histogram, 0, sizeof(aec->delay_histogram));
|
||||
|
||||
// Default target suppression level
|
||||
aec->targetSupp = -11.5;
|
||||
aec->minOverDrive = 2.0;
|
||||
@ -561,6 +580,10 @@ static void ProcessBlock(aec_t *aec, const short *farend,
|
||||
float fft[PART_LEN2];
|
||||
float xf[2][PART_LEN1], yf[2][PART_LEN1], ef[2][PART_LEN1];
|
||||
complex_t df[PART_LEN1];
|
||||
float far_spectrum = 0.0f;
|
||||
float near_spectrum = 0.0f;
|
||||
float abs_far_spectrum[PART_LEN1];
|
||||
float abs_near_spectrum[PART_LEN1];
|
||||
|
||||
const float gPow[2] = {0.9f, 0.1f};
|
||||
|
||||
@ -625,10 +648,15 @@ static void ProcessBlock(aec_t *aec, const short *farend,
|
||||
|
||||
// Power smoothing
|
||||
for (i = 0; i < PART_LEN1; i++) {
|
||||
aec->xPow[i] = gPow[0] * aec->xPow[i] + gPow[1] * NR_PART *
|
||||
(xf[0][i] * xf[0][i] + xf[1][i] * xf[1][i]);
|
||||
aec->dPow[i] = gPow[0] * aec->dPow[i] + gPow[1] *
|
||||
(df[i][0] * df[i][0] + df[i][1] * df[i][1]);
|
||||
far_spectrum = xf[0][i] * xf[0][i] + xf[1][i] * xf[1][i];
|
||||
aec->xPow[i] = gPow[0] * aec->xPow[i] + gPow[1] * NR_PART * far_spectrum;
|
||||
// Calculate absolute spectra
|
||||
abs_far_spectrum[i] = sqrtf(far_spectrum);
|
||||
|
||||
near_spectrum = df[i][0] * df[i][0] + df[i][1] * df[i][1];
|
||||
aec->dPow[i] = gPow[0] * aec->dPow[i] + gPow[1] * near_spectrum;
|
||||
// Calculate absolute spectra
|
||||
abs_near_spectrum[i] = sqrtf(near_spectrum);
|
||||
}
|
||||
|
||||
// Estimate noise power. Wait until dPow is more stable.
|
||||
@ -663,6 +691,20 @@ static void ProcessBlock(aec_t *aec, const short *farend,
|
||||
aec->noisePow = aec->dMinPow;
|
||||
}
|
||||
|
||||
// Block wise delay estimation used for logging
|
||||
if (aec->delay_logging_enabled) {
|
||||
int delay_estimate = 0;
|
||||
// Estimate the delay
|
||||
delay_estimate = WebRtc_DelayEstimatorProcessFloat(aec->delay_estimator,
|
||||
abs_far_spectrum,
|
||||
abs_near_spectrum,
|
||||
PART_LEN1,
|
||||
aec->echoState);
|
||||
if (delay_estimate >= 0) {
|
||||
// Update delay estimate buffer
|
||||
aec->delay_histogram[delay_estimate]++;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the xfBuf block position.
|
||||
aec->xfBufBlockPos--;
|
||||
|
@ -33,6 +33,8 @@
|
||||
#define PREF_BAND_SIZE 24
|
||||
|
||||
#define BLOCKL_MAX FRAME_LEN
|
||||
// Maximum delay in fixed point delay estimator, used for logging
|
||||
enum {kMaxDelay = 100};
|
||||
|
||||
typedef float complex_t[2];
|
||||
// For performance reasons, some arrays of complex numbers are replaced by twice
|
||||
@ -141,6 +143,10 @@ typedef struct {
|
||||
int flag_Hband_cn; //for comfort noise
|
||||
float cn_scale_Hband; //scale for comfort noise in H band
|
||||
|
||||
int delay_histogram[kMaxDelay];
|
||||
int delay_logging_enabled;
|
||||
void* delay_estimator;
|
||||
|
||||
#ifdef AEC_DEBUG
|
||||
FILE *farFile;
|
||||
FILE *nearFile;
|
||||
|
@ -11,16 +11,18 @@
|
||||
/*
|
||||
* Contains the API functions for the AEC.
|
||||
*/
|
||||
#include "echo_cancellation.h"
|
||||
|
||||
#include <math.h>
|
||||
#ifdef AEC_DEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "echo_cancellation.h"
|
||||
#include "aec_core.h"
|
||||
#include "ring_buffer.h"
|
||||
#include "resampler.h"
|
||||
#ifdef AEC_DEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
#include "ring_buffer.h"
|
||||
|
||||
#define BUF_SIZE_FRAMES 50 // buffer size (frames)
|
||||
// Maximum length of resampled signal. Must be an integer multiple of frames
|
||||
@ -215,7 +217,7 @@ WebRtc_Word32 WebRtcAec_Init(void *aecInst, WebRtc_Word32 sampFreq, WebRtc_Word3
|
||||
return -1;
|
||||
}
|
||||
|
||||
aecpc->initFlag = initCheck; // indicates that initilisation has been done
|
||||
aecpc->initFlag = initCheck; // indicates that initialization has been done
|
||||
|
||||
if (aecpc->sampFreq == 32000) {
|
||||
aecpc->splitSampFreq = 16000;
|
||||
@ -254,6 +256,7 @@ WebRtc_Word32 WebRtcAec_Init(void *aecInst, WebRtc_Word32 sampFreq, WebRtc_Word3
|
||||
aecConfig.nlpMode = kAecNlpModerate;
|
||||
aecConfig.skewMode = kAecFalse;
|
||||
aecConfig.metricsMode = kAecFalse;
|
||||
aecConfig.delay_logging = kAecFalse;
|
||||
|
||||
if (WebRtcAec_set_config(aecpc, aecConfig) == -1) {
|
||||
aecpc->lastError = AEC_UNSPECIFIED_ERROR;
|
||||
@ -566,6 +569,15 @@ WebRtc_Word32 WebRtcAec_set_config(void *aecInst, AecConfig config)
|
||||
WebRtcAec_InitMetrics(aecpc->aec);
|
||||
}
|
||||
|
||||
if (config.delay_logging != kAecFalse && config.delay_logging != kAecTrue) {
|
||||
aecpc->lastError = AEC_BAD_PARAMETER_ERROR;
|
||||
return -1;
|
||||
}
|
||||
aecpc->aec->delay_logging_enabled = config.delay_logging;
|
||||
if (aecpc->aec->delay_logging_enabled == kAecTrue) {
|
||||
memset(aecpc->aec->delay_histogram, 0, sizeof(aecpc->aec->delay_histogram));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -590,6 +602,7 @@ WebRtc_Word32 WebRtcAec_get_config(void *aecInst, AecConfig *config)
|
||||
config->nlpMode = aecpc->nlpMode;
|
||||
config->skewMode = aecpc->skewMode;
|
||||
config->metricsMode = aecpc->aec->metricsMode;
|
||||
config->delay_logging = aecpc->aec->delay_logging_enabled;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -717,6 +730,69 @@ WebRtc_Word32 WebRtcAec_GetMetrics(void *aecInst, AecMetrics *metrics)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WebRtcAec_GetDelayMetrics(void* handle, int* median, int* std) {
|
||||
aecpc_t* self = handle;
|
||||
int i = 0;
|
||||
int delay_values = 0;
|
||||
int num_delay_values = 0;
|
||||
int my_median = 0;
|
||||
float l1_norm = 0;
|
||||
|
||||
if (self == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (median == NULL) {
|
||||
self->lastError = AEC_NULL_POINTER_ERROR;
|
||||
return -1;
|
||||
}
|
||||
if (std == NULL) {
|
||||
self->lastError = AEC_NULL_POINTER_ERROR;
|
||||
return -1;
|
||||
}
|
||||
if (self->initFlag != initCheck) {
|
||||
self->lastError = AEC_UNINITIALIZED_ERROR;
|
||||
return -1;
|
||||
}
|
||||
if (self->aec->delay_logging_enabled == 0) {
|
||||
// Logging disabled
|
||||
self->lastError = AEC_UNSUPPORTED_FUNCTION_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Get number of delay values since last update
|
||||
for (i = 0; i < kMaxDelay; i++) {
|
||||
num_delay_values += self->aec->delay_histogram[i];
|
||||
}
|
||||
if (num_delay_values == 0) {
|
||||
// We have no new delay value data
|
||||
*median = -1;
|
||||
*std = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
delay_values = num_delay_values >> 1; // Start value for median count down
|
||||
// Get median of delay values since last update
|
||||
for (i = 0; i < kMaxDelay; i++) {
|
||||
delay_values -= self->aec->delay_histogram[i];
|
||||
if (delay_values < 0) {
|
||||
my_median = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*median = my_median;
|
||||
|
||||
// Calculate the L1 norm, with median value as central moment
|
||||
for (i = 0; i < kMaxDelay; i++) {
|
||||
l1_norm += (float) (fabs(i - my_median) * self->aec->delay_histogram[i]);
|
||||
}
|
||||
*std = (int) (l1_norm / (float) num_delay_values + 0.5f);
|
||||
|
||||
// Reset histogram
|
||||
memset(self->aec->delay_histogram, 0, sizeof(self->aec->delay_histogram));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
WebRtc_Word32 WebRtcAec_get_version(WebRtc_Word8 *versionStr, WebRtc_Word16 len)
|
||||
{
|
||||
const char version[] = "AEC 2.5.0";
|
||||
|
@ -322,6 +322,16 @@ class EchoCancellation {
|
||||
// TODO(ajm): discuss the metrics update period.
|
||||
virtual int GetMetrics(Metrics* metrics) = 0;
|
||||
|
||||
// Enables computation and logging of delay values. Statistics are obtained
|
||||
// through |GetDelayMetrics()|.
|
||||
virtual int enable_delay_logging(bool enable) = 0;
|
||||
virtual bool is_delay_logging_enabled() const = 0;
|
||||
|
||||
// The delay metrics consists of the delay |median| and the delay standard
|
||||
// deviation |std|. The values are averaged over the time period since the
|
||||
// last call to |GetDelayMetrics()|.
|
||||
virtual int GetDelayMetrics(int* median, int* std) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~EchoCancellation() {};
|
||||
};
|
||||
|
@ -66,7 +66,8 @@ EchoCancellationImpl::EchoCancellationImpl(const AudioProcessingImpl* apm)
|
||||
device_sample_rate_hz_(48000),
|
||||
stream_drift_samples_(0),
|
||||
was_stream_drift_set_(false),
|
||||
stream_has_echo_(false) {}
|
||||
stream_has_echo_(false),
|
||||
delay_logging_enabled_(false) {}
|
||||
|
||||
EchoCancellationImpl::~EchoCancellationImpl() {}
|
||||
|
||||
@ -283,6 +284,39 @@ bool EchoCancellationImpl::stream_has_echo() const {
|
||||
return stream_has_echo_;
|
||||
}
|
||||
|
||||
int EchoCancellationImpl::enable_delay_logging(bool enable) {
|
||||
CriticalSectionScoped crit_scoped(*apm_->crit());
|
||||
delay_logging_enabled_ = enable;
|
||||
return Configure();
|
||||
}
|
||||
|
||||
bool EchoCancellationImpl::is_delay_logging_enabled() const {
|
||||
return delay_logging_enabled_;
|
||||
}
|
||||
|
||||
// TODO(bjornv): How should we handle the multi-channel case?
|
||||
int EchoCancellationImpl::GetDelayMetrics(int* median, int* std) {
|
||||
CriticalSectionScoped crit_scoped(*apm_->crit());
|
||||
if (median == NULL) {
|
||||
return apm_->kNullPointerError;
|
||||
}
|
||||
if (std == NULL) {
|
||||
return apm_->kNullPointerError;
|
||||
}
|
||||
|
||||
if (!is_component_enabled() || !delay_logging_enabled_) {
|
||||
return apm_->kNotEnabledError;
|
||||
}
|
||||
|
||||
Handle* my_handle = static_cast<Handle*>(handle(0));
|
||||
if (WebRtcAec_GetDelayMetrics(my_handle, median, std) !=
|
||||
apm_->kNoError) {
|
||||
return GetHandleError(my_handle);
|
||||
}
|
||||
|
||||
return apm_->kNoError;
|
||||
}
|
||||
|
||||
int EchoCancellationImpl::Initialize() {
|
||||
int err = ProcessingComponent::Initialize();
|
||||
if (err != apm_->kNoError || !is_component_enabled()) {
|
||||
@ -332,6 +366,7 @@ int EchoCancellationImpl::ConfigureHandle(void* handle) const {
|
||||
config.metricsMode = metrics_enabled_;
|
||||
config.nlpMode = MapSetting(suppression_level_);
|
||||
config.skewMode = drift_compensation_enabled_;
|
||||
config.delay_logging = delay_logging_enabled_;
|
||||
|
||||
return WebRtcAec_set_config(static_cast<Handle*>(handle), config);
|
||||
}
|
||||
|
@ -49,6 +49,9 @@ class EchoCancellationImpl : public EchoCancellation,
|
||||
virtual bool are_metrics_enabled() const;
|
||||
virtual bool stream_has_echo() const;
|
||||
virtual int GetMetrics(Metrics* metrics);
|
||||
virtual int enable_delay_logging(bool enable);
|
||||
virtual bool is_delay_logging_enabled() const;
|
||||
virtual int GetDelayMetrics(int* median, int* std);
|
||||
|
||||
// ProcessingComponent implementation.
|
||||
virtual void* CreateHandle() const;
|
||||
@ -66,6 +69,7 @@ class EchoCancellationImpl : public EchoCancellation,
|
||||
int stream_drift_samples_;
|
||||
bool was_stream_drift_set_;
|
||||
bool stream_has_echo_;
|
||||
bool delay_logging_enabled_;
|
||||
};
|
||||
} // namespace webrtc
|
||||
|
||||
|
@ -93,8 +93,8 @@ void usage() {
|
||||
printf("\n -aec Echo cancellation\n");
|
||||
printf(" --drift_compensation\n");
|
||||
printf(" --no_drift_compensation\n");
|
||||
printf(" --echo_metrics\n");
|
||||
printf(" --no_echo_metrics\n");
|
||||
printf(" --no_delay_logging\n");
|
||||
printf("\n -aecm Echo control mobile\n");
|
||||
printf(" --aecm_echo_path_in_file FILE\n");
|
||||
printf(" --aecm_echo_path_out_file FILE\n");
|
||||
@ -218,6 +218,10 @@ void void_main(int argc, char* argv[]) {
|
||||
|
||||
} else if (strcmp(argv[i], "-aec") == 0) {
|
||||
ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->Enable(true));
|
||||
ASSERT_EQ(apm->kNoError,
|
||||
apm->echo_cancellation()->enable_metrics(true));
|
||||
ASSERT_EQ(apm->kNoError,
|
||||
apm->echo_cancellation()->enable_delay_logging(true));
|
||||
|
||||
} else if (strcmp(argv[i], "--drift_compensation") == 0) {
|
||||
ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->Enable(true));
|
||||
@ -230,16 +234,16 @@ void void_main(int argc, char* argv[]) {
|
||||
ASSERT_EQ(apm->kNoError,
|
||||
apm->echo_cancellation()->enable_drift_compensation(false));
|
||||
|
||||
} else if (strcmp(argv[i], "--echo_metrics") == 0) {
|
||||
ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->Enable(true));
|
||||
ASSERT_EQ(apm->kNoError,
|
||||
apm->echo_cancellation()->enable_metrics(true));
|
||||
|
||||
} else if (strcmp(argv[i], "--no_echo_metrics") == 0) {
|
||||
ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->Enable(true));
|
||||
ASSERT_EQ(apm->kNoError,
|
||||
apm->echo_cancellation()->enable_metrics(false));
|
||||
|
||||
} else if (strcmp(argv[i], "--no_delay_logging") == 0) {
|
||||
ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->Enable(true));
|
||||
ASSERT_EQ(apm->kNoError,
|
||||
apm->echo_cancellation()->enable_delay_logging(false));
|
||||
|
||||
} else if (strcmp(argv[i], "-aecm") == 0) {
|
||||
ASSERT_EQ(apm->kNoError, apm->echo_control_mobile()->Enable(true));
|
||||
|
||||
@ -884,6 +888,14 @@ void void_main(int argc, char* argv[]) {
|
||||
printf("ANLP: ");
|
||||
PrintStat(metrics.a_nlp);
|
||||
}
|
||||
if (apm->echo_cancellation()->is_delay_logging_enabled()) {
|
||||
int median = 0;
|
||||
int std = 0;
|
||||
apm->echo_cancellation()->GetDelayMetrics(&median, &std);
|
||||
printf("\n--Delay metrics--\n");
|
||||
printf("Median: %3d\n", median);
|
||||
printf("Standard deviation: %3d\n", std);
|
||||
}
|
||||
}
|
||||
|
||||
if (!pb_file) {
|
||||
|
@ -457,6 +457,8 @@ TEST_F(ApmTest, Process) {
|
||||
apm_->echo_cancellation()->enable_drift_compensation(true));
|
||||
EXPECT_EQ(apm_->kNoError,
|
||||
apm_->echo_cancellation()->enable_metrics(true));
|
||||
EXPECT_EQ(apm_->kNoError,
|
||||
apm_->echo_cancellation()->enable_delay_logging(true));
|
||||
EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
|
||||
|
||||
EXPECT_EQ(apm_->kNoError,
|
||||
@ -591,6 +593,10 @@ TEST_F(ApmTest, Process) {
|
||||
EchoCancellation::Metrics echo_metrics;
|
||||
EXPECT_EQ(apm_->kNoError,
|
||||
apm_->echo_cancellation()->GetMetrics(&echo_metrics));
|
||||
int median = 0;
|
||||
int std = 0;
|
||||
EXPECT_EQ(apm_->kNoError,
|
||||
apm_->echo_cancellation()->GetDelayMetrics(&median, &std));
|
||||
#endif
|
||||
|
||||
if (!write_output_data) {
|
||||
@ -612,6 +618,11 @@ TEST_F(ApmTest, Process) {
|
||||
reference.echo_return_loss_enhancement());
|
||||
TestStats(echo_metrics.a_nlp,
|
||||
reference.a_nlp());
|
||||
|
||||
webrtc::audioproc::Test::DelayMetrics reference_delay =
|
||||
test->delay_metrics();
|
||||
EXPECT_EQ(median, reference_delay.median());
|
||||
EXPECT_EQ(std, reference_delay.std());
|
||||
#endif
|
||||
} else {
|
||||
test->set_has_echo_count(has_echo_count);
|
||||
@ -632,6 +643,11 @@ TEST_F(ApmTest, Process) {
|
||||
message->mutable_echo_return_loss_enhancement());
|
||||
WriteStatsMessage(echo_metrics.a_nlp,
|
||||
message->mutable_a_nlp());
|
||||
|
||||
webrtc::audioproc::Test::DelayMetrics* message_delay =
|
||||
test->mutable_delay_metrics();
|
||||
message_delay->set_median(median);
|
||||
message_delay->set_std(std);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -696,6 +712,18 @@ TEST_F(ApmTest, EchoCancellation) {
|
||||
apm_->echo_cancellation()->enable_metrics(false));
|
||||
EXPECT_FALSE(apm_->echo_cancellation()->are_metrics_enabled());
|
||||
|
||||
int median = 0;
|
||||
int std = 0;
|
||||
EXPECT_EQ(apm_->kNotEnabledError,
|
||||
apm_->echo_cancellation()->GetDelayMetrics(&median, &std));
|
||||
|
||||
EXPECT_EQ(apm_->kNoError,
|
||||
apm_->echo_cancellation()->enable_delay_logging(true));
|
||||
EXPECT_TRUE(apm_->echo_cancellation()->is_delay_logging_enabled());
|
||||
EXPECT_EQ(apm_->kNoError,
|
||||
apm_->echo_cancellation()->enable_delay_logging(false));
|
||||
EXPECT_FALSE(apm_->echo_cancellation()->is_delay_logging_enabled());
|
||||
|
||||
EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
|
||||
EXPECT_TRUE(apm_->echo_cancellation()->is_enabled());
|
||||
EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(false));
|
||||
|
@ -35,6 +35,13 @@ message Test {
|
||||
}
|
||||
|
||||
optional EchoMetrics echo_metrics = 11;
|
||||
|
||||
message DelayMetrics {
|
||||
optional int32 median = 1;
|
||||
optional int32 std = 2;
|
||||
}
|
||||
|
||||
optional DelayMetrics delay_metrics = 12;
|
||||
}
|
||||
|
||||
message OutputData {
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user