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.
17 #include "webrtc/common_audio/include/audio_util.h"
18 #include "webrtc/common_audio/resampler/include/push_resampler.h"
19 #include "webrtc/common_audio/resampler/push_sinc_resampler.h"
20 #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
21 #include "webrtc/modules/audio_processing/include/audio_processing.h"
22 #include "webrtc/modules/audio_processing/test/test_utils.h"
23 #include "webrtc/modules/interface/module_common_types.h"
24 #include "webrtc/system_wrappers/interface/event_wrapper.h"
25 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
26 #include "webrtc/system_wrappers/interface/trace.h"
27 #include "webrtc/test/testsupport/fileutils.h"
28 #include "webrtc/test/testsupport/gtest_disable.h"
29 #ifdef WEBRTC_ANDROID_PLATFORM_BUILD
30 #include "gtest/gtest.h"
31 #include "external/webrtc/webrtc/modules/audio_processing/test/unittest.pb.h"
33 #include "testing/gtest/include/gtest/gtest.h"
34 #include "webrtc/audio_processing/unittest.pb.h"
40 // TODO(bjornv): This is not feasible until the functionality has been
41 // re-implemented; see comment at the bottom of this file. For now, the user has
42 // to hard code the |write_ref_data| value.
43 // When false, this will compare the output data with the results stored to
44 // file. This is the typical case. When the file should be updated, it can
45 // be set to true with the command-line switch --write_ref_data.
46 bool write_ref_data = false;
47 const int kChannels[] = {1, 2};
48 const size_t kChannelsSize = sizeof(kChannels) / sizeof(*kChannels);
50 const int kSampleRates[] = {8000, 16000, 32000};
51 const size_t kSampleRatesSize = sizeof(kSampleRates) / sizeof(*kSampleRates);
53 #if defined(WEBRTC_AUDIOPROC_FIXED_PROFILE)
54 // AECM doesn't support super-wb.
55 const int kProcessSampleRates[] = {8000, 16000};
56 #elif defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
57 const int kProcessSampleRates[] = {8000, 16000, 32000};
59 const size_t kProcessSampleRatesSize = sizeof(kProcessSampleRates) /
60 sizeof(*kProcessSampleRates);
62 void ConvertToFloat(const int16_t* int_data, ChannelBuffer<float>* cb) {
63 ChannelBuffer<int16_t> cb_int(cb->samples_per_channel(),
65 Deinterleave(int_data,
66 cb->samples_per_channel(),
69 S16ToFloat(cb_int.data(),
70 cb->samples_per_channel() * cb->num_channels(),
74 void ConvertToFloat(const AudioFrame& frame, ChannelBuffer<float>* cb) {
75 ConvertToFloat(frame.data_, cb);
78 // Number of channels including the keyboard channel.
79 int TotalChannelsFromLayout(AudioProcessing::ChannelLayout layout) {
81 case AudioProcessing::kMono:
83 case AudioProcessing::kMonoAndKeyboard:
84 case AudioProcessing::kStereo:
86 case AudioProcessing::kStereoAndKeyboard:
93 int TruncateToMultipleOf10(int value) {
94 return (value / 10) * 10;
97 void MixStereoToMono(const float* stereo, float* mono,
98 int samples_per_channel) {
99 for (int i = 0; i < samples_per_channel; ++i)
100 mono[i] = (stereo[i * 2] + stereo[i * 2 + 1]) / 2;
103 void MixStereoToMono(const int16_t* stereo, int16_t* mono,
104 int samples_per_channel) {
105 for (int i = 0; i < samples_per_channel; ++i)
106 mono[i] = (stereo[i * 2] + stereo[i * 2 + 1]) >> 1;
109 void CopyLeftToRightChannel(int16_t* stereo, int samples_per_channel) {
110 for (int i = 0; i < samples_per_channel; i++) {
111 stereo[i * 2 + 1] = stereo[i * 2];
115 void VerifyChannelsAreEqual(int16_t* stereo, int samples_per_channel) {
116 for (int i = 0; i < samples_per_channel; i++) {
117 EXPECT_EQ(stereo[i * 2 + 1], stereo[i * 2]);
121 void SetFrameTo(AudioFrame* frame, int16_t value) {
122 for (int i = 0; i < frame->samples_per_channel_ * frame->num_channels_; ++i) {
123 frame->data_[i] = value;
127 void SetFrameTo(AudioFrame* frame, int16_t left, int16_t right) {
128 ASSERT_EQ(2, frame->num_channels_);
129 for (int i = 0; i < frame->samples_per_channel_ * 2; i += 2) {
130 frame->data_[i] = left;
131 frame->data_[i + 1] = right;
135 void ScaleFrame(AudioFrame* frame, float scale) {
136 for (int i = 0; i < frame->samples_per_channel_ * frame->num_channels_; ++i) {
137 frame->data_[i] = FloatS16ToS16(frame->data_[i] * scale);
141 bool FrameDataAreEqual(const AudioFrame& frame1, const AudioFrame& frame2) {
142 if (frame1.samples_per_channel_ != frame2.samples_per_channel_) {
145 if (frame1.num_channels_ != frame2.num_channels_) {
148 if (memcmp(frame1.data_, frame2.data_,
149 frame1.samples_per_channel_ * frame1.num_channels_ *
156 void EnableAllAPComponents(AudioProcessing* ap) {
157 #if defined(WEBRTC_AUDIOPROC_FIXED_PROFILE)
158 EXPECT_NOERR(ap->echo_control_mobile()->Enable(true));
160 EXPECT_NOERR(ap->gain_control()->set_mode(GainControl::kAdaptiveDigital));
161 EXPECT_NOERR(ap->gain_control()->Enable(true));
162 #elif defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
163 EXPECT_NOERR(ap->echo_cancellation()->enable_drift_compensation(true));
164 EXPECT_NOERR(ap->echo_cancellation()->enable_metrics(true));
165 EXPECT_NOERR(ap->echo_cancellation()->enable_delay_logging(true));
166 EXPECT_NOERR(ap->echo_cancellation()->Enable(true));
168 EXPECT_NOERR(ap->gain_control()->set_mode(GainControl::kAdaptiveAnalog));
169 EXPECT_NOERR(ap->gain_control()->set_analog_level_limits(0, 255));
170 EXPECT_NOERR(ap->gain_control()->Enable(true));
173 EXPECT_NOERR(ap->high_pass_filter()->Enable(true));
174 EXPECT_NOERR(ap->level_estimator()->Enable(true));
175 EXPECT_NOERR(ap->noise_suppression()->Enable(true));
177 EXPECT_NOERR(ap->voice_detection()->Enable(true));
180 // These functions are only used by ApmTest.Process.
183 return a > 0 ? a: -a;
186 int16_t MaxAudioFrame(const AudioFrame& frame) {
187 const int length = frame.samples_per_channel_ * frame.num_channels_;
188 int16_t max_data = AbsValue(frame.data_[0]);
189 for (int i = 1; i < length; i++) {
190 max_data = std::max(max_data, AbsValue(frame.data_[i]));
196 #if defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
197 void TestStats(const AudioProcessing::Statistic& test,
198 const audioproc::Test::Statistic& reference) {
199 EXPECT_EQ(reference.instant(), test.instant);
200 EXPECT_EQ(reference.average(), test.average);
201 EXPECT_EQ(reference.maximum(), test.maximum);
202 EXPECT_EQ(reference.minimum(), test.minimum);
205 void WriteStatsMessage(const AudioProcessing::Statistic& output,
206 audioproc::Test::Statistic* msg) {
207 msg->set_instant(output.instant);
208 msg->set_average(output.average);
209 msg->set_maximum(output.maximum);
210 msg->set_minimum(output.minimum);
214 void OpenFileAndWriteMessage(const std::string filename,
215 const ::google::protobuf::MessageLite& msg) {
216 #if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
217 FILE* file = fopen(filename.c_str(), "wb");
218 ASSERT_TRUE(file != NULL);
220 int32_t size = msg.ByteSize();
222 scoped_ptr<uint8_t[]> array(new uint8_t[size]);
223 ASSERT_TRUE(msg.SerializeToArray(array.get(), size));
225 ASSERT_EQ(1u, fwrite(&size, sizeof(size), 1, file));
226 ASSERT_EQ(static_cast<size_t>(size),
227 fwrite(array.get(), sizeof(array[0]), size, file));
230 std::cout << "Warning: Writing new reference is only allowed on Linux!"
235 std::string ResourceFilePath(std::string name, int sample_rate_hz) {
236 std::ostringstream ss;
237 // Resource files are all stereo.
238 ss << name << sample_rate_hz / 1000 << "_stereo";
239 return test::ResourcePath(ss.str(), "pcm");
242 std::string OutputFilePath(std::string name,
246 int num_input_channels,
247 int num_output_channels,
248 int num_reverse_channels) {
249 std::ostringstream ss;
250 ss << name << "_i" << num_input_channels << "_" << input_rate / 1000
251 << "_r" << num_reverse_channels << "_" << reverse_rate / 1000 << "_";
252 if (num_output_channels == 1) {
254 } else if (num_output_channels == 2) {
259 ss << output_rate / 1000 << ".pcm";
261 return test::OutputPath() + ss.str();
264 void OpenFileAndReadMessage(const std::string filename,
265 ::google::protobuf::MessageLite* msg) {
266 FILE* file = fopen(filename.c_str(), "rb");
267 ASSERT_TRUE(file != NULL);
268 ReadMessageFromFile(file, msg);
272 class ApmTest : public ::testing::Test {
275 virtual void SetUp();
276 virtual void TearDown();
278 static void SetUpTestCase() {
279 Trace::CreateTrace();
280 std::string trace_filename = test::OutputPath() + "audioproc_trace.txt";
281 ASSERT_EQ(0, Trace::SetTraceFile(trace_filename.c_str()));
284 static void TearDownTestCase() {
285 Trace::ReturnTrace();
288 // Used to select between int and float interface tests.
294 void Init(int sample_rate_hz,
295 int output_sample_rate_hz,
296 int reverse_sample_rate_hz,
297 int num_reverse_channels,
298 int num_input_channels,
299 int num_output_channels,
300 bool open_output_file);
301 void Init(AudioProcessing* ap);
302 void EnableAllComponents();
303 bool ReadFrame(FILE* file, AudioFrame* frame);
304 bool ReadFrame(FILE* file, AudioFrame* frame, ChannelBuffer<float>* cb);
305 void ReadFrameWithRewind(FILE* file, AudioFrame* frame);
306 void ReadFrameWithRewind(FILE* file, AudioFrame* frame,
307 ChannelBuffer<float>* cb);
308 void ProcessWithDefaultStreamParameters(AudioFrame* frame);
309 void ProcessDelayVerificationTest(int delay_ms, int system_delay_ms,
310 int delay_min, int delay_max);
311 void TestChangingChannels(int num_channels,
312 AudioProcessing::Error expected_return);
313 void RunQuantizedVolumeDoesNotGetStuckTest(int sample_rate);
314 void RunManualVolumeChangeIsPossibleTest(int sample_rate);
315 void StreamParametersTest(Format format);
316 int ProcessStreamChooser(Format format);
317 int AnalyzeReverseStreamChooser(Format format);
318 void ProcessDebugDump(const std::string& in_filename,
319 const std::string& out_filename,
321 void VerifyDebugDumpTest(Format format);
323 const std::string output_path_;
324 const std::string ref_path_;
325 const std::string ref_filename_;
326 scoped_ptr<AudioProcessing> apm_;
328 AudioFrame* revframe_;
329 scoped_ptr<ChannelBuffer<float> > float_cb_;
330 scoped_ptr<ChannelBuffer<float> > revfloat_cb_;
331 int output_sample_rate_hz_;
332 int num_output_channels_;
339 : output_path_(test::OutputPath()),
340 ref_path_(test::ProjectRootPath() + "data/audio_processing/"),
341 #if defined(WEBRTC_AUDIOPROC_FIXED_PROFILE)
342 ref_filename_(ref_path_ + "output_data_fixed.pb"),
343 #elif defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
344 ref_filename_(ref_path_ + "output_data_float.pb"),
348 output_sample_rate_hz_(0),
349 num_output_channels_(0),
354 config.Set<ExperimentalAgc>(new ExperimentalAgc(false));
355 apm_.reset(AudioProcessing::Create(config));
358 void ApmTest::SetUp() {
359 ASSERT_TRUE(apm_.get() != NULL);
361 frame_ = new AudioFrame();
362 revframe_ = new AudioFrame();
364 #if defined(WEBRTC_AUDIOPROC_FIXED_PROFILE)
365 Init(16000, 16000, 16000, 2, 2, 2, false);
367 Init(32000, 32000, 32000, 2, 2, 2, false);
371 void ApmTest::TearDown() {
383 ASSERT_EQ(0, fclose(far_file_));
388 ASSERT_EQ(0, fclose(near_file_));
393 ASSERT_EQ(0, fclose(out_file_));
398 void ApmTest::Init(AudioProcessing* ap) {
400 ap->Initialize(frame_->sample_rate_hz_,
401 output_sample_rate_hz_,
402 revframe_->sample_rate_hz_,
403 LayoutFromChannels(frame_->num_channels_),
404 LayoutFromChannels(num_output_channels_),
405 LayoutFromChannels(revframe_->num_channels_)));
408 void ApmTest::Init(int sample_rate_hz,
409 int output_sample_rate_hz,
410 int reverse_sample_rate_hz,
411 int num_input_channels,
412 int num_output_channels,
413 int num_reverse_channels,
414 bool open_output_file) {
415 SetContainerFormat(sample_rate_hz, num_input_channels, frame_, &float_cb_);
416 output_sample_rate_hz_ = output_sample_rate_hz;
417 num_output_channels_ = num_output_channels;
419 SetContainerFormat(reverse_sample_rate_hz, num_reverse_channels, revframe_,
424 ASSERT_EQ(0, fclose(far_file_));
426 std::string filename = ResourceFilePath("far", sample_rate_hz);
427 far_file_ = fopen(filename.c_str(), "rb");
428 ASSERT_TRUE(far_file_ != NULL) << "Could not open file " <<
432 ASSERT_EQ(0, fclose(near_file_));
434 filename = ResourceFilePath("near", sample_rate_hz);
435 near_file_ = fopen(filename.c_str(), "rb");
436 ASSERT_TRUE(near_file_ != NULL) << "Could not open file " <<
439 if (open_output_file) {
441 ASSERT_EQ(0, fclose(out_file_));
443 filename = OutputFilePath("out",
445 output_sample_rate_hz,
446 reverse_sample_rate_hz,
449 num_reverse_channels);
450 out_file_ = fopen(filename.c_str(), "wb");
451 ASSERT_TRUE(out_file_ != NULL) << "Could not open file " <<
456 void ApmTest::EnableAllComponents() {
457 EnableAllAPComponents(apm_.get());
460 bool ApmTest::ReadFrame(FILE* file, AudioFrame* frame,
461 ChannelBuffer<float>* cb) {
462 // The files always contain stereo audio.
463 size_t frame_size = frame->samples_per_channel_ * 2;
464 size_t read_count = fread(frame->data_,
468 if (read_count != frame_size) {
469 // Check that the file really ended.
470 EXPECT_NE(0, feof(file));
471 return false; // This is expected.
474 if (frame->num_channels_ == 1) {
475 MixStereoToMono(frame->data_, frame->data_,
476 frame->samples_per_channel_);
480 ConvertToFloat(*frame, cb);
485 bool ApmTest::ReadFrame(FILE* file, AudioFrame* frame) {
486 return ReadFrame(file, frame, NULL);
489 // If the end of the file has been reached, rewind it and attempt to read the
491 void ApmTest::ReadFrameWithRewind(FILE* file, AudioFrame* frame,
492 ChannelBuffer<float>* cb) {
493 if (!ReadFrame(near_file_, frame_, cb)) {
495 ASSERT_TRUE(ReadFrame(near_file_, frame_, cb));
499 void ApmTest::ReadFrameWithRewind(FILE* file, AudioFrame* frame) {
500 ReadFrameWithRewind(file, frame, NULL);
503 void ApmTest::ProcessWithDefaultStreamParameters(AudioFrame* frame) {
504 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
505 apm_->echo_cancellation()->set_stream_drift_samples(0);
506 EXPECT_EQ(apm_->kNoError,
507 apm_->gain_control()->set_stream_analog_level(127));
508 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame));
511 int ApmTest::ProcessStreamChooser(Format format) {
512 if (format == kIntFormat) {
513 return apm_->ProcessStream(frame_);
515 return apm_->ProcessStream(float_cb_->channels(),
516 frame_->samples_per_channel_,
517 frame_->sample_rate_hz_,
518 LayoutFromChannels(frame_->num_channels_),
519 output_sample_rate_hz_,
520 LayoutFromChannels(num_output_channels_),
521 float_cb_->channels());
524 int ApmTest::AnalyzeReverseStreamChooser(Format format) {
525 if (format == kIntFormat) {
526 return apm_->AnalyzeReverseStream(revframe_);
528 return apm_->AnalyzeReverseStream(
529 revfloat_cb_->channels(),
530 revframe_->samples_per_channel_,
531 revframe_->sample_rate_hz_,
532 LayoutFromChannels(revframe_->num_channels_));
535 void ApmTest::ProcessDelayVerificationTest(int delay_ms, int system_delay_ms,
536 int delay_min, int delay_max) {
537 // The |revframe_| and |frame_| should include the proper frame information,
538 // hence can be used for extracting information.
539 AudioFrame tmp_frame;
540 std::queue<AudioFrame*> frame_queue;
543 tmp_frame.CopyFrom(*revframe_);
544 SetFrameTo(&tmp_frame, 0);
546 EXPECT_EQ(apm_->kNoError, apm_->Initialize());
547 // Initialize the |frame_queue| with empty frames.
548 int frame_delay = delay_ms / 10;
549 while (frame_delay < 0) {
550 AudioFrame* frame = new AudioFrame();
551 frame->CopyFrom(tmp_frame);
552 frame_queue.push(frame);
556 while (frame_delay > 0) {
557 AudioFrame* frame = new AudioFrame();
558 frame->CopyFrom(tmp_frame);
559 frame_queue.push(frame);
562 // Run for 4.5 seconds, skipping statistics from the first 2.5 seconds. We
563 // need enough frames with audio to have reliable estimates, but as few as
564 // possible to keep processing time down. 4.5 seconds seemed to be a good
565 // compromise for this recording.
566 for (int frame_count = 0; frame_count < 450; ++frame_count) {
567 AudioFrame* frame = new AudioFrame();
568 frame->CopyFrom(tmp_frame);
569 // Use the near end recording, since that has more speech in it.
570 ASSERT_TRUE(ReadFrame(near_file_, frame));
571 frame_queue.push(frame);
572 AudioFrame* reverse_frame = frame;
573 AudioFrame* process_frame = frame_queue.front();
575 reverse_frame = frame_queue.front();
576 // When we call ProcessStream() the frame is modified, so we can't use the
577 // pointer directly when things are non-causal. Use an intermediate frame
578 // and copy the data.
579 process_frame = &tmp_frame;
580 process_frame->CopyFrom(*frame);
582 EXPECT_EQ(apm_->kNoError, apm_->AnalyzeReverseStream(reverse_frame));
583 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(system_delay_ms));
584 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(process_frame));
585 frame = frame_queue.front();
589 if (frame_count == 250) {
592 // Discard the first delay metrics to avoid convergence effects.
593 EXPECT_EQ(apm_->kNoError,
594 apm_->echo_cancellation()->GetDelayMetrics(&median, &std));
599 while (!frame_queue.empty()) {
600 AudioFrame* frame = frame_queue.front();
604 // Calculate expected delay estimate and acceptable regions. Further,
605 // limit them w.r.t. AEC delay estimation support.
606 const int samples_per_ms = std::min(16, frame_->samples_per_channel_ / 10);
607 int expected_median = std::min(std::max(delay_ms - system_delay_ms,
608 delay_min), delay_max);
609 int expected_median_high = std::min(std::max(
610 expected_median + 96 / samples_per_ms, delay_min), delay_max);
611 int expected_median_low = std::min(std::max(
612 expected_median - 96 / samples_per_ms, delay_min), delay_max);
613 // Verify delay metrics.
616 EXPECT_EQ(apm_->kNoError,
617 apm_->echo_cancellation()->GetDelayMetrics(&median, &std));
618 EXPECT_GE(expected_median_high, median);
619 EXPECT_LE(expected_median_low, median);
622 void ApmTest::StreamParametersTest(Format format) {
623 // No errors when the components are disabled.
624 EXPECT_EQ(apm_->kNoError, ProcessStreamChooser(format));
626 // -- Missing AGC level --
627 EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
628 EXPECT_EQ(apm_->kStreamParameterNotSetError,
629 ProcessStreamChooser(format));
631 // Resets after successful ProcessStream().
632 EXPECT_EQ(apm_->kNoError,
633 apm_->gain_control()->set_stream_analog_level(127));
634 EXPECT_EQ(apm_->kNoError, ProcessStreamChooser(format));
635 EXPECT_EQ(apm_->kStreamParameterNotSetError,
636 ProcessStreamChooser(format));
638 // Other stream parameters set correctly.
639 EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
640 EXPECT_EQ(apm_->kNoError,
641 apm_->echo_cancellation()->enable_drift_compensation(true));
642 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
643 apm_->echo_cancellation()->set_stream_drift_samples(0);
644 EXPECT_EQ(apm_->kStreamParameterNotSetError,
645 ProcessStreamChooser(format));
646 EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(false));
647 EXPECT_EQ(apm_->kNoError,
648 apm_->echo_cancellation()->enable_drift_compensation(false));
650 // -- Missing delay --
651 EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
652 EXPECT_EQ(apm_->kNoError, ProcessStreamChooser(format));
653 EXPECT_EQ(apm_->kStreamParameterNotSetError,
654 ProcessStreamChooser(format));
656 // Resets after successful ProcessStream().
657 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
658 EXPECT_EQ(apm_->kNoError, ProcessStreamChooser(format));
659 EXPECT_EQ(apm_->kStreamParameterNotSetError,
660 ProcessStreamChooser(format));
662 // Other stream parameters set correctly.
663 EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
664 EXPECT_EQ(apm_->kNoError,
665 apm_->echo_cancellation()->enable_drift_compensation(true));
666 apm_->echo_cancellation()->set_stream_drift_samples(0);
667 EXPECT_EQ(apm_->kNoError,
668 apm_->gain_control()->set_stream_analog_level(127));
669 EXPECT_EQ(apm_->kStreamParameterNotSetError,
670 ProcessStreamChooser(format));
671 EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(false));
673 // -- Missing drift --
674 EXPECT_EQ(apm_->kStreamParameterNotSetError,
675 ProcessStreamChooser(format));
677 // Resets after successful ProcessStream().
678 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
679 apm_->echo_cancellation()->set_stream_drift_samples(0);
680 EXPECT_EQ(apm_->kNoError, ProcessStreamChooser(format));
681 EXPECT_EQ(apm_->kStreamParameterNotSetError,
682 ProcessStreamChooser(format));
684 // Other stream parameters set correctly.
685 EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
686 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
687 EXPECT_EQ(apm_->kNoError,
688 apm_->gain_control()->set_stream_analog_level(127));
689 EXPECT_EQ(apm_->kStreamParameterNotSetError,
690 ProcessStreamChooser(format));
692 // -- No stream parameters --
693 EXPECT_EQ(apm_->kNoError,
694 AnalyzeReverseStreamChooser(format));
695 EXPECT_EQ(apm_->kStreamParameterNotSetError,
696 ProcessStreamChooser(format));
699 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
700 apm_->echo_cancellation()->set_stream_drift_samples(0);
701 EXPECT_EQ(apm_->kNoError,
702 apm_->gain_control()->set_stream_analog_level(127));
703 EXPECT_EQ(apm_->kNoError, ProcessStreamChooser(format));
706 TEST_F(ApmTest, StreamParametersInt) {
707 StreamParametersTest(kIntFormat);
710 TEST_F(ApmTest, StreamParametersFloat) {
711 StreamParametersTest(kFloatFormat);
714 TEST_F(ApmTest, DefaultDelayOffsetIsZero) {
715 EXPECT_EQ(0, apm_->delay_offset_ms());
716 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(50));
717 EXPECT_EQ(50, apm_->stream_delay_ms());
720 TEST_F(ApmTest, DelayOffsetWithLimitsIsSetProperly) {
721 // High limit of 500 ms.
722 apm_->set_delay_offset_ms(100);
723 EXPECT_EQ(100, apm_->delay_offset_ms());
724 EXPECT_EQ(apm_->kBadStreamParameterWarning, apm_->set_stream_delay_ms(450));
725 EXPECT_EQ(500, apm_->stream_delay_ms());
726 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
727 EXPECT_EQ(200, apm_->stream_delay_ms());
729 // Low limit of 0 ms.
730 apm_->set_delay_offset_ms(-50);
731 EXPECT_EQ(-50, apm_->delay_offset_ms());
732 EXPECT_EQ(apm_->kBadStreamParameterWarning, apm_->set_stream_delay_ms(20));
733 EXPECT_EQ(0, apm_->stream_delay_ms());
734 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
735 EXPECT_EQ(50, apm_->stream_delay_ms());
738 void ApmTest::TestChangingChannels(int num_channels,
739 AudioProcessing::Error expected_return) {
740 frame_->num_channels_ = num_channels;
741 EXPECT_EQ(expected_return, apm_->ProcessStream(frame_));
742 EXPECT_EQ(expected_return, apm_->AnalyzeReverseStream(frame_));
745 TEST_F(ApmTest, Channels) {
746 // Testing number of invalid channels.
747 TestChangingChannels(0, apm_->kBadNumberChannelsError);
748 TestChangingChannels(3, apm_->kBadNumberChannelsError);
749 // Testing number of valid channels.
750 for (int i = 1; i < 3; i++) {
751 TestChangingChannels(i, kNoErr);
752 EXPECT_EQ(i, apm_->num_input_channels());
753 // We always force the number of reverse channels used for processing to 1.
754 EXPECT_EQ(1, apm_->num_reverse_channels());
758 TEST_F(ApmTest, SampleRatesInt) {
759 // Testing invalid sample rates
760 SetContainerFormat(10000, 2, frame_, &float_cb_);
761 EXPECT_EQ(apm_->kBadSampleRateError, ProcessStreamChooser(kIntFormat));
762 // Testing valid sample rates
763 int fs[] = {8000, 16000, 32000};
764 for (size_t i = 0; i < sizeof(fs) / sizeof(*fs); i++) {
765 SetContainerFormat(fs[i], 2, frame_, &float_cb_);
766 EXPECT_NOERR(ProcessStreamChooser(kIntFormat));
767 EXPECT_EQ(fs[i], apm_->input_sample_rate_hz());
771 TEST_F(ApmTest, EchoCancellation) {
772 EXPECT_EQ(apm_->kNoError,
773 apm_->echo_cancellation()->enable_drift_compensation(true));
774 EXPECT_TRUE(apm_->echo_cancellation()->is_drift_compensation_enabled());
775 EXPECT_EQ(apm_->kNoError,
776 apm_->echo_cancellation()->enable_drift_compensation(false));
777 EXPECT_FALSE(apm_->echo_cancellation()->is_drift_compensation_enabled());
779 EchoCancellation::SuppressionLevel level[] = {
780 EchoCancellation::kLowSuppression,
781 EchoCancellation::kModerateSuppression,
782 EchoCancellation::kHighSuppression,
784 for (size_t i = 0; i < sizeof(level)/sizeof(*level); i++) {
785 EXPECT_EQ(apm_->kNoError,
786 apm_->echo_cancellation()->set_suppression_level(level[i]));
788 apm_->echo_cancellation()->suppression_level());
791 EchoCancellation::Metrics metrics;
792 EXPECT_EQ(apm_->kNotEnabledError,
793 apm_->echo_cancellation()->GetMetrics(&metrics));
795 EXPECT_EQ(apm_->kNoError,
796 apm_->echo_cancellation()->enable_metrics(true));
797 EXPECT_TRUE(apm_->echo_cancellation()->are_metrics_enabled());
798 EXPECT_EQ(apm_->kNoError,
799 apm_->echo_cancellation()->enable_metrics(false));
800 EXPECT_FALSE(apm_->echo_cancellation()->are_metrics_enabled());
804 EXPECT_EQ(apm_->kNotEnabledError,
805 apm_->echo_cancellation()->GetDelayMetrics(&median, &std));
807 EXPECT_EQ(apm_->kNoError,
808 apm_->echo_cancellation()->enable_delay_logging(true));
809 EXPECT_TRUE(apm_->echo_cancellation()->is_delay_logging_enabled());
810 EXPECT_EQ(apm_->kNoError,
811 apm_->echo_cancellation()->enable_delay_logging(false));
812 EXPECT_FALSE(apm_->echo_cancellation()->is_delay_logging_enabled());
814 EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
815 EXPECT_TRUE(apm_->echo_cancellation()->is_enabled());
816 EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(false));
817 EXPECT_FALSE(apm_->echo_cancellation()->is_enabled());
819 EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
820 EXPECT_TRUE(apm_->echo_cancellation()->is_enabled());
821 EXPECT_TRUE(apm_->echo_cancellation()->aec_core() != NULL);
822 EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(false));
823 EXPECT_FALSE(apm_->echo_cancellation()->is_enabled());
824 EXPECT_FALSE(apm_->echo_cancellation()->aec_core() != NULL);
827 TEST_F(ApmTest, DISABLED_EchoCancellationReportsCorrectDelays) {
829 EXPECT_EQ(apm_->kNoError,
830 apm_->echo_cancellation()->enable_drift_compensation(false));
831 EXPECT_EQ(apm_->kNoError,
832 apm_->echo_cancellation()->enable_metrics(false));
833 EXPECT_EQ(apm_->kNoError,
834 apm_->echo_cancellation()->enable_delay_logging(true));
835 EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
837 config.Set<ReportedDelay>(new ReportedDelay(true));
838 apm_->SetExtraOptions(config);
840 // Internally in the AEC the amount of lookahead the delay estimation can
841 // handle is 15 blocks and the maximum delay is set to 60 blocks.
842 const int kLookaheadBlocks = 15;
843 const int kMaxDelayBlocks = 60;
844 // The AEC has a startup time before it actually starts to process. This
845 // procedure can flush the internal far-end buffer, which of course affects
846 // the delay estimation. Therefore, we set a system_delay high enough to
847 // avoid that. The smallest system_delay you can report without flushing the
848 // buffer is 66 ms in 8 kHz.
850 // It is known that for 16 kHz (and 32 kHz) sampling frequency there is an
851 // additional stuffing of 8 ms on the fly, but it seems to have no impact on
852 // delay estimation. This should be noted though. In case of test failure,
853 // this could be the cause.
854 const int kSystemDelayMs = 66;
855 // Test a couple of corner cases and verify that the estimated delay is
856 // within a valid region (set to +-1.5 blocks). Note that these cases are
857 // sampling frequency dependent.
858 for (size_t i = 0; i < kProcessSampleRatesSize; i++) {
859 Init(kProcessSampleRates[i],
860 kProcessSampleRates[i],
861 kProcessSampleRates[i],
866 // Sampling frequency dependent variables.
867 const int num_ms_per_block = std::max(4,
868 640 / frame_->samples_per_channel_);
869 const int delay_min_ms = -kLookaheadBlocks * num_ms_per_block;
870 const int delay_max_ms = (kMaxDelayBlocks - 1) * num_ms_per_block;
872 // 1) Verify correct delay estimate at lookahead boundary.
873 int delay_ms = TruncateToMultipleOf10(kSystemDelayMs + delay_min_ms);
874 ProcessDelayVerificationTest(delay_ms, kSystemDelayMs, delay_min_ms,
876 // 2) A delay less than maximum lookahead should give an delay estimate at
877 // the boundary (= -kLookaheadBlocks * num_ms_per_block).
879 ProcessDelayVerificationTest(delay_ms, kSystemDelayMs, delay_min_ms,
881 // 3) Three values around zero delay. Note that we need to compensate for
882 // the fake system_delay.
883 delay_ms = TruncateToMultipleOf10(kSystemDelayMs - 10);
884 ProcessDelayVerificationTest(delay_ms, kSystemDelayMs, delay_min_ms,
886 delay_ms = TruncateToMultipleOf10(kSystemDelayMs);
887 ProcessDelayVerificationTest(delay_ms, kSystemDelayMs, delay_min_ms,
889 delay_ms = TruncateToMultipleOf10(kSystemDelayMs + 10);
890 ProcessDelayVerificationTest(delay_ms, kSystemDelayMs, delay_min_ms,
892 // 4) Verify correct delay estimate at maximum delay boundary.
893 delay_ms = TruncateToMultipleOf10(kSystemDelayMs + delay_max_ms);
894 ProcessDelayVerificationTest(delay_ms, kSystemDelayMs, delay_min_ms,
896 // 5) A delay above the maximum delay should give an estimate at the
897 // boundary (= (kMaxDelayBlocks - 1) * num_ms_per_block).
899 ProcessDelayVerificationTest(delay_ms, kSystemDelayMs, delay_min_ms,
904 TEST_F(ApmTest, EchoControlMobile) {
905 // AECM won't use super-wideband.
906 SetFrameSampleRate(frame_, 32000);
907 EXPECT_NOERR(apm_->ProcessStream(frame_));
908 EXPECT_EQ(apm_->kBadSampleRateError,
909 apm_->echo_control_mobile()->Enable(true));
910 SetFrameSampleRate(frame_, 16000);
911 EXPECT_NOERR(apm_->ProcessStream(frame_));
912 EXPECT_EQ(apm_->kNoError,
913 apm_->echo_control_mobile()->Enable(true));
914 SetFrameSampleRate(frame_, 32000);
915 EXPECT_EQ(apm_->kUnsupportedComponentError, apm_->ProcessStream(frame_));
917 // Turn AECM on (and AEC off)
918 Init(16000, 16000, 16000, 2, 2, 2, false);
919 EXPECT_EQ(apm_->kNoError, apm_->echo_control_mobile()->Enable(true));
920 EXPECT_TRUE(apm_->echo_control_mobile()->is_enabled());
922 // Toggle routing modes
923 EchoControlMobile::RoutingMode mode[] = {
924 EchoControlMobile::kQuietEarpieceOrHeadset,
925 EchoControlMobile::kEarpiece,
926 EchoControlMobile::kLoudEarpiece,
927 EchoControlMobile::kSpeakerphone,
928 EchoControlMobile::kLoudSpeakerphone,
930 for (size_t i = 0; i < sizeof(mode)/sizeof(*mode); i++) {
931 EXPECT_EQ(apm_->kNoError,
932 apm_->echo_control_mobile()->set_routing_mode(mode[i]));
934 apm_->echo_control_mobile()->routing_mode());
936 // Turn comfort noise off/on
937 EXPECT_EQ(apm_->kNoError,
938 apm_->echo_control_mobile()->enable_comfort_noise(false));
939 EXPECT_FALSE(apm_->echo_control_mobile()->is_comfort_noise_enabled());
940 EXPECT_EQ(apm_->kNoError,
941 apm_->echo_control_mobile()->enable_comfort_noise(true));
942 EXPECT_TRUE(apm_->echo_control_mobile()->is_comfort_noise_enabled());
943 // Set and get echo path
944 const size_t echo_path_size =
945 apm_->echo_control_mobile()->echo_path_size_bytes();
946 scoped_ptr<char[]> echo_path_in(new char[echo_path_size]);
947 scoped_ptr<char[]> echo_path_out(new char[echo_path_size]);
948 EXPECT_EQ(apm_->kNullPointerError,
949 apm_->echo_control_mobile()->SetEchoPath(NULL, echo_path_size));
950 EXPECT_EQ(apm_->kNullPointerError,
951 apm_->echo_control_mobile()->GetEchoPath(NULL, echo_path_size));
952 EXPECT_EQ(apm_->kBadParameterError,
953 apm_->echo_control_mobile()->GetEchoPath(echo_path_out.get(), 1));
954 EXPECT_EQ(apm_->kNoError,
955 apm_->echo_control_mobile()->GetEchoPath(echo_path_out.get(),
957 for (size_t i = 0; i < echo_path_size; i++) {
958 echo_path_in[i] = echo_path_out[i] + 1;
960 EXPECT_EQ(apm_->kBadParameterError,
961 apm_->echo_control_mobile()->SetEchoPath(echo_path_in.get(), 1));
962 EXPECT_EQ(apm_->kNoError,
963 apm_->echo_control_mobile()->SetEchoPath(echo_path_in.get(),
965 EXPECT_EQ(apm_->kNoError,
966 apm_->echo_control_mobile()->GetEchoPath(echo_path_out.get(),
968 for (size_t i = 0; i < echo_path_size; i++) {
969 EXPECT_EQ(echo_path_in[i], echo_path_out[i]);
972 // Process a few frames with NS in the default disabled state. This exercises
973 // a different codepath than with it enabled.
974 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
975 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
976 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
977 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
980 EXPECT_EQ(apm_->kNoError, apm_->echo_control_mobile()->Enable(false));
981 EXPECT_FALSE(apm_->echo_control_mobile()->is_enabled());
984 TEST_F(ApmTest, GainControl) {
985 // Testing gain modes
986 EXPECT_EQ(apm_->kNoError,
987 apm_->gain_control()->set_mode(
988 apm_->gain_control()->mode()));
990 GainControl::Mode mode[] = {
991 GainControl::kAdaptiveAnalog,
992 GainControl::kAdaptiveDigital,
993 GainControl::kFixedDigital
995 for (size_t i = 0; i < sizeof(mode)/sizeof(*mode); i++) {
996 EXPECT_EQ(apm_->kNoError,
997 apm_->gain_control()->set_mode(mode[i]));
998 EXPECT_EQ(mode[i], apm_->gain_control()->mode());
1000 // Testing invalid target levels
1001 EXPECT_EQ(apm_->kBadParameterError,
1002 apm_->gain_control()->set_target_level_dbfs(-3));
1003 EXPECT_EQ(apm_->kBadParameterError,
1004 apm_->gain_control()->set_target_level_dbfs(-40));
1005 // Testing valid target levels
1006 EXPECT_EQ(apm_->kNoError,
1007 apm_->gain_control()->set_target_level_dbfs(
1008 apm_->gain_control()->target_level_dbfs()));
1010 int level_dbfs[] = {0, 6, 31};
1011 for (size_t i = 0; i < sizeof(level_dbfs)/sizeof(*level_dbfs); i++) {
1012 EXPECT_EQ(apm_->kNoError,
1013 apm_->gain_control()->set_target_level_dbfs(level_dbfs[i]));
1014 EXPECT_EQ(level_dbfs[i], apm_->gain_control()->target_level_dbfs());
1017 // Testing invalid compression gains
1018 EXPECT_EQ(apm_->kBadParameterError,
1019 apm_->gain_control()->set_compression_gain_db(-1));
1020 EXPECT_EQ(apm_->kBadParameterError,
1021 apm_->gain_control()->set_compression_gain_db(100));
1023 // Testing valid compression gains
1024 EXPECT_EQ(apm_->kNoError,
1025 apm_->gain_control()->set_compression_gain_db(
1026 apm_->gain_control()->compression_gain_db()));
1028 int gain_db[] = {0, 10, 90};
1029 for (size_t i = 0; i < sizeof(gain_db)/sizeof(*gain_db); i++) {
1030 EXPECT_EQ(apm_->kNoError,
1031 apm_->gain_control()->set_compression_gain_db(gain_db[i]));
1032 EXPECT_EQ(gain_db[i], apm_->gain_control()->compression_gain_db());
1035 // Testing limiter off/on
1036 EXPECT_EQ(apm_->kNoError, apm_->gain_control()->enable_limiter(false));
1037 EXPECT_FALSE(apm_->gain_control()->is_limiter_enabled());
1038 EXPECT_EQ(apm_->kNoError, apm_->gain_control()->enable_limiter(true));
1039 EXPECT_TRUE(apm_->gain_control()->is_limiter_enabled());
1041 // Testing invalid level limits
1042 EXPECT_EQ(apm_->kBadParameterError,
1043 apm_->gain_control()->set_analog_level_limits(-1, 512));
1044 EXPECT_EQ(apm_->kBadParameterError,
1045 apm_->gain_control()->set_analog_level_limits(100000, 512));
1046 EXPECT_EQ(apm_->kBadParameterError,
1047 apm_->gain_control()->set_analog_level_limits(512, -1));
1048 EXPECT_EQ(apm_->kBadParameterError,
1049 apm_->gain_control()->set_analog_level_limits(512, 100000));
1050 EXPECT_EQ(apm_->kBadParameterError,
1051 apm_->gain_control()->set_analog_level_limits(512, 255));
1053 // Testing valid level limits
1054 EXPECT_EQ(apm_->kNoError,
1055 apm_->gain_control()->set_analog_level_limits(
1056 apm_->gain_control()->analog_level_minimum(),
1057 apm_->gain_control()->analog_level_maximum()));
1059 int min_level[] = {0, 255, 1024};
1060 for (size_t i = 0; i < sizeof(min_level)/sizeof(*min_level); i++) {
1061 EXPECT_EQ(apm_->kNoError,
1062 apm_->gain_control()->set_analog_level_limits(min_level[i], 1024));
1063 EXPECT_EQ(min_level[i], apm_->gain_control()->analog_level_minimum());
1066 int max_level[] = {0, 1024, 65535};
1067 for (size_t i = 0; i < sizeof(min_level)/sizeof(*min_level); i++) {
1068 EXPECT_EQ(apm_->kNoError,
1069 apm_->gain_control()->set_analog_level_limits(0, max_level[i]));
1070 EXPECT_EQ(max_level[i], apm_->gain_control()->analog_level_maximum());
1073 // TODO(ajm): stream_is_saturated() and stream_analog_level()
1076 EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(false));
1077 EXPECT_FALSE(apm_->gain_control()->is_enabled());
1080 void ApmTest::RunQuantizedVolumeDoesNotGetStuckTest(int sample_rate) {
1081 Init(sample_rate, sample_rate, sample_rate, 2, 2, 2, false);
1082 EXPECT_EQ(apm_->kNoError,
1083 apm_->gain_control()->set_mode(GainControl::kAdaptiveAnalog));
1084 EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
1086 int out_analog_level = 0;
1087 for (int i = 0; i < 2000; ++i) {
1088 ReadFrameWithRewind(near_file_, frame_);
1089 // Ensure the audio is at a low level, so the AGC will try to increase it.
1090 ScaleFrame(frame_, 0.25);
1092 // Always pass in the same volume.
1093 EXPECT_EQ(apm_->kNoError,
1094 apm_->gain_control()->set_stream_analog_level(100));
1095 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1096 out_analog_level = apm_->gain_control()->stream_analog_level();
1099 // Ensure the AGC is still able to reach the maximum.
1100 EXPECT_EQ(255, out_analog_level);
1103 // Verifies that despite volume slider quantization, the AGC can continue to
1104 // increase its volume.
1105 TEST_F(ApmTest, QuantizedVolumeDoesNotGetStuck) {
1106 for (size_t i = 0; i < kSampleRatesSize; ++i) {
1107 RunQuantizedVolumeDoesNotGetStuckTest(kSampleRates[i]);
1111 void ApmTest::RunManualVolumeChangeIsPossibleTest(int sample_rate) {
1112 Init(sample_rate, sample_rate, sample_rate, 2, 2, 2, false);
1113 EXPECT_EQ(apm_->kNoError,
1114 apm_->gain_control()->set_mode(GainControl::kAdaptiveAnalog));
1115 EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
1117 int out_analog_level = 100;
1118 for (int i = 0; i < 1000; ++i) {
1119 ReadFrameWithRewind(near_file_, frame_);
1120 // Ensure the audio is at a low level, so the AGC will try to increase it.
1121 ScaleFrame(frame_, 0.25);
1123 EXPECT_EQ(apm_->kNoError,
1124 apm_->gain_control()->set_stream_analog_level(out_analog_level));
1125 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1126 out_analog_level = apm_->gain_control()->stream_analog_level();
1129 // Ensure the volume was raised.
1130 EXPECT_GT(out_analog_level, 100);
1131 int highest_level_reached = out_analog_level;
1132 // Simulate a user manual volume change.
1133 out_analog_level = 100;
1135 for (int i = 0; i < 300; ++i) {
1136 ReadFrameWithRewind(near_file_, frame_);
1137 ScaleFrame(frame_, 0.25);
1139 EXPECT_EQ(apm_->kNoError,
1140 apm_->gain_control()->set_stream_analog_level(out_analog_level));
1141 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1142 out_analog_level = apm_->gain_control()->stream_analog_level();
1143 // Check that AGC respected the manually adjusted volume.
1144 EXPECT_LT(out_analog_level, highest_level_reached);
1146 // Check that the volume was still raised.
1147 EXPECT_GT(out_analog_level, 100);
1150 TEST_F(ApmTest, ManualVolumeChangeIsPossible) {
1151 for (size_t i = 0; i < kSampleRatesSize; ++i) {
1152 RunManualVolumeChangeIsPossibleTest(kSampleRates[i]);
1156 TEST_F(ApmTest, NoiseSuppression) {
1157 // Test valid suppression levels.
1158 NoiseSuppression::Level level[] = {
1159 NoiseSuppression::kLow,
1160 NoiseSuppression::kModerate,
1161 NoiseSuppression::kHigh,
1162 NoiseSuppression::kVeryHigh
1164 for (size_t i = 0; i < sizeof(level)/sizeof(*level); i++) {
1165 EXPECT_EQ(apm_->kNoError,
1166 apm_->noise_suppression()->set_level(level[i]));
1167 EXPECT_EQ(level[i], apm_->noise_suppression()->level());
1171 EXPECT_EQ(apm_->kNoError, apm_->noise_suppression()->Enable(true));
1172 EXPECT_TRUE(apm_->noise_suppression()->is_enabled());
1173 EXPECT_EQ(apm_->kNoError, apm_->noise_suppression()->Enable(false));
1174 EXPECT_FALSE(apm_->noise_suppression()->is_enabled());
1177 TEST_F(ApmTest, HighPassFilter) {
1178 // Turn HP filter on/off
1179 EXPECT_EQ(apm_->kNoError, apm_->high_pass_filter()->Enable(true));
1180 EXPECT_TRUE(apm_->high_pass_filter()->is_enabled());
1181 EXPECT_EQ(apm_->kNoError, apm_->high_pass_filter()->Enable(false));
1182 EXPECT_FALSE(apm_->high_pass_filter()->is_enabled());
1185 TEST_F(ApmTest, LevelEstimator) {
1186 // Turn level estimator on/off
1187 EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(false));
1188 EXPECT_FALSE(apm_->level_estimator()->is_enabled());
1190 EXPECT_EQ(apm_->kNotEnabledError, apm_->level_estimator()->RMS());
1192 EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(true));
1193 EXPECT_TRUE(apm_->level_estimator()->is_enabled());
1195 // Run this test in wideband; in super-wb, the splitting filter distorts the
1196 // audio enough to cause deviation from the expectation for small values.
1197 frame_->samples_per_channel_ = 160;
1198 frame_->num_channels_ = 2;
1199 frame_->sample_rate_hz_ = 16000;
1201 // Min value if no frames have been processed.
1202 EXPECT_EQ(127, apm_->level_estimator()->RMS());
1204 // Min value on zero frames.
1205 SetFrameTo(frame_, 0);
1206 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1207 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1208 EXPECT_EQ(127, apm_->level_estimator()->RMS());
1210 // Try a few RMS values.
1211 // (These also test that the value resets after retrieving it.)
1212 SetFrameTo(frame_, 32767);
1213 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1214 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1215 EXPECT_EQ(0, apm_->level_estimator()->RMS());
1217 SetFrameTo(frame_, 30000);
1218 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1219 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1220 EXPECT_EQ(1, apm_->level_estimator()->RMS());
1222 SetFrameTo(frame_, 10000);
1223 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1224 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1225 EXPECT_EQ(10, apm_->level_estimator()->RMS());
1227 SetFrameTo(frame_, 10);
1228 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1229 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1230 EXPECT_EQ(70, apm_->level_estimator()->RMS());
1232 // Verify reset after enable/disable.
1233 SetFrameTo(frame_, 32767);
1234 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1235 EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(false));
1236 EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(true));
1237 SetFrameTo(frame_, 1);
1238 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1239 EXPECT_EQ(90, apm_->level_estimator()->RMS());
1241 // Verify reset after initialize.
1242 SetFrameTo(frame_, 32767);
1243 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1244 EXPECT_EQ(apm_->kNoError, apm_->Initialize());
1245 SetFrameTo(frame_, 1);
1246 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1247 EXPECT_EQ(90, apm_->level_estimator()->RMS());
1250 TEST_F(ApmTest, VoiceDetection) {
1251 // Test external VAD
1252 EXPECT_EQ(apm_->kNoError,
1253 apm_->voice_detection()->set_stream_has_voice(true));
1254 EXPECT_TRUE(apm_->voice_detection()->stream_has_voice());
1255 EXPECT_EQ(apm_->kNoError,
1256 apm_->voice_detection()->set_stream_has_voice(false));
1257 EXPECT_FALSE(apm_->voice_detection()->stream_has_voice());
1259 // Test valid likelihoods
1260 VoiceDetection::Likelihood likelihood[] = {
1261 VoiceDetection::kVeryLowLikelihood,
1262 VoiceDetection::kLowLikelihood,
1263 VoiceDetection::kModerateLikelihood,
1264 VoiceDetection::kHighLikelihood
1266 for (size_t i = 0; i < sizeof(likelihood)/sizeof(*likelihood); i++) {
1267 EXPECT_EQ(apm_->kNoError,
1268 apm_->voice_detection()->set_likelihood(likelihood[i]));
1269 EXPECT_EQ(likelihood[i], apm_->voice_detection()->likelihood());
1272 /* TODO(bjornv): Enable once VAD supports other frame lengths than 10 ms
1273 // Test invalid frame sizes
1274 EXPECT_EQ(apm_->kBadParameterError,
1275 apm_->voice_detection()->set_frame_size_ms(12));
1277 // Test valid frame sizes
1278 for (int i = 10; i <= 30; i += 10) {
1279 EXPECT_EQ(apm_->kNoError,
1280 apm_->voice_detection()->set_frame_size_ms(i));
1281 EXPECT_EQ(i, apm_->voice_detection()->frame_size_ms());
1286 EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(true));
1287 EXPECT_TRUE(apm_->voice_detection()->is_enabled());
1288 EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(false));
1289 EXPECT_FALSE(apm_->voice_detection()->is_enabled());
1291 // Test that AudioFrame activity is maintained when VAD is disabled.
1292 EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(false));
1293 AudioFrame::VADActivity activity[] = {
1294 AudioFrame::kVadActive,
1295 AudioFrame::kVadPassive,
1296 AudioFrame::kVadUnknown
1298 for (size_t i = 0; i < sizeof(activity)/sizeof(*activity); i++) {
1299 frame_->vad_activity_ = activity[i];
1300 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1301 EXPECT_EQ(activity[i], frame_->vad_activity_);
1304 // Test that AudioFrame activity is set when VAD is enabled.
1305 EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(true));
1306 frame_->vad_activity_ = AudioFrame::kVadUnknown;
1307 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1308 EXPECT_NE(AudioFrame::kVadUnknown, frame_->vad_activity_);
1310 // TODO(bjornv): Add tests for streamed voice; stream_has_voice()
1313 TEST_F(ApmTest, AllProcessingDisabledByDefault) {
1314 EXPECT_FALSE(apm_->echo_cancellation()->is_enabled());
1315 EXPECT_FALSE(apm_->echo_control_mobile()->is_enabled());
1316 EXPECT_FALSE(apm_->gain_control()->is_enabled());
1317 EXPECT_FALSE(apm_->high_pass_filter()->is_enabled());
1318 EXPECT_FALSE(apm_->level_estimator()->is_enabled());
1319 EXPECT_FALSE(apm_->noise_suppression()->is_enabled());
1320 EXPECT_FALSE(apm_->voice_detection()->is_enabled());
1323 TEST_F(ApmTest, NoProcessingWhenAllComponentsDisabled) {
1324 for (size_t i = 0; i < kSampleRatesSize; i++) {
1325 Init(kSampleRates[i], kSampleRates[i], kSampleRates[i], 2, 2, 2, false);
1326 SetFrameTo(frame_, 1000, 2000);
1327 AudioFrame frame_copy;
1328 frame_copy.CopyFrom(*frame_);
1329 for (int j = 0; j < 1000; j++) {
1330 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1331 EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy));
1336 TEST_F(ApmTest, IdenticalInputChannelsResultInIdenticalOutputChannels) {
1337 EnableAllComponents();
1339 for (size_t i = 0; i < kProcessSampleRatesSize; i++) {
1340 Init(kProcessSampleRates[i],
1341 kProcessSampleRates[i],
1342 kProcessSampleRates[i],
1347 int analog_level = 127;
1348 ASSERT_EQ(0, feof(far_file_));
1349 ASSERT_EQ(0, feof(near_file_));
1350 while (ReadFrame(far_file_, revframe_) && ReadFrame(near_file_, frame_)) {
1351 CopyLeftToRightChannel(revframe_->data_, revframe_->samples_per_channel_);
1353 ASSERT_EQ(kNoErr, apm_->AnalyzeReverseStream(revframe_));
1355 CopyLeftToRightChannel(frame_->data_, frame_->samples_per_channel_);
1356 frame_->vad_activity_ = AudioFrame::kVadUnknown;
1358 ASSERT_EQ(kNoErr, apm_->set_stream_delay_ms(0));
1359 apm_->echo_cancellation()->set_stream_drift_samples(0);
1361 apm_->gain_control()->set_stream_analog_level(analog_level));
1362 ASSERT_EQ(kNoErr, apm_->ProcessStream(frame_));
1363 analog_level = apm_->gain_control()->stream_analog_level();
1365 VerifyChannelsAreEqual(frame_->data_, frame_->samples_per_channel_);
1372 TEST_F(ApmTest, SplittingFilter) {
1373 // Verify the filter is not active through undistorted audio when:
1374 // 1. No components are enabled...
1375 SetFrameTo(frame_, 1000);
1376 AudioFrame frame_copy;
1377 frame_copy.CopyFrom(*frame_);
1378 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1379 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1380 EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy));
1382 // 2. Only the level estimator is enabled...
1383 SetFrameTo(frame_, 1000);
1384 frame_copy.CopyFrom(*frame_);
1385 EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(true));
1386 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1387 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1388 EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy));
1389 EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(false));
1391 // 3. Only VAD is enabled...
1392 SetFrameTo(frame_, 1000);
1393 frame_copy.CopyFrom(*frame_);
1394 EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(true));
1395 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1396 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1397 EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy));
1398 EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(false));
1400 // 4. Both VAD and the level estimator are enabled...
1401 SetFrameTo(frame_, 1000);
1402 frame_copy.CopyFrom(*frame_);
1403 EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(true));
1404 EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(true));
1405 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1406 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1407 EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy));
1408 EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(false));
1409 EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(false));
1411 // 5. Not using super-wb.
1412 frame_->samples_per_channel_ = 160;
1413 frame_->num_channels_ = 2;
1414 frame_->sample_rate_hz_ = 16000;
1415 // Enable AEC, which would require the filter in super-wb. We rely on the
1416 // first few frames of data being unaffected by the AEC.
1417 // TODO(andrew): This test, and the one below, rely rather tenuously on the
1418 // behavior of the AEC. Think of something more robust.
1419 EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
1420 // Make sure we have extended filter enabled. This makes sure nothing is
1421 // touched until we have a farend frame.
1423 config.Set<DelayCorrection>(new DelayCorrection(true));
1424 apm_->SetExtraOptions(config);
1425 SetFrameTo(frame_, 1000);
1426 frame_copy.CopyFrom(*frame_);
1427 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
1428 apm_->echo_cancellation()->set_stream_drift_samples(0);
1429 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1430 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
1431 apm_->echo_cancellation()->set_stream_drift_samples(0);
1432 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1433 EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy));
1435 // Check the test is valid. We should have distortion from the filter
1436 // when AEC is enabled (which won't affect the audio).
1437 frame_->samples_per_channel_ = 320;
1438 frame_->num_channels_ = 2;
1439 frame_->sample_rate_hz_ = 32000;
1440 SetFrameTo(frame_, 1000);
1441 frame_copy.CopyFrom(*frame_);
1442 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
1443 apm_->echo_cancellation()->set_stream_drift_samples(0);
1444 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1445 EXPECT_FALSE(FrameDataAreEqual(*frame_, frame_copy));
1448 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
1449 void ApmTest::ProcessDebugDump(const std::string& in_filename,
1450 const std::string& out_filename,
1452 FILE* in_file = fopen(in_filename.c_str(), "rb");
1453 ASSERT_TRUE(in_file != NULL);
1454 audioproc::Event event_msg;
1455 bool first_init = true;
1457 while (ReadMessageFromFile(in_file, &event_msg)) {
1458 if (event_msg.type() == audioproc::Event::INIT) {
1459 const audioproc::Init msg = event_msg.init();
1460 int reverse_sample_rate = msg.sample_rate();
1461 if (msg.has_reverse_sample_rate()) {
1462 reverse_sample_rate = msg.reverse_sample_rate();
1464 int output_sample_rate = msg.sample_rate();
1465 if (msg.has_output_sample_rate()) {
1466 output_sample_rate = msg.output_sample_rate();
1469 Init(msg.sample_rate(),
1471 reverse_sample_rate,
1472 msg.num_input_channels(),
1473 msg.num_output_channels(),
1474 msg.num_reverse_channels(),
1477 // StartDebugRecording() writes an additional init message. Don't start
1478 // recording until after the first init to avoid the extra message.
1479 EXPECT_NOERR(apm_->StartDebugRecording(out_filename.c_str()));
1483 } else if (event_msg.type() == audioproc::Event::REVERSE_STREAM) {
1484 const audioproc::ReverseStream msg = event_msg.reverse_stream();
1486 if (msg.channel_size() > 0) {
1487 ASSERT_EQ(revframe_->num_channels_, msg.channel_size());
1488 for (int i = 0; i < msg.channel_size(); ++i) {
1489 memcpy(revfloat_cb_->channel(i), msg.channel(i).data(),
1490 msg.channel(i).size());
1493 memcpy(revframe_->data_, msg.data().data(), msg.data().size());
1494 if (format == kFloatFormat) {
1495 // We're using an int16 input file; convert to float.
1496 ConvertToFloat(*revframe_, revfloat_cb_.get());
1499 AnalyzeReverseStreamChooser(format);
1501 } else if (event_msg.type() == audioproc::Event::STREAM) {
1502 const audioproc::Stream msg = event_msg.stream();
1503 // ProcessStream could have changed this for the output frame.
1504 frame_->num_channels_ = apm_->num_input_channels();
1506 EXPECT_NOERR(apm_->gain_control()->set_stream_analog_level(msg.level()));
1507 EXPECT_NOERR(apm_->set_stream_delay_ms(msg.delay()));
1508 apm_->echo_cancellation()->set_stream_drift_samples(msg.drift());
1509 if (msg.has_keypress()) {
1510 apm_->set_stream_key_pressed(msg.keypress());
1512 apm_->set_stream_key_pressed(true);
1515 if (msg.input_channel_size() > 0) {
1516 ASSERT_EQ(frame_->num_channels_, msg.input_channel_size());
1517 for (int i = 0; i < msg.input_channel_size(); ++i) {
1518 memcpy(float_cb_->channel(i), msg.input_channel(i).data(),
1519 msg.input_channel(i).size());
1522 memcpy(frame_->data_, msg.input_data().data(), msg.input_data().size());
1523 if (format == kFloatFormat) {
1524 // We're using an int16 input file; convert to float.
1525 ConvertToFloat(*frame_, float_cb_.get());
1528 ProcessStreamChooser(format);
1531 EXPECT_NOERR(apm_->StopDebugRecording());
1535 void ApmTest::VerifyDebugDumpTest(Format format) {
1536 const std::string in_filename = test::ResourcePath("ref03", "aecdump");
1537 std::string format_string;
1540 format_string = "_int";
1543 format_string = "_float";
1546 const std::string ref_filename =
1547 test::OutputPath() + "ref" + format_string + ".aecdump";
1548 const std::string out_filename =
1549 test::OutputPath() + "out" + format_string + ".aecdump";
1550 EnableAllComponents();
1551 ProcessDebugDump(in_filename, ref_filename, format);
1552 ProcessDebugDump(ref_filename, out_filename, format);
1554 FILE* ref_file = fopen(ref_filename.c_str(), "rb");
1555 FILE* out_file = fopen(out_filename.c_str(), "rb");
1556 ASSERT_TRUE(ref_file != NULL);
1557 ASSERT_TRUE(out_file != NULL);
1558 scoped_ptr<uint8_t[]> ref_bytes;
1559 scoped_ptr<uint8_t[]> out_bytes;
1561 size_t ref_size = ReadMessageBytesFromFile(ref_file, &ref_bytes);
1562 size_t out_size = ReadMessageBytesFromFile(out_file, &out_bytes);
1563 size_t bytes_read = 0;
1564 while (ref_size > 0 && out_size > 0) {
1565 bytes_read += ref_size;
1566 EXPECT_EQ(ref_size, out_size);
1567 EXPECT_EQ(0, memcmp(ref_bytes.get(), out_bytes.get(), ref_size));
1568 ref_size = ReadMessageBytesFromFile(ref_file, &ref_bytes);
1569 out_size = ReadMessageBytesFromFile(out_file, &out_bytes);
1571 EXPECT_GT(bytes_read, 0u);
1572 EXPECT_NE(0, feof(ref_file));
1573 EXPECT_NE(0, feof(out_file));
1574 ASSERT_EQ(0, fclose(ref_file));
1575 ASSERT_EQ(0, fclose(out_file));
1578 TEST_F(ApmTest, VerifyDebugDumpInt) {
1579 VerifyDebugDumpTest(kIntFormat);
1582 TEST_F(ApmTest, VerifyDebugDumpFloat) {
1583 VerifyDebugDumpTest(kFloatFormat);
1587 // TODO(andrew): expand test to verify output.
1588 TEST_F(ApmTest, DebugDump) {
1589 const std::string filename = test::OutputPath() + "debug.aec";
1590 EXPECT_EQ(apm_->kNullPointerError,
1591 apm_->StartDebugRecording(static_cast<const char*>(NULL)));
1593 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
1594 // Stopping without having started should be OK.
1595 EXPECT_EQ(apm_->kNoError, apm_->StopDebugRecording());
1597 EXPECT_EQ(apm_->kNoError, apm_->StartDebugRecording(filename.c_str()));
1598 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1599 EXPECT_EQ(apm_->kNoError, apm_->AnalyzeReverseStream(revframe_));
1600 EXPECT_EQ(apm_->kNoError, apm_->StopDebugRecording());
1602 // Verify the file has been written.
1603 FILE* fid = fopen(filename.c_str(), "r");
1604 ASSERT_TRUE(fid != NULL);
1607 ASSERT_EQ(0, fclose(fid));
1608 ASSERT_EQ(0, remove(filename.c_str()));
1610 EXPECT_EQ(apm_->kUnsupportedFunctionError,
1611 apm_->StartDebugRecording(filename.c_str()));
1612 EXPECT_EQ(apm_->kUnsupportedFunctionError, apm_->StopDebugRecording());
1614 // Verify the file has NOT been written.
1615 ASSERT_TRUE(fopen(filename.c_str(), "r") == NULL);
1616 #endif // WEBRTC_AUDIOPROC_DEBUG_DUMP
1619 // TODO(andrew): expand test to verify output.
1620 TEST_F(ApmTest, DebugDumpFromFileHandle) {
1622 EXPECT_EQ(apm_->kNullPointerError, apm_->StartDebugRecording(fid));
1623 const std::string filename = test::OutputPath() + "debug.aec";
1624 fid = fopen(filename.c_str(), "w");
1627 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
1628 // Stopping without having started should be OK.
1629 EXPECT_EQ(apm_->kNoError, apm_->StopDebugRecording());
1631 EXPECT_EQ(apm_->kNoError, apm_->StartDebugRecording(fid));
1632 EXPECT_EQ(apm_->kNoError, apm_->AnalyzeReverseStream(revframe_));
1633 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1634 EXPECT_EQ(apm_->kNoError, apm_->StopDebugRecording());
1636 // Verify the file has been written.
1637 fid = fopen(filename.c_str(), "r");
1638 ASSERT_TRUE(fid != NULL);
1641 ASSERT_EQ(0, fclose(fid));
1642 ASSERT_EQ(0, remove(filename.c_str()));
1644 EXPECT_EQ(apm_->kUnsupportedFunctionError,
1645 apm_->StartDebugRecording(fid));
1646 EXPECT_EQ(apm_->kUnsupportedFunctionError, apm_->StopDebugRecording());
1648 ASSERT_EQ(0, fclose(fid));
1649 #endif // WEBRTC_AUDIOPROC_DEBUG_DUMP
1652 TEST_F(ApmTest, FloatAndIntInterfacesGiveSimilarResults) {
1653 audioproc::OutputData ref_data;
1654 OpenFileAndReadMessage(ref_filename_, &ref_data);
1657 config.Set<ExperimentalAgc>(new ExperimentalAgc(false));
1658 scoped_ptr<AudioProcessing> fapm(AudioProcessing::Create(config));
1659 EnableAllComponents();
1660 EnableAllAPComponents(fapm.get());
1661 for (int i = 0; i < ref_data.test_size(); i++) {
1662 printf("Running test %d of %d...\n", i + 1, ref_data.test_size());
1664 audioproc::Test* test = ref_data.mutable_test(i);
1665 // TODO(ajm): Restore downmixing test cases.
1666 if (test->num_input_channels() != test->num_output_channels())
1669 const int num_render_channels = test->num_reverse_channels();
1670 const int num_input_channels = test->num_input_channels();
1671 const int num_output_channels = test->num_output_channels();
1672 const int samples_per_channel = test->sample_rate() *
1673 AudioProcessing::kChunkSizeMs / 1000;
1674 const int output_length = samples_per_channel * num_output_channels;
1676 Init(test->sample_rate(), test->sample_rate(), test->sample_rate(),
1677 num_input_channels, num_output_channels, num_render_channels, true);
1680 ChannelBuffer<int16_t> output_cb(samples_per_channel, num_input_channels);
1681 ChannelBuffer<int16_t> output_int16(samples_per_channel,
1682 num_input_channels);
1684 int analog_level = 127;
1685 while (ReadFrame(far_file_, revframe_, revfloat_cb_.get()) &&
1686 ReadFrame(near_file_, frame_, float_cb_.get())) {
1687 frame_->vad_activity_ = AudioFrame::kVadUnknown;
1689 EXPECT_NOERR(apm_->AnalyzeReverseStream(revframe_));
1690 EXPECT_NOERR(fapm->AnalyzeReverseStream(
1691 revfloat_cb_->channels(),
1692 samples_per_channel,
1693 test->sample_rate(),
1694 LayoutFromChannels(num_render_channels)));
1696 EXPECT_NOERR(apm_->set_stream_delay_ms(0));
1697 EXPECT_NOERR(fapm->set_stream_delay_ms(0));
1698 apm_->echo_cancellation()->set_stream_drift_samples(0);
1699 fapm->echo_cancellation()->set_stream_drift_samples(0);
1700 EXPECT_NOERR(apm_->gain_control()->set_stream_analog_level(analog_level));
1701 EXPECT_NOERR(fapm->gain_control()->set_stream_analog_level(analog_level));
1703 EXPECT_NOERR(apm_->ProcessStream(frame_));
1704 Deinterleave(frame_->data_, samples_per_channel, num_output_channels,
1705 output_int16.channels());
1707 EXPECT_NOERR(fapm->ProcessStream(
1708 float_cb_->channels(),
1709 samples_per_channel,
1710 test->sample_rate(),
1711 LayoutFromChannels(num_input_channels),
1712 test->sample_rate(),
1713 LayoutFromChannels(num_output_channels),
1714 float_cb_->channels()));
1716 FloatToS16(float_cb_->data(), output_length, output_cb.data());
1717 for (int j = 0; j < num_output_channels; ++j) {
1719 float snr = ComputeSNR(output_int16.channel(j), output_cb.channel(j),
1720 samples_per_channel, &variance);
1721 #if defined(WEBRTC_AUDIOPROC_FIXED_PROFILE)
1722 // There are a few chunks in the fixed-point profile that give low SNR.
1723 // Listening confirmed the difference is acceptable.
1724 const float kVarianceThreshold = 150;
1725 const float kSNRThreshold = 10;
1727 const float kVarianceThreshold = 20;
1728 const float kSNRThreshold = 20;
1730 // Skip frames with low energy.
1731 if (sqrt(variance) > kVarianceThreshold) {
1732 EXPECT_LT(kSNRThreshold, snr);
1736 analog_level = fapm->gain_control()->stream_analog_level();
1737 EXPECT_EQ(apm_->gain_control()->stream_analog_level(),
1738 fapm->gain_control()->stream_analog_level());
1739 EXPECT_EQ(apm_->echo_cancellation()->stream_has_echo(),
1740 fapm->echo_cancellation()->stream_has_echo());
1741 EXPECT_NEAR(apm_->noise_suppression()->speech_probability(),
1742 fapm->noise_suppression()->speech_probability(),
1745 // Reset in case of downmixing.
1746 frame_->num_channels_ = test->num_input_channels();
1753 // TODO(andrew): Add a test to process a few frames with different combinations
1754 // of enabled components.
1756 TEST_F(ApmTest, Process) {
1757 GOOGLE_PROTOBUF_VERIFY_VERSION;
1758 audioproc::OutputData ref_data;
1760 if (!write_ref_data) {
1761 OpenFileAndReadMessage(ref_filename_, &ref_data);
1763 // Write the desired tests to the protobuf reference file.
1764 for (size_t i = 0; i < kChannelsSize; i++) {
1765 for (size_t j = 0; j < kChannelsSize; j++) {
1766 for (size_t l = 0; l < kProcessSampleRatesSize; l++) {
1767 audioproc::Test* test = ref_data.add_test();
1768 test->set_num_reverse_channels(kChannels[i]);
1769 test->set_num_input_channels(kChannels[j]);
1770 test->set_num_output_channels(kChannels[j]);
1771 test->set_sample_rate(kProcessSampleRates[l]);
1777 EnableAllComponents();
1779 for (int i = 0; i < ref_data.test_size(); i++) {
1780 printf("Running test %d of %d...\n", i + 1, ref_data.test_size());
1782 audioproc::Test* test = ref_data.mutable_test(i);
1783 // TODO(ajm): We no longer allow different input and output channels. Skip
1784 // these tests for now, but they should be removed from the set.
1785 if (test->num_input_channels() != test->num_output_channels())
1788 Init(test->sample_rate(),
1789 test->sample_rate(),
1790 test->sample_rate(),
1791 test->num_input_channels(),
1792 test->num_output_channels(),
1793 test->num_reverse_channels(),
1796 int frame_count = 0;
1797 int has_echo_count = 0;
1798 int has_voice_count = 0;
1799 int is_saturated_count = 0;
1800 int analog_level = 127;
1801 int analog_level_average = 0;
1802 int max_output_average = 0;
1803 float ns_speech_prob_average = 0.0f;
1805 while (ReadFrame(far_file_, revframe_) && ReadFrame(near_file_, frame_)) {
1806 EXPECT_EQ(apm_->kNoError, apm_->AnalyzeReverseStream(revframe_));
1808 frame_->vad_activity_ = AudioFrame::kVadUnknown;
1810 EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
1811 apm_->echo_cancellation()->set_stream_drift_samples(0);
1812 EXPECT_EQ(apm_->kNoError,
1813 apm_->gain_control()->set_stream_analog_level(analog_level));
1815 EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1817 // Ensure the frame was downmixed properly.
1818 EXPECT_EQ(test->num_output_channels(), frame_->num_channels_);
1820 max_output_average += MaxAudioFrame(*frame_);
1822 if (apm_->echo_cancellation()->stream_has_echo()) {
1826 analog_level = apm_->gain_control()->stream_analog_level();
1827 analog_level_average += analog_level;
1828 if (apm_->gain_control()->stream_is_saturated()) {
1829 is_saturated_count++;
1831 if (apm_->voice_detection()->stream_has_voice()) {
1833 EXPECT_EQ(AudioFrame::kVadActive, frame_->vad_activity_);
1835 EXPECT_EQ(AudioFrame::kVadPassive, frame_->vad_activity_);
1838 ns_speech_prob_average += apm_->noise_suppression()->speech_probability();
1840 size_t frame_size = frame_->samples_per_channel_ * frame_->num_channels_;
1841 size_t write_count = fwrite(frame_->data_,
1845 ASSERT_EQ(frame_size, write_count);
1847 // Reset in case of downmixing.
1848 frame_->num_channels_ = test->num_input_channels();
1851 max_output_average /= frame_count;
1852 analog_level_average /= frame_count;
1853 ns_speech_prob_average /= frame_count;
1855 #if defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
1856 EchoCancellation::Metrics echo_metrics;
1857 EXPECT_EQ(apm_->kNoError,
1858 apm_->echo_cancellation()->GetMetrics(&echo_metrics));
1861 EXPECT_EQ(apm_->kNoError,
1862 apm_->echo_cancellation()->GetDelayMetrics(&median, &std));
1864 int rms_level = apm_->level_estimator()->RMS();
1865 EXPECT_LE(0, rms_level);
1866 EXPECT_GE(127, rms_level);
1869 if (!write_ref_data) {
1870 const int kIntNear = 1;
1871 // When running the test on a N7 we get a {2, 6} difference of
1872 // |has_voice_count| and |max_output_average| is up to 18 higher.
1873 // All numbers being consistently higher on N7 compare to ref_data.
1874 // TODO(bjornv): If we start getting more of these offsets on Android we
1875 // should consider a different approach. Either using one slack for all,
1876 // or generate a separate android reference.
1877 #if defined(WEBRTC_ANDROID)
1878 const int kHasVoiceCountOffset = 3;
1879 const int kHasVoiceCountNear = 3;
1880 const int kMaxOutputAverageOffset = 9;
1881 const int kMaxOutputAverageNear = 9;
1883 const int kHasVoiceCountOffset = 0;
1884 const int kHasVoiceCountNear = kIntNear;
1885 const int kMaxOutputAverageOffset = 0;
1886 const int kMaxOutputAverageNear = kIntNear;
1888 EXPECT_NEAR(test->has_echo_count(), has_echo_count, kIntNear);
1889 EXPECT_NEAR(test->has_voice_count(),
1890 has_voice_count - kHasVoiceCountOffset,
1891 kHasVoiceCountNear);
1892 EXPECT_NEAR(test->is_saturated_count(), is_saturated_count, kIntNear);
1894 EXPECT_NEAR(test->analog_level_average(), analog_level_average, kIntNear);
1895 EXPECT_NEAR(test->max_output_average(),
1896 max_output_average - kMaxOutputAverageOffset,
1897 kMaxOutputAverageNear);
1899 #if defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
1900 audioproc::Test::EchoMetrics reference = test->echo_metrics();
1901 TestStats(echo_metrics.residual_echo_return_loss,
1902 reference.residual_echo_return_loss());
1903 TestStats(echo_metrics.echo_return_loss,
1904 reference.echo_return_loss());
1905 TestStats(echo_metrics.echo_return_loss_enhancement,
1906 reference.echo_return_loss_enhancement());
1907 TestStats(echo_metrics.a_nlp,
1910 const double kFloatNear = 0.0005;
1911 audioproc::Test::DelayMetrics reference_delay = test->delay_metrics();
1912 EXPECT_NEAR(reference_delay.median(), median, kIntNear);
1913 EXPECT_NEAR(reference_delay.std(), std, kIntNear);
1915 EXPECT_NEAR(test->rms_level(), rms_level, kIntNear);
1917 EXPECT_NEAR(test->ns_speech_probability_average(),
1918 ns_speech_prob_average,
1922 test->set_has_echo_count(has_echo_count);
1923 test->set_has_voice_count(has_voice_count);
1924 test->set_is_saturated_count(is_saturated_count);
1926 test->set_analog_level_average(analog_level_average);
1927 test->set_max_output_average(max_output_average);
1929 #if defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
1930 audioproc::Test::EchoMetrics* message = test->mutable_echo_metrics();
1931 WriteStatsMessage(echo_metrics.residual_echo_return_loss,
1932 message->mutable_residual_echo_return_loss());
1933 WriteStatsMessage(echo_metrics.echo_return_loss,
1934 message->mutable_echo_return_loss());
1935 WriteStatsMessage(echo_metrics.echo_return_loss_enhancement,
1936 message->mutable_echo_return_loss_enhancement());
1937 WriteStatsMessage(echo_metrics.a_nlp,
1938 message->mutable_a_nlp());
1940 audioproc::Test::DelayMetrics* message_delay =
1941 test->mutable_delay_metrics();
1942 message_delay->set_median(median);
1943 message_delay->set_std(std);
1945 test->set_rms_level(rms_level);
1947 EXPECT_LE(0.0f, ns_speech_prob_average);
1948 EXPECT_GE(1.0f, ns_speech_prob_average);
1949 test->set_ns_speech_probability_average(ns_speech_prob_average);
1957 if (write_ref_data) {
1958 OpenFileAndWriteMessage(ref_filename_, ref_data);
1962 TEST_F(ApmTest, NoErrorsWithKeyboardChannel) {
1963 struct ChannelFormat {
1964 AudioProcessing::ChannelLayout in_layout;
1965 AudioProcessing::ChannelLayout out_layout;
1967 ChannelFormat cf[] = {
1968 {AudioProcessing::kMonoAndKeyboard, AudioProcessing::kMono},
1969 {AudioProcessing::kStereoAndKeyboard, AudioProcessing::kMono},
1970 {AudioProcessing::kStereoAndKeyboard, AudioProcessing::kStereo},
1972 size_t channel_format_size = sizeof(cf) / sizeof(*cf);
1974 scoped_ptr<AudioProcessing> ap(AudioProcessing::Create());
1975 // Enable one component just to ensure some processing takes place.
1976 ap->noise_suppression()->Enable(true);
1977 for (size_t i = 0; i < channel_format_size; ++i) {
1978 const int in_rate = 44100;
1979 const int out_rate = 48000;
1980 ChannelBuffer<float> in_cb(SamplesFromRate(in_rate),
1981 TotalChannelsFromLayout(cf[i].in_layout));
1982 ChannelBuffer<float> out_cb(SamplesFromRate(out_rate),
1983 ChannelsFromLayout(cf[i].out_layout));
1985 // Run over a few chunks.
1986 for (int j = 0; j < 10; ++j) {
1987 EXPECT_NOERR(ap->ProcessStream(
1989 in_cb.samples_per_channel(),
1994 out_cb.channels()));
1999 // Reads a 10 ms chunk of int16 interleaved audio from the given (assumed
2000 // stereo) file, converts to deinterleaved float (optionally downmixing) and
2001 // returns the result in |cb|. Returns false if the file ended (or on error) and
2004 // |int_data| and |float_data| are just temporary space that must be
2005 // sufficiently large to hold the 10 ms chunk.
2006 bool ReadChunk(FILE* file, int16_t* int_data, float* float_data,
2007 ChannelBuffer<float>* cb) {
2008 // The files always contain stereo audio.
2009 size_t frame_size = cb->samples_per_channel() * 2;
2010 size_t read_count = fread(int_data, sizeof(int16_t), frame_size, file);
2011 if (read_count != frame_size) {
2012 // Check that the file really ended.
2014 return false; // This is expected.
2017 S16ToFloat(int_data, frame_size, float_data);
2018 if (cb->num_channels() == 1) {
2019 MixStereoToMono(float_data, cb->data(), cb->samples_per_channel());
2021 Deinterleave(float_data, cb->samples_per_channel(), 2,
2028 // Compares the reference and test arrays over a region around the expected
2029 // delay. Finds the highest SNR in that region and adds the variance and squared
2030 // error results to the supplied accumulators.
2031 void UpdateBestSNR(const float* ref,
2035 double* variance_acc,
2036 double* sq_error_acc) {
2037 double best_snr = std::numeric_limits<double>::min();
2038 double best_variance = 0;
2039 double best_sq_error = 0;
2040 // Search over a region of eight samples around the expected delay.
2041 for (int delay = std::max(expected_delay - 4, 0); delay <= expected_delay + 4;
2043 double sq_error = 0;
2044 double variance = 0;
2045 for (int i = 0; i < length - delay; ++i) {
2046 double error = test[i + delay] - ref[i];
2047 sq_error += error * error;
2048 variance += ref[i] * ref[i];
2051 if (sq_error == 0) {
2052 *variance_acc += variance;
2055 double snr = variance / sq_error;
2056 if (snr > best_snr) {
2058 best_variance = variance;
2059 best_sq_error = sq_error;
2063 *variance_acc += best_variance;
2064 *sq_error_acc += best_sq_error;
2067 // Used to test a multitude of sample rate and channel combinations. It works
2068 // by first producing a set of reference files (in SetUpTestCase) that are
2069 // assumed to be correct, as the used parameters are verified by other tests
2070 // in this collection. Primarily the reference files are all produced at
2071 // "native" rates which do not involve any resampling.
2073 // Each test pass produces an output file with a particular format. The output
2074 // is matched against the reference file closest to its internal processing
2075 // format. If necessary the output is resampled back to its process format.
2076 // Due to the resampling distortion, we don't expect identical results, but
2077 // enforce SNR thresholds which vary depending on the format. 0 is a special
2078 // case SNR which corresponds to inf, or zero error.
2079 typedef std::tr1::tuple<int, int, int, double> AudioProcessingTestData;
2080 class AudioProcessingTest
2081 : public testing::TestWithParam<AudioProcessingTestData> {
2083 AudioProcessingTest()
2084 : input_rate_(std::tr1::get<0>(GetParam())),
2085 output_rate_(std::tr1::get<1>(GetParam())),
2086 reverse_rate_(std::tr1::get<2>(GetParam())),
2087 expected_snr_(std::tr1::get<3>(GetParam())) {}
2089 virtual ~AudioProcessingTest() {}
2091 static void SetUpTestCase() {
2092 // Create all needed output reference files.
2093 const int kNativeRates[] = {8000, 16000, 32000};
2094 const size_t kNativeRatesSize =
2095 sizeof(kNativeRates) / sizeof(*kNativeRates);
2096 const int kNumChannels[] = {1, 2};
2097 const size_t kNumChannelsSize =
2098 sizeof(kNumChannels) / sizeof(*kNumChannels);
2099 for (size_t i = 0; i < kNativeRatesSize; ++i) {
2100 for (size_t j = 0; j < kNumChannelsSize; ++j) {
2101 for (size_t k = 0; k < kNumChannelsSize; ++k) {
2102 // The reference files always have matching input and output channels.
2103 ProcessFormat(kNativeRates[i],
2115 // Runs a process pass on files with the given parameters and dumps the output
2116 // to a file specified with |output_file_prefix|.
2117 static void ProcessFormat(int input_rate,
2120 int num_input_channels,
2121 int num_output_channels,
2122 int num_reverse_channels,
2123 std::string output_file_prefix) {
2125 config.Set<ExperimentalAgc>(new ExperimentalAgc(false));
2126 scoped_ptr<AudioProcessing> ap(AudioProcessing::Create(config));
2127 EnableAllAPComponents(ap.get());
2128 ap->Initialize(input_rate,
2131 LayoutFromChannels(num_input_channels),
2132 LayoutFromChannels(num_output_channels),
2133 LayoutFromChannels(num_reverse_channels));
2135 FILE* far_file = fopen(ResourceFilePath("far", reverse_rate).c_str(), "rb");
2136 FILE* near_file = fopen(ResourceFilePath("near", input_rate).c_str(), "rb");
2137 FILE* out_file = fopen(OutputFilePath(output_file_prefix,
2142 num_output_channels,
2143 num_reverse_channels).c_str(), "wb");
2144 ASSERT_TRUE(far_file != NULL);
2145 ASSERT_TRUE(near_file != NULL);
2146 ASSERT_TRUE(out_file != NULL);
2148 ChannelBuffer<float> fwd_cb(SamplesFromRate(input_rate),
2149 num_input_channels);
2150 ChannelBuffer<float> rev_cb(SamplesFromRate(reverse_rate),
2151 num_reverse_channels);
2152 ChannelBuffer<float> out_cb(SamplesFromRate(output_rate),
2153 num_output_channels);
2155 // Temporary buffers.
2156 const int max_length =
2157 2 * std::max(out_cb.samples_per_channel(),
2158 std::max(fwd_cb.samples_per_channel(),
2159 rev_cb.samples_per_channel()));
2160 scoped_ptr<float[]> float_data(new float[max_length]);
2161 scoped_ptr<int16_t[]> int_data(new int16_t[max_length]);
2163 int analog_level = 127;
2164 while (ReadChunk(far_file, int_data.get(), float_data.get(), &rev_cb) &&
2165 ReadChunk(near_file, int_data.get(), float_data.get(), &fwd_cb)) {
2166 EXPECT_NOERR(ap->AnalyzeReverseStream(
2168 rev_cb.samples_per_channel(),
2170 LayoutFromChannels(num_reverse_channels)));
2172 EXPECT_NOERR(ap->set_stream_delay_ms(0));
2173 ap->echo_cancellation()->set_stream_drift_samples(0);
2174 EXPECT_NOERR(ap->gain_control()->set_stream_analog_level(analog_level));
2176 EXPECT_NOERR(ap->ProcessStream(
2178 fwd_cb.samples_per_channel(),
2180 LayoutFromChannels(num_input_channels),
2182 LayoutFromChannels(num_output_channels),
2183 out_cb.channels()));
2185 Interleave(out_cb.channels(),
2186 out_cb.samples_per_channel(),
2187 out_cb.num_channels(),
2189 // Dump output to file.
2190 ASSERT_EQ(static_cast<size_t>(out_cb.length()),
2191 fwrite(float_data.get(), sizeof(float_data[0]),
2192 out_cb.length(), out_file));
2194 analog_level = ap->gain_control()->stream_analog_level();
2205 double expected_snr_;
2208 TEST_P(AudioProcessingTest, Formats) {
2209 struct ChannelFormat {
2214 ChannelFormat cf[] = {
2222 size_t channel_format_size = sizeof(cf) / sizeof(*cf);
2224 for (size_t i = 0; i < channel_format_size; ++i) {
2225 ProcessFormat(input_rate_,
2232 int min_ref_rate = std::min(input_rate_, output_rate_);
2234 if (min_ref_rate > 16000) {
2236 } else if (min_ref_rate > 8000) {
2241 #ifdef WEBRTC_AUDIOPROC_FIXED_PROFILE
2242 ref_rate = std::min(ref_rate, 16000);
2245 FILE* out_file = fopen(OutputFilePath("out",
2251 cf[i].num_reverse).c_str(), "rb");
2252 // The reference files always have matching input and output channels.
2253 FILE* ref_file = fopen(OutputFilePath("ref",
2259 cf[i].num_reverse).c_str(), "rb");
2260 ASSERT_TRUE(out_file != NULL);
2261 ASSERT_TRUE(ref_file != NULL);
2263 const int ref_length = SamplesFromRate(ref_rate) * cf[i].num_output;
2264 const int out_length = SamplesFromRate(output_rate_) * cf[i].num_output;
2265 // Data from the reference file.
2266 scoped_ptr<float[]> ref_data(new float[ref_length]);
2267 // Data from the output file.
2268 scoped_ptr<float[]> out_data(new float[out_length]);
2269 // Data from the resampled output, in case the reference and output rates
2271 scoped_ptr<float[]> cmp_data(new float[ref_length]);
2273 PushResampler<float> resampler;
2274 resampler.InitializeIfNeeded(output_rate_, ref_rate, cf[i].num_output);
2276 // Compute the resampling delay of the output relative to the reference,
2277 // to find the region over which we should search for the best SNR.
2278 float expected_delay_sec = 0;
2279 if (input_rate_ != ref_rate) {
2280 // Input resampling delay.
2281 expected_delay_sec +=
2282 PushSincResampler::AlgorithmicDelaySeconds(input_rate_);
2284 if (output_rate_ != ref_rate) {
2285 // Output resampling delay.
2286 expected_delay_sec +=
2287 PushSincResampler::AlgorithmicDelaySeconds(ref_rate);
2288 // Delay of converting the output back to its processing rate for testing.
2289 expected_delay_sec +=
2290 PushSincResampler::AlgorithmicDelaySeconds(output_rate_);
2292 int expected_delay = floor(expected_delay_sec * ref_rate + 0.5f) *
2295 double variance = 0;
2296 double sq_error = 0;
2297 while (fread(out_data.get(), sizeof(out_data[0]), out_length, out_file) &&
2298 fread(ref_data.get(), sizeof(ref_data[0]), ref_length, ref_file)) {
2299 float* out_ptr = out_data.get();
2300 if (output_rate_ != ref_rate) {
2301 // Resample the output back to its internal processing rate if necssary.
2302 ASSERT_EQ(ref_length, resampler.Resample(out_ptr,
2306 out_ptr = cmp_data.get();
2309 // Update the |sq_error| and |variance| accumulators with the highest SNR
2310 // of reference vs output.
2311 UpdateBestSNR(ref_data.get(),
2319 std::cout << "(" << input_rate_ << ", "
2320 << output_rate_ << ", "
2321 << reverse_rate_ << ", "
2322 << cf[i].num_input << ", "
2323 << cf[i].num_output << ", "
2324 << cf[i].num_reverse << "): ";
2326 double snr = 10 * log10(variance / sq_error);
2327 EXPECT_GE(snr, expected_snr_);
2328 EXPECT_NE(0, expected_snr_);
2329 std::cout << "SNR=" << snr << " dB" << std::endl;
2331 EXPECT_EQ(expected_snr_, 0);
2332 std::cout << "SNR=" << "inf dB" << std::endl;
2340 #if defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
2341 INSTANTIATE_TEST_CASE_P(
2342 CommonFormats, AudioProcessingTest, testing::Values(
2343 std::tr1::make_tuple(48000, 48000, 48000, 20),
2344 std::tr1::make_tuple(48000, 48000, 32000, 20),
2345 std::tr1::make_tuple(48000, 48000, 16000, 20),
2346 std::tr1::make_tuple(48000, 44100, 48000, 15),
2347 std::tr1::make_tuple(48000, 44100, 32000, 15),
2348 std::tr1::make_tuple(48000, 44100, 16000, 15),
2349 std::tr1::make_tuple(48000, 32000, 48000, 20),
2350 std::tr1::make_tuple(48000, 32000, 32000, 20),
2351 std::tr1::make_tuple(48000, 32000, 16000, 20),
2352 std::tr1::make_tuple(48000, 16000, 48000, 20),
2353 std::tr1::make_tuple(48000, 16000, 32000, 20),
2354 std::tr1::make_tuple(48000, 16000, 16000, 20),
2356 std::tr1::make_tuple(44100, 48000, 48000, 20),
2357 std::tr1::make_tuple(44100, 48000, 32000, 20),
2358 std::tr1::make_tuple(44100, 48000, 16000, 20),
2359 std::tr1::make_tuple(44100, 44100, 48000, 15),
2360 std::tr1::make_tuple(44100, 44100, 32000, 15),
2361 std::tr1::make_tuple(44100, 44100, 16000, 15),
2362 std::tr1::make_tuple(44100, 32000, 48000, 20),
2363 std::tr1::make_tuple(44100, 32000, 32000, 20),
2364 std::tr1::make_tuple(44100, 32000, 16000, 20),
2365 std::tr1::make_tuple(44100, 16000, 48000, 20),
2366 std::tr1::make_tuple(44100, 16000, 32000, 20),
2367 std::tr1::make_tuple(44100, 16000, 16000, 20),
2369 std::tr1::make_tuple(32000, 48000, 48000, 25),
2370 std::tr1::make_tuple(32000, 48000, 32000, 25),
2371 std::tr1::make_tuple(32000, 48000, 16000, 25),
2372 std::tr1::make_tuple(32000, 44100, 48000, 20),
2373 std::tr1::make_tuple(32000, 44100, 32000, 20),
2374 std::tr1::make_tuple(32000, 44100, 16000, 20),
2375 std::tr1::make_tuple(32000, 32000, 48000, 30),
2376 std::tr1::make_tuple(32000, 32000, 32000, 0),
2377 std::tr1::make_tuple(32000, 32000, 16000, 30),
2378 std::tr1::make_tuple(32000, 16000, 48000, 20),
2379 std::tr1::make_tuple(32000, 16000, 32000, 20),
2380 std::tr1::make_tuple(32000, 16000, 16000, 20),
2382 std::tr1::make_tuple(16000, 48000, 48000, 25),
2383 std::tr1::make_tuple(16000, 48000, 32000, 25),
2384 std::tr1::make_tuple(16000, 48000, 16000, 25),
2385 std::tr1::make_tuple(16000, 44100, 48000, 15),
2386 std::tr1::make_tuple(16000, 44100, 32000, 15),
2387 std::tr1::make_tuple(16000, 44100, 16000, 15),
2388 std::tr1::make_tuple(16000, 32000, 48000, 25),
2389 std::tr1::make_tuple(16000, 32000, 32000, 25),
2390 std::tr1::make_tuple(16000, 32000, 16000, 25),
2391 std::tr1::make_tuple(16000, 16000, 48000, 30),
2392 std::tr1::make_tuple(16000, 16000, 32000, 30),
2393 std::tr1::make_tuple(16000, 16000, 16000, 0)));
2395 #elif defined(WEBRTC_AUDIOPROC_FIXED_PROFILE)
2396 INSTANTIATE_TEST_CASE_P(
2397 CommonFormats, AudioProcessingTest, testing::Values(
2398 std::tr1::make_tuple(48000, 48000, 48000, 20),
2399 std::tr1::make_tuple(48000, 48000, 32000, 20),
2400 std::tr1::make_tuple(48000, 48000, 16000, 20),
2401 std::tr1::make_tuple(48000, 44100, 48000, 15),
2402 std::tr1::make_tuple(48000, 44100, 32000, 15),
2403 std::tr1::make_tuple(48000, 44100, 16000, 15),
2404 std::tr1::make_tuple(48000, 32000, 48000, 20),
2405 std::tr1::make_tuple(48000, 32000, 32000, 20),
2406 std::tr1::make_tuple(48000, 32000, 16000, 20),
2407 std::tr1::make_tuple(48000, 16000, 48000, 20),
2408 std::tr1::make_tuple(48000, 16000, 32000, 20),
2409 std::tr1::make_tuple(48000, 16000, 16000, 20),
2411 std::tr1::make_tuple(44100, 48000, 48000, 19),
2412 std::tr1::make_tuple(44100, 48000, 32000, 19),
2413 std::tr1::make_tuple(44100, 48000, 16000, 19),
2414 std::tr1::make_tuple(44100, 44100, 48000, 15),
2415 std::tr1::make_tuple(44100, 44100, 32000, 15),
2416 std::tr1::make_tuple(44100, 44100, 16000, 15),
2417 std::tr1::make_tuple(44100, 32000, 48000, 19),
2418 std::tr1::make_tuple(44100, 32000, 32000, 19),
2419 std::tr1::make_tuple(44100, 32000, 16000, 19),
2420 std::tr1::make_tuple(44100, 16000, 48000, 19),
2421 std::tr1::make_tuple(44100, 16000, 32000, 19),
2422 std::tr1::make_tuple(44100, 16000, 16000, 19),
2424 std::tr1::make_tuple(32000, 48000, 48000, 19),
2425 std::tr1::make_tuple(32000, 48000, 32000, 19),
2426 std::tr1::make_tuple(32000, 48000, 16000, 19),
2427 std::tr1::make_tuple(32000, 44100, 48000, 15),
2428 std::tr1::make_tuple(32000, 44100, 32000, 15),
2429 std::tr1::make_tuple(32000, 44100, 16000, 15),
2430 std::tr1::make_tuple(32000, 32000, 48000, 19),
2431 std::tr1::make_tuple(32000, 32000, 32000, 19),
2432 std::tr1::make_tuple(32000, 32000, 16000, 19),
2433 std::tr1::make_tuple(32000, 16000, 48000, 19),
2434 std::tr1::make_tuple(32000, 16000, 32000, 19),
2435 std::tr1::make_tuple(32000, 16000, 16000, 19),
2437 std::tr1::make_tuple(16000, 48000, 48000, 25),
2438 std::tr1::make_tuple(16000, 48000, 32000, 25),
2439 std::tr1::make_tuple(16000, 48000, 16000, 25),
2440 std::tr1::make_tuple(16000, 44100, 48000, 15),
2441 std::tr1::make_tuple(16000, 44100, 32000, 15),
2442 std::tr1::make_tuple(16000, 44100, 16000, 15),
2443 std::tr1::make_tuple(16000, 32000, 48000, 25),
2444 std::tr1::make_tuple(16000, 32000, 32000, 25),
2445 std::tr1::make_tuple(16000, 32000, 16000, 25),
2446 std::tr1::make_tuple(16000, 16000, 48000, 30),
2447 std::tr1::make_tuple(16000, 16000, 32000, 30),
2448 std::tr1::make_tuple(16000, 16000, 16000, 0)));
2451 // TODO(henrike): re-implement functionality lost when removing the old main
2453 // https://code.google.com/p/webrtc/issues/detail?id=1981
2456 } // namespace webrtc