Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / audio_processing / test / audio_processing_unittest.cc
1 /*
2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3  *
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.
9  */
10
11 #include <math.h>
12 #include <stdio.h>
13 #include <algorithm>
14 #include <limits>
15 #include <queue>
16
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"
32 #else
33 #include "testing/gtest/include/gtest/gtest.h"
34 #include "webrtc/audio_processing/unittest.pb.h"
35 #endif
36
37 namespace webrtc {
38 namespace {
39
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);
49
50 const int kSampleRates[] = {8000, 16000, 32000};
51 const size_t kSampleRatesSize = sizeof(kSampleRates) / sizeof(*kSampleRates);
52
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};
58 #endif
59 const size_t kProcessSampleRatesSize = sizeof(kProcessSampleRates) /
60     sizeof(*kProcessSampleRates);
61
62 void ConvertToFloat(const int16_t* int_data, ChannelBuffer<float>* cb) {
63   ChannelBuffer<int16_t> cb_int(cb->samples_per_channel(),
64                                 cb->num_channels());
65   Deinterleave(int_data,
66                cb->samples_per_channel(),
67                cb->num_channels(),
68                cb_int.channels());
69   ScaleToFloat(cb_int.data(),
70                cb->samples_per_channel() * cb->num_channels(),
71                cb->data());
72 }
73
74 void ConvertToFloat(const AudioFrame& frame, ChannelBuffer<float>* cb) {
75   ConvertToFloat(frame.data_, cb);
76 }
77
78 // Number of channels including the keyboard channel.
79 int TotalChannelsFromLayout(AudioProcessing::ChannelLayout layout) {
80   switch (layout) {
81     case AudioProcessing::kMono:
82       return 1;
83     case AudioProcessing::kMonoAndKeyboard:
84     case AudioProcessing::kStereo:
85       return 2;
86     case AudioProcessing::kStereoAndKeyboard:
87       return 3;
88   }
89   assert(false);
90   return -1;
91 }
92
93 int TruncateToMultipleOf10(int value) {
94   return (value / 10) * 10;
95 }
96
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;
101   }
102 }
103
104 void MixStereoToMono(const int16_t* stereo, int16_t* mono,
105                      int samples_per_channel) {
106   for (int i = 0; i < samples_per_channel; i++)
107     mono[i] = (stereo[i * 2] + stereo[i * 2 + 1]) >> 1;
108 }
109
110 void CopyLeftToRightChannel(int16_t* stereo, int samples_per_channel) {
111   for (int i = 0; i < samples_per_channel; i++) {
112     stereo[i * 2 + 1] = stereo[i * 2];
113   }
114 }
115
116 void VerifyChannelsAreEqual(int16_t* stereo, int samples_per_channel) {
117   for (int i = 0; i < samples_per_channel; i++) {
118     EXPECT_EQ(stereo[i * 2 + 1], stereo[i * 2]);
119   }
120 }
121
122 void SetFrameTo(AudioFrame* frame, int16_t value) {
123   for (int i = 0; i < frame->samples_per_channel_ * frame->num_channels_; ++i) {
124     frame->data_[i] = value;
125   }
126 }
127
128 void SetFrameTo(AudioFrame* frame, int16_t left, int16_t right) {
129   ASSERT_EQ(2, frame->num_channels_);
130   for (int i = 0; i < frame->samples_per_channel_ * 2; i += 2) {
131     frame->data_[i] = left;
132     frame->data_[i + 1] = right;
133   }
134 }
135
136 void ScaleFrame(AudioFrame* frame, float scale) {
137   for (int i = 0; i < frame->samples_per_channel_ * frame->num_channels_; ++i) {
138     frame->data_[i] = RoundToInt16(frame->data_[i] * scale);
139   }
140 }
141
142 bool FrameDataAreEqual(const AudioFrame& frame1, const AudioFrame& frame2) {
143   if (frame1.samples_per_channel_ != frame2.samples_per_channel_) {
144     return false;
145   }
146   if (frame1.num_channels_ != frame2.num_channels_) {
147     return false;
148   }
149   if (memcmp(frame1.data_, frame2.data_,
150              frame1.samples_per_channel_ * frame1.num_channels_ *
151                  sizeof(int16_t))) {
152     return false;
153   }
154   return true;
155 }
156
157 void EnableAllAPComponents(AudioProcessing* ap) {
158 #if defined(WEBRTC_AUDIOPROC_FIXED_PROFILE)
159   EXPECT_NOERR(ap->echo_control_mobile()->Enable(true));
160
161   EXPECT_NOERR(ap->gain_control()->set_mode(GainControl::kAdaptiveDigital));
162   EXPECT_NOERR(ap->gain_control()->Enable(true));
163 #elif defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
164   EXPECT_NOERR(ap->echo_cancellation()->enable_drift_compensation(true));
165   EXPECT_NOERR(ap->echo_cancellation()->enable_metrics(true));
166   EXPECT_NOERR(ap->echo_cancellation()->enable_delay_logging(true));
167   EXPECT_NOERR(ap->echo_cancellation()->Enable(true));
168
169   EXPECT_NOERR(ap->gain_control()->set_mode(GainControl::kAdaptiveAnalog));
170   EXPECT_NOERR(ap->gain_control()->set_analog_level_limits(0, 255));
171   EXPECT_NOERR(ap->gain_control()->Enable(true));
172 #endif
173
174   EXPECT_NOERR(ap->high_pass_filter()->Enable(true));
175   EXPECT_NOERR(ap->level_estimator()->Enable(true));
176   EXPECT_NOERR(ap->noise_suppression()->Enable(true));
177
178   EXPECT_NOERR(ap->voice_detection()->Enable(true));
179 }
180
181 // These functions are only used by ApmTest.Process.
182 template <class T>
183 T AbsValue(T a) {
184   return a > 0 ? a: -a;
185 }
186
187 int16_t MaxAudioFrame(const AudioFrame& frame) {
188   const int length = frame.samples_per_channel_ * frame.num_channels_;
189   int16_t max_data = AbsValue(frame.data_[0]);
190   for (int i = 1; i < length; i++) {
191     max_data = std::max(max_data, AbsValue(frame.data_[i]));
192   }
193
194   return max_data;
195 }
196
197 #if defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
198 void TestStats(const AudioProcessing::Statistic& test,
199                const audioproc::Test::Statistic& reference) {
200   EXPECT_EQ(reference.instant(), test.instant);
201   EXPECT_EQ(reference.average(), test.average);
202   EXPECT_EQ(reference.maximum(), test.maximum);
203   EXPECT_EQ(reference.minimum(), test.minimum);
204 }
205
206 void WriteStatsMessage(const AudioProcessing::Statistic& output,
207                        audioproc::Test::Statistic* msg) {
208   msg->set_instant(output.instant);
209   msg->set_average(output.average);
210   msg->set_maximum(output.maximum);
211   msg->set_minimum(output.minimum);
212 }
213 #endif
214
215 void OpenFileAndWriteMessage(const std::string filename,
216                              const ::google::protobuf::MessageLite& msg) {
217 #if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
218   FILE* file = fopen(filename.c_str(), "wb");
219   ASSERT_TRUE(file != NULL);
220
221   int32_t size = msg.ByteSize();
222   ASSERT_GT(size, 0);
223   scoped_ptr<uint8_t[]> array(new uint8_t[size]);
224   ASSERT_TRUE(msg.SerializeToArray(array.get(), size));
225
226   ASSERT_EQ(1u, fwrite(&size, sizeof(size), 1, file));
227   ASSERT_EQ(static_cast<size_t>(size),
228       fwrite(array.get(), sizeof(array[0]), size, file));
229   fclose(file);
230 #else
231   std::cout << "Warning: Writing new reference is only allowed on Linux!"
232       << std::endl;
233 #endif
234 }
235
236 std::string ResourceFilePath(std::string name, int sample_rate_hz) {
237   std::ostringstream ss;
238   // Resource files are all stereo.
239   ss << name << sample_rate_hz / 1000 << "_stereo";
240   return test::ResourcePath(ss.str(), "pcm");
241 }
242
243 std::string OutputFilePath(std::string name,
244                            int input_rate,
245                            int output_rate,
246                            int reverse_rate,
247                            int num_input_channels,
248                            int num_output_channels,
249                            int num_reverse_channels) {
250   std::ostringstream ss;
251   ss << name << "_i" << num_input_channels << "_" << input_rate / 1000
252      << "_r" << num_reverse_channels << "_" << reverse_rate  / 1000 << "_";
253   if (num_output_channels == 1) {
254     ss << "mono";
255   } else if (num_output_channels == 2) {
256     ss << "stereo";
257   } else {
258     assert(false);
259   }
260   ss << output_rate / 1000 << ".pcm";
261
262   return test::OutputPath() + ss.str();
263 }
264
265 void OpenFileAndReadMessage(const std::string filename,
266                             ::google::protobuf::MessageLite* msg) {
267   FILE* file = fopen(filename.c_str(), "rb");
268   ASSERT_TRUE(file != NULL);
269   ReadMessageFromFile(file, msg);
270   fclose(file);
271 }
272
273 class ApmTest : public ::testing::Test {
274  protected:
275   ApmTest();
276   virtual void SetUp();
277   virtual void TearDown();
278
279   static void SetUpTestCase() {
280     Trace::CreateTrace();
281     std::string trace_filename = test::OutputPath() + "audioproc_trace.txt";
282     ASSERT_EQ(0, Trace::SetTraceFile(trace_filename.c_str()));
283   }
284
285   static void TearDownTestCase() {
286     Trace::ReturnTrace();
287   }
288
289   // Used to select between int and float interface tests.
290   enum Format {
291     kIntFormat,
292     kFloatFormat
293   };
294
295   void Init(int sample_rate_hz,
296             int output_sample_rate_hz,
297             int reverse_sample_rate_hz,
298             int num_reverse_channels,
299             int num_input_channels,
300             int num_output_channels,
301             bool open_output_file);
302   void Init(AudioProcessing* ap);
303   void EnableAllComponents();
304   bool ReadFrame(FILE* file, AudioFrame* frame);
305   bool ReadFrame(FILE* file, AudioFrame* frame, ChannelBuffer<float>* cb);
306   void ReadFrameWithRewind(FILE* file, AudioFrame* frame);
307   void ReadFrameWithRewind(FILE* file, AudioFrame* frame,
308                            ChannelBuffer<float>* cb);
309   void ProcessWithDefaultStreamParameters(AudioFrame* frame);
310   void ProcessDelayVerificationTest(int delay_ms, int system_delay_ms,
311                                     int delay_min, int delay_max);
312   void TestChangingChannels(int num_channels,
313                             AudioProcessing::Error expected_return);
314   void RunQuantizedVolumeDoesNotGetStuckTest(int sample_rate);
315   void RunManualVolumeChangeIsPossibleTest(int sample_rate);
316   void StreamParametersTest(Format format);
317   int ProcessStreamChooser(Format format);
318   int AnalyzeReverseStreamChooser(Format format);
319   void ProcessDebugDump(const std::string& in_filename,
320                         const std::string& out_filename,
321                         Format format);
322   void VerifyDebugDumpTest(Format format);
323
324   const std::string output_path_;
325   const std::string ref_path_;
326   const std::string ref_filename_;
327   scoped_ptr<AudioProcessing> apm_;
328   AudioFrame* frame_;
329   AudioFrame* revframe_;
330   scoped_ptr<ChannelBuffer<float> > float_cb_;
331   scoped_ptr<ChannelBuffer<float> > revfloat_cb_;
332   int output_sample_rate_hz_;
333   int num_output_channels_;
334   FILE* far_file_;
335   FILE* near_file_;
336   FILE* out_file_;
337 };
338
339 ApmTest::ApmTest()
340     : output_path_(test::OutputPath()),
341       ref_path_(test::ProjectRootPath() + "data/audio_processing/"),
342 #if defined(WEBRTC_AUDIOPROC_FIXED_PROFILE)
343       ref_filename_(ref_path_ + "output_data_fixed.pb"),
344 #elif defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
345       ref_filename_(ref_path_ + "output_data_float.pb"),
346 #endif
347       frame_(NULL),
348       revframe_(NULL),
349       output_sample_rate_hz_(0),
350       num_output_channels_(0),
351       far_file_(NULL),
352       near_file_(NULL),
353       out_file_(NULL) {
354   Config config;
355   config.Set<ExperimentalAgc>(new ExperimentalAgc(false));
356   apm_.reset(AudioProcessing::Create(config));
357 }
358
359 void ApmTest::SetUp() {
360   ASSERT_TRUE(apm_.get() != NULL);
361
362   frame_ = new AudioFrame();
363   revframe_ = new AudioFrame();
364
365 #if defined(WEBRTC_AUDIOPROC_FIXED_PROFILE)
366   Init(16000, 16000, 16000, 2, 2, 2, false);
367 #else
368   Init(32000, 32000, 32000, 2, 2, 2, false);
369 #endif
370 }
371
372 void ApmTest::TearDown() {
373   if (frame_) {
374     delete frame_;
375   }
376   frame_ = NULL;
377
378   if (revframe_) {
379     delete revframe_;
380   }
381   revframe_ = NULL;
382
383   if (far_file_) {
384     ASSERT_EQ(0, fclose(far_file_));
385   }
386   far_file_ = NULL;
387
388   if (near_file_) {
389     ASSERT_EQ(0, fclose(near_file_));
390   }
391   near_file_ = NULL;
392
393   if (out_file_) {
394     ASSERT_EQ(0, fclose(out_file_));
395   }
396   out_file_ = NULL;
397 }
398
399 void ApmTest::Init(AudioProcessing* ap) {
400   ASSERT_EQ(kNoErr,
401             ap->Initialize(frame_->sample_rate_hz_,
402                            output_sample_rate_hz_,
403                            revframe_->sample_rate_hz_,
404                            LayoutFromChannels(frame_->num_channels_),
405                            LayoutFromChannels(num_output_channels_),
406                            LayoutFromChannels(revframe_->num_channels_)));
407 }
408
409 void ApmTest::Init(int sample_rate_hz,
410                    int output_sample_rate_hz,
411                    int reverse_sample_rate_hz,
412                    int num_input_channels,
413                    int num_output_channels,
414                    int num_reverse_channels,
415                    bool open_output_file) {
416   SetContainerFormat(sample_rate_hz, num_input_channels, frame_, &float_cb_);
417   output_sample_rate_hz_ = output_sample_rate_hz;
418   num_output_channels_ = num_output_channels;
419
420   SetContainerFormat(reverse_sample_rate_hz, num_reverse_channels, revframe_,
421                      &revfloat_cb_);
422   Init(apm_.get());
423
424   if (far_file_) {
425     ASSERT_EQ(0, fclose(far_file_));
426   }
427   std::string filename = ResourceFilePath("far", sample_rate_hz);
428   far_file_ = fopen(filename.c_str(), "rb");
429   ASSERT_TRUE(far_file_ != NULL) << "Could not open file " <<
430       filename << "\n";
431
432   if (near_file_) {
433     ASSERT_EQ(0, fclose(near_file_));
434   }
435   filename = ResourceFilePath("near", sample_rate_hz);
436   near_file_ = fopen(filename.c_str(), "rb");
437   ASSERT_TRUE(near_file_ != NULL) << "Could not open file " <<
438         filename << "\n";
439
440   if (open_output_file) {
441     if (out_file_) {
442       ASSERT_EQ(0, fclose(out_file_));
443     }
444     filename = OutputFilePath("out",
445                               sample_rate_hz,
446                               output_sample_rate_hz,
447                               reverse_sample_rate_hz,
448                               num_input_channels,
449                               num_output_channels,
450                               num_reverse_channels);
451     out_file_ = fopen(filename.c_str(), "wb");
452     ASSERT_TRUE(out_file_ != NULL) << "Could not open file " <<
453           filename << "\n";
454   }
455 }
456
457 void ApmTest::EnableAllComponents() {
458   EnableAllAPComponents(apm_.get());
459 }
460
461 bool ApmTest::ReadFrame(FILE* file, AudioFrame* frame,
462                         ChannelBuffer<float>* cb) {
463   // The files always contain stereo audio.
464   size_t frame_size = frame->samples_per_channel_ * 2;
465   size_t read_count = fread(frame->data_,
466                             sizeof(int16_t),
467                             frame_size,
468                             file);
469   if (read_count != frame_size) {
470     // Check that the file really ended.
471     EXPECT_NE(0, feof(file));
472     return false;  // This is expected.
473   }
474
475   if (frame->num_channels_ == 1) {
476     MixStereoToMono(frame->data_, frame->data_,
477                     frame->samples_per_channel_);
478   }
479
480   if (cb) {
481     ConvertToFloat(*frame, cb);
482   }
483   return true;
484 }
485
486 bool ApmTest::ReadFrame(FILE* file, AudioFrame* frame) {
487   return ReadFrame(file, frame, NULL);
488 }
489
490 // If the end of the file has been reached, rewind it and attempt to read the
491 // frame again.
492 void ApmTest::ReadFrameWithRewind(FILE* file, AudioFrame* frame,
493                                   ChannelBuffer<float>* cb) {
494   if (!ReadFrame(near_file_, frame_, cb)) {
495     rewind(near_file_);
496     ASSERT_TRUE(ReadFrame(near_file_, frame_, cb));
497   }
498 }
499
500 void ApmTest::ReadFrameWithRewind(FILE* file, AudioFrame* frame) {
501   ReadFrameWithRewind(file, frame, NULL);
502 }
503
504 void ApmTest::ProcessWithDefaultStreamParameters(AudioFrame* frame) {
505   EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
506   apm_->echo_cancellation()->set_stream_drift_samples(0);
507   EXPECT_EQ(apm_->kNoError,
508       apm_->gain_control()->set_stream_analog_level(127));
509   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame));
510 }
511
512 int ApmTest::ProcessStreamChooser(Format format) {
513   if (format == kIntFormat) {
514     return apm_->ProcessStream(frame_);
515   }
516   return apm_->ProcessStream(float_cb_->channels(),
517                              frame_->samples_per_channel_,
518                              frame_->sample_rate_hz_,
519                              LayoutFromChannels(frame_->num_channels_),
520                              output_sample_rate_hz_,
521                              LayoutFromChannels(num_output_channels_),
522                              float_cb_->channels());
523 }
524
525 int ApmTest::AnalyzeReverseStreamChooser(Format format) {
526   if (format == kIntFormat) {
527     return apm_->AnalyzeReverseStream(revframe_);
528   }
529   return apm_->AnalyzeReverseStream(
530       revfloat_cb_->channels(),
531       revframe_->samples_per_channel_,
532       revframe_->sample_rate_hz_,
533       LayoutFromChannels(revframe_->num_channels_));
534 }
535
536 void ApmTest::ProcessDelayVerificationTest(int delay_ms, int system_delay_ms,
537                                            int delay_min, int delay_max) {
538   // The |revframe_| and |frame_| should include the proper frame information,
539   // hence can be used for extracting information.
540   AudioFrame tmp_frame;
541   std::queue<AudioFrame*> frame_queue;
542   bool causal = true;
543
544   tmp_frame.CopyFrom(*revframe_);
545   SetFrameTo(&tmp_frame, 0);
546
547   EXPECT_EQ(apm_->kNoError, apm_->Initialize());
548   // Initialize the |frame_queue| with empty frames.
549   int frame_delay = delay_ms / 10;
550   while (frame_delay < 0) {
551     AudioFrame* frame = new AudioFrame();
552     frame->CopyFrom(tmp_frame);
553     frame_queue.push(frame);
554     frame_delay++;
555     causal = false;
556   }
557   while (frame_delay > 0) {
558     AudioFrame* frame = new AudioFrame();
559     frame->CopyFrom(tmp_frame);
560     frame_queue.push(frame);
561     frame_delay--;
562   }
563   // Run for 4.5 seconds, skipping statistics from the first 2.5 seconds.  We
564   // need enough frames with audio to have reliable estimates, but as few as
565   // possible to keep processing time down.  4.5 seconds seemed to be a good
566   // compromise for this recording.
567   for (int frame_count = 0; frame_count < 450; ++frame_count) {
568     AudioFrame* frame = new AudioFrame();
569     frame->CopyFrom(tmp_frame);
570     // Use the near end recording, since that has more speech in it.
571     ASSERT_TRUE(ReadFrame(near_file_, frame));
572     frame_queue.push(frame);
573     AudioFrame* reverse_frame = frame;
574     AudioFrame* process_frame = frame_queue.front();
575     if (!causal) {
576       reverse_frame = frame_queue.front();
577       // When we call ProcessStream() the frame is modified, so we can't use the
578       // pointer directly when things are non-causal. Use an intermediate frame
579       // and copy the data.
580       process_frame = &tmp_frame;
581       process_frame->CopyFrom(*frame);
582     }
583     EXPECT_EQ(apm_->kNoError, apm_->AnalyzeReverseStream(reverse_frame));
584     EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(system_delay_ms));
585     EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(process_frame));
586     frame = frame_queue.front();
587     frame_queue.pop();
588     delete frame;
589
590     if (frame_count == 250) {
591       int median;
592       int std;
593       // Discard the first delay metrics to avoid convergence effects.
594       EXPECT_EQ(apm_->kNoError,
595                 apm_->echo_cancellation()->GetDelayMetrics(&median, &std));
596     }
597   }
598
599   rewind(near_file_);
600   while (!frame_queue.empty()) {
601     AudioFrame* frame = frame_queue.front();
602     frame_queue.pop();
603     delete frame;
604   }
605   // Calculate expected delay estimate and acceptable regions. Further,
606   // limit them w.r.t. AEC delay estimation support.
607   const int samples_per_ms = std::min(16, frame_->samples_per_channel_ / 10);
608   int expected_median = std::min(std::max(delay_ms - system_delay_ms,
609                                           delay_min), delay_max);
610   int expected_median_high = std::min(std::max(
611       expected_median + 96 / samples_per_ms, delay_min), delay_max);
612   int expected_median_low = std::min(std::max(
613       expected_median - 96 / samples_per_ms, delay_min), delay_max);
614   // Verify delay metrics.
615   int median;
616   int std;
617   EXPECT_EQ(apm_->kNoError,
618             apm_->echo_cancellation()->GetDelayMetrics(&median, &std));
619   EXPECT_GE(expected_median_high, median);
620   EXPECT_LE(expected_median_low, median);
621 }
622
623 void ApmTest::StreamParametersTest(Format format) {
624   // No errors when the components are disabled.
625   EXPECT_EQ(apm_->kNoError, ProcessStreamChooser(format));
626
627   // -- Missing AGC level --
628   EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
629   EXPECT_EQ(apm_->kStreamParameterNotSetError,
630             ProcessStreamChooser(format));
631
632   // Resets after successful ProcessStream().
633   EXPECT_EQ(apm_->kNoError,
634             apm_->gain_control()->set_stream_analog_level(127));
635   EXPECT_EQ(apm_->kNoError, ProcessStreamChooser(format));
636   EXPECT_EQ(apm_->kStreamParameterNotSetError,
637             ProcessStreamChooser(format));
638
639   // Other stream parameters set correctly.
640   EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
641   EXPECT_EQ(apm_->kNoError,
642             apm_->echo_cancellation()->enable_drift_compensation(true));
643   EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
644   apm_->echo_cancellation()->set_stream_drift_samples(0);
645   EXPECT_EQ(apm_->kStreamParameterNotSetError,
646             ProcessStreamChooser(format));
647   EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(false));
648   EXPECT_EQ(apm_->kNoError,
649             apm_->echo_cancellation()->enable_drift_compensation(false));
650
651   // -- Missing delay --
652   EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
653   EXPECT_EQ(apm_->kNoError, ProcessStreamChooser(format));
654   EXPECT_EQ(apm_->kStreamParameterNotSetError,
655             ProcessStreamChooser(format));
656
657   // Resets after successful ProcessStream().
658   EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
659   EXPECT_EQ(apm_->kNoError, ProcessStreamChooser(format));
660   EXPECT_EQ(apm_->kStreamParameterNotSetError,
661             ProcessStreamChooser(format));
662
663   // Other stream parameters set correctly.
664   EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
665   EXPECT_EQ(apm_->kNoError,
666             apm_->echo_cancellation()->enable_drift_compensation(true));
667   apm_->echo_cancellation()->set_stream_drift_samples(0);
668   EXPECT_EQ(apm_->kNoError,
669             apm_->gain_control()->set_stream_analog_level(127));
670   EXPECT_EQ(apm_->kStreamParameterNotSetError,
671             ProcessStreamChooser(format));
672   EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(false));
673
674   // -- Missing drift --
675   EXPECT_EQ(apm_->kStreamParameterNotSetError,
676             ProcessStreamChooser(format));
677
678   // Resets after successful ProcessStream().
679   EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
680   apm_->echo_cancellation()->set_stream_drift_samples(0);
681   EXPECT_EQ(apm_->kNoError, ProcessStreamChooser(format));
682   EXPECT_EQ(apm_->kStreamParameterNotSetError,
683             ProcessStreamChooser(format));
684
685   // Other stream parameters set correctly.
686   EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
687   EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
688   EXPECT_EQ(apm_->kNoError,
689             apm_->gain_control()->set_stream_analog_level(127));
690   EXPECT_EQ(apm_->kStreamParameterNotSetError,
691             ProcessStreamChooser(format));
692
693   // -- No stream parameters --
694   EXPECT_EQ(apm_->kNoError,
695             AnalyzeReverseStreamChooser(format));
696   EXPECT_EQ(apm_->kStreamParameterNotSetError,
697             ProcessStreamChooser(format));
698
699   // -- All there --
700   EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
701   apm_->echo_cancellation()->set_stream_drift_samples(0);
702   EXPECT_EQ(apm_->kNoError,
703             apm_->gain_control()->set_stream_analog_level(127));
704   EXPECT_EQ(apm_->kNoError, ProcessStreamChooser(format));
705 }
706
707 TEST_F(ApmTest, StreamParametersInt) {
708   StreamParametersTest(kIntFormat);
709 }
710
711 TEST_F(ApmTest, StreamParametersFloat) {
712   StreamParametersTest(kFloatFormat);
713 }
714
715 TEST_F(ApmTest, DefaultDelayOffsetIsZero) {
716   EXPECT_EQ(0, apm_->delay_offset_ms());
717   EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(50));
718   EXPECT_EQ(50, apm_->stream_delay_ms());
719 }
720
721 TEST_F(ApmTest, DelayOffsetWithLimitsIsSetProperly) {
722   // High limit of 500 ms.
723   apm_->set_delay_offset_ms(100);
724   EXPECT_EQ(100, apm_->delay_offset_ms());
725   EXPECT_EQ(apm_->kBadStreamParameterWarning, apm_->set_stream_delay_ms(450));
726   EXPECT_EQ(500, apm_->stream_delay_ms());
727   EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
728   EXPECT_EQ(200, apm_->stream_delay_ms());
729
730   // Low limit of 0 ms.
731   apm_->set_delay_offset_ms(-50);
732   EXPECT_EQ(-50, apm_->delay_offset_ms());
733   EXPECT_EQ(apm_->kBadStreamParameterWarning, apm_->set_stream_delay_ms(20));
734   EXPECT_EQ(0, apm_->stream_delay_ms());
735   EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
736   EXPECT_EQ(50, apm_->stream_delay_ms());
737 }
738
739 void ApmTest::TestChangingChannels(int num_channels,
740                                    AudioProcessing::Error expected_return) {
741   frame_->num_channels_ = num_channels;
742   EXPECT_EQ(expected_return, apm_->ProcessStream(frame_));
743   EXPECT_EQ(expected_return, apm_->AnalyzeReverseStream(frame_));
744 }
745
746 TEST_F(ApmTest, Channels) {
747   // Testing number of invalid channels.
748   TestChangingChannels(0, apm_->kBadNumberChannelsError);
749   TestChangingChannels(3, apm_->kBadNumberChannelsError);
750   // Testing number of valid channels.
751   for (int i = 1; i < 3; i++) {
752     TestChangingChannels(i, kNoErr);
753     EXPECT_EQ(i, apm_->num_input_channels());
754     // We always force the number of reverse channels used for processing to 1.
755     EXPECT_EQ(1, apm_->num_reverse_channels());
756   }
757 }
758
759 TEST_F(ApmTest, SampleRatesInt) {
760   // Testing invalid sample rates
761   SetContainerFormat(10000, 2, frame_, &float_cb_);
762   EXPECT_EQ(apm_->kBadSampleRateError, ProcessStreamChooser(kIntFormat));
763   // Testing valid sample rates
764   int fs[] = {8000, 16000, 32000};
765   for (size_t i = 0; i < sizeof(fs) / sizeof(*fs); i++) {
766     SetContainerFormat(fs[i], 2, frame_, &float_cb_);
767     EXPECT_NOERR(ProcessStreamChooser(kIntFormat));
768     EXPECT_EQ(fs[i], apm_->input_sample_rate_hz());
769   }
770 }
771
772 TEST_F(ApmTest, EchoCancellation) {
773   EXPECT_EQ(apm_->kNoError,
774             apm_->echo_cancellation()->enable_drift_compensation(true));
775   EXPECT_TRUE(apm_->echo_cancellation()->is_drift_compensation_enabled());
776   EXPECT_EQ(apm_->kNoError,
777             apm_->echo_cancellation()->enable_drift_compensation(false));
778   EXPECT_FALSE(apm_->echo_cancellation()->is_drift_compensation_enabled());
779
780   EchoCancellation::SuppressionLevel level[] = {
781     EchoCancellation::kLowSuppression,
782     EchoCancellation::kModerateSuppression,
783     EchoCancellation::kHighSuppression,
784   };
785   for (size_t i = 0; i < sizeof(level)/sizeof(*level); i++) {
786     EXPECT_EQ(apm_->kNoError,
787         apm_->echo_cancellation()->set_suppression_level(level[i]));
788     EXPECT_EQ(level[i],
789         apm_->echo_cancellation()->suppression_level());
790   }
791
792   EchoCancellation::Metrics metrics;
793   EXPECT_EQ(apm_->kNotEnabledError,
794             apm_->echo_cancellation()->GetMetrics(&metrics));
795
796   EXPECT_EQ(apm_->kNoError,
797             apm_->echo_cancellation()->enable_metrics(true));
798   EXPECT_TRUE(apm_->echo_cancellation()->are_metrics_enabled());
799   EXPECT_EQ(apm_->kNoError,
800             apm_->echo_cancellation()->enable_metrics(false));
801   EXPECT_FALSE(apm_->echo_cancellation()->are_metrics_enabled());
802
803   int median = 0;
804   int std = 0;
805   EXPECT_EQ(apm_->kNotEnabledError,
806             apm_->echo_cancellation()->GetDelayMetrics(&median, &std));
807
808   EXPECT_EQ(apm_->kNoError,
809             apm_->echo_cancellation()->enable_delay_logging(true));
810   EXPECT_TRUE(apm_->echo_cancellation()->is_delay_logging_enabled());
811   EXPECT_EQ(apm_->kNoError,
812             apm_->echo_cancellation()->enable_delay_logging(false));
813   EXPECT_FALSE(apm_->echo_cancellation()->is_delay_logging_enabled());
814
815   EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
816   EXPECT_TRUE(apm_->echo_cancellation()->is_enabled());
817   EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(false));
818   EXPECT_FALSE(apm_->echo_cancellation()->is_enabled());
819
820   EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
821   EXPECT_TRUE(apm_->echo_cancellation()->is_enabled());
822   EXPECT_TRUE(apm_->echo_cancellation()->aec_core() != NULL);
823   EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(false));
824   EXPECT_FALSE(apm_->echo_cancellation()->is_enabled());
825   EXPECT_FALSE(apm_->echo_cancellation()->aec_core() != NULL);
826 }
827
828 TEST_F(ApmTest, DISABLED_EchoCancellationReportsCorrectDelays) {
829   // Enable AEC only.
830   EXPECT_EQ(apm_->kNoError,
831             apm_->echo_cancellation()->enable_drift_compensation(false));
832   EXPECT_EQ(apm_->kNoError,
833             apm_->echo_cancellation()->enable_metrics(false));
834   EXPECT_EQ(apm_->kNoError,
835             apm_->echo_cancellation()->enable_delay_logging(true));
836   EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
837   Config config;
838   config.Set<ReportedDelay>(new ReportedDelay(true));
839   apm_->SetExtraOptions(config);
840
841   // Internally in the AEC the amount of lookahead the delay estimation can
842   // handle is 15 blocks and the maximum delay is set to 60 blocks.
843   const int kLookaheadBlocks = 15;
844   const int kMaxDelayBlocks = 60;
845   // The AEC has a startup time before it actually starts to process. This
846   // procedure can flush the internal far-end buffer, which of course affects
847   // the delay estimation. Therefore, we set a system_delay high enough to
848   // avoid that. The smallest system_delay you can report without flushing the
849   // buffer is 66 ms in 8 kHz.
850   //
851   // It is known that for 16 kHz (and 32 kHz) sampling frequency there is an
852   // additional stuffing of 8 ms on the fly, but it seems to have no impact on
853   // delay estimation. This should be noted though. In case of test failure,
854   // this could be the cause.
855   const int kSystemDelayMs = 66;
856   // Test a couple of corner cases and verify that the estimated delay is
857   // within a valid region (set to +-1.5 blocks). Note that these cases are
858   // sampling frequency dependent.
859   for (size_t i = 0; i < kProcessSampleRatesSize; i++) {
860     Init(kProcessSampleRates[i],
861          kProcessSampleRates[i],
862          kProcessSampleRates[i],
863          2,
864          2,
865          2,
866          false);
867     // Sampling frequency dependent variables.
868     const int num_ms_per_block = std::max(4,
869                                           640 / frame_->samples_per_channel_);
870     const int delay_min_ms = -kLookaheadBlocks * num_ms_per_block;
871     const int delay_max_ms = (kMaxDelayBlocks - 1) * num_ms_per_block;
872
873     // 1) Verify correct delay estimate at lookahead boundary.
874     int delay_ms = TruncateToMultipleOf10(kSystemDelayMs + delay_min_ms);
875     ProcessDelayVerificationTest(delay_ms, kSystemDelayMs, delay_min_ms,
876                                  delay_max_ms);
877     // 2) A delay less than maximum lookahead should give an delay estimate at
878     //    the boundary (= -kLookaheadBlocks * num_ms_per_block).
879     delay_ms -= 20;
880     ProcessDelayVerificationTest(delay_ms, kSystemDelayMs, delay_min_ms,
881                                  delay_max_ms);
882     // 3) Three values around zero delay. Note that we need to compensate for
883     //    the fake system_delay.
884     delay_ms = TruncateToMultipleOf10(kSystemDelayMs - 10);
885     ProcessDelayVerificationTest(delay_ms, kSystemDelayMs, delay_min_ms,
886                                  delay_max_ms);
887     delay_ms = TruncateToMultipleOf10(kSystemDelayMs);
888     ProcessDelayVerificationTest(delay_ms, kSystemDelayMs, delay_min_ms,
889                                  delay_max_ms);
890     delay_ms = TruncateToMultipleOf10(kSystemDelayMs + 10);
891     ProcessDelayVerificationTest(delay_ms, kSystemDelayMs, delay_min_ms,
892                                  delay_max_ms);
893     // 4) Verify correct delay estimate at maximum delay boundary.
894     delay_ms = TruncateToMultipleOf10(kSystemDelayMs + delay_max_ms);
895     ProcessDelayVerificationTest(delay_ms, kSystemDelayMs, delay_min_ms,
896                                  delay_max_ms);
897     // 5) A delay above the maximum delay should give an estimate at the
898     //    boundary (= (kMaxDelayBlocks - 1) * num_ms_per_block).
899     delay_ms += 20;
900     ProcessDelayVerificationTest(delay_ms, kSystemDelayMs, delay_min_ms,
901                                  delay_max_ms);
902   }
903 }
904
905 TEST_F(ApmTest, EchoControlMobile) {
906   // AECM won't use super-wideband.
907   SetFrameSampleRate(frame_, 32000);
908   EXPECT_NOERR(apm_->ProcessStream(frame_));
909   EXPECT_EQ(apm_->kBadSampleRateError,
910             apm_->echo_control_mobile()->Enable(true));
911   SetFrameSampleRate(frame_, 16000);
912   EXPECT_NOERR(apm_->ProcessStream(frame_));
913   EXPECT_EQ(apm_->kNoError,
914             apm_->echo_control_mobile()->Enable(true));
915   SetFrameSampleRate(frame_, 32000);
916   EXPECT_EQ(apm_->kUnsupportedComponentError, apm_->ProcessStream(frame_));
917
918   // Turn AECM on (and AEC off)
919   Init(16000, 16000, 16000, 2, 2, 2, false);
920   EXPECT_EQ(apm_->kNoError, apm_->echo_control_mobile()->Enable(true));
921   EXPECT_TRUE(apm_->echo_control_mobile()->is_enabled());
922
923   // Toggle routing modes
924   EchoControlMobile::RoutingMode mode[] = {
925       EchoControlMobile::kQuietEarpieceOrHeadset,
926       EchoControlMobile::kEarpiece,
927       EchoControlMobile::kLoudEarpiece,
928       EchoControlMobile::kSpeakerphone,
929       EchoControlMobile::kLoudSpeakerphone,
930   };
931   for (size_t i = 0; i < sizeof(mode)/sizeof(*mode); i++) {
932     EXPECT_EQ(apm_->kNoError,
933         apm_->echo_control_mobile()->set_routing_mode(mode[i]));
934     EXPECT_EQ(mode[i],
935         apm_->echo_control_mobile()->routing_mode());
936   }
937   // Turn comfort noise off/on
938   EXPECT_EQ(apm_->kNoError,
939       apm_->echo_control_mobile()->enable_comfort_noise(false));
940   EXPECT_FALSE(apm_->echo_control_mobile()->is_comfort_noise_enabled());
941   EXPECT_EQ(apm_->kNoError,
942       apm_->echo_control_mobile()->enable_comfort_noise(true));
943   EXPECT_TRUE(apm_->echo_control_mobile()->is_comfort_noise_enabled());
944   // Set and get echo path
945   const size_t echo_path_size =
946       apm_->echo_control_mobile()->echo_path_size_bytes();
947   scoped_ptr<char[]> echo_path_in(new char[echo_path_size]);
948   scoped_ptr<char[]> echo_path_out(new char[echo_path_size]);
949   EXPECT_EQ(apm_->kNullPointerError,
950             apm_->echo_control_mobile()->SetEchoPath(NULL, echo_path_size));
951   EXPECT_EQ(apm_->kNullPointerError,
952             apm_->echo_control_mobile()->GetEchoPath(NULL, echo_path_size));
953   EXPECT_EQ(apm_->kBadParameterError,
954             apm_->echo_control_mobile()->GetEchoPath(echo_path_out.get(), 1));
955   EXPECT_EQ(apm_->kNoError,
956             apm_->echo_control_mobile()->GetEchoPath(echo_path_out.get(),
957                                                      echo_path_size));
958   for (size_t i = 0; i < echo_path_size; i++) {
959     echo_path_in[i] = echo_path_out[i] + 1;
960   }
961   EXPECT_EQ(apm_->kBadParameterError,
962             apm_->echo_control_mobile()->SetEchoPath(echo_path_in.get(), 1));
963   EXPECT_EQ(apm_->kNoError,
964             apm_->echo_control_mobile()->SetEchoPath(echo_path_in.get(),
965                                                      echo_path_size));
966   EXPECT_EQ(apm_->kNoError,
967             apm_->echo_control_mobile()->GetEchoPath(echo_path_out.get(),
968                                                      echo_path_size));
969   for (size_t i = 0; i < echo_path_size; i++) {
970     EXPECT_EQ(echo_path_in[i], echo_path_out[i]);
971   }
972
973   // Process a few frames with NS in the default disabled state. This exercises
974   // a different codepath than with it enabled.
975   EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
976   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
977   EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
978   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
979
980   // Turn AECM off
981   EXPECT_EQ(apm_->kNoError, apm_->echo_control_mobile()->Enable(false));
982   EXPECT_FALSE(apm_->echo_control_mobile()->is_enabled());
983 }
984
985 TEST_F(ApmTest, GainControl) {
986   // Testing gain modes
987   EXPECT_EQ(apm_->kNoError,
988       apm_->gain_control()->set_mode(
989       apm_->gain_control()->mode()));
990
991   GainControl::Mode mode[] = {
992     GainControl::kAdaptiveAnalog,
993     GainControl::kAdaptiveDigital,
994     GainControl::kFixedDigital
995   };
996   for (size_t i = 0; i < sizeof(mode)/sizeof(*mode); i++) {
997     EXPECT_EQ(apm_->kNoError,
998         apm_->gain_control()->set_mode(mode[i]));
999     EXPECT_EQ(mode[i], apm_->gain_control()->mode());
1000   }
1001   // Testing invalid target levels
1002   EXPECT_EQ(apm_->kBadParameterError,
1003       apm_->gain_control()->set_target_level_dbfs(-3));
1004   EXPECT_EQ(apm_->kBadParameterError,
1005       apm_->gain_control()->set_target_level_dbfs(-40));
1006   // Testing valid target levels
1007   EXPECT_EQ(apm_->kNoError,
1008       apm_->gain_control()->set_target_level_dbfs(
1009       apm_->gain_control()->target_level_dbfs()));
1010
1011   int level_dbfs[] = {0, 6, 31};
1012   for (size_t i = 0; i < sizeof(level_dbfs)/sizeof(*level_dbfs); i++) {
1013     EXPECT_EQ(apm_->kNoError,
1014         apm_->gain_control()->set_target_level_dbfs(level_dbfs[i]));
1015     EXPECT_EQ(level_dbfs[i], apm_->gain_control()->target_level_dbfs());
1016   }
1017
1018   // Testing invalid compression gains
1019   EXPECT_EQ(apm_->kBadParameterError,
1020       apm_->gain_control()->set_compression_gain_db(-1));
1021   EXPECT_EQ(apm_->kBadParameterError,
1022       apm_->gain_control()->set_compression_gain_db(100));
1023
1024   // Testing valid compression gains
1025   EXPECT_EQ(apm_->kNoError,
1026       apm_->gain_control()->set_compression_gain_db(
1027       apm_->gain_control()->compression_gain_db()));
1028
1029   int gain_db[] = {0, 10, 90};
1030   for (size_t i = 0; i < sizeof(gain_db)/sizeof(*gain_db); i++) {
1031     EXPECT_EQ(apm_->kNoError,
1032         apm_->gain_control()->set_compression_gain_db(gain_db[i]));
1033     EXPECT_EQ(gain_db[i], apm_->gain_control()->compression_gain_db());
1034   }
1035
1036   // Testing limiter off/on
1037   EXPECT_EQ(apm_->kNoError, apm_->gain_control()->enable_limiter(false));
1038   EXPECT_FALSE(apm_->gain_control()->is_limiter_enabled());
1039   EXPECT_EQ(apm_->kNoError, apm_->gain_control()->enable_limiter(true));
1040   EXPECT_TRUE(apm_->gain_control()->is_limiter_enabled());
1041
1042   // Testing invalid level limits
1043   EXPECT_EQ(apm_->kBadParameterError,
1044       apm_->gain_control()->set_analog_level_limits(-1, 512));
1045   EXPECT_EQ(apm_->kBadParameterError,
1046       apm_->gain_control()->set_analog_level_limits(100000, 512));
1047   EXPECT_EQ(apm_->kBadParameterError,
1048       apm_->gain_control()->set_analog_level_limits(512, -1));
1049   EXPECT_EQ(apm_->kBadParameterError,
1050       apm_->gain_control()->set_analog_level_limits(512, 100000));
1051   EXPECT_EQ(apm_->kBadParameterError,
1052       apm_->gain_control()->set_analog_level_limits(512, 255));
1053
1054   // Testing valid level limits
1055   EXPECT_EQ(apm_->kNoError,
1056       apm_->gain_control()->set_analog_level_limits(
1057       apm_->gain_control()->analog_level_minimum(),
1058       apm_->gain_control()->analog_level_maximum()));
1059
1060   int min_level[] = {0, 255, 1024};
1061   for (size_t i = 0; i < sizeof(min_level)/sizeof(*min_level); i++) {
1062     EXPECT_EQ(apm_->kNoError,
1063         apm_->gain_control()->set_analog_level_limits(min_level[i], 1024));
1064     EXPECT_EQ(min_level[i], apm_->gain_control()->analog_level_minimum());
1065   }
1066
1067   int max_level[] = {0, 1024, 65535};
1068   for (size_t i = 0; i < sizeof(min_level)/sizeof(*min_level); i++) {
1069     EXPECT_EQ(apm_->kNoError,
1070         apm_->gain_control()->set_analog_level_limits(0, max_level[i]));
1071     EXPECT_EQ(max_level[i], apm_->gain_control()->analog_level_maximum());
1072   }
1073
1074   // TODO(ajm): stream_is_saturated() and stream_analog_level()
1075
1076   // Turn AGC off
1077   EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(false));
1078   EXPECT_FALSE(apm_->gain_control()->is_enabled());
1079 }
1080
1081 void ApmTest::RunQuantizedVolumeDoesNotGetStuckTest(int sample_rate) {
1082   Init(sample_rate, sample_rate, sample_rate, 2, 2, 2, false);
1083   EXPECT_EQ(apm_->kNoError,
1084             apm_->gain_control()->set_mode(GainControl::kAdaptiveAnalog));
1085   EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
1086
1087   int out_analog_level = 0;
1088   for (int i = 0; i < 2000; ++i) {
1089     ReadFrameWithRewind(near_file_, frame_);
1090     // Ensure the audio is at a low level, so the AGC will try to increase it.
1091     ScaleFrame(frame_, 0.25);
1092
1093     // Always pass in the same volume.
1094     EXPECT_EQ(apm_->kNoError,
1095         apm_->gain_control()->set_stream_analog_level(100));
1096     EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1097     out_analog_level = apm_->gain_control()->stream_analog_level();
1098   }
1099
1100   // Ensure the AGC is still able to reach the maximum.
1101   EXPECT_EQ(255, out_analog_level);
1102 }
1103
1104 // Verifies that despite volume slider quantization, the AGC can continue to
1105 // increase its volume.
1106 TEST_F(ApmTest, QuantizedVolumeDoesNotGetStuck) {
1107   for (size_t i = 0; i < kSampleRatesSize; ++i) {
1108     RunQuantizedVolumeDoesNotGetStuckTest(kSampleRates[i]);
1109   }
1110 }
1111
1112 void ApmTest::RunManualVolumeChangeIsPossibleTest(int sample_rate) {
1113   Init(sample_rate, sample_rate, sample_rate, 2, 2, 2, false);
1114   EXPECT_EQ(apm_->kNoError,
1115             apm_->gain_control()->set_mode(GainControl::kAdaptiveAnalog));
1116   EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
1117
1118   int out_analog_level = 100;
1119   for (int i = 0; i < 1000; ++i) {
1120     ReadFrameWithRewind(near_file_, frame_);
1121     // Ensure the audio is at a low level, so the AGC will try to increase it.
1122     ScaleFrame(frame_, 0.25);
1123
1124     EXPECT_EQ(apm_->kNoError,
1125         apm_->gain_control()->set_stream_analog_level(out_analog_level));
1126     EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1127     out_analog_level = apm_->gain_control()->stream_analog_level();
1128   }
1129
1130   // Ensure the volume was raised.
1131   EXPECT_GT(out_analog_level, 100);
1132   int highest_level_reached = out_analog_level;
1133   // Simulate a user manual volume change.
1134   out_analog_level = 100;
1135
1136   for (int i = 0; i < 300; ++i) {
1137     ReadFrameWithRewind(near_file_, frame_);
1138     ScaleFrame(frame_, 0.25);
1139
1140     EXPECT_EQ(apm_->kNoError,
1141         apm_->gain_control()->set_stream_analog_level(out_analog_level));
1142     EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1143     out_analog_level = apm_->gain_control()->stream_analog_level();
1144     // Check that AGC respected the manually adjusted volume.
1145     EXPECT_LT(out_analog_level, highest_level_reached);
1146   }
1147   // Check that the volume was still raised.
1148   EXPECT_GT(out_analog_level, 100);
1149 }
1150
1151 TEST_F(ApmTest, ManualVolumeChangeIsPossible) {
1152   for (size_t i = 0; i < kSampleRatesSize; ++i) {
1153     RunManualVolumeChangeIsPossibleTest(kSampleRates[i]);
1154   }
1155 }
1156
1157 TEST_F(ApmTest, NoiseSuppression) {
1158   // Test valid suppression levels.
1159   NoiseSuppression::Level level[] = {
1160     NoiseSuppression::kLow,
1161     NoiseSuppression::kModerate,
1162     NoiseSuppression::kHigh,
1163     NoiseSuppression::kVeryHigh
1164   };
1165   for (size_t i = 0; i < sizeof(level)/sizeof(*level); i++) {
1166     EXPECT_EQ(apm_->kNoError,
1167         apm_->noise_suppression()->set_level(level[i]));
1168     EXPECT_EQ(level[i], apm_->noise_suppression()->level());
1169   }
1170
1171   // Turn NS on/off
1172   EXPECT_EQ(apm_->kNoError, apm_->noise_suppression()->Enable(true));
1173   EXPECT_TRUE(apm_->noise_suppression()->is_enabled());
1174   EXPECT_EQ(apm_->kNoError, apm_->noise_suppression()->Enable(false));
1175   EXPECT_FALSE(apm_->noise_suppression()->is_enabled());
1176 }
1177
1178 TEST_F(ApmTest, HighPassFilter) {
1179   // Turn HP filter on/off
1180   EXPECT_EQ(apm_->kNoError, apm_->high_pass_filter()->Enable(true));
1181   EXPECT_TRUE(apm_->high_pass_filter()->is_enabled());
1182   EXPECT_EQ(apm_->kNoError, apm_->high_pass_filter()->Enable(false));
1183   EXPECT_FALSE(apm_->high_pass_filter()->is_enabled());
1184 }
1185
1186 TEST_F(ApmTest, LevelEstimator) {
1187   // Turn level estimator on/off
1188   EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(false));
1189   EXPECT_FALSE(apm_->level_estimator()->is_enabled());
1190
1191   EXPECT_EQ(apm_->kNotEnabledError, apm_->level_estimator()->RMS());
1192
1193   EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(true));
1194   EXPECT_TRUE(apm_->level_estimator()->is_enabled());
1195
1196   // Run this test in wideband; in super-wb, the splitting filter distorts the
1197   // audio enough to cause deviation from the expectation for small values.
1198   frame_->samples_per_channel_ = 160;
1199   frame_->num_channels_ = 2;
1200   frame_->sample_rate_hz_ = 16000;
1201
1202   // Min value if no frames have been processed.
1203   EXPECT_EQ(127, apm_->level_estimator()->RMS());
1204
1205   // Min value on zero frames.
1206   SetFrameTo(frame_, 0);
1207   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1208   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1209   EXPECT_EQ(127, apm_->level_estimator()->RMS());
1210
1211   // Try a few RMS values.
1212   // (These also test that the value resets after retrieving it.)
1213   SetFrameTo(frame_, 32767);
1214   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1215   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1216   EXPECT_EQ(0, apm_->level_estimator()->RMS());
1217
1218   SetFrameTo(frame_, 30000);
1219   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1220   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1221   EXPECT_EQ(1, apm_->level_estimator()->RMS());
1222
1223   SetFrameTo(frame_, 10000);
1224   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1225   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1226   EXPECT_EQ(10, apm_->level_estimator()->RMS());
1227
1228   SetFrameTo(frame_, 10);
1229   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1230   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1231   EXPECT_EQ(70, apm_->level_estimator()->RMS());
1232
1233   // Verify reset after enable/disable.
1234   SetFrameTo(frame_, 32767);
1235   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1236   EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(false));
1237   EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(true));
1238   SetFrameTo(frame_, 1);
1239   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1240   EXPECT_EQ(90, apm_->level_estimator()->RMS());
1241
1242   // Verify reset after initialize.
1243   SetFrameTo(frame_, 32767);
1244   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1245   EXPECT_EQ(apm_->kNoError, apm_->Initialize());
1246   SetFrameTo(frame_, 1);
1247   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1248   EXPECT_EQ(90, apm_->level_estimator()->RMS());
1249 }
1250
1251 TEST_F(ApmTest, VoiceDetection) {
1252   // Test external VAD
1253   EXPECT_EQ(apm_->kNoError,
1254             apm_->voice_detection()->set_stream_has_voice(true));
1255   EXPECT_TRUE(apm_->voice_detection()->stream_has_voice());
1256   EXPECT_EQ(apm_->kNoError,
1257             apm_->voice_detection()->set_stream_has_voice(false));
1258   EXPECT_FALSE(apm_->voice_detection()->stream_has_voice());
1259
1260   // Test valid likelihoods
1261   VoiceDetection::Likelihood likelihood[] = {
1262       VoiceDetection::kVeryLowLikelihood,
1263       VoiceDetection::kLowLikelihood,
1264       VoiceDetection::kModerateLikelihood,
1265       VoiceDetection::kHighLikelihood
1266   };
1267   for (size_t i = 0; i < sizeof(likelihood)/sizeof(*likelihood); i++) {
1268     EXPECT_EQ(apm_->kNoError,
1269               apm_->voice_detection()->set_likelihood(likelihood[i]));
1270     EXPECT_EQ(likelihood[i], apm_->voice_detection()->likelihood());
1271   }
1272
1273   /* TODO(bjornv): Enable once VAD supports other frame lengths than 10 ms
1274   // Test invalid frame sizes
1275   EXPECT_EQ(apm_->kBadParameterError,
1276       apm_->voice_detection()->set_frame_size_ms(12));
1277
1278   // Test valid frame sizes
1279   for (int i = 10; i <= 30; i += 10) {
1280     EXPECT_EQ(apm_->kNoError,
1281         apm_->voice_detection()->set_frame_size_ms(i));
1282     EXPECT_EQ(i, apm_->voice_detection()->frame_size_ms());
1283   }
1284   */
1285
1286   // Turn VAD on/off
1287   EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(true));
1288   EXPECT_TRUE(apm_->voice_detection()->is_enabled());
1289   EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(false));
1290   EXPECT_FALSE(apm_->voice_detection()->is_enabled());
1291
1292   // Test that AudioFrame activity is maintained when VAD is disabled.
1293   EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(false));
1294   AudioFrame::VADActivity activity[] = {
1295       AudioFrame::kVadActive,
1296       AudioFrame::kVadPassive,
1297       AudioFrame::kVadUnknown
1298   };
1299   for (size_t i = 0; i < sizeof(activity)/sizeof(*activity); i++) {
1300     frame_->vad_activity_ = activity[i];
1301     EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1302     EXPECT_EQ(activity[i], frame_->vad_activity_);
1303   }
1304
1305   // Test that AudioFrame activity is set when VAD is enabled.
1306   EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(true));
1307   frame_->vad_activity_ = AudioFrame::kVadUnknown;
1308   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1309   EXPECT_NE(AudioFrame::kVadUnknown, frame_->vad_activity_);
1310
1311   // TODO(bjornv): Add tests for streamed voice; stream_has_voice()
1312 }
1313
1314 TEST_F(ApmTest, AllProcessingDisabledByDefault) {
1315   EXPECT_FALSE(apm_->echo_cancellation()->is_enabled());
1316   EXPECT_FALSE(apm_->echo_control_mobile()->is_enabled());
1317   EXPECT_FALSE(apm_->gain_control()->is_enabled());
1318   EXPECT_FALSE(apm_->high_pass_filter()->is_enabled());
1319   EXPECT_FALSE(apm_->level_estimator()->is_enabled());
1320   EXPECT_FALSE(apm_->noise_suppression()->is_enabled());
1321   EXPECT_FALSE(apm_->voice_detection()->is_enabled());
1322 }
1323
1324 TEST_F(ApmTest, NoProcessingWhenAllComponentsDisabled) {
1325   for (size_t i = 0; i < kSampleRatesSize; i++) {
1326     Init(kSampleRates[i], kSampleRates[i], kSampleRates[i], 2, 2, 2, false);
1327     SetFrameTo(frame_, 1000, 2000);
1328     AudioFrame frame_copy;
1329     frame_copy.CopyFrom(*frame_);
1330     for (int j = 0; j < 1000; j++) {
1331       EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1332       EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy));
1333     }
1334   }
1335 }
1336
1337 TEST_F(ApmTest, IdenticalInputChannelsResultInIdenticalOutputChannels) {
1338   EnableAllComponents();
1339
1340   for (size_t i = 0; i < kProcessSampleRatesSize; i++) {
1341     Init(kProcessSampleRates[i],
1342          kProcessSampleRates[i],
1343          kProcessSampleRates[i],
1344          2,
1345          2,
1346          2,
1347          false);
1348     int analog_level = 127;
1349     ASSERT_EQ(0, feof(far_file_));
1350     ASSERT_EQ(0, feof(near_file_));
1351     while (ReadFrame(far_file_, revframe_) && ReadFrame(near_file_, frame_)) {
1352       CopyLeftToRightChannel(revframe_->data_, revframe_->samples_per_channel_);
1353
1354       ASSERT_EQ(kNoErr, apm_->AnalyzeReverseStream(revframe_));
1355
1356       CopyLeftToRightChannel(frame_->data_, frame_->samples_per_channel_);
1357       frame_->vad_activity_ = AudioFrame::kVadUnknown;
1358
1359       ASSERT_EQ(kNoErr, apm_->set_stream_delay_ms(0));
1360       apm_->echo_cancellation()->set_stream_drift_samples(0);
1361       ASSERT_EQ(kNoErr,
1362           apm_->gain_control()->set_stream_analog_level(analog_level));
1363       ASSERT_EQ(kNoErr, apm_->ProcessStream(frame_));
1364       analog_level = apm_->gain_control()->stream_analog_level();
1365
1366       VerifyChannelsAreEqual(frame_->data_, frame_->samples_per_channel_);
1367     }
1368     rewind(far_file_);
1369     rewind(near_file_);
1370   }
1371 }
1372
1373 TEST_F(ApmTest, SplittingFilter) {
1374   // Verify the filter is not active through undistorted audio when:
1375   // 1. No components are enabled...
1376   SetFrameTo(frame_, 1000);
1377   AudioFrame frame_copy;
1378   frame_copy.CopyFrom(*frame_);
1379   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1380   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1381   EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy));
1382
1383   // 2. Only the level estimator is enabled...
1384   SetFrameTo(frame_, 1000);
1385   frame_copy.CopyFrom(*frame_);
1386   EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(true));
1387   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1388   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1389   EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy));
1390   EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(false));
1391
1392   // 3. Only VAD is enabled...
1393   SetFrameTo(frame_, 1000);
1394   frame_copy.CopyFrom(*frame_);
1395   EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(true));
1396   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1397   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1398   EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy));
1399   EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(false));
1400
1401   // 4. Both VAD and the level estimator are enabled...
1402   SetFrameTo(frame_, 1000);
1403   frame_copy.CopyFrom(*frame_);
1404   EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(true));
1405   EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(true));
1406   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1407   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1408   EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy));
1409   EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(false));
1410   EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(false));
1411
1412   // 5. Not using super-wb.
1413   frame_->samples_per_channel_ = 160;
1414   frame_->num_channels_ = 2;
1415   frame_->sample_rate_hz_ = 16000;
1416   // Enable AEC, which would require the filter in super-wb. We rely on the
1417   // first few frames of data being unaffected by the AEC.
1418   // TODO(andrew): This test, and the one below, rely rather tenuously on the
1419   // behavior of the AEC. Think of something more robust.
1420   EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
1421   // Make sure we have extended filter enabled. This makes sure nothing is
1422   // touched until we have a farend frame.
1423   Config config;
1424   config.Set<DelayCorrection>(new DelayCorrection(true));
1425   apm_->SetExtraOptions(config);
1426   SetFrameTo(frame_, 1000);
1427   frame_copy.CopyFrom(*frame_);
1428   EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
1429   apm_->echo_cancellation()->set_stream_drift_samples(0);
1430   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1431   EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
1432   apm_->echo_cancellation()->set_stream_drift_samples(0);
1433   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1434   EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy));
1435
1436   // Check the test is valid. We should have distortion from the filter
1437   // when AEC is enabled (which won't affect the audio).
1438   frame_->samples_per_channel_ = 320;
1439   frame_->num_channels_ = 2;
1440   frame_->sample_rate_hz_ = 32000;
1441   SetFrameTo(frame_, 1000);
1442   frame_copy.CopyFrom(*frame_);
1443   EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
1444   apm_->echo_cancellation()->set_stream_drift_samples(0);
1445   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1446   EXPECT_FALSE(FrameDataAreEqual(*frame_, frame_copy));
1447 }
1448
1449 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
1450 void ApmTest::ProcessDebugDump(const std::string& in_filename,
1451                                const std::string& out_filename,
1452                                Format format) {
1453   FILE* in_file = fopen(in_filename.c_str(), "rb");
1454   ASSERT_TRUE(in_file != NULL);
1455   audioproc::Event event_msg;
1456   bool first_init = true;
1457
1458   while (ReadMessageFromFile(in_file, &event_msg)) {
1459     if (event_msg.type() == audioproc::Event::INIT) {
1460       const audioproc::Init msg = event_msg.init();
1461       int reverse_sample_rate = msg.sample_rate();
1462       if (msg.has_reverse_sample_rate()) {
1463         reverse_sample_rate = msg.reverse_sample_rate();
1464       }
1465       int output_sample_rate = msg.sample_rate();
1466       if (msg.has_output_sample_rate()) {
1467         output_sample_rate = msg.output_sample_rate();
1468       }
1469
1470       Init(msg.sample_rate(),
1471            output_sample_rate,
1472            reverse_sample_rate,
1473            msg.num_input_channels(),
1474            msg.num_output_channels(),
1475            msg.num_reverse_channels(),
1476            false);
1477       if (first_init) {
1478         // StartDebugRecording() writes an additional init message. Don't start
1479         // recording until after the first init to avoid the extra message.
1480         EXPECT_NOERR(apm_->StartDebugRecording(out_filename.c_str()));
1481         first_init = false;
1482       }
1483
1484     } else if (event_msg.type() == audioproc::Event::REVERSE_STREAM) {
1485       const audioproc::ReverseStream msg = event_msg.reverse_stream();
1486
1487       if (msg.channel_size() > 0) {
1488         ASSERT_EQ(revframe_->num_channels_, msg.channel_size());
1489         for (int i = 0; i < msg.channel_size(); ++i) {
1490            memcpy(revfloat_cb_->channel(i), msg.channel(i).data(),
1491                   msg.channel(i).size());
1492         }
1493       } else {
1494         memcpy(revframe_->data_, msg.data().data(), msg.data().size());
1495         if (format == kFloatFormat) {
1496           // We're using an int16 input file; convert to float.
1497           ConvertToFloat(*revframe_, revfloat_cb_.get());
1498         }
1499       }
1500       AnalyzeReverseStreamChooser(format);
1501
1502     } else if (event_msg.type() == audioproc::Event::STREAM) {
1503       const audioproc::Stream msg = event_msg.stream();
1504       // ProcessStream could have changed this for the output frame.
1505       frame_->num_channels_ = apm_->num_input_channels();
1506
1507       EXPECT_NOERR(apm_->gain_control()->set_stream_analog_level(msg.level()));
1508       EXPECT_NOERR(apm_->set_stream_delay_ms(msg.delay()));
1509       apm_->echo_cancellation()->set_stream_drift_samples(msg.drift());
1510       if (msg.has_keypress()) {
1511         apm_->set_stream_key_pressed(msg.keypress());
1512       } else {
1513         apm_->set_stream_key_pressed(true);
1514       }
1515
1516       if (msg.input_channel_size() > 0) {
1517         ASSERT_EQ(frame_->num_channels_, msg.input_channel_size());
1518         for (int i = 0; i < msg.input_channel_size(); ++i) {
1519            memcpy(float_cb_->channel(i), msg.input_channel(i).data(),
1520                   msg.input_channel(i).size());
1521         }
1522       } else {
1523         memcpy(frame_->data_, msg.input_data().data(), msg.input_data().size());
1524         if (format == kFloatFormat) {
1525           // We're using an int16 input file; convert to float.
1526           ConvertToFloat(*frame_, float_cb_.get());
1527         }
1528       }
1529       ProcessStreamChooser(format);
1530     }
1531   }
1532   EXPECT_NOERR(apm_->StopDebugRecording());
1533   fclose(in_file);
1534 }
1535
1536 void ApmTest::VerifyDebugDumpTest(Format format) {
1537   const std::string in_filename = test::ResourcePath("ref03", "aecdump");
1538   std::string format_string;
1539   switch (format) {
1540     case kIntFormat:
1541       format_string = "_int";
1542       break;
1543     case kFloatFormat:
1544       format_string = "_float";
1545       break;
1546   }
1547   const std::string ref_filename =
1548       test::OutputPath() + "ref" + format_string + ".aecdump";
1549   const std::string out_filename =
1550       test::OutputPath() + "out" + format_string + ".aecdump";
1551   EnableAllComponents();
1552   ProcessDebugDump(in_filename, ref_filename, format);
1553   ProcessDebugDump(ref_filename, out_filename, format);
1554
1555   FILE* ref_file = fopen(ref_filename.c_str(), "rb");
1556   FILE* out_file = fopen(out_filename.c_str(), "rb");
1557   ASSERT_TRUE(ref_file != NULL);
1558   ASSERT_TRUE(out_file != NULL);
1559   scoped_ptr<uint8_t[]> ref_bytes;
1560   scoped_ptr<uint8_t[]> out_bytes;
1561
1562   size_t ref_size = ReadMessageBytesFromFile(ref_file, &ref_bytes);
1563   size_t out_size = ReadMessageBytesFromFile(out_file, &out_bytes);
1564   size_t bytes_read = 0;
1565   while (ref_size > 0 && out_size > 0) {
1566     bytes_read += ref_size;
1567     EXPECT_EQ(ref_size, out_size);
1568     EXPECT_EQ(0, memcmp(ref_bytes.get(), out_bytes.get(), ref_size));
1569     ref_size = ReadMessageBytesFromFile(ref_file, &ref_bytes);
1570     out_size = ReadMessageBytesFromFile(out_file, &out_bytes);
1571   }
1572   EXPECT_GT(bytes_read, 0u);
1573   EXPECT_NE(0, feof(ref_file));
1574   EXPECT_NE(0, feof(out_file));
1575   ASSERT_EQ(0, fclose(ref_file));
1576   ASSERT_EQ(0, fclose(out_file));
1577 }
1578
1579 TEST_F(ApmTest, VerifyDebugDumpInt) {
1580   VerifyDebugDumpTest(kIntFormat);
1581 }
1582
1583 TEST_F(ApmTest, VerifyDebugDumpFloat) {
1584   VerifyDebugDumpTest(kFloatFormat);
1585 }
1586 #endif
1587
1588 // TODO(andrew): expand test to verify output.
1589 TEST_F(ApmTest, DebugDump) {
1590   const std::string filename = test::OutputPath() + "debug.aec";
1591   EXPECT_EQ(apm_->kNullPointerError,
1592             apm_->StartDebugRecording(static_cast<const char*>(NULL)));
1593
1594 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
1595   // Stopping without having started should be OK.
1596   EXPECT_EQ(apm_->kNoError, apm_->StopDebugRecording());
1597
1598   EXPECT_EQ(apm_->kNoError, apm_->StartDebugRecording(filename.c_str()));
1599   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1600   EXPECT_EQ(apm_->kNoError, apm_->AnalyzeReverseStream(revframe_));
1601   EXPECT_EQ(apm_->kNoError, apm_->StopDebugRecording());
1602
1603   // Verify the file has been written.
1604   FILE* fid = fopen(filename.c_str(), "r");
1605   ASSERT_TRUE(fid != NULL);
1606
1607   // Clean it up.
1608   ASSERT_EQ(0, fclose(fid));
1609   ASSERT_EQ(0, remove(filename.c_str()));
1610 #else
1611   EXPECT_EQ(apm_->kUnsupportedFunctionError,
1612             apm_->StartDebugRecording(filename.c_str()));
1613   EXPECT_EQ(apm_->kUnsupportedFunctionError, apm_->StopDebugRecording());
1614
1615   // Verify the file has NOT been written.
1616   ASSERT_TRUE(fopen(filename.c_str(), "r") == NULL);
1617 #endif  // WEBRTC_AUDIOPROC_DEBUG_DUMP
1618 }
1619
1620 // TODO(andrew): expand test to verify output.
1621 TEST_F(ApmTest, DebugDumpFromFileHandle) {
1622   FILE* fid = NULL;
1623   EXPECT_EQ(apm_->kNullPointerError, apm_->StartDebugRecording(fid));
1624   const std::string filename = test::OutputPath() + "debug.aec";
1625   fid = fopen(filename.c_str(), "w");
1626   ASSERT_TRUE(fid);
1627
1628 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
1629   // Stopping without having started should be OK.
1630   EXPECT_EQ(apm_->kNoError, apm_->StopDebugRecording());
1631
1632   EXPECT_EQ(apm_->kNoError, apm_->StartDebugRecording(fid));
1633   EXPECT_EQ(apm_->kNoError, apm_->AnalyzeReverseStream(revframe_));
1634   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1635   EXPECT_EQ(apm_->kNoError, apm_->StopDebugRecording());
1636
1637   // Verify the file has been written.
1638   fid = fopen(filename.c_str(), "r");
1639   ASSERT_TRUE(fid != NULL);
1640
1641   // Clean it up.
1642   ASSERT_EQ(0, fclose(fid));
1643   ASSERT_EQ(0, remove(filename.c_str()));
1644 #else
1645   EXPECT_EQ(apm_->kUnsupportedFunctionError,
1646             apm_->StartDebugRecording(fid));
1647   EXPECT_EQ(apm_->kUnsupportedFunctionError, apm_->StopDebugRecording());
1648
1649   ASSERT_EQ(0, fclose(fid));
1650 #endif  // WEBRTC_AUDIOPROC_DEBUG_DUMP
1651 }
1652
1653 TEST_F(ApmTest, FloatAndIntInterfacesGiveIdenticalResults) {
1654   audioproc::OutputData ref_data;
1655   OpenFileAndReadMessage(ref_filename_, &ref_data);
1656
1657   Config config;
1658   config.Set<ExperimentalAgc>(new ExperimentalAgc(false));
1659   scoped_ptr<AudioProcessing> fapm(AudioProcessing::Create(config));
1660   EnableAllComponents();
1661   EnableAllAPComponents(fapm.get());
1662   for (int i = 0; i < ref_data.test_size(); i++) {
1663     printf("Running test %d of %d...\n", i + 1, ref_data.test_size());
1664
1665     audioproc::Test* test = ref_data.mutable_test(i);
1666     // TODO(ajm): Restore downmixing test cases.
1667     if (test->num_input_channels() != test->num_output_channels())
1668       continue;
1669
1670     const int num_render_channels = test->num_reverse_channels();
1671     const int num_input_channels = test->num_input_channels();
1672     const int num_output_channels = test->num_output_channels();
1673     const int samples_per_channel = test->sample_rate() *
1674         AudioProcessing::kChunkSizeMs / 1000;
1675     const int output_length = samples_per_channel * num_output_channels;
1676
1677     Init(test->sample_rate(), test->sample_rate(), test->sample_rate(),
1678          num_input_channels, num_output_channels, num_render_channels, true);
1679     Init(fapm.get());
1680
1681     ChannelBuffer<int16_t> output_cb(samples_per_channel, num_input_channels);
1682     scoped_ptr<int16_t[]> output_int16(new int16_t[output_length]);
1683
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;
1688
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)));
1695
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));
1702
1703       EXPECT_NOERR(apm_->ProcessStream(frame_));
1704       // TODO(ajm): Update to support different output rates.
1705       EXPECT_NOERR(fapm->ProcessStream(
1706           float_cb_->channels(),
1707           samples_per_channel,
1708           test->sample_rate(),
1709           LayoutFromChannels(num_input_channels),
1710           test->sample_rate(),
1711           LayoutFromChannels(num_output_channels),
1712           float_cb_->channels()));
1713
1714       // Convert to interleaved int16.
1715       ScaleAndRoundToInt16(float_cb_->data(), output_length, output_cb.data());
1716       Interleave(output_cb.channels(),
1717                  samples_per_channel,
1718                  num_output_channels,
1719                  output_int16.get());
1720       // Verify float and int16 paths produce identical output.
1721       EXPECT_EQ(0, memcmp(frame_->data_, output_int16.get(), output_length));
1722
1723       analog_level = fapm->gain_control()->stream_analog_level();
1724       EXPECT_EQ(apm_->gain_control()->stream_analog_level(),
1725                 fapm->gain_control()->stream_analog_level());
1726       EXPECT_EQ(apm_->echo_cancellation()->stream_has_echo(),
1727                 fapm->echo_cancellation()->stream_has_echo());
1728       EXPECT_EQ(apm_->voice_detection()->stream_has_voice(),
1729                 fapm->voice_detection()->stream_has_voice());
1730       EXPECT_EQ(apm_->noise_suppression()->speech_probability(),
1731                 fapm->noise_suppression()->speech_probability());
1732
1733       // Reset in case of downmixing.
1734       frame_->num_channels_ = test->num_input_channels();
1735     }
1736     rewind(far_file_);
1737     rewind(near_file_);
1738   }
1739 }
1740
1741 // TODO(andrew): Add a test to process a few frames with different combinations
1742 // of enabled components.
1743
1744 TEST_F(ApmTest, Process) {
1745   GOOGLE_PROTOBUF_VERIFY_VERSION;
1746   audioproc::OutputData ref_data;
1747
1748   if (!write_ref_data) {
1749     OpenFileAndReadMessage(ref_filename_, &ref_data);
1750   } else {
1751     // Write the desired tests to the protobuf reference file.
1752     for (size_t i = 0; i < kChannelsSize; i++) {
1753       for (size_t j = 0; j < kChannelsSize; j++) {
1754         for (size_t l = 0; l < kProcessSampleRatesSize; l++) {
1755           audioproc::Test* test = ref_data.add_test();
1756           test->set_num_reverse_channels(kChannels[i]);
1757           test->set_num_input_channels(kChannels[j]);
1758           test->set_num_output_channels(kChannels[j]);
1759           test->set_sample_rate(kProcessSampleRates[l]);
1760         }
1761       }
1762     }
1763   }
1764
1765   EnableAllComponents();
1766
1767   for (int i = 0; i < ref_data.test_size(); i++) {
1768     printf("Running test %d of %d...\n", i + 1, ref_data.test_size());
1769
1770     audioproc::Test* test = ref_data.mutable_test(i);
1771     // TODO(ajm): We no longer allow different input and output channels. Skip
1772     // these tests for now, but they should be removed from the set.
1773     if (test->num_input_channels() != test->num_output_channels())
1774       continue;
1775
1776     Init(test->sample_rate(),
1777          test->sample_rate(),
1778          test->sample_rate(),
1779          test->num_input_channels(),
1780          test->num_output_channels(),
1781          test->num_reverse_channels(),
1782          true);
1783
1784     int frame_count = 0;
1785     int has_echo_count = 0;
1786     int has_voice_count = 0;
1787     int is_saturated_count = 0;
1788     int analog_level = 127;
1789     int analog_level_average = 0;
1790     int max_output_average = 0;
1791     float ns_speech_prob_average = 0.0f;
1792
1793     while (ReadFrame(far_file_, revframe_) && ReadFrame(near_file_, frame_)) {
1794       EXPECT_EQ(apm_->kNoError, apm_->AnalyzeReverseStream(revframe_));
1795
1796       frame_->vad_activity_ = AudioFrame::kVadUnknown;
1797
1798       EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
1799       apm_->echo_cancellation()->set_stream_drift_samples(0);
1800       EXPECT_EQ(apm_->kNoError,
1801           apm_->gain_control()->set_stream_analog_level(analog_level));
1802
1803       EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1804
1805       // Ensure the frame was downmixed properly.
1806       EXPECT_EQ(test->num_output_channels(), frame_->num_channels_);
1807
1808       max_output_average += MaxAudioFrame(*frame_);
1809
1810       if (apm_->echo_cancellation()->stream_has_echo()) {
1811         has_echo_count++;
1812       }
1813
1814       analog_level = apm_->gain_control()->stream_analog_level();
1815       analog_level_average += analog_level;
1816       if (apm_->gain_control()->stream_is_saturated()) {
1817         is_saturated_count++;
1818       }
1819       if (apm_->voice_detection()->stream_has_voice()) {
1820         has_voice_count++;
1821         EXPECT_EQ(AudioFrame::kVadActive, frame_->vad_activity_);
1822       } else {
1823         EXPECT_EQ(AudioFrame::kVadPassive, frame_->vad_activity_);
1824       }
1825
1826       ns_speech_prob_average += apm_->noise_suppression()->speech_probability();
1827
1828       size_t frame_size = frame_->samples_per_channel_ * frame_->num_channels_;
1829       size_t write_count = fwrite(frame_->data_,
1830                                   sizeof(int16_t),
1831                                   frame_size,
1832                                   out_file_);
1833       ASSERT_EQ(frame_size, write_count);
1834
1835       // Reset in case of downmixing.
1836       frame_->num_channels_ = test->num_input_channels();
1837       frame_count++;
1838     }
1839     max_output_average /= frame_count;
1840     analog_level_average /= frame_count;
1841     ns_speech_prob_average /= frame_count;
1842
1843 #if defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
1844     EchoCancellation::Metrics echo_metrics;
1845     EXPECT_EQ(apm_->kNoError,
1846               apm_->echo_cancellation()->GetMetrics(&echo_metrics));
1847     int median = 0;
1848     int std = 0;
1849     EXPECT_EQ(apm_->kNoError,
1850               apm_->echo_cancellation()->GetDelayMetrics(&median, &std));
1851
1852     int rms_level = apm_->level_estimator()->RMS();
1853     EXPECT_LE(0, rms_level);
1854     EXPECT_GE(127, rms_level);
1855 #endif
1856
1857     if (!write_ref_data) {
1858       const int kIntNear = 1;
1859       // When running the test on a N7 we get a {2, 6} difference of
1860       // |has_voice_count| and |max_output_average| is up to 18 higher.
1861       // All numbers being consistently higher on N7 compare to ref_data.
1862       // TODO(bjornv): If we start getting more of these offsets on Android we
1863       // should consider a different approach. Either using one slack for all,
1864       // or generate a separate android reference.
1865 #if defined(WEBRTC_ANDROID)
1866       const int kHasVoiceCountOffset = 3;
1867       const int kHasVoiceCountNear = 3;
1868       const int kMaxOutputAverageOffset = 9;
1869       const int kMaxOutputAverageNear = 9;
1870 #else
1871       const int kHasVoiceCountOffset = 0;
1872       const int kHasVoiceCountNear = kIntNear;
1873       const int kMaxOutputAverageOffset = 0;
1874       const int kMaxOutputAverageNear = kIntNear;
1875 #endif
1876       EXPECT_NEAR(test->has_echo_count(), has_echo_count, kIntNear);
1877       EXPECT_NEAR(test->has_voice_count(),
1878                   has_voice_count - kHasVoiceCountOffset,
1879                   kHasVoiceCountNear);
1880       EXPECT_NEAR(test->is_saturated_count(), is_saturated_count, kIntNear);
1881
1882       EXPECT_NEAR(test->analog_level_average(), analog_level_average, kIntNear);
1883       EXPECT_NEAR(test->max_output_average(),
1884                   max_output_average - kMaxOutputAverageOffset,
1885                   kMaxOutputAverageNear);
1886
1887 #if defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
1888       audioproc::Test::EchoMetrics reference = test->echo_metrics();
1889       TestStats(echo_metrics.residual_echo_return_loss,
1890                 reference.residual_echo_return_loss());
1891       TestStats(echo_metrics.echo_return_loss,
1892                 reference.echo_return_loss());
1893       TestStats(echo_metrics.echo_return_loss_enhancement,
1894                 reference.echo_return_loss_enhancement());
1895       TestStats(echo_metrics.a_nlp,
1896                 reference.a_nlp());
1897
1898       const double kFloatNear = 0.0005;
1899       audioproc::Test::DelayMetrics reference_delay = test->delay_metrics();
1900       EXPECT_NEAR(reference_delay.median(), median, kIntNear);
1901       EXPECT_NEAR(reference_delay.std(), std, kIntNear);
1902
1903       EXPECT_NEAR(test->rms_level(), rms_level, kIntNear);
1904
1905       EXPECT_NEAR(test->ns_speech_probability_average(),
1906                   ns_speech_prob_average,
1907                   kFloatNear);
1908 #endif
1909     } else {
1910       test->set_has_echo_count(has_echo_count);
1911       test->set_has_voice_count(has_voice_count);
1912       test->set_is_saturated_count(is_saturated_count);
1913
1914       test->set_analog_level_average(analog_level_average);
1915       test->set_max_output_average(max_output_average);
1916
1917 #if defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
1918       audioproc::Test::EchoMetrics* message = test->mutable_echo_metrics();
1919       WriteStatsMessage(echo_metrics.residual_echo_return_loss,
1920                         message->mutable_residual_echo_return_loss());
1921       WriteStatsMessage(echo_metrics.echo_return_loss,
1922                         message->mutable_echo_return_loss());
1923       WriteStatsMessage(echo_metrics.echo_return_loss_enhancement,
1924                         message->mutable_echo_return_loss_enhancement());
1925       WriteStatsMessage(echo_metrics.a_nlp,
1926                         message->mutable_a_nlp());
1927
1928       audioproc::Test::DelayMetrics* message_delay =
1929           test->mutable_delay_metrics();
1930       message_delay->set_median(median);
1931       message_delay->set_std(std);
1932
1933       test->set_rms_level(rms_level);
1934
1935       EXPECT_LE(0.0f, ns_speech_prob_average);
1936       EXPECT_GE(1.0f, ns_speech_prob_average);
1937       test->set_ns_speech_probability_average(ns_speech_prob_average);
1938 #endif
1939     }
1940
1941     rewind(far_file_);
1942     rewind(near_file_);
1943   }
1944
1945   if (write_ref_data) {
1946     OpenFileAndWriteMessage(ref_filename_, ref_data);
1947   }
1948 }
1949
1950 TEST_F(ApmTest, NoErrorsWithKeyboardChannel) {
1951   struct ChannelFormat {
1952     AudioProcessing::ChannelLayout in_layout;
1953     AudioProcessing::ChannelLayout out_layout;
1954   };
1955   ChannelFormat cf[] = {
1956     {AudioProcessing::kMonoAndKeyboard, AudioProcessing::kMono},
1957     {AudioProcessing::kStereoAndKeyboard, AudioProcessing::kMono},
1958     {AudioProcessing::kStereoAndKeyboard, AudioProcessing::kStereo},
1959   };
1960   size_t channel_format_size = sizeof(cf) / sizeof(*cf);
1961
1962   scoped_ptr<AudioProcessing> ap(AudioProcessing::Create());
1963   // Enable one component just to ensure some processing takes place.
1964   ap->noise_suppression()->Enable(true);
1965   for (size_t i = 0; i < channel_format_size; ++i) {
1966     const int in_rate = 44100;
1967     const int out_rate = 48000;
1968     ChannelBuffer<float> in_cb(SamplesFromRate(in_rate),
1969                                TotalChannelsFromLayout(cf[i].in_layout));
1970     ChannelBuffer<float> out_cb(SamplesFromRate(out_rate),
1971                                 ChannelsFromLayout(cf[i].out_layout));
1972
1973     // Run over a few chunks.
1974     for (int j = 0; j < 10; ++j) {
1975       EXPECT_NOERR(ap->ProcessStream(
1976           in_cb.channels(),
1977           in_cb.samples_per_channel(),
1978           in_rate,
1979           cf[i].in_layout,
1980           out_rate,
1981           cf[i].out_layout,
1982           out_cb.channels()));
1983     }
1984   }
1985 }
1986
1987 // Reads a 10 ms chunk of int16 interleaved audio from the given (assumed
1988 // stereo) file, converts to deinterleaved float (optionally downmixing) and
1989 // returns the result in |cb|. Returns false if the file ended (or on error) and
1990 // true otherwise.
1991 //
1992 // |int_data| and |float_data| are just temporary space that must be
1993 // sufficiently large to hold the 10 ms chunk.
1994 bool ReadChunk(FILE* file, int16_t* int_data, float* float_data,
1995                ChannelBuffer<float>* cb) {
1996   // The files always contain stereo audio.
1997   size_t frame_size = cb->samples_per_channel() * 2;
1998   size_t read_count = fread(int_data, sizeof(int16_t), frame_size, file);
1999   if (read_count != frame_size) {
2000     // Check that the file really ended.
2001     assert(feof(file));
2002     return false;  // This is expected.
2003   }
2004
2005   ScaleToFloat(int_data, frame_size, float_data);
2006   if (cb->num_channels() == 1) {
2007     MixStereoToMono(float_data, cb->data(), cb->samples_per_channel());
2008   } else {
2009     Deinterleave(float_data, cb->samples_per_channel(), 2,
2010                  cb->channels());
2011   }
2012
2013   return true;
2014 }
2015
2016 // Compares the reference and test arrays over a region around the expected
2017 // delay. Finds the highest SNR in that region and adds the variance and squared
2018 // error results to the supplied accumulators.
2019 void UpdateBestSNR(const float* ref,
2020                    const float* test,
2021                    int length,
2022                    int expected_delay,
2023                    double* variance_acc,
2024                    double* sq_error_acc) {
2025   double best_snr = std::numeric_limits<double>::min();
2026   double best_variance = 0;
2027   double best_sq_error = 0;
2028   // Search over a region of eight samples around the expected delay.
2029   for (int delay = std::max(expected_delay - 4, 0); delay <= expected_delay + 4;
2030        ++delay) {
2031     double sq_error = 0;
2032     double variance = 0;
2033     for (int i = 0; i < length - delay; ++i) {
2034       double error = test[i + delay] - ref[i];
2035       sq_error += error * error;
2036       variance += ref[i] * ref[i];
2037     }
2038
2039     if (sq_error == 0) {
2040       *variance_acc += variance;
2041       return;
2042     }
2043     double snr = variance / sq_error;
2044     if (snr > best_snr) {
2045       best_snr = snr;
2046       best_variance = variance;
2047       best_sq_error = sq_error;
2048     }
2049   }
2050
2051   *variance_acc += best_variance;
2052   *sq_error_acc += best_sq_error;
2053 }
2054
2055 // Used to test a multitude of sample rate and channel combinations. It works
2056 // by first producing a set of reference files (in SetUpTestCase) that are
2057 // assumed to be correct, as the used parameters are verified by other tests
2058 // in this collection. Primarily the reference files are all produced at
2059 // "native" rates which do not involve any resampling.
2060
2061 // Each test pass produces an output file with a particular format. The output
2062 // is matched against the reference file closest to its internal processing
2063 // format. If necessary the output is resampled back to its process format.
2064 // Due to the resampling distortion, we don't expect identical results, but
2065 // enforce SNR thresholds which vary depending on the format. 0 is a special
2066 // case SNR which corresponds to inf, or zero error.
2067 typedef std::tr1::tuple<int, int, int, double> AudioProcessingTestData;
2068 class AudioProcessingTest
2069     : public testing::TestWithParam<AudioProcessingTestData> {
2070  public:
2071   AudioProcessingTest()
2072       : input_rate_(std::tr1::get<0>(GetParam())),
2073         output_rate_(std::tr1::get<1>(GetParam())),
2074         reverse_rate_(std::tr1::get<2>(GetParam())),
2075         expected_snr_(std::tr1::get<3>(GetParam())) {}
2076
2077   virtual ~AudioProcessingTest() {}
2078
2079   static void SetUpTestCase() {
2080     // Create all needed output reference files.
2081     const int kNativeRates[] = {8000, 16000, 32000};
2082     const size_t kNativeRatesSize =
2083         sizeof(kNativeRates) / sizeof(*kNativeRates);
2084     const int kNumChannels[] = {1, 2};
2085     const size_t kNumChannelsSize =
2086         sizeof(kNumChannels) / sizeof(*kNumChannels);
2087     for (size_t i = 0; i < kNativeRatesSize; ++i) {
2088       for (size_t j = 0; j < kNumChannelsSize; ++j) {
2089         for (size_t k = 0; k < kNumChannelsSize; ++k) {
2090           // The reference files always have matching input and output channels.
2091           ProcessFormat(kNativeRates[i],
2092                         kNativeRates[i],
2093                         kNativeRates[i],
2094                         kNumChannels[j],
2095                         kNumChannels[j],
2096                         kNumChannels[k],
2097                         "ref");
2098         }
2099       }
2100     }
2101   }
2102
2103   // Runs a process pass on files with the given parameters and dumps the output
2104   // to a file specified with |output_file_prefix|.
2105   static void ProcessFormat(int input_rate,
2106                             int output_rate,
2107                             int reverse_rate,
2108                             int num_input_channels,
2109                             int num_output_channels,
2110                             int num_reverse_channels,
2111                             std::string output_file_prefix) {
2112     scoped_ptr<AudioProcessing> ap(AudioProcessing::Create());
2113     EnableAllAPComponents(ap.get());
2114     ap->Initialize(input_rate,
2115                    output_rate,
2116                    reverse_rate,
2117                    LayoutFromChannels(num_input_channels),
2118                    LayoutFromChannels(num_output_channels),
2119                    LayoutFromChannels(num_reverse_channels));
2120
2121     FILE* far_file = fopen(ResourceFilePath("far", reverse_rate).c_str(), "rb");
2122     FILE* near_file = fopen(ResourceFilePath("near", input_rate).c_str(), "rb");
2123     FILE* out_file = fopen(OutputFilePath(output_file_prefix,
2124                                           input_rate,
2125                                           output_rate,
2126                                           reverse_rate,
2127                                           num_input_channels,
2128                                           num_output_channels,
2129                                           num_reverse_channels).c_str(), "wb");
2130     ASSERT_TRUE(far_file != NULL);
2131     ASSERT_TRUE(near_file != NULL);
2132     ASSERT_TRUE(out_file != NULL);
2133
2134     ChannelBuffer<float> fwd_cb(SamplesFromRate(input_rate),
2135                                 num_input_channels);
2136     ChannelBuffer<float> rev_cb(SamplesFromRate(reverse_rate),
2137                                 num_reverse_channels);
2138     ChannelBuffer<float> out_cb(SamplesFromRate(output_rate),
2139                                 num_output_channels);
2140
2141     // Temporary buffers.
2142     const int max_length =
2143         2 * std::max(out_cb.samples_per_channel(),
2144                      std::max(fwd_cb.samples_per_channel(),
2145                               rev_cb.samples_per_channel()));
2146     scoped_ptr<float[]> float_data(new float[max_length]);
2147     scoped_ptr<int16_t[]> int_data(new int16_t[max_length]);
2148
2149     int analog_level = 127;
2150     while (ReadChunk(far_file, int_data.get(), float_data.get(), &rev_cb) &&
2151            ReadChunk(near_file, int_data.get(), float_data.get(), &fwd_cb)) {
2152       EXPECT_NOERR(ap->AnalyzeReverseStream(
2153           rev_cb.channels(),
2154           rev_cb.samples_per_channel(),
2155           reverse_rate,
2156           LayoutFromChannels(num_reverse_channels)));
2157
2158       EXPECT_NOERR(ap->set_stream_delay_ms(0));
2159       ap->echo_cancellation()->set_stream_drift_samples(0);
2160       EXPECT_NOERR(ap->gain_control()->set_stream_analog_level(analog_level));
2161
2162       EXPECT_NOERR(ap->ProcessStream(
2163           fwd_cb.channels(),
2164           fwd_cb.samples_per_channel(),
2165           input_rate,
2166           LayoutFromChannels(num_input_channels),
2167           output_rate,
2168           LayoutFromChannels(num_output_channels),
2169           out_cb.channels()));
2170
2171       Interleave(out_cb.channels(),
2172                  out_cb.samples_per_channel(),
2173                  out_cb.num_channels(),
2174                  float_data.get());
2175       // Dump output to file.
2176       ASSERT_EQ(static_cast<size_t>(out_cb.length()),
2177                 fwrite(float_data.get(), sizeof(float_data[0]),
2178                        out_cb.length(), out_file));
2179
2180       analog_level = ap->gain_control()->stream_analog_level();
2181     }
2182     fclose(far_file);
2183     fclose(near_file);
2184     fclose(out_file);
2185   }
2186
2187  protected:
2188   int input_rate_;
2189   int output_rate_;
2190   int reverse_rate_;
2191   double expected_snr_;
2192 };
2193
2194 TEST_P(AudioProcessingTest, Formats) {
2195   struct ChannelFormat {
2196     int num_input;
2197     int num_output;
2198     int num_reverse;
2199   };
2200   ChannelFormat cf[] = {
2201     {1, 1, 1},
2202     {1, 1, 2},
2203     {2, 1, 1},
2204     {2, 1, 2},
2205     {2, 2, 1},
2206     {2, 2, 2},
2207   };
2208   size_t channel_format_size = sizeof(cf) / sizeof(*cf);
2209
2210   for (size_t i = 0; i < channel_format_size; ++i) {
2211     ProcessFormat(input_rate_,
2212                   output_rate_,
2213                   reverse_rate_,
2214                   cf[i].num_input,
2215                   cf[i].num_output,
2216                   cf[i].num_reverse,
2217                   "out");
2218     int min_ref_rate = std::min(input_rate_, output_rate_);
2219     int ref_rate;
2220     if (min_ref_rate > 16000) {
2221       ref_rate = 32000;
2222     } else if (min_ref_rate > 8000) {
2223       ref_rate = 16000;
2224     } else {
2225       ref_rate = 8000;
2226     }
2227 #ifdef WEBRTC_AUDIOPROC_FIXED_PROFILE
2228     ref_rate = std::min(ref_rate, 16000);
2229 #endif
2230
2231     FILE* out_file = fopen(OutputFilePath("out",
2232                                           input_rate_,
2233                                           output_rate_,
2234                                           reverse_rate_,
2235                                           cf[i].num_input,
2236                                           cf[i].num_output,
2237                                           cf[i].num_reverse).c_str(), "rb");
2238     // The reference files always have matching input and output channels.
2239     FILE* ref_file = fopen(OutputFilePath("ref",
2240                                           ref_rate,
2241                                           ref_rate,
2242                                           ref_rate,
2243                                           cf[i].num_output,
2244                                           cf[i].num_output,
2245                                           cf[i].num_reverse).c_str(), "rb");
2246     ASSERT_TRUE(out_file != NULL);
2247     ASSERT_TRUE(ref_file != NULL);
2248
2249     const int ref_length = SamplesFromRate(ref_rate) * cf[i].num_output;
2250     const int out_length = SamplesFromRate(output_rate_) * cf[i].num_output;
2251     // Data from the reference file.
2252     scoped_ptr<float[]> ref_data(new float[ref_length]);
2253     // Data from the output file.
2254     scoped_ptr<float[]> out_data(new float[out_length]);
2255     // Data from the resampled output, in case the reference and output rates
2256     // don't match.
2257     scoped_ptr<float[]> cmp_data(new float[ref_length]);
2258
2259     PushResampler<float> resampler;
2260     resampler.InitializeIfNeeded(output_rate_, ref_rate, cf[i].num_output);
2261
2262     // Compute the resampling delay of the output relative to the reference,
2263     // to find the region over which we should search for the best SNR.
2264     float expected_delay_sec = 0;
2265     if (input_rate_ != ref_rate) {
2266       // Input resampling delay.
2267       expected_delay_sec +=
2268           PushSincResampler::AlgorithmicDelaySeconds(input_rate_);
2269     }
2270     if (output_rate_ != ref_rate) {
2271       // Output resampling delay.
2272       expected_delay_sec +=
2273           PushSincResampler::AlgorithmicDelaySeconds(ref_rate);
2274       // Delay of converting the output back to its processing rate for testing.
2275       expected_delay_sec +=
2276           PushSincResampler::AlgorithmicDelaySeconds(output_rate_);
2277     }
2278     int expected_delay = floor(expected_delay_sec * ref_rate + 0.5f) *
2279                          cf[i].num_output;
2280
2281     double variance = 0;
2282     double sq_error = 0;
2283     while (fread(out_data.get(), sizeof(out_data[0]), out_length, out_file) &&
2284            fread(ref_data.get(), sizeof(ref_data[0]), ref_length, ref_file)) {
2285       float* out_ptr = out_data.get();
2286       if (output_rate_ != ref_rate) {
2287         // Resample the output back to its internal processing rate if necssary.
2288         ASSERT_EQ(ref_length, resampler.Resample(out_ptr,
2289                                                  out_length,
2290                                                  cmp_data.get(),
2291                                                  ref_length));
2292         out_ptr = cmp_data.get();
2293       }
2294
2295       // Update the |sq_error| and |variance| accumulators with the highest SNR
2296       // of reference vs output.
2297       UpdateBestSNR(ref_data.get(),
2298                     out_ptr,
2299                     ref_length,
2300                     expected_delay,
2301                     &variance,
2302                     &sq_error);
2303     }
2304
2305     std::cout << "(" << input_rate_ << ", "
2306                      << output_rate_ << ", "
2307                      << reverse_rate_ << ", "
2308                      << cf[i].num_input << ", "
2309                      << cf[i].num_output << ", "
2310                      << cf[i].num_reverse << "): ";
2311     if (sq_error > 0) {
2312       double snr = 10 * log10(variance / sq_error);
2313       EXPECT_GE(snr, expected_snr_);
2314       EXPECT_NE(0, expected_snr_);
2315       std::cout << "SNR=" << snr << " dB" << std::endl;
2316     } else {
2317       EXPECT_EQ(expected_snr_, 0);
2318       std::cout << "SNR=" << "inf dB" << std::endl;
2319     }
2320
2321     fclose(out_file);
2322     fclose(ref_file);
2323   }
2324 }
2325
2326 #if defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
2327 INSTANTIATE_TEST_CASE_P(
2328     CommonFormats, AudioProcessingTest, testing::Values(
2329         std::tr1::make_tuple(48000, 48000, 48000, 20),
2330         std::tr1::make_tuple(48000, 48000, 32000, 20),
2331         std::tr1::make_tuple(48000, 48000, 16000, 20),
2332         std::tr1::make_tuple(48000, 44100, 48000, 15),
2333         std::tr1::make_tuple(48000, 44100, 32000, 15),
2334         std::tr1::make_tuple(48000, 44100, 16000, 15),
2335         std::tr1::make_tuple(48000, 32000, 48000, 20),
2336         std::tr1::make_tuple(48000, 32000, 32000, 20),
2337         std::tr1::make_tuple(48000, 32000, 16000, 20),
2338         std::tr1::make_tuple(48000, 16000, 48000, 20),
2339         std::tr1::make_tuple(48000, 16000, 32000, 20),
2340         std::tr1::make_tuple(48000, 16000, 16000, 20),
2341
2342         std::tr1::make_tuple(44100, 48000, 48000, 20),
2343         std::tr1::make_tuple(44100, 48000, 32000, 20),
2344         std::tr1::make_tuple(44100, 48000, 16000, 20),
2345         std::tr1::make_tuple(44100, 44100, 48000, 15),
2346         std::tr1::make_tuple(44100, 44100, 32000, 15),
2347         std::tr1::make_tuple(44100, 44100, 16000, 15),
2348         std::tr1::make_tuple(44100, 32000, 48000, 20),
2349         std::tr1::make_tuple(44100, 32000, 32000, 20),
2350         std::tr1::make_tuple(44100, 32000, 16000, 20),
2351         std::tr1::make_tuple(44100, 16000, 48000, 20),
2352         std::tr1::make_tuple(44100, 16000, 32000, 20),
2353         std::tr1::make_tuple(44100, 16000, 16000, 20),
2354
2355         std::tr1::make_tuple(32000, 48000, 48000, 25),
2356         std::tr1::make_tuple(32000, 48000, 32000, 25),
2357         std::tr1::make_tuple(32000, 48000, 16000, 25),
2358         std::tr1::make_tuple(32000, 44100, 48000, 20),
2359         std::tr1::make_tuple(32000, 44100, 32000, 20),
2360         std::tr1::make_tuple(32000, 44100, 16000, 20),
2361         std::tr1::make_tuple(32000, 32000, 48000, 30),
2362         std::tr1::make_tuple(32000, 32000, 32000, 0),
2363         std::tr1::make_tuple(32000, 32000, 16000, 30),
2364         std::tr1::make_tuple(32000, 16000, 48000, 20),
2365         std::tr1::make_tuple(32000, 16000, 32000, 20),
2366         std::tr1::make_tuple(32000, 16000, 16000, 20),
2367
2368         std::tr1::make_tuple(16000, 48000, 48000, 25),
2369         std::tr1::make_tuple(16000, 48000, 32000, 25),
2370         std::tr1::make_tuple(16000, 48000, 16000, 25),
2371         std::tr1::make_tuple(16000, 44100, 48000, 15),
2372         std::tr1::make_tuple(16000, 44100, 32000, 15),
2373         std::tr1::make_tuple(16000, 44100, 16000, 15),
2374         std::tr1::make_tuple(16000, 32000, 48000, 25),
2375         std::tr1::make_tuple(16000, 32000, 32000, 25),
2376         std::tr1::make_tuple(16000, 32000, 16000, 25),
2377         std::tr1::make_tuple(16000, 16000, 48000, 30),
2378         std::tr1::make_tuple(16000, 16000, 32000, 30),
2379         std::tr1::make_tuple(16000, 16000, 16000, 0)));
2380
2381 #elif defined(WEBRTC_AUDIOPROC_FIXED_PROFILE)
2382 INSTANTIATE_TEST_CASE_P(
2383     CommonFormats, AudioProcessingTest, testing::Values(
2384         std::tr1::make_tuple(48000, 48000, 48000, 20),
2385         std::tr1::make_tuple(48000, 48000, 32000, 20),
2386         std::tr1::make_tuple(48000, 48000, 16000, 20),
2387         std::tr1::make_tuple(48000, 44100, 48000, 15),
2388         std::tr1::make_tuple(48000, 44100, 32000, 15),
2389         std::tr1::make_tuple(48000, 44100, 16000, 15),
2390         std::tr1::make_tuple(48000, 32000, 48000, 20),
2391         std::tr1::make_tuple(48000, 32000, 32000, 20),
2392         std::tr1::make_tuple(48000, 32000, 16000, 20),
2393         std::tr1::make_tuple(48000, 16000, 48000, 20),
2394         std::tr1::make_tuple(48000, 16000, 32000, 20),
2395         std::tr1::make_tuple(48000, 16000, 16000, 20),
2396
2397         std::tr1::make_tuple(44100, 48000, 48000, 19),
2398         std::tr1::make_tuple(44100, 48000, 32000, 19),
2399         std::tr1::make_tuple(44100, 48000, 16000, 19),
2400         std::tr1::make_tuple(44100, 44100, 48000, 15),
2401         std::tr1::make_tuple(44100, 44100, 32000, 15),
2402         std::tr1::make_tuple(44100, 44100, 16000, 15),
2403         std::tr1::make_tuple(44100, 32000, 48000, 19),
2404         std::tr1::make_tuple(44100, 32000, 32000, 19),
2405         std::tr1::make_tuple(44100, 32000, 16000, 19),
2406         std::tr1::make_tuple(44100, 16000, 48000, 19),
2407         std::tr1::make_tuple(44100, 16000, 32000, 19),
2408         std::tr1::make_tuple(44100, 16000, 16000, 19),
2409
2410         std::tr1::make_tuple(32000, 48000, 48000, 19),
2411         std::tr1::make_tuple(32000, 48000, 32000, 19),
2412         std::tr1::make_tuple(32000, 48000, 16000, 19),
2413         std::tr1::make_tuple(32000, 44100, 48000, 15),
2414         std::tr1::make_tuple(32000, 44100, 32000, 15),
2415         std::tr1::make_tuple(32000, 44100, 16000, 15),
2416         std::tr1::make_tuple(32000, 32000, 48000, 19),
2417         std::tr1::make_tuple(32000, 32000, 32000, 19),
2418         std::tr1::make_tuple(32000, 32000, 16000, 19),
2419         std::tr1::make_tuple(32000, 16000, 48000, 19),
2420         std::tr1::make_tuple(32000, 16000, 32000, 19),
2421         std::tr1::make_tuple(32000, 16000, 16000, 19),
2422
2423         std::tr1::make_tuple(16000, 48000, 48000, 25),
2424         std::tr1::make_tuple(16000, 48000, 32000, 25),
2425         std::tr1::make_tuple(16000, 48000, 16000, 25),
2426         std::tr1::make_tuple(16000, 44100, 48000, 15),
2427         std::tr1::make_tuple(16000, 44100, 32000, 15),
2428         std::tr1::make_tuple(16000, 44100, 16000, 15),
2429         std::tr1::make_tuple(16000, 32000, 48000, 25),
2430         std::tr1::make_tuple(16000, 32000, 32000, 25),
2431         std::tr1::make_tuple(16000, 32000, 16000, 25),
2432         std::tr1::make_tuple(16000, 16000, 48000, 30),
2433         std::tr1::make_tuple(16000, 16000, 32000, 30),
2434         std::tr1::make_tuple(16000, 16000, 16000, 0)));
2435 #endif
2436
2437 // TODO(henrike): re-implement functionality lost when removing the old main
2438 //                function. See
2439 //                https://code.google.com/p/webrtc/issues/detail?id=1981
2440
2441 }  // namespace
2442 }  // namespace webrtc