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