Home | History | Annotate | Download | only in unit_test
      1 /*
      2  *  Copyright (c) 2011 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 <cstdio>
     12 
     13 #include <gtest/gtest.h>
     14 
     15 #include "audio_processing.h"
     16 #include "audio_processing_unittest.pb.h"
     17 #include "event_wrapper.h"
     18 #include "module_common_types.h"
     19 #include "thread_wrapper.h"
     20 #include "trace.h"
     21 #include "signal_processing_library.h"
     22 
     23 using webrtc::AudioProcessing;
     24 using webrtc::AudioFrame;
     25 using webrtc::GainControl;
     26 using webrtc::NoiseSuppression;
     27 using webrtc::EchoCancellation;
     28 using webrtc::EventWrapper;
     29 using webrtc::Trace;
     30 using webrtc::LevelEstimator;
     31 using webrtc::EchoCancellation;
     32 using webrtc::EchoControlMobile;
     33 using webrtc::VoiceDetection;
     34 
     35 namespace {
     36 // When true, this will compare the output data with the results stored to
     37 // file. This is the typical case. When the file should be updated, it can
     38 // be set to false with the command-line switch --write_output_data.
     39 bool global_read_output_data = true;
     40 
     41 class ApmEnvironment : public ::testing::Environment {
     42  public:
     43   virtual void SetUp() {
     44     Trace::CreateTrace();
     45     ASSERT_EQ(0, Trace::SetTraceFile("apm_trace.txt"));
     46   }
     47 
     48   virtual void TearDown() {
     49     Trace::ReturnTrace();
     50   }
     51 };
     52 
     53 class ApmTest : public ::testing::Test {
     54  protected:
     55   ApmTest();
     56   virtual void SetUp();
     57   virtual void TearDown();
     58 
     59   webrtc::AudioProcessing* apm_;
     60   webrtc::AudioFrame* frame_;
     61   webrtc::AudioFrame* revframe_;
     62   FILE* far_file_;
     63   FILE* near_file_;
     64   bool update_output_data_;
     65 };
     66 
     67 ApmTest::ApmTest()
     68     : apm_(NULL),
     69       far_file_(NULL),
     70       near_file_(NULL),
     71       frame_(NULL),
     72       revframe_(NULL) {}
     73 
     74 void ApmTest::SetUp() {
     75   apm_ = AudioProcessing::Create(0);
     76   ASSERT_TRUE(apm_ != NULL);
     77 
     78   frame_ = new AudioFrame();
     79   revframe_ = new AudioFrame();
     80 
     81   ASSERT_EQ(apm_->kNoError, apm_->set_sample_rate_hz(32000));
     82   ASSERT_EQ(apm_->kNoError, apm_->set_num_channels(2, 2));
     83   ASSERT_EQ(apm_->kNoError, apm_->set_num_reverse_channels(2));
     84 
     85   frame_->_payloadDataLengthInSamples = 320;
     86   frame_->_audioChannel = 2;
     87   frame_->_frequencyInHz = 32000;
     88   revframe_->_payloadDataLengthInSamples = 320;
     89   revframe_->_audioChannel = 2;
     90   revframe_->_frequencyInHz = 32000;
     91 
     92   far_file_ = fopen("aec_far.pcm", "rb");
     93   ASSERT_TRUE(far_file_ != NULL) << "Could not open input file aec_far.pcm\n";
     94   near_file_ = fopen("aec_near.pcm", "rb");
     95   ASSERT_TRUE(near_file_ != NULL) << "Could not open input file aec_near.pcm\n";
     96 }
     97 
     98 void ApmTest::TearDown() {
     99   if (frame_) {
    100     delete frame_;
    101   }
    102   frame_ = NULL;
    103 
    104   if (revframe_) {
    105     delete revframe_;
    106   }
    107   revframe_ = NULL;
    108 
    109   if (far_file_) {
    110     ASSERT_EQ(0, fclose(far_file_));
    111   }
    112   far_file_ = NULL;
    113 
    114   if (near_file_) {
    115     ASSERT_EQ(0, fclose(near_file_));
    116   }
    117   near_file_ = NULL;
    118 
    119   if (apm_ != NULL) {
    120     AudioProcessing::Destroy(apm_);
    121   }
    122   apm_ = NULL;
    123 }
    124 
    125 void MixStereoToMono(WebRtc_Word16* stereo,
    126                      WebRtc_Word16* mono,
    127                      int numSamples) {
    128   for (int i = 0; i < numSamples; i++) {
    129     int int32 = (static_cast<int>(stereo[i * 2]) +
    130                  static_cast<int>(stereo[i * 2 + 1])) >> 1;
    131     mono[i] = static_cast<WebRtc_Word16>(int32);
    132   }
    133 }
    134 
    135 void WriteMessageLiteToFile(const char* filename,
    136                             const ::google::protobuf::MessageLite& message) {
    137   assert(filename != NULL);
    138 
    139   FILE* file = fopen(filename, "wb");
    140   ASSERT_TRUE(file != NULL) << "Could not open " << filename;
    141   int size = message.ByteSize();
    142   ASSERT_GT(size, 0);
    143   unsigned char* array = new unsigned char[size];
    144   ASSERT_TRUE(message.SerializeToArray(array, size));
    145 
    146   ASSERT_EQ(1, fwrite(&size, sizeof(int), 1, file));
    147   ASSERT_EQ(size, fwrite(array, sizeof(unsigned char), size, file));
    148 
    149   delete [] array;
    150   fclose(file);
    151 }
    152 
    153 void ReadMessageLiteFromFile(const char* filename,
    154                              ::google::protobuf::MessageLite* message) {
    155   assert(filename != NULL);
    156   assert(message != NULL);
    157 
    158   FILE* file = fopen(filename, "rb");
    159   ASSERT_TRUE(file != NULL) << "Could not open " << filename;
    160   int size = 0;
    161   ASSERT_EQ(1, fread(&size, sizeof(int), 1, file));
    162   ASSERT_GT(size, 0);
    163   unsigned char* array = new unsigned char[size];
    164   ASSERT_EQ(size, fread(array, sizeof(unsigned char), size, file));
    165 
    166   ASSERT_TRUE(message->ParseFromArray(array, size));
    167 
    168   delete [] array;
    169   fclose(file);
    170 }
    171 
    172 struct ThreadData {
    173   ThreadData(int thread_num_, AudioProcessing* ap_)
    174       : thread_num(thread_num_),
    175         error(false),
    176         ap(ap_) {}
    177   int thread_num;
    178   bool error;
    179   AudioProcessing* ap;
    180 };
    181 
    182 // Don't use GTest here; non-thread-safe on Windows (as of 1.5.0).
    183 bool DeadlockProc(void* thread_object) {
    184   ThreadData* thread_data = static_cast<ThreadData*>(thread_object);
    185   AudioProcessing* ap = thread_data->ap;
    186   int err = ap->kNoError;
    187 
    188   AudioFrame primary_frame;
    189   AudioFrame reverse_frame;
    190   primary_frame._payloadDataLengthInSamples = 320;
    191   primary_frame._audioChannel = 2;
    192   primary_frame._frequencyInHz = 32000;
    193   reverse_frame._payloadDataLengthInSamples = 320;
    194   reverse_frame._audioChannel = 2;
    195   reverse_frame._frequencyInHz = 32000;
    196 
    197   ap->echo_cancellation()->Enable(true);
    198   ap->gain_control()->Enable(true);
    199   ap->high_pass_filter()->Enable(true);
    200   ap->level_estimator()->Enable(true);
    201   ap->noise_suppression()->Enable(true);
    202   ap->voice_detection()->Enable(true);
    203 
    204   if (thread_data->thread_num % 2 == 0) {
    205     err = ap->AnalyzeReverseStream(&reverse_frame);
    206     if (err != ap->kNoError) {
    207       printf("Error in AnalyzeReverseStream(): %d\n", err);
    208       thread_data->error = true;
    209       return false;
    210     }
    211   }
    212 
    213   if (thread_data->thread_num % 2 == 1) {
    214     ap->set_stream_delay_ms(0);
    215     ap->echo_cancellation()->set_stream_drift_samples(0);
    216     ap->gain_control()->set_stream_analog_level(0);
    217     err = ap->ProcessStream(&primary_frame);
    218     if (err == ap->kStreamParameterNotSetError) {
    219       printf("Expected kStreamParameterNotSetError in ProcessStream(): %d\n",
    220           err);
    221     } else if (err != ap->kNoError) {
    222       printf("Error in ProcessStream(): %d\n", err);
    223       thread_data->error = true;
    224       return false;
    225     }
    226     ap->gain_control()->stream_analog_level();
    227   }
    228 
    229   EventWrapper* event = EventWrapper::Create();
    230   event->Wait(1);
    231   delete event;
    232   event = NULL;
    233 
    234   return true;
    235 }
    236 
    237 /*TEST_F(ApmTest, Deadlock) {
    238   const int num_threads = 16;
    239   std::vector<ThreadWrapper*> threads(num_threads);
    240   std::vector<ThreadData*> thread_data(num_threads);
    241 
    242   ASSERT_EQ(apm_->kNoError, apm_->set_sample_rate_hz(32000));
    243   ASSERT_EQ(apm_->kNoError, apm_->set_num_channels(2, 2));
    244   ASSERT_EQ(apm_->kNoError, apm_->set_num_reverse_channels(2));
    245 
    246   for (int i = 0; i < num_threads; i++) {
    247     thread_data[i] = new ThreadData(i, apm_);
    248     threads[i] = ThreadWrapper::CreateThread(DeadlockProc,
    249                                              thread_data[i],
    250                                              kNormalPriority,
    251                                              0);
    252     ASSERT_TRUE(threads[i] != NULL);
    253     unsigned int thread_id = 0;
    254     threads[i]->Start(thread_id);
    255   }
    256 
    257   EventWrapper* event = EventWrapper::Create();
    258   ASSERT_EQ(kEventTimeout, event->Wait(5000));
    259   delete event;
    260   event = NULL;
    261 
    262   for (int i = 0; i < num_threads; i++) {
    263     // This will return false if the thread has deadlocked.
    264     ASSERT_TRUE(threads[i]->Stop());
    265     ASSERT_FALSE(thread_data[i]->error);
    266     delete threads[i];
    267     threads[i] = NULL;
    268     delete thread_data[i];
    269     thread_data[i] = NULL;
    270   }
    271 }*/
    272 
    273 TEST_F(ApmTest, StreamParameters) {
    274   // No errors when the components are disabled.
    275   EXPECT_EQ(apm_->kNoError,
    276             apm_->ProcessStream(frame_));
    277 
    278   // Missing agc level
    279   EXPECT_EQ(apm_->kNoError, apm_->Initialize());
    280   EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
    281   EXPECT_EQ(apm_->kStreamParameterNotSetError,
    282             apm_->ProcessStream(frame_));
    283   EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
    284   EXPECT_EQ(apm_->kNoError,
    285             apm_->echo_cancellation()->set_stream_drift_samples(0));
    286   EXPECT_EQ(apm_->kStreamParameterNotSetError,
    287             apm_->ProcessStream(frame_));
    288   EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(false));
    289 
    290   // Missing delay
    291   EXPECT_EQ(apm_->kNoError, apm_->Initialize());
    292   EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
    293   EXPECT_EQ(apm_->kStreamParameterNotSetError,
    294             apm_->ProcessStream(frame_));
    295   EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
    296   EXPECT_EQ(apm_->kNoError,
    297             apm_->echo_cancellation()->set_stream_drift_samples(0));
    298   EXPECT_EQ(apm_->kNoError,
    299             apm_->gain_control()->set_stream_analog_level(127));
    300   EXPECT_EQ(apm_->kStreamParameterNotSetError,
    301             apm_->ProcessStream(frame_));
    302   EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(false));
    303 
    304   // Missing drift
    305   EXPECT_EQ(apm_->kNoError, apm_->Initialize());
    306   EXPECT_EQ(apm_->kNoError,
    307             apm_->echo_cancellation()->enable_drift_compensation(true));
    308   EXPECT_EQ(apm_->kStreamParameterNotSetError,
    309             apm_->ProcessStream(frame_));
    310   EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
    311   EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
    312   EXPECT_EQ(apm_->kNoError,
    313             apm_->gain_control()->set_stream_analog_level(127));
    314   EXPECT_EQ(apm_->kStreamParameterNotSetError,
    315             apm_->ProcessStream(frame_));
    316 
    317   // No stream parameters
    318   EXPECT_EQ(apm_->kNoError, apm_->Initialize());
    319   EXPECT_EQ(apm_->kNoError,
    320             apm_->AnalyzeReverseStream(revframe_));
    321   EXPECT_EQ(apm_->kStreamParameterNotSetError,
    322             apm_->ProcessStream(frame_));
    323 
    324   // All there
    325   EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
    326   EXPECT_EQ(apm_->kNoError, apm_->Initialize());
    327   EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
    328   EXPECT_EQ(apm_->kNoError,
    329             apm_->echo_cancellation()->set_stream_drift_samples(0));
    330   EXPECT_EQ(apm_->kNoError,
    331             apm_->gain_control()->set_stream_analog_level(127));
    332   EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
    333 }
    334 
    335 TEST_F(ApmTest, Channels) {
    336   // Testing number of invalid channels
    337   EXPECT_EQ(apm_->kBadParameterError, apm_->set_num_channels(0, 1));
    338   EXPECT_EQ(apm_->kBadParameterError, apm_->set_num_channels(1, 0));
    339   EXPECT_EQ(apm_->kBadParameterError, apm_->set_num_channels(3, 1));
    340   EXPECT_EQ(apm_->kBadParameterError, apm_->set_num_channels(1, 3));
    341   EXPECT_EQ(apm_->kBadParameterError, apm_->set_num_reverse_channels(0));
    342   EXPECT_EQ(apm_->kBadParameterError, apm_->set_num_reverse_channels(3));
    343   // Testing number of valid channels
    344   for (int i = 1; i < 3; i++) {
    345     for (int j = 1; j < 3; j++) {
    346       if (j > i) {
    347         EXPECT_EQ(apm_->kBadParameterError, apm_->set_num_channels(i, j));
    348       } else {
    349         EXPECT_EQ(apm_->kNoError, apm_->set_num_channels(i, j));
    350         EXPECT_EQ(j, apm_->num_output_channels());
    351       }
    352     }
    353     EXPECT_EQ(i, apm_->num_input_channels());
    354     EXPECT_EQ(apm_->kNoError, apm_->set_num_reverse_channels(i));
    355     EXPECT_EQ(i, apm_->num_reverse_channels());
    356   }
    357 }
    358 
    359 TEST_F(ApmTest, SampleRates) {
    360   // Testing invalid sample rates
    361   EXPECT_EQ(apm_->kBadParameterError, apm_->set_sample_rate_hz(10000));
    362   // Testing valid sample rates
    363   int fs[] = {8000, 16000, 32000};
    364   for (size_t i = 0; i < sizeof(fs) / sizeof(*fs); i++) {
    365     EXPECT_EQ(apm_->kNoError, apm_->set_sample_rate_hz(fs[i]));
    366     EXPECT_EQ(fs[i], apm_->sample_rate_hz());
    367   }
    368 }
    369 
    370 TEST_F(ApmTest, Process) {
    371   GOOGLE_PROTOBUF_VERIFY_VERSION;
    372   audio_processing_unittest::OutputData output_data;
    373 
    374   if (global_read_output_data) {
    375     ReadMessageLiteFromFile("output_data.pb", &output_data);
    376 
    377   } else {
    378     // We don't have a file; add the required tests to the protobuf.
    379     int rev_ch[] = {1, 2};
    380     int ch[] = {1, 2};
    381     int fs[] = {8000, 16000, 32000};
    382     for (size_t i = 0; i < sizeof(rev_ch) / sizeof(*rev_ch); i++) {
    383       for (size_t j = 0; j < sizeof(ch) / sizeof(*ch); j++) {
    384         for (size_t k = 0; k < sizeof(fs) / sizeof(*fs); k++) {
    385           audio_processing_unittest::Test* test = output_data.add_test();
    386           test->set_numreversechannels(rev_ch[i]);
    387           test->set_numchannels(ch[j]);
    388           test->set_samplerate(fs[k]);
    389         }
    390       }
    391     }
    392   }
    393 
    394   EXPECT_EQ(apm_->kNoError,
    395             apm_->echo_cancellation()->enable_drift_compensation(true));
    396   EXPECT_EQ(apm_->kNoError,
    397             apm_->echo_cancellation()->enable_metrics(true));
    398   EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
    399 
    400   EXPECT_EQ(apm_->kNoError,
    401             apm_->gain_control()->set_mode(GainControl::kAdaptiveAnalog));
    402   EXPECT_EQ(apm_->kNoError,
    403             apm_->gain_control()->set_analog_level_limits(0, 255));
    404   EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
    405 
    406   EXPECT_EQ(apm_->kNoError,
    407             apm_->high_pass_filter()->Enable(true));
    408 
    409   //EXPECT_EQ(apm_->kNoError,
    410   //          apm_->level_estimator()->Enable(true));
    411 
    412   EXPECT_EQ(apm_->kNoError,
    413             apm_->noise_suppression()->Enable(true));
    414 
    415   EXPECT_EQ(apm_->kNoError,
    416             apm_->voice_detection()->Enable(true));
    417 
    418   for (int i = 0; i < output_data.test_size(); i++) {
    419     printf("Running test %d of %d...\n", i + 1, output_data.test_size());
    420 
    421     audio_processing_unittest::Test* test = output_data.mutable_test(i);
    422     const int num_samples = test->samplerate() / 100;
    423     revframe_->_payloadDataLengthInSamples = num_samples;
    424     revframe_->_audioChannel = test->numreversechannels();
    425     revframe_->_frequencyInHz = test->samplerate();
    426     frame_->_payloadDataLengthInSamples = num_samples;
    427     frame_->_audioChannel = test->numchannels();
    428     frame_->_frequencyInHz = test->samplerate();
    429 
    430     EXPECT_EQ(apm_->kNoError, apm_->Initialize());
    431     ASSERT_EQ(apm_->kNoError, apm_->set_sample_rate_hz(test->samplerate()));
    432     ASSERT_EQ(apm_->kNoError, apm_->set_num_channels(frame_->_audioChannel,
    433                                                      frame_->_audioChannel));
    434     ASSERT_EQ(apm_->kNoError,
    435         apm_->set_num_reverse_channels(revframe_->_audioChannel));
    436 
    437 
    438     int has_echo_count = 0;
    439     int has_voice_count = 0;
    440     int is_saturated_count = 0;
    441 
    442     while (1) {
    443       WebRtc_Word16 temp_data[640];
    444       int analog_level = 127;
    445 
    446       // Read far-end frame
    447       size_t read_count = fread(temp_data,
    448                                 sizeof(WebRtc_Word16),
    449                                 num_samples * 2,
    450                                 far_file_);
    451       if (read_count != static_cast<size_t>(num_samples * 2)) {
    452         // Check that the file really ended.
    453         ASSERT_NE(0, feof(far_file_));
    454         break; // This is expected.
    455       }
    456 
    457       if (revframe_->_audioChannel == 1) {
    458         MixStereoToMono(temp_data, revframe_->_payloadData,
    459             revframe_->_payloadDataLengthInSamples);
    460       } else {
    461         memcpy(revframe_->_payloadData,
    462                &temp_data[0],
    463                sizeof(WebRtc_Word16) * read_count);
    464       }
    465 
    466       EXPECT_EQ(apm_->kNoError,
    467           apm_->AnalyzeReverseStream(revframe_));
    468 
    469       EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
    470       EXPECT_EQ(apm_->kNoError,
    471           apm_->echo_cancellation()->set_stream_drift_samples(0));
    472       EXPECT_EQ(apm_->kNoError,
    473           apm_->gain_control()->set_stream_analog_level(analog_level));
    474 
    475       // Read near-end frame
    476       read_count = fread(temp_data,
    477                          sizeof(WebRtc_Word16),
    478                          num_samples * 2,
    479                          near_file_);
    480       if (read_count != static_cast<size_t>(num_samples * 2)) {
    481         // Check that the file really ended.
    482         ASSERT_NE(0, feof(near_file_));
    483         break; // This is expected.
    484       }
    485 
    486       if (frame_->_audioChannel == 1) {
    487         MixStereoToMono(temp_data, frame_->_payloadData, num_samples);
    488       } else {
    489         memcpy(frame_->_payloadData,
    490                &temp_data[0],
    491                sizeof(WebRtc_Word16) * read_count);
    492       }
    493 
    494       EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
    495 
    496       if (apm_->echo_cancellation()->stream_has_echo()) {
    497         has_echo_count++;
    498       }
    499 
    500       analog_level = apm_->gain_control()->stream_analog_level();
    501       if (apm_->gain_control()->stream_is_saturated()) {
    502         is_saturated_count++;
    503       }
    504       if (apm_->voice_detection()->stream_has_voice()) {
    505         has_voice_count++;
    506       }
    507     }
    508 
    509     //<-- Statistics -->
    510     //LevelEstimator::Metrics far_metrics;
    511     //LevelEstimator::Metrics near_metrics;
    512     //EchoCancellation::Metrics echo_metrics;
    513     //LevelEstimator::Metrics far_metrics_ref_;
    514     //LevelEstimator::Metrics near_metrics_ref_;
    515     //EchoCancellation::Metrics echo_metrics_ref_;
    516     //EXPECT_EQ(apm_->kNoError,
    517     //          apm_->echo_cancellation()->GetMetrics(&echo_metrics));
    518     //EXPECT_EQ(apm_->kNoError,
    519     //          apm_->level_estimator()->GetMetrics(&near_metrics,
    520 
    521     // TODO(ajm): check echo metrics and output audio.
    522     if (global_read_output_data) {
    523       EXPECT_EQ(has_echo_count,
    524                 test->hasechocount());
    525       EXPECT_EQ(has_voice_count,
    526                 test->hasvoicecount());
    527       EXPECT_EQ(is_saturated_count,
    528                 test->issaturatedcount());
    529     } else {
    530       test->set_hasechocount(has_echo_count);
    531       test->set_hasvoicecount(has_voice_count);
    532       test->set_issaturatedcount(is_saturated_count);
    533     }
    534 
    535     rewind(far_file_);
    536     rewind(near_file_);
    537   }
    538 
    539   if (!global_read_output_data) {
    540     WriteMessageLiteToFile("output_data.pb", output_data);
    541   }
    542 
    543   google::protobuf::ShutdownProtobufLibrary();
    544 }
    545 
    546 TEST_F(ApmTest, EchoCancellation) {
    547   EXPECT_EQ(apm_->kNoError,
    548             apm_->echo_cancellation()->enable_drift_compensation(true));
    549   EXPECT_TRUE(apm_->echo_cancellation()->is_drift_compensation_enabled());
    550   EXPECT_EQ(apm_->kNoError,
    551             apm_->echo_cancellation()->enable_drift_compensation(false));
    552   EXPECT_FALSE(apm_->echo_cancellation()->is_drift_compensation_enabled());
    553 
    554   EXPECT_EQ(apm_->kBadParameterError,
    555       apm_->echo_cancellation()->set_device_sample_rate_hz(4000));
    556   EXPECT_EQ(apm_->kBadParameterError,
    557       apm_->echo_cancellation()->set_device_sample_rate_hz(100000));
    558 
    559   int rate[] = {16000, 44100, 48000};
    560   for (size_t i = 0; i < sizeof(rate)/sizeof(*rate); i++) {
    561     EXPECT_EQ(apm_->kNoError,
    562         apm_->echo_cancellation()->set_device_sample_rate_hz(rate[i]));
    563     EXPECT_EQ(rate[i],
    564         apm_->echo_cancellation()->device_sample_rate_hz());
    565   }
    566 
    567   EXPECT_EQ(apm_->kBadParameterError,
    568       apm_->echo_cancellation()->set_suppression_level(
    569           static_cast<EchoCancellation::SuppressionLevel>(-1)));
    570 
    571   EXPECT_EQ(apm_->kBadParameterError,
    572       apm_->echo_cancellation()->set_suppression_level(
    573           static_cast<EchoCancellation::SuppressionLevel>(4)));
    574 
    575   EchoCancellation::SuppressionLevel level[] = {
    576     EchoCancellation::kLowSuppression,
    577     EchoCancellation::kModerateSuppression,
    578     EchoCancellation::kHighSuppression,
    579   };
    580   for (size_t i = 0; i < sizeof(level)/sizeof(*level); i++) {
    581     EXPECT_EQ(apm_->kNoError,
    582         apm_->echo_cancellation()->set_suppression_level(level[i]));
    583     EXPECT_EQ(level[i],
    584         apm_->echo_cancellation()->suppression_level());
    585   }
    586 
    587   EchoCancellation::Metrics metrics;
    588   EXPECT_EQ(apm_->kNotEnabledError,
    589             apm_->echo_cancellation()->GetMetrics(&metrics));
    590 
    591   EXPECT_EQ(apm_->kNoError,
    592             apm_->echo_cancellation()->enable_metrics(true));
    593   EXPECT_TRUE(apm_->echo_cancellation()->are_metrics_enabled());
    594   EXPECT_EQ(apm_->kNoError,
    595             apm_->echo_cancellation()->enable_metrics(false));
    596   EXPECT_FALSE(apm_->echo_cancellation()->are_metrics_enabled());
    597 
    598   EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
    599   EXPECT_TRUE(apm_->echo_cancellation()->is_enabled());
    600   EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(false));
    601   EXPECT_FALSE(apm_->echo_cancellation()->is_enabled());
    602 }
    603 
    604 TEST_F(ApmTest, EchoControlMobile) {
    605   // AECM won't use super-wideband.
    606   EXPECT_EQ(apm_->kNoError, apm_->set_sample_rate_hz(32000));
    607   EXPECT_EQ(apm_->kBadSampleRateError, apm_->echo_control_mobile()->Enable(true));
    608   EXPECT_EQ(apm_->kNoError, apm_->set_sample_rate_hz(16000));
    609   // Turn AECM on (and AEC off)
    610   EXPECT_EQ(apm_->kNoError, apm_->echo_control_mobile()->Enable(true));
    611   EXPECT_TRUE(apm_->echo_control_mobile()->is_enabled());
    612 
    613   EXPECT_EQ(apm_->kBadParameterError,
    614       apm_->echo_control_mobile()->set_routing_mode(
    615       static_cast<EchoControlMobile::RoutingMode>(-1)));
    616   EXPECT_EQ(apm_->kBadParameterError,
    617       apm_->echo_control_mobile()->set_routing_mode(
    618       static_cast<EchoControlMobile::RoutingMode>(5)));
    619 
    620   // Toggle routing modes
    621   EchoControlMobile::RoutingMode mode[] = {
    622       EchoControlMobile::kQuietEarpieceOrHeadset,
    623       EchoControlMobile::kEarpiece,
    624       EchoControlMobile::kLoudEarpiece,
    625       EchoControlMobile::kSpeakerphone,
    626       EchoControlMobile::kLoudSpeakerphone,
    627   };
    628   for (size_t i = 0; i < sizeof(mode)/sizeof(*mode); i++) {
    629     EXPECT_EQ(apm_->kNoError,
    630         apm_->echo_control_mobile()->set_routing_mode(mode[i]));
    631     EXPECT_EQ(mode[i],
    632         apm_->echo_control_mobile()->routing_mode());
    633   }
    634   // Turn comfort noise off/on
    635   EXPECT_EQ(apm_->kNoError,
    636       apm_->echo_control_mobile()->enable_comfort_noise(false));
    637   EXPECT_FALSE(apm_->echo_control_mobile()->is_comfort_noise_enabled());
    638   EXPECT_EQ(apm_->kNoError,
    639       apm_->echo_control_mobile()->enable_comfort_noise(true));
    640   EXPECT_TRUE(apm_->echo_control_mobile()->is_comfort_noise_enabled());
    641   // Turn AECM off
    642   EXPECT_EQ(apm_->kNoError, apm_->echo_control_mobile()->Enable(false));
    643   EXPECT_FALSE(apm_->echo_control_mobile()->is_enabled());
    644 }
    645 
    646 TEST_F(ApmTest, GainControl) {
    647   // Testing gain modes
    648   EXPECT_EQ(apm_->kBadParameterError,
    649       apm_->gain_control()->set_mode(static_cast<GainControl::Mode>(-1)));
    650 
    651   EXPECT_EQ(apm_->kBadParameterError,
    652       apm_->gain_control()->set_mode(static_cast<GainControl::Mode>(3)));
    653 
    654   EXPECT_EQ(apm_->kNoError,
    655       apm_->gain_control()->set_mode(
    656       apm_->gain_control()->mode()));
    657 
    658   GainControl::Mode mode[] = {
    659     GainControl::kAdaptiveAnalog,
    660     GainControl::kAdaptiveDigital,
    661     GainControl::kFixedDigital
    662   };
    663   for (size_t i = 0; i < sizeof(mode)/sizeof(*mode); i++) {
    664     EXPECT_EQ(apm_->kNoError,
    665         apm_->gain_control()->set_mode(mode[i]));
    666     EXPECT_EQ(mode[i], apm_->gain_control()->mode());
    667   }
    668   // Testing invalid target levels
    669   EXPECT_EQ(apm_->kBadParameterError,
    670       apm_->gain_control()->set_target_level_dbfs(-3));
    671   EXPECT_EQ(apm_->kBadParameterError,
    672       apm_->gain_control()->set_target_level_dbfs(-40));
    673   // Testing valid target levels
    674   EXPECT_EQ(apm_->kNoError,
    675       apm_->gain_control()->set_target_level_dbfs(
    676       apm_->gain_control()->target_level_dbfs()));
    677 
    678   int level_dbfs[] = {0, 6, 31};
    679   for (size_t i = 0; i < sizeof(level_dbfs)/sizeof(*level_dbfs); i++) {
    680     EXPECT_EQ(apm_->kNoError,
    681         apm_->gain_control()->set_target_level_dbfs(level_dbfs[i]));
    682     EXPECT_EQ(level_dbfs[i], apm_->gain_control()->target_level_dbfs());
    683   }
    684 
    685   // Testing invalid compression gains
    686   EXPECT_EQ(apm_->kBadParameterError,
    687       apm_->gain_control()->set_compression_gain_db(-1));
    688   EXPECT_EQ(apm_->kBadParameterError,
    689       apm_->gain_control()->set_compression_gain_db(100));
    690 
    691   // Testing valid compression gains
    692   EXPECT_EQ(apm_->kNoError,
    693       apm_->gain_control()->set_compression_gain_db(
    694       apm_->gain_control()->compression_gain_db()));
    695 
    696   int gain_db[] = {0, 10, 90};
    697   for (size_t i = 0; i < sizeof(gain_db)/sizeof(*gain_db); i++) {
    698     EXPECT_EQ(apm_->kNoError,
    699         apm_->gain_control()->set_compression_gain_db(gain_db[i]));
    700     EXPECT_EQ(gain_db[i], apm_->gain_control()->compression_gain_db());
    701   }
    702 
    703   // Testing limiter off/on
    704   EXPECT_EQ(apm_->kNoError, apm_->gain_control()->enable_limiter(false));
    705   EXPECT_FALSE(apm_->gain_control()->is_limiter_enabled());
    706   EXPECT_EQ(apm_->kNoError, apm_->gain_control()->enable_limiter(true));
    707   EXPECT_TRUE(apm_->gain_control()->is_limiter_enabled());
    708 
    709   // Testing invalid level limits
    710   EXPECT_EQ(apm_->kBadParameterError,
    711       apm_->gain_control()->set_analog_level_limits(-1, 512));
    712   EXPECT_EQ(apm_->kBadParameterError,
    713       apm_->gain_control()->set_analog_level_limits(100000, 512));
    714   EXPECT_EQ(apm_->kBadParameterError,
    715       apm_->gain_control()->set_analog_level_limits(512, -1));
    716   EXPECT_EQ(apm_->kBadParameterError,
    717       apm_->gain_control()->set_analog_level_limits(512, 100000));
    718   EXPECT_EQ(apm_->kBadParameterError,
    719       apm_->gain_control()->set_analog_level_limits(512, 255));
    720 
    721   // Testing valid level limits
    722   EXPECT_EQ(apm_->kNoError,
    723       apm_->gain_control()->set_analog_level_limits(
    724       apm_->gain_control()->analog_level_minimum(),
    725       apm_->gain_control()->analog_level_maximum()));
    726 
    727   int min_level[] = {0, 255, 1024};
    728   for (size_t i = 0; i < sizeof(min_level)/sizeof(*min_level); i++) {
    729     EXPECT_EQ(apm_->kNoError,
    730         apm_->gain_control()->set_analog_level_limits(min_level[i], 1024));
    731     EXPECT_EQ(min_level[i], apm_->gain_control()->analog_level_minimum());
    732   }
    733 
    734   int max_level[] = {0, 1024, 65535};
    735   for (size_t i = 0; i < sizeof(min_level)/sizeof(*min_level); i++) {
    736     EXPECT_EQ(apm_->kNoError,
    737         apm_->gain_control()->set_analog_level_limits(0, max_level[i]));
    738     EXPECT_EQ(max_level[i], apm_->gain_control()->analog_level_maximum());
    739   }
    740 
    741   // TODO(ajm): stream_is_saturated() and stream_analog_level()
    742 
    743   // Turn AGC off
    744   EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(false));
    745   EXPECT_FALSE(apm_->gain_control()->is_enabled());
    746 }
    747 
    748 TEST_F(ApmTest, NoiseSuppression) {
    749   // Tesing invalid suppression levels
    750   EXPECT_EQ(apm_->kBadParameterError,
    751       apm_->noise_suppression()->set_level(
    752           static_cast<NoiseSuppression::Level>(-1)));
    753 
    754   EXPECT_EQ(apm_->kBadParameterError,
    755       apm_->noise_suppression()->set_level(
    756           static_cast<NoiseSuppression::Level>(5)));
    757 
    758   // Tesing valid suppression levels
    759   NoiseSuppression::Level level[] = {
    760     NoiseSuppression::kLow,
    761     NoiseSuppression::kModerate,
    762     NoiseSuppression::kHigh,
    763     NoiseSuppression::kVeryHigh
    764   };
    765   for (size_t i = 0; i < sizeof(level)/sizeof(*level); i++) {
    766     EXPECT_EQ(apm_->kNoError,
    767         apm_->noise_suppression()->set_level(level[i]));
    768     EXPECT_EQ(level[i], apm_->noise_suppression()->level());
    769   }
    770 
    771   // Turing NS on/off
    772   EXPECT_EQ(apm_->kNoError, apm_->noise_suppression()->Enable(true));
    773   EXPECT_TRUE(apm_->noise_suppression()->is_enabled());
    774   EXPECT_EQ(apm_->kNoError, apm_->noise_suppression()->Enable(false));
    775   EXPECT_FALSE(apm_->noise_suppression()->is_enabled());
    776 }
    777 
    778 TEST_F(ApmTest, HighPassFilter) {
    779   // Turing HP filter on/off
    780   EXPECT_EQ(apm_->kNoError, apm_->high_pass_filter()->Enable(true));
    781   EXPECT_TRUE(apm_->high_pass_filter()->is_enabled());
    782   EXPECT_EQ(apm_->kNoError, apm_->high_pass_filter()->Enable(false));
    783   EXPECT_FALSE(apm_->high_pass_filter()->is_enabled());
    784 }
    785 
    786 TEST_F(ApmTest, LevelEstimator) {
    787   // Turing Level estimator on/off
    788   EXPECT_EQ(apm_->kUnsupportedComponentError,
    789             apm_->level_estimator()->Enable(true));
    790   EXPECT_FALSE(apm_->level_estimator()->is_enabled());
    791   EXPECT_EQ(apm_->kUnsupportedComponentError,
    792             apm_->level_estimator()->Enable(false));
    793   EXPECT_FALSE(apm_->level_estimator()->is_enabled());
    794 }
    795 
    796 TEST_F(ApmTest, VoiceDetection) {
    797   // Test external VAD
    798   EXPECT_EQ(apm_->kNoError,
    799             apm_->voice_detection()->set_stream_has_voice(true));
    800   EXPECT_TRUE(apm_->voice_detection()->stream_has_voice());
    801   EXPECT_EQ(apm_->kNoError,
    802             apm_->voice_detection()->set_stream_has_voice(false));
    803   EXPECT_FALSE(apm_->voice_detection()->stream_has_voice());
    804 
    805   // Tesing invalid likelihoods
    806   EXPECT_EQ(apm_->kBadParameterError,
    807       apm_->voice_detection()->set_likelihood(
    808           static_cast<VoiceDetection::Likelihood>(-1)));
    809 
    810   EXPECT_EQ(apm_->kBadParameterError,
    811       apm_->voice_detection()->set_likelihood(
    812           static_cast<VoiceDetection::Likelihood>(5)));
    813 
    814   // Tesing valid likelihoods
    815   VoiceDetection::Likelihood likelihood[] = {
    816       VoiceDetection::kVeryLowLikelihood,
    817       VoiceDetection::kLowLikelihood,
    818       VoiceDetection::kModerateLikelihood,
    819       VoiceDetection::kHighLikelihood
    820   };
    821   for (size_t i = 0; i < sizeof(likelihood)/sizeof(*likelihood); i++) {
    822     EXPECT_EQ(apm_->kNoError,
    823               apm_->voice_detection()->set_likelihood(likelihood[i]));
    824     EXPECT_EQ(likelihood[i], apm_->voice_detection()->likelihood());
    825   }
    826 
    827   /* TODO(bjornv): Enable once VAD supports other frame lengths than 10 ms
    828   // Tesing invalid frame sizes
    829   EXPECT_EQ(apm_->kBadParameterError,
    830       apm_->voice_detection()->set_frame_size_ms(12));
    831 
    832   // Tesing valid frame sizes
    833   for (int i = 10; i <= 30; i += 10) {
    834     EXPECT_EQ(apm_->kNoError,
    835         apm_->voice_detection()->set_frame_size_ms(i));
    836     EXPECT_EQ(i, apm_->voice_detection()->frame_size_ms());
    837   }
    838   */
    839 
    840   // Turing VAD on/off
    841   EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(true));
    842   EXPECT_TRUE(apm_->voice_detection()->is_enabled());
    843   EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(false));
    844   EXPECT_FALSE(apm_->voice_detection()->is_enabled());
    845 
    846   // TODO(bjornv): Add tests for streamed voice; stream_has_voice()
    847 }
    848 
    849 // Below are some ideas for tests from VPM.
    850 
    851 /*TEST_F(VideoProcessingModuleTest, GetVersionTest)
    852 {
    853 }
    854 
    855 TEST_F(VideoProcessingModuleTest, HandleNullBuffer)
    856 {
    857 }
    858 
    859 TEST_F(VideoProcessingModuleTest, HandleBadSize)
    860 {
    861 }
    862 
    863 TEST_F(VideoProcessingModuleTest, IdenticalResultsAfterReset)
    864 {
    865 }
    866 */
    867 }  // namespace
    868 
    869 int main(int argc, char** argv) {
    870   ::testing::InitGoogleTest(&argc, argv);
    871   ApmEnvironment* env = new ApmEnvironment; // GTest takes ownership.
    872   ::testing::AddGlobalTestEnvironment(env);
    873 
    874   for (int i = 1; i < argc; i++) {
    875     if (strcmp(argv[i], "--write_output_data") == 0) {
    876       global_read_output_data = false;
    877     }
    878   }
    879 
    880   return RUN_ALL_TESTS();
    881 }
    882