Home | History | Annotate | Download | only in test
      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
   2443