2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
16 #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
17 #include "webrtc/modules/audio_processing/include/audio_processing.h"
18 #include "webrtc/modules/audio_processing/test/test_utils.h"
19 #include "webrtc/modules/interface/module_common_types.h"
20 #include "webrtc/system_wrappers/interface/event_wrapper.h"
21 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
22 #include "webrtc/system_wrappers/interface/trace.h"
23 #include "webrtc/test/testsupport/fileutils.h"
24 #include "webrtc/test/testsupport/gtest_disable.h"
25 #ifdef WEBRTC_ANDROID_PLATFORM_BUILD
26 #include "gtest/gtest.h"
27 #include "external/webrtc/webrtc/modules/audio_processing/test/unittest.pb.h"
29 #include "testing/gtest/include/gtest/gtest.h"
30 #include "webrtc/audio_processing/unittest.pb.h"
33 #if (defined(WEBRTC_AUDIOPROC_FIXED_PROFILE)) || \
34 (defined(WEBRTC_LINUX) && defined(WEBRTC_ARCH_X86_64) && !defined(NDEBUG))
35 # define WEBRTC_AUDIOPROC_BIT_EXACT
38 using webrtc::AudioProcessing;
39 using webrtc::AudioFrame;
41 using webrtc::ExperimentalAgc;
42 using webrtc::GainControl;
43 using webrtc::NoiseSuppression;
44 using webrtc::EchoCancellation;
45 using webrtc::EventWrapper;
46 using webrtc::scoped_array;
47 using webrtc::scoped_ptr;
49 using webrtc::LevelEstimator;
50 using webrtc::EchoCancellation;
51 using webrtc::EchoControlMobile;
52 using webrtc::VoiceDetection;
55 // TODO(bjornv): This is not feasible until the functionality has been
56 // re-implemented; see comment at the bottom of this file.
57 // When false, this will compare the output data with the results stored to
58 // file. This is the typical case. When the file should be updated, it can
59 // be set to true with the command-line switch --write_ref_data.
60 #ifdef WEBRTC_AUDIOPROC_BIT_EXACT
61 bool write_ref_data = false;
62 const int kChannels[] = {1, 2};
63 const size_t kChannelsSize = sizeof(kChannels) / sizeof(*kChannels);
66 const int kSampleRates[] = {8000, 16000, 32000};
67 const size_t kSampleRatesSize = sizeof(kSampleRates) / sizeof(*kSampleRates);
69 #if defined(WEBRTC_AUDIOPROC_FIXED_PROFILE)
70 // AECM doesn't support super-wb.
71 const int kProcessSampleRates[] = {8000, 16000};
72 #elif defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
73 const int kProcessSampleRates[] = {8000, 16000, 32000};
75 const size_t kProcessSampleRatesSize = sizeof(kProcessSampleRates) /
76 sizeof(*kProcessSampleRates);
78 int TruncateToMultipleOf10(int value) {
79 return (value / 10) * 10;
82 // TODO(andrew): Use the MonoToStereo routine from AudioFrameOperations.
83 void MixStereoToMono(const int16_t* stereo,
85 int samples_per_channel) {
86 for (int i = 0; i < samples_per_channel; i++) {
87 int32_t mono_s32 = (static_cast<int32_t>(stereo[i * 2]) +
88 static_cast<int32_t>(stereo[i * 2 + 1])) >> 1;
89 mono[i] = static_cast<int16_t>(mono_s32);
93 void CopyLeftToRightChannel(int16_t* stereo, int samples_per_channel) {
94 for (int i = 0; i < samples_per_channel; i++) {
95 stereo[i * 2 + 1] = stereo[i * 2];
99 void VerifyChannelsAreEqual(int16_t* stereo, int samples_per_channel) {
100 for (int i = 0; i < samples_per_channel; i++) {
101 EXPECT_EQ(stereo[i * 2 + 1], stereo[i * 2]);
105 void SetFrameTo(AudioFrame* frame, int16_t value) {
106 for (int i = 0; i < frame->samples_per_channel_ * frame->num_channels_;
108 frame->data_[i] = value;
112 void SetFrameTo(AudioFrame* frame, int16_t left, int16_t right) {
113 ASSERT_EQ(2, frame->num_channels_);
114 for (int i = 0; i < frame->samples_per_channel_ * 2; i += 2) {
115 frame->data_[i] = left;
116 frame->data_[i + 1] = right;
120 bool FrameDataAreEqual(const AudioFrame& frame1, const AudioFrame& frame2) {
121 if (frame1.samples_per_channel_ !=
122 frame2.samples_per_channel_) {
125 if (frame1.num_channels_ !=
126 frame2.num_channels_) {
129 if (memcmp(frame1.data_, frame2.data_,
130 frame1.samples_per_channel_ * frame1.num_channels_ *
137 #ifdef WEBRTC_AUDIOPROC_BIT_EXACT
138 // These functions are only used by the bit-exact test.
141 return a > 0 ? a: -a;
144 int16_t MaxAudioFrame(const AudioFrame& frame) {
145 const int length = frame.samples_per_channel_ * frame.num_channels_;
146 int16_t max_data = AbsValue(frame.data_[0]);
147 for (int i = 1; i < length; i++) {
148 max_data = std::max(max_data, AbsValue(frame.data_[i]));
154 #if defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
155 void TestStats(const AudioProcessing::Statistic& test,
156 const webrtc::audioproc::Test::Statistic& reference) {
157 EXPECT_EQ(reference.instant(), test.instant);
158 EXPECT_EQ(reference.average(), test.average);
159 EXPECT_EQ(reference.maximum(), test.maximum);
160 EXPECT_EQ(reference.minimum(), test.minimum);
163 void WriteStatsMessage(const AudioProcessing::Statistic& output,
164 webrtc::audioproc::Test::Statistic* message) {
165 message->set_instant(output.instant);
166 message->set_average(output.average);
167 message->set_maximum(output.maximum);
168 message->set_minimum(output.minimum);
172 void WriteMessageLiteToFile(const std::string filename,
173 const ::google::protobuf::MessageLite& message) {
174 FILE* file = fopen(filename.c_str(), "wb");
175 ASSERT_TRUE(file != NULL) << "Could not open " << filename;
176 int size = message.ByteSize();
178 unsigned char* array = new unsigned char[size];
179 ASSERT_TRUE(message.SerializeToArray(array, size));
181 ASSERT_EQ(1u, fwrite(&size, sizeof(int), 1, file));
182 ASSERT_EQ(static_cast<size_t>(size),
183 fwrite(array, sizeof(unsigned char), size, file));
189 void ReadMessageLiteFromFile(const std::string filename,
190 ::google::protobuf::MessageLite* message) {
191 assert(message != NULL);
193 FILE* file = fopen(filename.c_str(), "rb");
194 ASSERT_TRUE(file != NULL) << "Could not open " << filename;
196 ASSERT_EQ(1u, fread(&size, sizeof(int), 1, file));
198 unsigned char* array = new unsigned char[size];
199 ASSERT_EQ(static_cast<size_t>(size),
200 fread(array, sizeof(unsigned char), size, file));
202 ASSERT_TRUE(message->ParseFromArray(array, size));
207 #endif // WEBRTC_AUDIOPROC_BIT_EXACT
209 class ApmTest : public ::testing::Test {
212 virtual void SetUp();
213 virtual void TearDown();
215 static void SetUpTestCase() {
216 Trace::CreateTrace();
217 std::string trace_filename = webrtc::test::OutputPath() +
218 "audioproc_trace.txt";
219 ASSERT_EQ(0, Trace::SetTraceFile(trace_filename.c_str()));
222 static void TearDownTestCase() {
223 Trace::ReturnTrace();
226 void Init(int sample_rate_hz, int num_reverse_channels,
227 int num_input_channels, int num_output_channels,
228 bool open_output_file);
229 std::string ResourceFilePath(std::string name, int sample_rate_hz);
230 std::string OutputFilePath(std::string name,
232 int num_reverse_channels,
233 int num_input_channels,
234 int num_output_channels);
235 void EnableAllComponents();
236 bool ReadFrame(FILE* file, AudioFrame* frame);
237 void ProcessWithDefaultStreamParameters(AudioFrame* frame);
238 void ProcessDelayVerificationTest(int delay_ms, int system_delay_ms,
239 int delay_min, int delay_max);
240 void TestChangingChannels(int num_channels,
241 AudioProcessing::Error expected_return);
243 const std::string output_path_;
244 const std::string ref_path_;
245 const std::string ref_filename_;
246 scoped_ptr<webrtc::AudioProcessing> apm_;
248 AudioFrame* revframe_;
255 : output_path_(webrtc::test::OutputPath()),
256 ref_path_(webrtc::test::ProjectRootPath() +
257 "data/audio_processing/"),
258 #if defined(WEBRTC_AUDIOPROC_FIXED_PROFILE)
259 ref_filename_(ref_path_ + "output_data_fixed.pb"),
260 #elif defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
261 ref_filename_(ref_path_ + "output_data_float.pb"),
269 config.Set<ExperimentalAgc>(new ExperimentalAgc(false));
270 apm_.reset(AudioProcessing::Create(config));
273 void ApmTest::SetUp() {
274 ASSERT_TRUE(apm_.get() != NULL);
276 frame_ = new AudioFrame();
277 revframe_ = new AudioFrame();
279 #if defined(WEBRTC_AUDIOPROC_FIXED_PROFILE)
280 Init(16000, 2, 2, 2, false);
282 Init(32000, 2, 2, 2, false);
286 void ApmTest::TearDown() {
298 ASSERT_EQ(0, fclose(far_file_));
303 ASSERT_EQ(0, fclose(near_file_));
308 ASSERT_EQ(0, fclose(out_file_));
313 std::string ApmTest::ResourceFilePath(std::string name, int sample_rate_hz) {
314 std::ostringstream ss;
315 // Resource files are all stereo.
316 ss << name << sample_rate_hz / 1000 << "_stereo";
317 return webrtc::test::ResourcePath(ss.str(), "pcm");
320 std::string ApmTest::OutputFilePath(std::string name,
322 int num_reverse_channels,
323 int num_input_channels,
324 int num_output_channels) {
325 std::ostringstream ss;
326 ss << name << sample_rate_hz / 1000 << "_" << num_reverse_channels << "r" <<
327 num_input_channels << "i" << "_";
328 if (num_output_channels == 1) {
330 } else if (num_output_channels == 2) {
338 return output_path_ + ss.str();
341 void ApmTest::Init(int sample_rate_hz, int num_reverse_channels,
342 int num_input_channels, int num_output_channels,
343 bool open_output_file) {
344 // We always use 10 ms frames.
345 const int samples_per_channel = kChunkSizeMs * sample_rate_hz / 1000;
346 frame_->samples_per_channel_ = samples_per_channel;
347 frame_->num_channels_ = num_input_channels;
348 frame_->sample_rate_hz_ = sample_rate_hz;
349 revframe_->samples_per_channel_ = samples_per_channel;
350 revframe_->num_channels_ = num_reverse_channels;
351 revframe_->sample_rate_hz_ = sample_rate_hz;
353 // Make one process call to ensure the audio parameters are set. It might
354 // result in a stream error which we can safely ignore.
355 int err = apm_->ProcessStream(frame_);
356 ASSERT_TRUE(err == kNoErr || err == apm_->kStreamParameterNotSetError);
357 ASSERT_EQ(apm_->kNoError, apm_->Initialize());
360 ASSERT_EQ(0, fclose(far_file_));
362 std::string filename = ResourceFilePath("far", sample_rate_hz);
363 far_file_ = fopen(filename.c_str(), "rb");
364 ASSERT_TRUE(far_file_ != NULL) << "Could not open file " <<
368 ASSERT_EQ(0, fclose(near_file_));
370 filename = ResourceFilePath("near", sample_rate_hz);
371 near_file_ = fopen(filename.c_str(), "rb");
372 ASSERT_TRUE(near_file_ != NULL) << "Could not open file " <<
375 if (open_output_file) {
377 ASSERT_EQ(0, fclose(out_file_));
379 filename = OutputFilePath("out", sample_rate_hz, num_reverse_channels,
380 num_input_channels, num_output_channels);
381 out_file_ = fopen(filename.c_str(), "wb");
382 ASSERT_TRUE(out_file_ != NULL) << "Could not open file " <<
387 void ApmTest::EnableAllComponents() {
388 #if defined(WEBRTC_AUDIOPROC_FIXED_PROFILE)
389 EXPECT_EQ(apm_->kNoError, apm_->echo_control_mobile()->Enable(true));
391 EXPECT_EQ(apm_->kNoError,
392 apm_->gain_control()->set_mode(GainControl::kAdaptiveDigital));
393 EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
394 #elif defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
395 EXPECT_EQ(apm_->kNoError,
396 apm_->echo_cancellation()->enable_drift_compensation(true));
397 EXPECT_EQ(apm_->kNoError,
398 apm_->echo_cancellation()->enable_metrics(true));
399 EXPECT_EQ(apm_->kNoError,
400 apm_->echo_cancellation()->enable_delay_logging(true));
401 EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
403 EXPECT_EQ(apm_->kNoError,
404 apm_->gain_control()->set_mode(GainControl::kAdaptiveAnalog));
405 EXPECT_EQ(apm_->kNoError,
406 apm_->gain_control()->set_analog_level_limits(0, 255));
407 EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
410 EXPECT_EQ(apm_->kNoError,
411 apm_->high_pass_filter()->Enable(true));
413 EXPECT_EQ(apm_->kNoError,
414 apm_->level_estimator()->Enable(true));
416 EXPECT_EQ(apm_->kNoError,
417 apm_->noise_suppression()->Enable(true));
419 EXPECT_EQ(apm_->kNoError,
420 apm_->voice_detection()->Enable(true));
423 bool ApmTest::ReadFrame(FILE* file, AudioFrame* frame) {
424 // The files always contain stereo audio.
425 size_t frame_size = frame->samples_per_channel_ * 2;
426 size_t read_count = fread(frame->data_,
430 if (read_count != frame_size) {
431 // Check that the file really ended.
432 EXPECT_NE(0, feof(file));
433 return false; // This is expected.
436 if (frame->num_channels_ == 1) {
437 MixStereoToMono(frame->data_, frame->data_,
438 frame->samples_per_channel_);
444 void ApmTest::ProcessWithDefaultStreamParameters(AudioFrame* frame) {
445 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
446 apm_->echo_cancellation()->set_stream_drift_samples(0);
447 EXPECT_EQ(apm_->kNoError,
448 apm_->gain_control()->set_stream_analog_level(127));
449 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame));
452 void ApmTest::ProcessDelayVerificationTest(int delay_ms, int system_delay_ms,
453 int delay_min, int delay_max) {
454 // The |revframe_| and |frame_| should include the proper frame information,
455 // hence can be used for extracting information.
456 webrtc::AudioFrame tmp_frame;
457 std::queue<webrtc::AudioFrame*> frame_queue;
460 tmp_frame.CopyFrom(*revframe_);
461 SetFrameTo(&tmp_frame, 0);
463 EXPECT_EQ(apm_->kNoError, apm_->Initialize());
464 // Initialize the |frame_queue| with empty frames.
465 int frame_delay = delay_ms / 10;
466 while (frame_delay < 0) {
467 webrtc::AudioFrame* frame = new AudioFrame();
468 frame->CopyFrom(tmp_frame);
469 frame_queue.push(frame);
473 while (frame_delay > 0) {
474 webrtc::AudioFrame* frame = new AudioFrame();
475 frame->CopyFrom(tmp_frame);
476 frame_queue.push(frame);
479 // Run for 4.5 seconds, skipping statistics from the first 2.5 seconds. We
480 // need enough frames with audio to have reliable estimates, but as few as
481 // possible to keep processing time down. 4.5 seconds seemed to be a good
482 // compromise for this recording.
483 for (int frame_count = 0; frame_count < 450; ++frame_count) {
484 webrtc::AudioFrame* frame = new AudioFrame();
485 frame->CopyFrom(tmp_frame);
486 // Use the near end recording, since that has more speech in it.
487 ASSERT_TRUE(ReadFrame(near_file_, frame));
488 frame_queue.push(frame);
489 webrtc::AudioFrame* reverse_frame = frame;
490 webrtc::AudioFrame* process_frame = frame_queue.front();
492 reverse_frame = frame_queue.front();
493 // When we call ProcessStream() the frame is modified, so we can't use the
494 // pointer directly when things are non-causal. Use an intermediate frame
495 // and copy the data.
496 process_frame = &tmp_frame;
497 process_frame->CopyFrom(*frame);
499 EXPECT_EQ(apm_->kNoError, apm_->AnalyzeReverseStream(reverse_frame));
500 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(system_delay_ms));
501 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(process_frame));
502 frame = frame_queue.front();
506 if (frame_count == 250) {
509 // Discard the first delay metrics to avoid convergence effects.
510 EXPECT_EQ(apm_->kNoError,
511 apm_->echo_cancellation()->GetDelayMetrics(&median, &std));
516 while (!frame_queue.empty()) {
517 webrtc::AudioFrame* frame = frame_queue.front();
521 // Calculate expected delay estimate and acceptable regions. Further,
522 // limit them w.r.t. AEC delay estimation support.
523 const int samples_per_ms = std::min(16, frame_->samples_per_channel_ / 10);
524 int expected_median = std::min(std::max(delay_ms - system_delay_ms,
525 delay_min), delay_max);
526 int expected_median_high = std::min(std::max(
527 expected_median + 96 / samples_per_ms, delay_min), delay_max);
528 int expected_median_low = std::min(std::max(
529 expected_median - 96 / samples_per_ms, delay_min), delay_max);
530 // Verify delay metrics.
533 EXPECT_EQ(apm_->kNoError,
534 apm_->echo_cancellation()->GetDelayMetrics(&median, &std));
535 EXPECT_GE(expected_median_high, median);
536 EXPECT_LE(expected_median_low, median);
539 TEST_F(ApmTest, StreamParameters) {
540 // No errors when the components are disabled.
541 EXPECT_EQ(apm_->kNoError,
542 apm_->ProcessStream(frame_));
544 // -- Missing AGC level --
545 EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
546 EXPECT_EQ(apm_->kStreamParameterNotSetError, apm_->ProcessStream(frame_));
548 // Resets after successful ProcessStream().
549 EXPECT_EQ(apm_->kNoError,
550 apm_->gain_control()->set_stream_analog_level(127));
551 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
552 EXPECT_EQ(apm_->kStreamParameterNotSetError, apm_->ProcessStream(frame_));
554 // Other stream parameters set correctly.
555 EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
556 EXPECT_EQ(apm_->kNoError,
557 apm_->echo_cancellation()->enable_drift_compensation(true));
558 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
559 apm_->echo_cancellation()->set_stream_drift_samples(0);
560 EXPECT_EQ(apm_->kStreamParameterNotSetError,
561 apm_->ProcessStream(frame_));
562 EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(false));
563 EXPECT_EQ(apm_->kNoError,
564 apm_->echo_cancellation()->enable_drift_compensation(false));
566 // -- Missing delay --
567 EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
568 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
569 EXPECT_EQ(apm_->kStreamParameterNotSetError, apm_->ProcessStream(frame_));
571 // Resets after successful ProcessStream().
572 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
573 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
574 EXPECT_EQ(apm_->kStreamParameterNotSetError, apm_->ProcessStream(frame_));
576 // Other stream parameters set correctly.
577 EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
578 EXPECT_EQ(apm_->kNoError,
579 apm_->echo_cancellation()->enable_drift_compensation(true));
580 apm_->echo_cancellation()->set_stream_drift_samples(0);
581 EXPECT_EQ(apm_->kNoError,
582 apm_->gain_control()->set_stream_analog_level(127));
583 EXPECT_EQ(apm_->kStreamParameterNotSetError, apm_->ProcessStream(frame_));
584 EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(false));
586 // -- Missing drift --
587 EXPECT_EQ(apm_->kStreamParameterNotSetError, apm_->ProcessStream(frame_));
589 // Resets after successful ProcessStream().
590 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
591 apm_->echo_cancellation()->set_stream_drift_samples(0);
592 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
593 EXPECT_EQ(apm_->kStreamParameterNotSetError, apm_->ProcessStream(frame_));
595 // Other stream parameters set correctly.
596 EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
597 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
598 EXPECT_EQ(apm_->kNoError,
599 apm_->gain_control()->set_stream_analog_level(127));
600 EXPECT_EQ(apm_->kStreamParameterNotSetError, apm_->ProcessStream(frame_));
602 // -- No stream parameters --
603 EXPECT_EQ(apm_->kNoError,
604 apm_->AnalyzeReverseStream(revframe_));
605 EXPECT_EQ(apm_->kStreamParameterNotSetError,
606 apm_->ProcessStream(frame_));
609 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
610 apm_->echo_cancellation()->set_stream_drift_samples(0);
611 EXPECT_EQ(apm_->kNoError,
612 apm_->gain_control()->set_stream_analog_level(127));
613 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
616 TEST_F(ApmTest, DefaultDelayOffsetIsZero) {
617 EXPECT_EQ(0, apm_->delay_offset_ms());
618 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(50));
619 EXPECT_EQ(50, apm_->stream_delay_ms());
622 TEST_F(ApmTest, DelayOffsetWithLimitsIsSetProperly) {
623 // High limit of 500 ms.
624 apm_->set_delay_offset_ms(100);
625 EXPECT_EQ(100, apm_->delay_offset_ms());
626 EXPECT_EQ(apm_->kBadStreamParameterWarning, apm_->set_stream_delay_ms(450));
627 EXPECT_EQ(500, apm_->stream_delay_ms());
628 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
629 EXPECT_EQ(200, apm_->stream_delay_ms());
631 // Low limit of 0 ms.
632 apm_->set_delay_offset_ms(-50);
633 EXPECT_EQ(-50, apm_->delay_offset_ms());
634 EXPECT_EQ(apm_->kBadStreamParameterWarning, apm_->set_stream_delay_ms(20));
635 EXPECT_EQ(0, apm_->stream_delay_ms());
636 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
637 EXPECT_EQ(50, apm_->stream_delay_ms());
640 void ApmTest::TestChangingChannels(int num_channels,
641 AudioProcessing::Error expected_return) {
642 frame_->num_channels_ = num_channels;
643 EXPECT_EQ(expected_return, apm_->ProcessStream(frame_));
644 EXPECT_EQ(expected_return, apm_->AnalyzeReverseStream(frame_));
647 TEST_F(ApmTest, Channels) {
648 // Testing number of invalid channels.
649 TestChangingChannels(0, apm_->kBadNumberChannelsError);
650 TestChangingChannels(3, apm_->kBadNumberChannelsError);
651 // Testing number of valid channels.
652 for (int i = 1; i < 3; i++) {
653 TestChangingChannels(i, kNoErr);
654 EXPECT_EQ(i, apm_->num_input_channels());
655 EXPECT_EQ(i, apm_->num_reverse_channels());
659 TEST_F(ApmTest, SampleRates) {
660 // Testing invalid sample rates
661 SetFrameSampleRate(frame_, 10000);
662 EXPECT_EQ(apm_->kBadSampleRateError, apm_->ProcessStream(frame_));
663 // Testing valid sample rates
664 int fs[] = {8000, 16000, 32000};
665 for (size_t i = 0; i < sizeof(fs) / sizeof(*fs); i++) {
666 SetFrameSampleRate(frame_, fs[i]);
667 EXPECT_EQ(kNoErr, apm_->ProcessStream(frame_));
668 EXPECT_EQ(fs[i], apm_->sample_rate_hz());
672 TEST_F(ApmTest, EchoCancellation) {
673 EXPECT_EQ(apm_->kNoError,
674 apm_->echo_cancellation()->enable_drift_compensation(true));
675 EXPECT_TRUE(apm_->echo_cancellation()->is_drift_compensation_enabled());
676 EXPECT_EQ(apm_->kNoError,
677 apm_->echo_cancellation()->enable_drift_compensation(false));
678 EXPECT_FALSE(apm_->echo_cancellation()->is_drift_compensation_enabled());
680 EXPECT_EQ(apm_->kBadParameterError,
681 apm_->echo_cancellation()->set_device_sample_rate_hz(4000));
682 EXPECT_EQ(apm_->kBadParameterError,
683 apm_->echo_cancellation()->set_device_sample_rate_hz(100000));
685 int rate[] = {16000, 44100, 48000};
686 for (size_t i = 0; i < sizeof(rate)/sizeof(*rate); i++) {
687 EXPECT_EQ(apm_->kNoError,
688 apm_->echo_cancellation()->set_device_sample_rate_hz(rate[i]));
690 apm_->echo_cancellation()->device_sample_rate_hz());
693 EchoCancellation::SuppressionLevel level[] = {
694 EchoCancellation::kLowSuppression,
695 EchoCancellation::kModerateSuppression,
696 EchoCancellation::kHighSuppression,
698 for (size_t i = 0; i < sizeof(level)/sizeof(*level); i++) {
699 EXPECT_EQ(apm_->kNoError,
700 apm_->echo_cancellation()->set_suppression_level(level[i]));
702 apm_->echo_cancellation()->suppression_level());
705 EchoCancellation::Metrics metrics;
706 EXPECT_EQ(apm_->kNotEnabledError,
707 apm_->echo_cancellation()->GetMetrics(&metrics));
709 EXPECT_EQ(apm_->kNoError,
710 apm_->echo_cancellation()->enable_metrics(true));
711 EXPECT_TRUE(apm_->echo_cancellation()->are_metrics_enabled());
712 EXPECT_EQ(apm_->kNoError,
713 apm_->echo_cancellation()->enable_metrics(false));
714 EXPECT_FALSE(apm_->echo_cancellation()->are_metrics_enabled());
718 EXPECT_EQ(apm_->kNotEnabledError,
719 apm_->echo_cancellation()->GetDelayMetrics(&median, &std));
721 EXPECT_EQ(apm_->kNoError,
722 apm_->echo_cancellation()->enable_delay_logging(true));
723 EXPECT_TRUE(apm_->echo_cancellation()->is_delay_logging_enabled());
724 EXPECT_EQ(apm_->kNoError,
725 apm_->echo_cancellation()->enable_delay_logging(false));
726 EXPECT_FALSE(apm_->echo_cancellation()->is_delay_logging_enabled());
728 EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
729 EXPECT_TRUE(apm_->echo_cancellation()->is_enabled());
730 EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(false));
731 EXPECT_FALSE(apm_->echo_cancellation()->is_enabled());
733 EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
734 EXPECT_TRUE(apm_->echo_cancellation()->is_enabled());
735 EXPECT_TRUE(apm_->echo_cancellation()->aec_core() != NULL);
736 EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(false));
737 EXPECT_FALSE(apm_->echo_cancellation()->is_enabled());
738 EXPECT_FALSE(apm_->echo_cancellation()->aec_core() != NULL);
741 TEST_F(ApmTest, EchoCancellationReportsCorrectDelays) {
743 EXPECT_EQ(apm_->kNoError,
744 apm_->echo_cancellation()->enable_drift_compensation(false));
745 EXPECT_EQ(apm_->kNoError,
746 apm_->echo_cancellation()->enable_metrics(false));
747 EXPECT_EQ(apm_->kNoError,
748 apm_->echo_cancellation()->enable_delay_logging(true));
749 EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
751 // Internally in the AEC the amount of lookahead the delay estimation can
752 // handle is 15 blocks and the maximum delay is set to 60 blocks.
753 const int kLookaheadBlocks = 15;
754 const int kMaxDelayBlocks = 60;
755 // The AEC has a startup time before it actually starts to process. This
756 // procedure can flush the internal far-end buffer, which of course affects
757 // the delay estimation. Therefore, we set a system_delay high enough to
758 // avoid that. The smallest system_delay you can report without flushing the
759 // buffer is 66 ms in 8 kHz.
761 // It is known that for 16 kHz (and 32 kHz) sampling frequency there is an
762 // additional stuffing of 8 ms on the fly, but it seems to have no impact on
763 // delay estimation. This should be noted though. In case of test failure,
764 // this could be the cause.
765 const int kSystemDelayMs = 66;
766 // Test a couple of corner cases and verify that the estimated delay is
767 // within a valid region (set to +-1.5 blocks). Note that these cases are
768 // sampling frequency dependent.
769 for (size_t i = 0; i < kProcessSampleRatesSize; i++) {
770 Init(kProcessSampleRates[i], 2, 2, 2, false);
771 // Sampling frequency dependent variables.
772 const int num_ms_per_block = std::max(4,
773 640 / frame_->samples_per_channel_);
774 const int delay_min_ms = -kLookaheadBlocks * num_ms_per_block;
775 const int delay_max_ms = (kMaxDelayBlocks - 1) * num_ms_per_block;
777 // 1) Verify correct delay estimate at lookahead boundary.
778 int delay_ms = TruncateToMultipleOf10(kSystemDelayMs + delay_min_ms);
779 ProcessDelayVerificationTest(delay_ms, kSystemDelayMs, delay_min_ms,
781 // 2) A delay less than maximum lookahead should give an delay estimate at
782 // the boundary (= -kLookaheadBlocks * num_ms_per_block).
784 ProcessDelayVerificationTest(delay_ms, kSystemDelayMs, delay_min_ms,
786 // 3) Three values around zero delay. Note that we need to compensate for
787 // the fake system_delay.
788 delay_ms = TruncateToMultipleOf10(kSystemDelayMs - 10);
789 ProcessDelayVerificationTest(delay_ms, kSystemDelayMs, delay_min_ms,
791 delay_ms = TruncateToMultipleOf10(kSystemDelayMs);
792 ProcessDelayVerificationTest(delay_ms, kSystemDelayMs, delay_min_ms,
794 delay_ms = TruncateToMultipleOf10(kSystemDelayMs + 10);
795 ProcessDelayVerificationTest(delay_ms, kSystemDelayMs, delay_min_ms,
797 // 4) Verify correct delay estimate at maximum delay boundary.
798 delay_ms = TruncateToMultipleOf10(kSystemDelayMs + delay_max_ms);
799 ProcessDelayVerificationTest(delay_ms, kSystemDelayMs, delay_min_ms,
801 // 5) A delay above the maximum delay should give an estimate at the
802 // boundary (= (kMaxDelayBlocks - 1) * num_ms_per_block).
804 ProcessDelayVerificationTest(delay_ms, kSystemDelayMs, delay_min_ms,
809 TEST_F(ApmTest, EchoControlMobile) {
810 // AECM won't use super-wideband.
811 SetFrameSampleRate(frame_, 32000);
812 EXPECT_EQ(kNoErr, apm_->ProcessStream(frame_));
813 EXPECT_EQ(apm_->kBadSampleRateError,
814 apm_->echo_control_mobile()->Enable(true));
815 SetFrameSampleRate(frame_, 16000);
816 EXPECT_EQ(kNoErr, apm_->ProcessStream(frame_));
817 EXPECT_EQ(apm_->kNoError,
818 apm_->echo_control_mobile()->Enable(true));
819 SetFrameSampleRate(frame_, 32000);
820 EXPECT_EQ(apm_->kUnsupportedComponentError, apm_->ProcessStream(frame_));
822 // Turn AECM on (and AEC off)
823 Init(16000, 2, 2, 2, false);
824 EXPECT_EQ(apm_->kNoError, apm_->echo_control_mobile()->Enable(true));
825 EXPECT_TRUE(apm_->echo_control_mobile()->is_enabled());
827 // Toggle routing modes
828 EchoControlMobile::RoutingMode mode[] = {
829 EchoControlMobile::kQuietEarpieceOrHeadset,
830 EchoControlMobile::kEarpiece,
831 EchoControlMobile::kLoudEarpiece,
832 EchoControlMobile::kSpeakerphone,
833 EchoControlMobile::kLoudSpeakerphone,
835 for (size_t i = 0; i < sizeof(mode)/sizeof(*mode); i++) {
836 EXPECT_EQ(apm_->kNoError,
837 apm_->echo_control_mobile()->set_routing_mode(mode[i]));
839 apm_->echo_control_mobile()->routing_mode());
841 // Turn comfort noise off/on
842 EXPECT_EQ(apm_->kNoError,
843 apm_->echo_control_mobile()->enable_comfort_noise(false));
844 EXPECT_FALSE(apm_->echo_control_mobile()->is_comfort_noise_enabled());
845 EXPECT_EQ(apm_->kNoError,
846 apm_->echo_control_mobile()->enable_comfort_noise(true));
847 EXPECT_TRUE(apm_->echo_control_mobile()->is_comfort_noise_enabled());
848 // Set and get echo path
849 const size_t echo_path_size =
850 apm_->echo_control_mobile()->echo_path_size_bytes();
851 scoped_array<char> echo_path_in(new char[echo_path_size]);
852 scoped_array<char> echo_path_out(new char[echo_path_size]);
853 EXPECT_EQ(apm_->kNullPointerError,
854 apm_->echo_control_mobile()->SetEchoPath(NULL, echo_path_size));
855 EXPECT_EQ(apm_->kNullPointerError,
856 apm_->echo_control_mobile()->GetEchoPath(NULL, echo_path_size));
857 EXPECT_EQ(apm_->kBadParameterError,
858 apm_->echo_control_mobile()->GetEchoPath(echo_path_out.get(), 1));
859 EXPECT_EQ(apm_->kNoError,
860 apm_->echo_control_mobile()->GetEchoPath(echo_path_out.get(),
862 for (size_t i = 0; i < echo_path_size; i++) {
863 echo_path_in[i] = echo_path_out[i] + 1;
865 EXPECT_EQ(apm_->kBadParameterError,
866 apm_->echo_control_mobile()->SetEchoPath(echo_path_in.get(), 1));
867 EXPECT_EQ(apm_->kNoError,
868 apm_->echo_control_mobile()->SetEchoPath(echo_path_in.get(),
870 EXPECT_EQ(apm_->kNoError,
871 apm_->echo_control_mobile()->GetEchoPath(echo_path_out.get(),
873 for (size_t i = 0; i < echo_path_size; i++) {
874 EXPECT_EQ(echo_path_in[i], echo_path_out[i]);
877 // Process a few frames with NS in the default disabled state. This exercises
878 // a different codepath than with it enabled.
879 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
880 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
881 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
882 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
885 EXPECT_EQ(apm_->kNoError, apm_->echo_control_mobile()->Enable(false));
886 EXPECT_FALSE(apm_->echo_control_mobile()->is_enabled());
889 TEST_F(ApmTest, GainControl) {
890 // Testing gain modes
891 EXPECT_EQ(apm_->kNoError,
892 apm_->gain_control()->set_mode(
893 apm_->gain_control()->mode()));
895 GainControl::Mode mode[] = {
896 GainControl::kAdaptiveAnalog,
897 GainControl::kAdaptiveDigital,
898 GainControl::kFixedDigital
900 for (size_t i = 0; i < sizeof(mode)/sizeof(*mode); i++) {
901 EXPECT_EQ(apm_->kNoError,
902 apm_->gain_control()->set_mode(mode[i]));
903 EXPECT_EQ(mode[i], apm_->gain_control()->mode());
905 // Testing invalid target levels
906 EXPECT_EQ(apm_->kBadParameterError,
907 apm_->gain_control()->set_target_level_dbfs(-3));
908 EXPECT_EQ(apm_->kBadParameterError,
909 apm_->gain_control()->set_target_level_dbfs(-40));
910 // Testing valid target levels
911 EXPECT_EQ(apm_->kNoError,
912 apm_->gain_control()->set_target_level_dbfs(
913 apm_->gain_control()->target_level_dbfs()));
915 int level_dbfs[] = {0, 6, 31};
916 for (size_t i = 0; i < sizeof(level_dbfs)/sizeof(*level_dbfs); i++) {
917 EXPECT_EQ(apm_->kNoError,
918 apm_->gain_control()->set_target_level_dbfs(level_dbfs[i]));
919 EXPECT_EQ(level_dbfs[i], apm_->gain_control()->target_level_dbfs());
922 // Testing invalid compression gains
923 EXPECT_EQ(apm_->kBadParameterError,
924 apm_->gain_control()->set_compression_gain_db(-1));
925 EXPECT_EQ(apm_->kBadParameterError,
926 apm_->gain_control()->set_compression_gain_db(100));
928 // Testing valid compression gains
929 EXPECT_EQ(apm_->kNoError,
930 apm_->gain_control()->set_compression_gain_db(
931 apm_->gain_control()->compression_gain_db()));
933 int gain_db[] = {0, 10, 90};
934 for (size_t i = 0; i < sizeof(gain_db)/sizeof(*gain_db); i++) {
935 EXPECT_EQ(apm_->kNoError,
936 apm_->gain_control()->set_compression_gain_db(gain_db[i]));
937 EXPECT_EQ(gain_db[i], apm_->gain_control()->compression_gain_db());
940 // Testing limiter off/on
941 EXPECT_EQ(apm_->kNoError, apm_->gain_control()->enable_limiter(false));
942 EXPECT_FALSE(apm_->gain_control()->is_limiter_enabled());
943 EXPECT_EQ(apm_->kNoError, apm_->gain_control()->enable_limiter(true));
944 EXPECT_TRUE(apm_->gain_control()->is_limiter_enabled());
946 // Testing invalid level limits
947 EXPECT_EQ(apm_->kBadParameterError,
948 apm_->gain_control()->set_analog_level_limits(-1, 512));
949 EXPECT_EQ(apm_->kBadParameterError,
950 apm_->gain_control()->set_analog_level_limits(100000, 512));
951 EXPECT_EQ(apm_->kBadParameterError,
952 apm_->gain_control()->set_analog_level_limits(512, -1));
953 EXPECT_EQ(apm_->kBadParameterError,
954 apm_->gain_control()->set_analog_level_limits(512, 100000));
955 EXPECT_EQ(apm_->kBadParameterError,
956 apm_->gain_control()->set_analog_level_limits(512, 255));
958 // Testing valid level limits
959 EXPECT_EQ(apm_->kNoError,
960 apm_->gain_control()->set_analog_level_limits(
961 apm_->gain_control()->analog_level_minimum(),
962 apm_->gain_control()->analog_level_maximum()));
964 int min_level[] = {0, 255, 1024};
965 for (size_t i = 0; i < sizeof(min_level)/sizeof(*min_level); i++) {
966 EXPECT_EQ(apm_->kNoError,
967 apm_->gain_control()->set_analog_level_limits(min_level[i], 1024));
968 EXPECT_EQ(min_level[i], apm_->gain_control()->analog_level_minimum());
971 int max_level[] = {0, 1024, 65535};
972 for (size_t i = 0; i < sizeof(min_level)/sizeof(*min_level); i++) {
973 EXPECT_EQ(apm_->kNoError,
974 apm_->gain_control()->set_analog_level_limits(0, max_level[i]));
975 EXPECT_EQ(max_level[i], apm_->gain_control()->analog_level_maximum());
978 // TODO(ajm): stream_is_saturated() and stream_analog_level()
981 EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(false));
982 EXPECT_FALSE(apm_->gain_control()->is_enabled());
985 TEST_F(ApmTest, NoiseSuppression) {
986 // Test valid suppression levels.
987 NoiseSuppression::Level level[] = {
988 NoiseSuppression::kLow,
989 NoiseSuppression::kModerate,
990 NoiseSuppression::kHigh,
991 NoiseSuppression::kVeryHigh
993 for (size_t i = 0; i < sizeof(level)/sizeof(*level); i++) {
994 EXPECT_EQ(apm_->kNoError,
995 apm_->noise_suppression()->set_level(level[i]));
996 EXPECT_EQ(level[i], apm_->noise_suppression()->level());
1000 EXPECT_EQ(apm_->kNoError, apm_->noise_suppression()->Enable(true));
1001 EXPECT_TRUE(apm_->noise_suppression()->is_enabled());
1002 EXPECT_EQ(apm_->kNoError, apm_->noise_suppression()->Enable(false));
1003 EXPECT_FALSE(apm_->noise_suppression()->is_enabled());
1006 TEST_F(ApmTest, HighPassFilter) {
1007 // Turn HP filter on/off
1008 EXPECT_EQ(apm_->kNoError, apm_->high_pass_filter()->Enable(true));
1009 EXPECT_TRUE(apm_->high_pass_filter()->is_enabled());
1010 EXPECT_EQ(apm_->kNoError, apm_->high_pass_filter()->Enable(false));
1011 EXPECT_FALSE(apm_->high_pass_filter()->is_enabled());
1014 TEST_F(ApmTest, LevelEstimator) {
1015 // Turn level estimator on/off
1016 EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(false));
1017 EXPECT_FALSE(apm_->level_estimator()->is_enabled());
1019 EXPECT_EQ(apm_->kNotEnabledError, apm_->level_estimator()->RMS());
1021 EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(true));
1022 EXPECT_TRUE(apm_->level_estimator()->is_enabled());
1024 // Run this test in wideband; in super-wb, the splitting filter distorts the
1025 // audio enough to cause deviation from the expectation for small values.
1026 frame_->samples_per_channel_ = 160;
1027 frame_->num_channels_ = 2;
1028 frame_->sample_rate_hz_ = 16000;
1030 // Min value if no frames have been processed.
1031 EXPECT_EQ(127, apm_->level_estimator()->RMS());
1033 // Min value on zero frames.
1034 SetFrameTo(frame_, 0);
1035 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1036 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1037 EXPECT_EQ(127, apm_->level_estimator()->RMS());
1039 // Try a few RMS values.
1040 // (These also test that the value resets after retrieving it.)
1041 SetFrameTo(frame_, 32767);
1042 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1043 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1044 EXPECT_EQ(0, apm_->level_estimator()->RMS());
1046 SetFrameTo(frame_, 30000);
1047 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1048 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1049 EXPECT_EQ(1, apm_->level_estimator()->RMS());
1051 SetFrameTo(frame_, 10000);
1052 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1053 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1054 EXPECT_EQ(10, apm_->level_estimator()->RMS());
1056 SetFrameTo(frame_, 10);
1057 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1058 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1059 EXPECT_EQ(70, apm_->level_estimator()->RMS());
1061 // Min value if energy_ == 0.
1062 SetFrameTo(frame_, 10000);
1063 uint32_t energy = frame_->energy_; // Save default to restore below.
1064 frame_->energy_ = 0;
1065 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1066 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1067 EXPECT_EQ(127, apm_->level_estimator()->RMS());
1068 frame_->energy_ = energy;
1070 // Verify reset after enable/disable.
1071 SetFrameTo(frame_, 32767);
1072 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1073 EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(false));
1074 EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(true));
1075 SetFrameTo(frame_, 1);
1076 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1077 EXPECT_EQ(90, apm_->level_estimator()->RMS());
1079 // Verify reset after initialize.
1080 SetFrameTo(frame_, 32767);
1081 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1082 EXPECT_EQ(apm_->kNoError, apm_->Initialize());
1083 SetFrameTo(frame_, 1);
1084 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1085 EXPECT_EQ(90, apm_->level_estimator()->RMS());
1088 TEST_F(ApmTest, VoiceDetection) {
1089 // Test external VAD
1090 EXPECT_EQ(apm_->kNoError,
1091 apm_->voice_detection()->set_stream_has_voice(true));
1092 EXPECT_TRUE(apm_->voice_detection()->stream_has_voice());
1093 EXPECT_EQ(apm_->kNoError,
1094 apm_->voice_detection()->set_stream_has_voice(false));
1095 EXPECT_FALSE(apm_->voice_detection()->stream_has_voice());
1097 // Test valid likelihoods
1098 VoiceDetection::Likelihood likelihood[] = {
1099 VoiceDetection::kVeryLowLikelihood,
1100 VoiceDetection::kLowLikelihood,
1101 VoiceDetection::kModerateLikelihood,
1102 VoiceDetection::kHighLikelihood
1104 for (size_t i = 0; i < sizeof(likelihood)/sizeof(*likelihood); i++) {
1105 EXPECT_EQ(apm_->kNoError,
1106 apm_->voice_detection()->set_likelihood(likelihood[i]));
1107 EXPECT_EQ(likelihood[i], apm_->voice_detection()->likelihood());
1110 /* TODO(bjornv): Enable once VAD supports other frame lengths than 10 ms
1111 // Test invalid frame sizes
1112 EXPECT_EQ(apm_->kBadParameterError,
1113 apm_->voice_detection()->set_frame_size_ms(12));
1115 // Test valid frame sizes
1116 for (int i = 10; i <= 30; i += 10) {
1117 EXPECT_EQ(apm_->kNoError,
1118 apm_->voice_detection()->set_frame_size_ms(i));
1119 EXPECT_EQ(i, apm_->voice_detection()->frame_size_ms());
1124 EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(true));
1125 EXPECT_TRUE(apm_->voice_detection()->is_enabled());
1126 EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(false));
1127 EXPECT_FALSE(apm_->voice_detection()->is_enabled());
1129 // Test that AudioFrame activity is maintained when VAD is disabled.
1130 EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(false));
1131 AudioFrame::VADActivity activity[] = {
1132 AudioFrame::kVadActive,
1133 AudioFrame::kVadPassive,
1134 AudioFrame::kVadUnknown
1136 for (size_t i = 0; i < sizeof(activity)/sizeof(*activity); i++) {
1137 frame_->vad_activity_ = activity[i];
1138 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1139 EXPECT_EQ(activity[i], frame_->vad_activity_);
1142 // Test that AudioFrame activity is set when VAD is enabled.
1143 EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(true));
1144 frame_->vad_activity_ = AudioFrame::kVadUnknown;
1145 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1146 EXPECT_NE(AudioFrame::kVadUnknown, frame_->vad_activity_);
1148 // TODO(bjornv): Add tests for streamed voice; stream_has_voice()
1151 TEST_F(ApmTest, AllProcessingDisabledByDefault) {
1152 EXPECT_FALSE(apm_->echo_cancellation()->is_enabled());
1153 EXPECT_FALSE(apm_->echo_control_mobile()->is_enabled());
1154 EXPECT_FALSE(apm_->gain_control()->is_enabled());
1155 EXPECT_FALSE(apm_->high_pass_filter()->is_enabled());
1156 EXPECT_FALSE(apm_->level_estimator()->is_enabled());
1157 EXPECT_FALSE(apm_->noise_suppression()->is_enabled());
1158 EXPECT_FALSE(apm_->voice_detection()->is_enabled());
1161 TEST_F(ApmTest, NoProcessingWhenAllComponentsDisabled) {
1162 for (size_t i = 0; i < kSampleRatesSize; i++) {
1163 Init(kSampleRates[i], 2, 2, 2, false);
1164 SetFrameTo(frame_, 1000, 2000);
1165 AudioFrame frame_copy;
1166 frame_copy.CopyFrom(*frame_);
1167 for (int j = 0; j < 1000; j++) {
1168 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1169 EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy));
1174 TEST_F(ApmTest, IdenticalInputChannelsResultInIdenticalOutputChannels) {
1175 EnableAllComponents();
1177 for (size_t i = 0; i < kProcessSampleRatesSize; i++) {
1178 Init(kProcessSampleRates[i], 2, 2, 2, false);
1179 int analog_level = 127;
1180 EXPECT_EQ(0, feof(far_file_));
1181 EXPECT_EQ(0, feof(near_file_));
1183 if (!ReadFrame(far_file_, revframe_)) break;
1184 CopyLeftToRightChannel(revframe_->data_, revframe_->samples_per_channel_);
1186 EXPECT_EQ(apm_->kNoError, apm_->AnalyzeReverseStream(revframe_));
1188 if (!ReadFrame(near_file_, frame_)) break;
1189 CopyLeftToRightChannel(frame_->data_, frame_->samples_per_channel_);
1190 frame_->vad_activity_ = AudioFrame::kVadUnknown;
1192 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
1193 apm_->echo_cancellation()->set_stream_drift_samples(0);
1194 EXPECT_EQ(apm_->kNoError,
1195 apm_->gain_control()->set_stream_analog_level(analog_level));
1196 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1197 analog_level = apm_->gain_control()->stream_analog_level();
1199 VerifyChannelsAreEqual(frame_->data_, frame_->samples_per_channel_);
1206 TEST_F(ApmTest, SplittingFilter) {
1207 // Verify the filter is not active through undistorted audio when:
1208 // 1. No components are enabled...
1209 SetFrameTo(frame_, 1000);
1210 AudioFrame frame_copy;
1211 frame_copy.CopyFrom(*frame_);
1212 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1213 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1214 EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy));
1216 // 2. Only the level estimator is enabled...
1217 SetFrameTo(frame_, 1000);
1218 frame_copy.CopyFrom(*frame_);
1219 EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(true));
1220 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1221 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1222 EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy));
1223 EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(false));
1225 // 3. Only VAD is enabled...
1226 SetFrameTo(frame_, 1000);
1227 frame_copy.CopyFrom(*frame_);
1228 EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(true));
1229 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1230 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1231 EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy));
1232 EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(false));
1234 // 4. Both VAD and the level estimator are enabled...
1235 SetFrameTo(frame_, 1000);
1236 frame_copy.CopyFrom(*frame_);
1237 EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(true));
1238 EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(true));
1239 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1240 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1241 EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy));
1242 EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(false));
1243 EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(false));
1245 // 5. Not using super-wb.
1246 frame_->samples_per_channel_ = 160;
1247 frame_->num_channels_ = 2;
1248 frame_->sample_rate_hz_ = 16000;
1249 // Enable AEC, which would require the filter in super-wb. We rely on the
1250 // first few frames of data being unaffected by the AEC.
1251 // TODO(andrew): This test, and the one below, rely rather tenuously on the
1252 // behavior of the AEC. Think of something more robust.
1253 EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
1254 SetFrameTo(frame_, 1000);
1255 frame_copy.CopyFrom(*frame_);
1256 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
1257 apm_->echo_cancellation()->set_stream_drift_samples(0);
1258 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1259 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
1260 apm_->echo_cancellation()->set_stream_drift_samples(0);
1261 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1262 EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy));
1264 // Check the test is valid. We should have distortion from the filter
1265 // when AEC is enabled (which won't affect the audio).
1266 frame_->samples_per_channel_ = 320;
1267 frame_->num_channels_ = 2;
1268 frame_->sample_rate_hz_ = 32000;
1269 SetFrameTo(frame_, 1000);
1270 frame_copy.CopyFrom(*frame_);
1271 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
1272 apm_->echo_cancellation()->set_stream_drift_samples(0);
1273 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1274 EXPECT_FALSE(FrameDataAreEqual(*frame_, frame_copy));
1277 // TODO(andrew): expand test to verify output.
1278 TEST_F(ApmTest, DebugDump) {
1279 const std::string filename = webrtc::test::OutputPath() + "debug.aec";
1280 EXPECT_EQ(apm_->kNullPointerError,
1281 apm_->StartDebugRecording(static_cast<const char*>(NULL)));
1283 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
1284 // Stopping without having started should be OK.
1285 EXPECT_EQ(apm_->kNoError, apm_->StopDebugRecording());
1287 EXPECT_EQ(apm_->kNoError, apm_->StartDebugRecording(filename.c_str()));
1288 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1289 EXPECT_EQ(apm_->kNoError, apm_->AnalyzeReverseStream(revframe_));
1290 EXPECT_EQ(apm_->kNoError, apm_->StopDebugRecording());
1292 // Verify the file has been written.
1293 FILE* fid = fopen(filename.c_str(), "r");
1294 ASSERT_TRUE(fid != NULL);
1297 ASSERT_EQ(0, fclose(fid));
1298 ASSERT_EQ(0, remove(filename.c_str()));
1300 EXPECT_EQ(apm_->kUnsupportedFunctionError,
1301 apm_->StartDebugRecording(filename.c_str()));
1302 EXPECT_EQ(apm_->kUnsupportedFunctionError, apm_->StopDebugRecording());
1304 // Verify the file has NOT been written.
1305 ASSERT_TRUE(fopen(filename.c_str(), "r") == NULL);
1306 #endif // WEBRTC_AUDIOPROC_DEBUG_DUMP
1309 // TODO(andrew): expand test to verify output.
1310 TEST_F(ApmTest, DebugDumpFromFileHandle) {
1312 EXPECT_EQ(apm_->kNullPointerError, apm_->StartDebugRecording(fid));
1313 const std::string filename = webrtc::test::OutputPath() + "debug.aec";
1314 fid = fopen(filename.c_str(), "w");
1317 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
1318 // Stopping without having started should be OK.
1319 EXPECT_EQ(apm_->kNoError, apm_->StopDebugRecording());
1321 EXPECT_EQ(apm_->kNoError, apm_->StartDebugRecording(fid));
1322 EXPECT_EQ(apm_->kNoError, apm_->AnalyzeReverseStream(revframe_));
1323 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1324 EXPECT_EQ(apm_->kNoError, apm_->StopDebugRecording());
1326 // Verify the file has been written.
1327 fid = fopen(filename.c_str(), "r");
1328 ASSERT_TRUE(fid != NULL);
1331 ASSERT_EQ(0, fclose(fid));
1332 ASSERT_EQ(0, remove(filename.c_str()));
1334 EXPECT_EQ(apm_->kUnsupportedFunctionError,
1335 apm_->StartDebugRecording(fid));
1336 EXPECT_EQ(apm_->kUnsupportedFunctionError, apm_->StopDebugRecording());
1338 ASSERT_EQ(0, fclose(fid));
1339 #endif // WEBRTC_AUDIOPROC_DEBUG_DUMP
1342 // TODO(andrew): Add a test to process a few frames with different combinations
1343 // of enabled components.
1345 // TODO(andrew): Make this test more robust such that it can be run on multiple
1346 // platforms. It currently requires bit-exactness.
1347 #ifdef WEBRTC_AUDIOPROC_BIT_EXACT
1348 TEST_F(ApmTest, DISABLED_ON_ANDROID(Process)) {
1349 GOOGLE_PROTOBUF_VERIFY_VERSION;
1350 webrtc::audioproc::OutputData ref_data;
1352 if (!write_ref_data) {
1353 ReadMessageLiteFromFile(ref_filename_, &ref_data);
1355 // Write the desired tests to the protobuf reference file.
1356 for (size_t i = 0; i < kChannelsSize; i++) {
1357 for (size_t j = 0; j < kChannelsSize; j++) {
1358 for (size_t l = 0; l < kProcessSampleRatesSize; l++) {
1359 webrtc::audioproc::Test* test = ref_data.add_test();
1360 test->set_num_reverse_channels(kChannels[i]);
1361 test->set_num_input_channels(kChannels[j]);
1362 test->set_num_output_channels(kChannels[j]);
1363 test->set_sample_rate(kProcessSampleRates[l]);
1369 EnableAllComponents();
1371 for (int i = 0; i < ref_data.test_size(); i++) {
1372 printf("Running test %d of %d...\n", i + 1, ref_data.test_size());
1374 webrtc::audioproc::Test* test = ref_data.mutable_test(i);
1375 // TODO(ajm): We no longer allow different input and output channels. Skip
1376 // these tests for now, but they should be removed from the set.
1377 if (test->num_input_channels() != test->num_output_channels())
1380 Init(test->sample_rate(), test->num_reverse_channels(),
1381 test->num_input_channels(), test->num_output_channels(), true);
1383 int frame_count = 0;
1384 int has_echo_count = 0;
1385 int has_voice_count = 0;
1386 int is_saturated_count = 0;
1387 int analog_level = 127;
1388 int analog_level_average = 0;
1389 int max_output_average = 0;
1390 float ns_speech_prob_average = 0.0f;
1393 if (!ReadFrame(far_file_, revframe_)) break;
1394 EXPECT_EQ(apm_->kNoError, apm_->AnalyzeReverseStream(revframe_));
1396 if (!ReadFrame(near_file_, frame_)) break;
1397 frame_->vad_activity_ = AudioFrame::kVadUnknown;
1399 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
1400 apm_->echo_cancellation()->set_stream_drift_samples(0);
1401 EXPECT_EQ(apm_->kNoError,
1402 apm_->gain_control()->set_stream_analog_level(analog_level));
1404 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1405 // Ensure the frame was downmixed properly.
1406 EXPECT_EQ(test->num_output_channels(), frame_->num_channels_);
1408 max_output_average += MaxAudioFrame(*frame_);
1410 if (apm_->echo_cancellation()->stream_has_echo()) {
1414 analog_level = apm_->gain_control()->stream_analog_level();
1415 analog_level_average += analog_level;
1416 if (apm_->gain_control()->stream_is_saturated()) {
1417 is_saturated_count++;
1419 if (apm_->voice_detection()->stream_has_voice()) {
1421 EXPECT_EQ(AudioFrame::kVadActive, frame_->vad_activity_);
1423 EXPECT_EQ(AudioFrame::kVadPassive, frame_->vad_activity_);
1426 ns_speech_prob_average += apm_->noise_suppression()->speech_probability();
1428 size_t frame_size = frame_->samples_per_channel_ * frame_->num_channels_;
1429 size_t write_count = fwrite(frame_->data_,
1433 ASSERT_EQ(frame_size, write_count);
1435 // Reset in case of downmixing.
1436 frame_->num_channels_ = test->num_input_channels();
1439 max_output_average /= frame_count;
1440 analog_level_average /= frame_count;
1441 ns_speech_prob_average /= frame_count;
1443 #if defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
1444 EchoCancellation::Metrics echo_metrics;
1445 EXPECT_EQ(apm_->kNoError,
1446 apm_->echo_cancellation()->GetMetrics(&echo_metrics));
1449 EXPECT_EQ(apm_->kNoError,
1450 apm_->echo_cancellation()->GetDelayMetrics(&median, &std));
1452 int rms_level = apm_->level_estimator()->RMS();
1453 EXPECT_LE(0, rms_level);
1454 EXPECT_GE(127, rms_level);
1457 if (!write_ref_data) {
1458 EXPECT_EQ(test->has_echo_count(), has_echo_count);
1459 EXPECT_EQ(test->has_voice_count(), has_voice_count);
1460 EXPECT_EQ(test->is_saturated_count(), is_saturated_count);
1462 EXPECT_EQ(test->analog_level_average(), analog_level_average);
1463 EXPECT_EQ(test->max_output_average(), max_output_average);
1465 #if defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
1466 webrtc::audioproc::Test::EchoMetrics reference =
1467 test->echo_metrics();
1468 TestStats(echo_metrics.residual_echo_return_loss,
1469 reference.residual_echo_return_loss());
1470 TestStats(echo_metrics.echo_return_loss,
1471 reference.echo_return_loss());
1472 TestStats(echo_metrics.echo_return_loss_enhancement,
1473 reference.echo_return_loss_enhancement());
1474 TestStats(echo_metrics.a_nlp,
1477 webrtc::audioproc::Test::DelayMetrics reference_delay =
1478 test->delay_metrics();
1479 EXPECT_EQ(reference_delay.median(), median);
1480 EXPECT_EQ(reference_delay.std(), std);
1482 EXPECT_EQ(test->rms_level(), rms_level);
1484 EXPECT_FLOAT_EQ(test->ns_speech_probability_average(),
1485 ns_speech_prob_average);
1488 test->set_has_echo_count(has_echo_count);
1489 test->set_has_voice_count(has_voice_count);
1490 test->set_is_saturated_count(is_saturated_count);
1492 test->set_analog_level_average(analog_level_average);
1493 test->set_max_output_average(max_output_average);
1495 #if defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
1496 webrtc::audioproc::Test::EchoMetrics* message =
1497 test->mutable_echo_metrics();
1498 WriteStatsMessage(echo_metrics.residual_echo_return_loss,
1499 message->mutable_residual_echo_return_loss());
1500 WriteStatsMessage(echo_metrics.echo_return_loss,
1501 message->mutable_echo_return_loss());
1502 WriteStatsMessage(echo_metrics.echo_return_loss_enhancement,
1503 message->mutable_echo_return_loss_enhancement());
1504 WriteStatsMessage(echo_metrics.a_nlp,
1505 message->mutable_a_nlp());
1507 webrtc::audioproc::Test::DelayMetrics* message_delay =
1508 test->mutable_delay_metrics();
1509 message_delay->set_median(median);
1510 message_delay->set_std(std);
1512 test->set_rms_level(rms_level);
1514 EXPECT_LE(0.0f, ns_speech_prob_average);
1515 EXPECT_GE(1.0f, ns_speech_prob_average);
1516 test->set_ns_speech_probability_average(ns_speech_prob_average);
1524 if (write_ref_data) {
1525 WriteMessageLiteToFile(ref_filename_, ref_data);
1528 #endif // WEBRTC_AUDIOPROC_BIT_EXACT
1530 // TODO(henrike): re-implement functionality lost when removing the old main
1532 // https://code.google.com/p/webrtc/issues/detail?id=1981