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 <stdio.h>
12
13#include "gtest/gtest.h"
14
15#include "audio_processing.h"
16#include "event_wrapper.h"
17#include "module_common_types.h"
18#include "scoped_ptr.h"
19#include "signal_processing_library.h"
20#include "testsupport/fileutils.h"
21#include "thread_wrapper.h"
22#include "trace.h"
23#ifdef WEBRTC_ANDROID
24#include "external/webrtc/src/modules/audio_processing/test/unittest.pb.h"
25#else
26#include "webrtc/audio_processing/unittest.pb.h"
27#endif
28
29using webrtc::AudioProcessing;
30using webrtc::AudioFrame;
31using webrtc::GainControl;
32using webrtc::NoiseSuppression;
33using webrtc::EchoCancellation;
34using webrtc::EventWrapper;
35using webrtc::scoped_array;
36using webrtc::Trace;
37using webrtc::LevelEstimator;
38using webrtc::EchoCancellation;
39using webrtc::EchoControlMobile;
40using webrtc::VoiceDetection;
41
42namespace {
43// When false, this will compare the output data with the results stored to
44// file. This is the typical case. When the file should be updated, it can
45// be set to true with the command-line switch --write_output_data.
46bool write_output_data = false;
47
48class ApmTest : public ::testing::Test {
49 protected:
50  ApmTest();
51  virtual void SetUp();
52  virtual void TearDown();
53
54  static void SetUpTestCase() {
55    Trace::CreateTrace();
56    std::string trace_filename = webrtc::test::OutputPath() +
57      "audioproc_trace.txt";
58    ASSERT_EQ(0, Trace::SetTraceFile(trace_filename.c_str()));
59  }
60
61  static void TearDownTestCase() {
62    Trace::ReturnTrace();
63  }
64  // Path to where the resource files to be used for this test are located.
65  const std::string resource_path;
66  const std::string output_filename;
67  webrtc::AudioProcessing* apm_;
68  webrtc::AudioFrame* frame_;
69  webrtc::AudioFrame* revframe_;
70  FILE* far_file_;
71  FILE* near_file_;
72};
73
74ApmTest::ApmTest()
75    : resource_path(webrtc::test::ProjectRootPath() +
76                    "test/data/audio_processing/"),
77#if defined(WEBRTC_APM_UNIT_TEST_FIXED_PROFILE)
78      output_filename(resource_path + "output_data_fixed.pb"),
79#elif defined(WEBRTC_APM_UNIT_TEST_FLOAT_PROFILE)
80      output_filename(resource_path + "output_data_float.pb"),
81#endif
82      apm_(NULL),
83      frame_(NULL),
84      revframe_(NULL),
85      far_file_(NULL),
86      near_file_(NULL) {}
87
88void ApmTest::SetUp() {
89  apm_ = AudioProcessing::Create(0);
90  ASSERT_TRUE(apm_ != NULL);
91
92  frame_ = new AudioFrame();
93  revframe_ = new AudioFrame();
94
95  ASSERT_EQ(apm_->kNoError, apm_->set_sample_rate_hz(32000));
96  ASSERT_EQ(apm_->kNoError, apm_->set_num_channels(2, 2));
97  ASSERT_EQ(apm_->kNoError, apm_->set_num_reverse_channels(2));
98
99  frame_->_payloadDataLengthInSamples = 320;
100  frame_->_audioChannel = 2;
101  frame_->_frequencyInHz = 32000;
102  revframe_->_payloadDataLengthInSamples = 320;
103  revframe_->_audioChannel = 2;
104  revframe_->_frequencyInHz = 32000;
105
106  std::string input_filename = resource_path + "aec_far.pcm";
107  far_file_ = fopen(input_filename.c_str(), "rb");
108  ASSERT_TRUE(far_file_ != NULL) << "Could not open input file " <<
109      input_filename << "\n";
110  input_filename = resource_path + "aec_near.pcm";
111  near_file_ = fopen(input_filename.c_str(), "rb");
112  ASSERT_TRUE(near_file_ != NULL) << "Could not open input file " <<
113        input_filename << "\n";
114}
115
116void ApmTest::TearDown() {
117  if (frame_) {
118    delete frame_;
119  }
120  frame_ = NULL;
121
122  if (revframe_) {
123    delete revframe_;
124  }
125  revframe_ = NULL;
126
127  if (far_file_) {
128    ASSERT_EQ(0, fclose(far_file_));
129  }
130  far_file_ = NULL;
131
132  if (near_file_) {
133    ASSERT_EQ(0, fclose(near_file_));
134  }
135  near_file_ = NULL;
136
137  if (apm_ != NULL) {
138    AudioProcessing::Destroy(apm_);
139  }
140  apm_ = NULL;
141}
142
143void MixStereoToMono(const int16_t* stereo,
144                     int16_t* mono,
145                     int samples_per_channel) {
146  for (int i = 0; i < samples_per_channel; i++) {
147    int32_t int32 = (static_cast<int32_t>(stereo[i * 2]) +
148                     static_cast<int32_t>(stereo[i * 2 + 1])) >> 1;
149    mono[i] = static_cast<int16_t>(int32);
150  }
151}
152
153template <class T>
154T MaxValue(T a, T b) {
155  return a > b ? a : b;
156}
157
158template <class T>
159T AbsValue(T a) {
160  return a > 0 ? a : -a;
161}
162
163void SetFrameTo(AudioFrame* frame, int16_t value) {
164  for (int i = 0; i < frame->_payloadDataLengthInSamples * frame->_audioChannel;
165      ++i) {
166    frame->_payloadData[i] = value;
167  }
168}
169
170int16_t MaxAudioFrame(const AudioFrame& frame) {
171  const int length = frame._payloadDataLengthInSamples * frame._audioChannel;
172  int16_t max = AbsValue(frame._payloadData[0]);
173  for (int i = 1; i < length; i++) {
174    max = MaxValue(max, AbsValue(frame._payloadData[i]));
175  }
176
177  return max;
178}
179
180bool FrameDataAreEqual(const AudioFrame& frame1, const AudioFrame& frame2) {
181  if (frame1._payloadDataLengthInSamples !=
182      frame2._payloadDataLengthInSamples) {
183    return false;
184  }
185  if (frame1._audioChannel !=
186      frame2._audioChannel) {
187    return false;
188  }
189  if (memcmp(frame1._payloadData, frame2._payloadData,
190             frame1._payloadDataLengthInSamples * frame1._audioChannel *
191               sizeof(int16_t))) {
192    return false;
193  }
194  return true;
195}
196
197void TestStats(const AudioProcessing::Statistic& test,
198               const webrtc::audioproc::Test::Statistic& reference) {
199  EXPECT_EQ(reference.instant(), test.instant);
200  EXPECT_EQ(reference.average(), test.average);
201  EXPECT_EQ(reference.maximum(), test.maximum);
202  EXPECT_EQ(reference.minimum(), test.minimum);
203}
204
205void WriteStatsMessage(const AudioProcessing::Statistic& output,
206                       webrtc::audioproc::Test::Statistic* message) {
207  message->set_instant(output.instant);
208  message->set_average(output.average);
209  message->set_maximum(output.maximum);
210  message->set_minimum(output.minimum);
211}
212
213void WriteMessageLiteToFile(const std::string filename,
214                            const ::google::protobuf::MessageLite& message) {
215  FILE* file = fopen(filename.c_str(), "wb");
216  ASSERT_TRUE(file != NULL) << "Could not open " << filename;
217  int size = message.ByteSize();
218  ASSERT_GT(size, 0);
219  unsigned char* array = new unsigned char[size];
220  ASSERT_TRUE(message.SerializeToArray(array, size));
221
222  ASSERT_EQ(1u, fwrite(&size, sizeof(int), 1, file));
223  ASSERT_EQ(static_cast<size_t>(size),
224      fwrite(array, sizeof(unsigned char), size, file));
225
226  delete [] array;
227  fclose(file);
228}
229
230void ReadMessageLiteFromFile(const std::string filename,
231                             ::google::protobuf::MessageLite* message) {
232  assert(message != NULL);
233
234  FILE* file = fopen(filename.c_str(), "rb");
235  ASSERT_TRUE(file != NULL) << "Could not open " << filename;
236  int size = 0;
237  ASSERT_EQ(1u, fread(&size, sizeof(int), 1, file));
238  ASSERT_GT(size, 0);
239  unsigned char* array = new unsigned char[size];
240  ASSERT_EQ(static_cast<size_t>(size),
241      fread(array, sizeof(unsigned char), size, file));
242
243  ASSERT_TRUE(message->ParseFromArray(array, size));
244
245  delete [] array;
246  fclose(file);
247}
248
249struct ThreadData {
250  ThreadData(int thread_num_, AudioProcessing* ap_)
251      : thread_num(thread_num_),
252        error(false),
253        ap(ap_) {}
254  int thread_num;
255  bool error;
256  AudioProcessing* ap;
257};
258
259// Don't use GTest here; non-thread-safe on Windows (as of 1.5.0).
260bool DeadlockProc(void* thread_object) {
261  ThreadData* thread_data = static_cast<ThreadData*>(thread_object);
262  AudioProcessing* ap = thread_data->ap;
263  int err = ap->kNoError;
264
265  AudioFrame primary_frame;
266  AudioFrame reverse_frame;
267  primary_frame._payloadDataLengthInSamples = 320;
268  primary_frame._audioChannel = 2;
269  primary_frame._frequencyInHz = 32000;
270  reverse_frame._payloadDataLengthInSamples = 320;
271  reverse_frame._audioChannel = 2;
272  reverse_frame._frequencyInHz = 32000;
273
274  ap->echo_cancellation()->Enable(true);
275  ap->gain_control()->Enable(true);
276  ap->high_pass_filter()->Enable(true);
277  ap->level_estimator()->Enable(true);
278  ap->noise_suppression()->Enable(true);
279  ap->voice_detection()->Enable(true);
280
281  if (thread_data->thread_num % 2 == 0) {
282    err = ap->AnalyzeReverseStream(&reverse_frame);
283    if (err != ap->kNoError) {
284      printf("Error in AnalyzeReverseStream(): %d\n", err);
285      thread_data->error = true;
286      return false;
287    }
288  }
289
290  if (thread_data->thread_num % 2 == 1) {
291    ap->set_stream_delay_ms(0);
292    ap->echo_cancellation()->set_stream_drift_samples(0);
293    ap->gain_control()->set_stream_analog_level(0);
294    err = ap->ProcessStream(&primary_frame);
295    if (err == ap->kStreamParameterNotSetError) {
296      printf("Expected kStreamParameterNotSetError in ProcessStream(): %d\n",
297          err);
298    } else if (err != ap->kNoError) {
299      printf("Error in ProcessStream(): %d\n", err);
300      thread_data->error = true;
301      return false;
302    }
303    ap->gain_control()->stream_analog_level();
304  }
305
306  EventWrapper* event = EventWrapper::Create();
307  event->Wait(1);
308  delete event;
309  event = NULL;
310
311  return true;
312}
313
314/*TEST_F(ApmTest, Deadlock) {
315  const int num_threads = 16;
316  std::vector<ThreadWrapper*> threads(num_threads);
317  std::vector<ThreadData*> thread_data(num_threads);
318
319  ASSERT_EQ(apm_->kNoError, apm_->set_sample_rate_hz(32000));
320  ASSERT_EQ(apm_->kNoError, apm_->set_num_channels(2, 2));
321  ASSERT_EQ(apm_->kNoError, apm_->set_num_reverse_channels(2));
322
323  for (int i = 0; i < num_threads; i++) {
324    thread_data[i] = new ThreadData(i, apm_);
325    threads[i] = ThreadWrapper::CreateThread(DeadlockProc,
326                                             thread_data[i],
327                                             kNormalPriority,
328                                             0);
329    ASSERT_TRUE(threads[i] != NULL);
330    unsigned int thread_id = 0;
331    threads[i]->Start(thread_id);
332  }
333
334  EventWrapper* event = EventWrapper::Create();
335  ASSERT_EQ(kEventTimeout, event->Wait(5000));
336  delete event;
337  event = NULL;
338
339  for (int i = 0; i < num_threads; i++) {
340    // This will return false if the thread has deadlocked.
341    ASSERT_TRUE(threads[i]->Stop());
342    ASSERT_FALSE(thread_data[i]->error);
343    delete threads[i];
344    threads[i] = NULL;
345    delete thread_data[i];
346    thread_data[i] = NULL;
347  }
348}*/
349
350TEST_F(ApmTest, StreamParameters) {
351  // No errors when the components are disabled.
352  EXPECT_EQ(apm_->kNoError,
353            apm_->ProcessStream(frame_));
354
355  // -- Missing AGC level --
356  EXPECT_EQ(apm_->kNoError, apm_->Initialize());
357  EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
358  EXPECT_EQ(apm_->kStreamParameterNotSetError, apm_->ProcessStream(frame_));
359
360  // Resets after successful ProcessStream().
361  EXPECT_EQ(apm_->kNoError,
362            apm_->gain_control()->set_stream_analog_level(127));
363  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
364  EXPECT_EQ(apm_->kStreamParameterNotSetError, apm_->ProcessStream(frame_));
365
366  // Other stream parameters set correctly.
367  EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
368  EXPECT_EQ(apm_->kNoError,
369            apm_->echo_cancellation()->enable_drift_compensation(true));
370  EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
371  EXPECT_EQ(apm_->kNoError,
372            apm_->echo_cancellation()->set_stream_drift_samples(0));
373  EXPECT_EQ(apm_->kStreamParameterNotSetError,
374            apm_->ProcessStream(frame_));
375  EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(false));
376  EXPECT_EQ(apm_->kNoError,
377            apm_->echo_cancellation()->enable_drift_compensation(false));
378
379  // -- Missing delay --
380  EXPECT_EQ(apm_->kNoError, apm_->Initialize());
381  EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
382  EXPECT_EQ(apm_->kStreamParameterNotSetError, apm_->ProcessStream(frame_));
383
384  // Resets after successful ProcessStream().
385  EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
386  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
387  EXPECT_EQ(apm_->kStreamParameterNotSetError, apm_->ProcessStream(frame_));
388
389  // Other stream parameters set correctly.
390  EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
391  EXPECT_EQ(apm_->kNoError,
392            apm_->echo_cancellation()->enable_drift_compensation(true));
393  EXPECT_EQ(apm_->kNoError,
394            apm_->echo_cancellation()->set_stream_drift_samples(0));
395  EXPECT_EQ(apm_->kNoError,
396            apm_->gain_control()->set_stream_analog_level(127));
397  EXPECT_EQ(apm_->kStreamParameterNotSetError, apm_->ProcessStream(frame_));
398  EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(false));
399
400  // -- Missing drift --
401  EXPECT_EQ(apm_->kNoError, apm_->Initialize());
402  EXPECT_EQ(apm_->kStreamParameterNotSetError, apm_->ProcessStream(frame_));
403
404  // Resets after successful ProcessStream().
405  EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
406  EXPECT_EQ(apm_->kNoError,
407            apm_->echo_cancellation()->set_stream_drift_samples(0));
408  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
409  EXPECT_EQ(apm_->kStreamParameterNotSetError, apm_->ProcessStream(frame_));
410
411  // Other stream parameters set correctly.
412  EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
413  EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
414  EXPECT_EQ(apm_->kNoError,
415            apm_->gain_control()->set_stream_analog_level(127));
416  EXPECT_EQ(apm_->kStreamParameterNotSetError, apm_->ProcessStream(frame_));
417
418  // -- No stream parameters --
419  EXPECT_EQ(apm_->kNoError, apm_->Initialize());
420  EXPECT_EQ(apm_->kNoError,
421            apm_->AnalyzeReverseStream(revframe_));
422  EXPECT_EQ(apm_->kStreamParameterNotSetError,
423            apm_->ProcessStream(frame_));
424
425  // -- All there --
426  EXPECT_EQ(apm_->kNoError, apm_->Initialize());
427  EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(100));
428  EXPECT_EQ(apm_->kNoError,
429            apm_->echo_cancellation()->set_stream_drift_samples(0));
430  EXPECT_EQ(apm_->kNoError,
431            apm_->gain_control()->set_stream_analog_level(127));
432  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
433}
434
435TEST_F(ApmTest, Channels) {
436  // Testing number of invalid channels
437  EXPECT_EQ(apm_->kBadParameterError, apm_->set_num_channels(0, 1));
438  EXPECT_EQ(apm_->kBadParameterError, apm_->set_num_channels(1, 0));
439  EXPECT_EQ(apm_->kBadParameterError, apm_->set_num_channels(3, 1));
440  EXPECT_EQ(apm_->kBadParameterError, apm_->set_num_channels(1, 3));
441  EXPECT_EQ(apm_->kBadParameterError, apm_->set_num_reverse_channels(0));
442  EXPECT_EQ(apm_->kBadParameterError, apm_->set_num_reverse_channels(3));
443  // Testing number of valid channels
444  for (int i = 1; i < 3; i++) {
445    for (int j = 1; j < 3; j++) {
446      if (j > i) {
447        EXPECT_EQ(apm_->kBadParameterError, apm_->set_num_channels(i, j));
448      } else {
449        EXPECT_EQ(apm_->kNoError, apm_->set_num_channels(i, j));
450        EXPECT_EQ(j, apm_->num_output_channels());
451      }
452    }
453    EXPECT_EQ(i, apm_->num_input_channels());
454    EXPECT_EQ(apm_->kNoError, apm_->set_num_reverse_channels(i));
455    EXPECT_EQ(i, apm_->num_reverse_channels());
456  }
457}
458
459TEST_F(ApmTest, SampleRates) {
460  // Testing invalid sample rates
461  EXPECT_EQ(apm_->kBadParameterError, apm_->set_sample_rate_hz(10000));
462  // Testing valid sample rates
463  int fs[] = {8000, 16000, 32000};
464  for (size_t i = 0; i < sizeof(fs) / sizeof(*fs); i++) {
465    EXPECT_EQ(apm_->kNoError, apm_->set_sample_rate_hz(fs[i]));
466    EXPECT_EQ(fs[i], apm_->sample_rate_hz());
467  }
468}
469
470
471TEST_F(ApmTest, EchoCancellation) {
472  EXPECT_EQ(apm_->kNoError,
473            apm_->echo_cancellation()->enable_drift_compensation(true));
474  EXPECT_TRUE(apm_->echo_cancellation()->is_drift_compensation_enabled());
475  EXPECT_EQ(apm_->kNoError,
476            apm_->echo_cancellation()->enable_drift_compensation(false));
477  EXPECT_FALSE(apm_->echo_cancellation()->is_drift_compensation_enabled());
478
479  EXPECT_EQ(apm_->kBadParameterError,
480      apm_->echo_cancellation()->set_device_sample_rate_hz(4000));
481  EXPECT_EQ(apm_->kBadParameterError,
482      apm_->echo_cancellation()->set_device_sample_rate_hz(100000));
483
484  int rate[] = {16000, 44100, 48000};
485  for (size_t i = 0; i < sizeof(rate)/sizeof(*rate); i++) {
486    EXPECT_EQ(apm_->kNoError,
487        apm_->echo_cancellation()->set_device_sample_rate_hz(rate[i]));
488    EXPECT_EQ(rate[i],
489        apm_->echo_cancellation()->device_sample_rate_hz());
490  }
491
492  EXPECT_EQ(apm_->kBadParameterError,
493      apm_->echo_cancellation()->set_suppression_level(
494          static_cast<EchoCancellation::SuppressionLevel>(-1)));
495
496  EXPECT_EQ(apm_->kBadParameterError,
497      apm_->echo_cancellation()->set_suppression_level(
498          static_cast<EchoCancellation::SuppressionLevel>(4)));
499
500  EchoCancellation::SuppressionLevel level[] = {
501    EchoCancellation::kLowSuppression,
502    EchoCancellation::kModerateSuppression,
503    EchoCancellation::kHighSuppression,
504  };
505  for (size_t i = 0; i < sizeof(level)/sizeof(*level); i++) {
506    EXPECT_EQ(apm_->kNoError,
507        apm_->echo_cancellation()->set_suppression_level(level[i]));
508    EXPECT_EQ(level[i],
509        apm_->echo_cancellation()->suppression_level());
510  }
511
512  EchoCancellation::Metrics metrics;
513  EXPECT_EQ(apm_->kNotEnabledError,
514            apm_->echo_cancellation()->GetMetrics(&metrics));
515
516  EXPECT_EQ(apm_->kNoError,
517            apm_->echo_cancellation()->enable_metrics(true));
518  EXPECT_TRUE(apm_->echo_cancellation()->are_metrics_enabled());
519  EXPECT_EQ(apm_->kNoError,
520            apm_->echo_cancellation()->enable_metrics(false));
521  EXPECT_FALSE(apm_->echo_cancellation()->are_metrics_enabled());
522
523  int median = 0;
524  int std = 0;
525  EXPECT_EQ(apm_->kNotEnabledError,
526            apm_->echo_cancellation()->GetDelayMetrics(&median, &std));
527
528  EXPECT_EQ(apm_->kNoError,
529            apm_->echo_cancellation()->enable_delay_logging(true));
530  EXPECT_TRUE(apm_->echo_cancellation()->is_delay_logging_enabled());
531  EXPECT_EQ(apm_->kNoError,
532            apm_->echo_cancellation()->enable_delay_logging(false));
533  EXPECT_FALSE(apm_->echo_cancellation()->is_delay_logging_enabled());
534
535  EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
536  EXPECT_TRUE(apm_->echo_cancellation()->is_enabled());
537  EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(false));
538  EXPECT_FALSE(apm_->echo_cancellation()->is_enabled());
539}
540
541TEST_F(ApmTest, EchoControlMobile) {
542  // AECM won't use super-wideband.
543  EXPECT_EQ(apm_->kNoError, apm_->set_sample_rate_hz(32000));
544  EXPECT_EQ(apm_->kBadSampleRateError, apm_->echo_control_mobile()->Enable(true));
545  EXPECT_EQ(apm_->kNoError, apm_->set_sample_rate_hz(16000));
546  // Turn AECM on (and AEC off)
547  EXPECT_EQ(apm_->kNoError, apm_->echo_control_mobile()->Enable(true));
548  EXPECT_TRUE(apm_->echo_control_mobile()->is_enabled());
549
550  EXPECT_EQ(apm_->kBadParameterError,
551      apm_->echo_control_mobile()->set_routing_mode(
552      static_cast<EchoControlMobile::RoutingMode>(-1)));
553  EXPECT_EQ(apm_->kBadParameterError,
554      apm_->echo_control_mobile()->set_routing_mode(
555      static_cast<EchoControlMobile::RoutingMode>(5)));
556
557  // Toggle routing modes
558  EchoControlMobile::RoutingMode mode[] = {
559      EchoControlMobile::kQuietEarpieceOrHeadset,
560      EchoControlMobile::kEarpiece,
561      EchoControlMobile::kLoudEarpiece,
562      EchoControlMobile::kSpeakerphone,
563      EchoControlMobile::kLoudSpeakerphone,
564  };
565  for (size_t i = 0; i < sizeof(mode)/sizeof(*mode); i++) {
566    EXPECT_EQ(apm_->kNoError,
567        apm_->echo_control_mobile()->set_routing_mode(mode[i]));
568    EXPECT_EQ(mode[i],
569        apm_->echo_control_mobile()->routing_mode());
570  }
571  // Turn comfort noise off/on
572  EXPECT_EQ(apm_->kNoError,
573      apm_->echo_control_mobile()->enable_comfort_noise(false));
574  EXPECT_FALSE(apm_->echo_control_mobile()->is_comfort_noise_enabled());
575  EXPECT_EQ(apm_->kNoError,
576      apm_->echo_control_mobile()->enable_comfort_noise(true));
577  EXPECT_TRUE(apm_->echo_control_mobile()->is_comfort_noise_enabled());
578  // Set and get echo path
579  const size_t echo_path_size =
580      apm_->echo_control_mobile()->echo_path_size_bytes();
581  scoped_array<char> echo_path_in(new char[echo_path_size]);
582  scoped_array<char> echo_path_out(new char[echo_path_size]);
583  EXPECT_EQ(apm_->kNullPointerError,
584            apm_->echo_control_mobile()->SetEchoPath(NULL, echo_path_size));
585  EXPECT_EQ(apm_->kNullPointerError,
586            apm_->echo_control_mobile()->GetEchoPath(NULL, echo_path_size));
587  EXPECT_EQ(apm_->kBadParameterError,
588            apm_->echo_control_mobile()->GetEchoPath(echo_path_out.get(), 1));
589  EXPECT_EQ(apm_->kNoError,
590            apm_->echo_control_mobile()->GetEchoPath(echo_path_out.get(),
591                                                     echo_path_size));
592  for (size_t i = 0; i < echo_path_size; i++) {
593    echo_path_in[i] = echo_path_out[i] + 1;
594  }
595  EXPECT_EQ(apm_->kBadParameterError,
596            apm_->echo_control_mobile()->SetEchoPath(echo_path_in.get(), 1));
597  EXPECT_EQ(apm_->kNoError,
598            apm_->echo_control_mobile()->SetEchoPath(echo_path_in.get(),
599                                                     echo_path_size));
600  EXPECT_EQ(apm_->kNoError,
601            apm_->echo_control_mobile()->GetEchoPath(echo_path_out.get(),
602                                                     echo_path_size));
603  for (size_t i = 0; i < echo_path_size; i++) {
604    EXPECT_EQ(echo_path_in[i], echo_path_out[i]);
605  }
606  // Turn AECM off
607  EXPECT_EQ(apm_->kNoError, apm_->echo_control_mobile()->Enable(false));
608  EXPECT_FALSE(apm_->echo_control_mobile()->is_enabled());
609}
610
611TEST_F(ApmTest, GainControl) {
612  // Testing gain modes
613  EXPECT_EQ(apm_->kBadParameterError,
614      apm_->gain_control()->set_mode(static_cast<GainControl::Mode>(-1)));
615
616  EXPECT_EQ(apm_->kBadParameterError,
617      apm_->gain_control()->set_mode(static_cast<GainControl::Mode>(3)));
618
619  EXPECT_EQ(apm_->kNoError,
620      apm_->gain_control()->set_mode(
621      apm_->gain_control()->mode()));
622
623  GainControl::Mode mode[] = {
624    GainControl::kAdaptiveAnalog,
625    GainControl::kAdaptiveDigital,
626    GainControl::kFixedDigital
627  };
628  for (size_t i = 0; i < sizeof(mode)/sizeof(*mode); i++) {
629    EXPECT_EQ(apm_->kNoError,
630        apm_->gain_control()->set_mode(mode[i]));
631    EXPECT_EQ(mode[i], apm_->gain_control()->mode());
632  }
633  // Testing invalid target levels
634  EXPECT_EQ(apm_->kBadParameterError,
635      apm_->gain_control()->set_target_level_dbfs(-3));
636  EXPECT_EQ(apm_->kBadParameterError,
637      apm_->gain_control()->set_target_level_dbfs(-40));
638  // Testing valid target levels
639  EXPECT_EQ(apm_->kNoError,
640      apm_->gain_control()->set_target_level_dbfs(
641      apm_->gain_control()->target_level_dbfs()));
642
643  int level_dbfs[] = {0, 6, 31};
644  for (size_t i = 0; i < sizeof(level_dbfs)/sizeof(*level_dbfs); i++) {
645    EXPECT_EQ(apm_->kNoError,
646        apm_->gain_control()->set_target_level_dbfs(level_dbfs[i]));
647    EXPECT_EQ(level_dbfs[i], apm_->gain_control()->target_level_dbfs());
648  }
649
650  // Testing invalid compression gains
651  EXPECT_EQ(apm_->kBadParameterError,
652      apm_->gain_control()->set_compression_gain_db(-1));
653  EXPECT_EQ(apm_->kBadParameterError,
654      apm_->gain_control()->set_compression_gain_db(100));
655
656  // Testing valid compression gains
657  EXPECT_EQ(apm_->kNoError,
658      apm_->gain_control()->set_compression_gain_db(
659      apm_->gain_control()->compression_gain_db()));
660
661  int gain_db[] = {0, 10, 90};
662  for (size_t i = 0; i < sizeof(gain_db)/sizeof(*gain_db); i++) {
663    EXPECT_EQ(apm_->kNoError,
664        apm_->gain_control()->set_compression_gain_db(gain_db[i]));
665    EXPECT_EQ(gain_db[i], apm_->gain_control()->compression_gain_db());
666  }
667
668  // Testing limiter off/on
669  EXPECT_EQ(apm_->kNoError, apm_->gain_control()->enable_limiter(false));
670  EXPECT_FALSE(apm_->gain_control()->is_limiter_enabled());
671  EXPECT_EQ(apm_->kNoError, apm_->gain_control()->enable_limiter(true));
672  EXPECT_TRUE(apm_->gain_control()->is_limiter_enabled());
673
674  // Testing invalid level limits
675  EXPECT_EQ(apm_->kBadParameterError,
676      apm_->gain_control()->set_analog_level_limits(-1, 512));
677  EXPECT_EQ(apm_->kBadParameterError,
678      apm_->gain_control()->set_analog_level_limits(100000, 512));
679  EXPECT_EQ(apm_->kBadParameterError,
680      apm_->gain_control()->set_analog_level_limits(512, -1));
681  EXPECT_EQ(apm_->kBadParameterError,
682      apm_->gain_control()->set_analog_level_limits(512, 100000));
683  EXPECT_EQ(apm_->kBadParameterError,
684      apm_->gain_control()->set_analog_level_limits(512, 255));
685
686  // Testing valid level limits
687  EXPECT_EQ(apm_->kNoError,
688      apm_->gain_control()->set_analog_level_limits(
689      apm_->gain_control()->analog_level_minimum(),
690      apm_->gain_control()->analog_level_maximum()));
691
692  int min_level[] = {0, 255, 1024};
693  for (size_t i = 0; i < sizeof(min_level)/sizeof(*min_level); i++) {
694    EXPECT_EQ(apm_->kNoError,
695        apm_->gain_control()->set_analog_level_limits(min_level[i], 1024));
696    EXPECT_EQ(min_level[i], apm_->gain_control()->analog_level_minimum());
697  }
698
699  int max_level[] = {0, 1024, 65535};
700  for (size_t i = 0; i < sizeof(min_level)/sizeof(*min_level); i++) {
701    EXPECT_EQ(apm_->kNoError,
702        apm_->gain_control()->set_analog_level_limits(0, max_level[i]));
703    EXPECT_EQ(max_level[i], apm_->gain_control()->analog_level_maximum());
704  }
705
706  // TODO(ajm): stream_is_saturated() and stream_analog_level()
707
708  // Turn AGC off
709  EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(false));
710  EXPECT_FALSE(apm_->gain_control()->is_enabled());
711}
712
713TEST_F(ApmTest, NoiseSuppression) {
714  // Tesing invalid suppression levels
715  EXPECT_EQ(apm_->kBadParameterError,
716      apm_->noise_suppression()->set_level(
717          static_cast<NoiseSuppression::Level>(-1)));
718
719  EXPECT_EQ(apm_->kBadParameterError,
720      apm_->noise_suppression()->set_level(
721          static_cast<NoiseSuppression::Level>(5)));
722
723  // Tesing valid suppression levels
724  NoiseSuppression::Level level[] = {
725    NoiseSuppression::kLow,
726    NoiseSuppression::kModerate,
727    NoiseSuppression::kHigh,
728    NoiseSuppression::kVeryHigh
729  };
730  for (size_t i = 0; i < sizeof(level)/sizeof(*level); i++) {
731    EXPECT_EQ(apm_->kNoError,
732        apm_->noise_suppression()->set_level(level[i]));
733    EXPECT_EQ(level[i], apm_->noise_suppression()->level());
734  }
735
736  // Turing NS on/off
737  EXPECT_EQ(apm_->kNoError, apm_->noise_suppression()->Enable(true));
738  EXPECT_TRUE(apm_->noise_suppression()->is_enabled());
739  EXPECT_EQ(apm_->kNoError, apm_->noise_suppression()->Enable(false));
740  EXPECT_FALSE(apm_->noise_suppression()->is_enabled());
741}
742
743TEST_F(ApmTest, HighPassFilter) {
744  // Turing HP filter on/off
745  EXPECT_EQ(apm_->kNoError, apm_->high_pass_filter()->Enable(true));
746  EXPECT_TRUE(apm_->high_pass_filter()->is_enabled());
747  EXPECT_EQ(apm_->kNoError, apm_->high_pass_filter()->Enable(false));
748  EXPECT_FALSE(apm_->high_pass_filter()->is_enabled());
749}
750
751TEST_F(ApmTest, LevelEstimator) {
752  // Turning level estimator on/off
753  EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(false));
754  EXPECT_FALSE(apm_->level_estimator()->is_enabled());
755
756  EXPECT_EQ(apm_->kNotEnabledError, apm_->level_estimator()->RMS());
757
758  EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(true));
759  EXPECT_TRUE(apm_->level_estimator()->is_enabled());
760
761  // Run this test in wideband; in super-wb, the splitting filter distorts the
762  // audio enough to cause deviation from the expectation for small values.
763  EXPECT_EQ(apm_->kNoError, apm_->set_sample_rate_hz(16000));
764  frame_->_payloadDataLengthInSamples = 160;
765  frame_->_audioChannel = 2;
766  frame_->_frequencyInHz = 16000;
767
768  // Min value if no frames have been processed.
769  EXPECT_EQ(127, apm_->level_estimator()->RMS());
770
771  // Min value on zero frames.
772  SetFrameTo(frame_, 0);
773  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
774  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
775  EXPECT_EQ(127, apm_->level_estimator()->RMS());
776
777  // Try a few RMS values.
778  // (These also test that the value resets after retrieving it.)
779  SetFrameTo(frame_, 32767);
780  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
781  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
782  EXPECT_EQ(0, apm_->level_estimator()->RMS());
783
784  SetFrameTo(frame_, 30000);
785  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
786  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
787  EXPECT_EQ(1, apm_->level_estimator()->RMS());
788
789  SetFrameTo(frame_, 10000);
790  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
791  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
792  EXPECT_EQ(10, apm_->level_estimator()->RMS());
793
794  SetFrameTo(frame_, 10);
795  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
796  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
797  EXPECT_EQ(70, apm_->level_estimator()->RMS());
798
799  // Min value if _energy == 0.
800  SetFrameTo(frame_, 10000);
801  uint32_t energy = frame_->_energy; // Save default to restore below.
802  frame_->_energy = 0;
803  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
804  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
805  EXPECT_EQ(127, apm_->level_estimator()->RMS());
806  frame_->_energy = energy;
807
808  // Verify reset after enable/disable.
809  SetFrameTo(frame_, 32767);
810  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
811  EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(false));
812  EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(true));
813  SetFrameTo(frame_, 1);
814  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
815  EXPECT_EQ(90, apm_->level_estimator()->RMS());
816
817  // Verify reset after initialize.
818  SetFrameTo(frame_, 32767);
819  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
820  EXPECT_EQ(apm_->kNoError, apm_->Initialize());
821  SetFrameTo(frame_, 1);
822  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
823  EXPECT_EQ(90, apm_->level_estimator()->RMS());
824}
825
826TEST_F(ApmTest, VoiceDetection) {
827  // Test external VAD
828  EXPECT_EQ(apm_->kNoError,
829            apm_->voice_detection()->set_stream_has_voice(true));
830  EXPECT_TRUE(apm_->voice_detection()->stream_has_voice());
831  EXPECT_EQ(apm_->kNoError,
832            apm_->voice_detection()->set_stream_has_voice(false));
833  EXPECT_FALSE(apm_->voice_detection()->stream_has_voice());
834
835  // Tesing invalid likelihoods
836  EXPECT_EQ(apm_->kBadParameterError,
837      apm_->voice_detection()->set_likelihood(
838          static_cast<VoiceDetection::Likelihood>(-1)));
839
840  EXPECT_EQ(apm_->kBadParameterError,
841      apm_->voice_detection()->set_likelihood(
842          static_cast<VoiceDetection::Likelihood>(5)));
843
844  // Tesing valid likelihoods
845  VoiceDetection::Likelihood likelihood[] = {
846      VoiceDetection::kVeryLowLikelihood,
847      VoiceDetection::kLowLikelihood,
848      VoiceDetection::kModerateLikelihood,
849      VoiceDetection::kHighLikelihood
850  };
851  for (size_t i = 0; i < sizeof(likelihood)/sizeof(*likelihood); i++) {
852    EXPECT_EQ(apm_->kNoError,
853              apm_->voice_detection()->set_likelihood(likelihood[i]));
854    EXPECT_EQ(likelihood[i], apm_->voice_detection()->likelihood());
855  }
856
857  /* TODO(bjornv): Enable once VAD supports other frame lengths than 10 ms
858  // Tesing invalid frame sizes
859  EXPECT_EQ(apm_->kBadParameterError,
860      apm_->voice_detection()->set_frame_size_ms(12));
861
862  // Tesing valid frame sizes
863  for (int i = 10; i <= 30; i += 10) {
864    EXPECT_EQ(apm_->kNoError,
865        apm_->voice_detection()->set_frame_size_ms(i));
866    EXPECT_EQ(i, apm_->voice_detection()->frame_size_ms());
867  }
868  */
869
870  // Turing VAD on/off
871  EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(true));
872  EXPECT_TRUE(apm_->voice_detection()->is_enabled());
873  EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(false));
874  EXPECT_FALSE(apm_->voice_detection()->is_enabled());
875
876  // Test that AudioFrame activity is maintained when VAD is disabled.
877  EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(false));
878  AudioFrame::VADActivity activity[] = {
879      AudioFrame::kVadActive,
880      AudioFrame::kVadPassive,
881      AudioFrame::kVadUnknown
882  };
883  for (size_t i = 0; i < sizeof(activity)/sizeof(*activity); i++) {
884    frame_->_vadActivity = activity[i];
885    EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
886    EXPECT_EQ(activity[i], frame_->_vadActivity);
887  }
888
889  // Test that AudioFrame activity is set when VAD is enabled.
890  EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(true));
891  frame_->_vadActivity = AudioFrame::kVadUnknown;
892  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
893  EXPECT_NE(AudioFrame::kVadUnknown, frame_->_vadActivity);
894
895  // TODO(bjornv): Add tests for streamed voice; stream_has_voice()
896}
897
898TEST_F(ApmTest, SplittingFilter) {
899  // Verify the filter is not active through undistorted audio when:
900  // 1. No components are enabled...
901  SetFrameTo(frame_, 1000);
902  AudioFrame frame_copy = *frame_;
903  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
904  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
905  EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy));
906
907  // 2. Only the level estimator is enabled...
908  SetFrameTo(frame_, 1000);
909  frame_copy = *frame_;
910  EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(true));
911  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
912  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
913  EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy));
914  EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(false));
915
916  // 3. Only VAD is enabled...
917  SetFrameTo(frame_, 1000);
918  frame_copy = *frame_;
919  EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(true));
920  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
921  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
922  EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy));
923  EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(false));
924
925  // 4. Both VAD and the level estimator are enabled...
926  SetFrameTo(frame_, 1000);
927  frame_copy = *frame_;
928  EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(true));
929  EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(true));
930  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
931  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
932  EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy));
933  EXPECT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(false));
934  EXPECT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(false));
935
936  // 5. Not using super-wb.
937  EXPECT_EQ(apm_->kNoError, apm_->set_sample_rate_hz(16000));
938  frame_->_payloadDataLengthInSamples = 160;
939  frame_->_audioChannel = 2;
940  frame_->_frequencyInHz = 16000;
941  // Enable AEC, which would require the filter in super-wb. We rely on the
942  // first few frames of data being unaffected by the AEC.
943  // TODO(andrew): This test, and the one below, rely rather tenuously on the
944  // behavior of the AEC. Think of something more robust.
945  EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
946  SetFrameTo(frame_, 1000);
947  frame_copy = *frame_;
948  EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
949  EXPECT_EQ(apm_->kNoError,
950            apm_->echo_cancellation()->set_stream_drift_samples(0));
951  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
952  EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
953  EXPECT_EQ(apm_->kNoError,
954            apm_->echo_cancellation()->set_stream_drift_samples(0));
955  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
956  EXPECT_TRUE(FrameDataAreEqual(*frame_, frame_copy));
957
958  // Check the test is valid. We should have distortion from the filter
959  // when AEC is enabled (which won't affect the audio).
960  EXPECT_EQ(apm_->kNoError, apm_->set_sample_rate_hz(32000));
961  frame_->_payloadDataLengthInSamples = 320;
962  frame_->_audioChannel = 2;
963  frame_->_frequencyInHz = 32000;
964  SetFrameTo(frame_, 1000);
965  frame_copy = *frame_;
966  EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
967  EXPECT_EQ(apm_->kNoError,
968            apm_->echo_cancellation()->set_stream_drift_samples(0));
969  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
970  EXPECT_FALSE(FrameDataAreEqual(*frame_, frame_copy));
971}
972
973// TODO(andrew): expand test to verify output.
974TEST_F(ApmTest, DebugDump) {
975  const std::string filename = webrtc::test::OutputPath() + "debug.aec";
976  EXPECT_EQ(apm_->kNullPointerError, apm_->StartDebugRecording(NULL));
977
978#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
979  // Stopping without having started should be OK.
980  EXPECT_EQ(apm_->kNoError, apm_->StopDebugRecording());
981
982  EXPECT_EQ(apm_->kNoError, apm_->StartDebugRecording(filename.c_str()));
983  EXPECT_EQ(apm_->kNoError, apm_->AnalyzeReverseStream(revframe_));
984  EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
985  EXPECT_EQ(apm_->kNoError, apm_->StopDebugRecording());
986
987  // Verify the file has been written.
988  ASSERT_TRUE(fopen(filename.c_str(), "r") != NULL);
989  // Clean it up.
990  ASSERT_EQ(0, remove(filename.c_str()));
991#else
992  EXPECT_EQ(apm_->kUnsupportedFunctionError,
993            apm_->StartDebugRecording(filename.c_str()));
994  EXPECT_EQ(apm_->kUnsupportedFunctionError, apm_->StopDebugRecording());
995
996  // Verify the file has NOT been written.
997  ASSERT_TRUE(fopen(filename.c_str(), "r") == NULL);
998#endif  // WEBRTC_AUDIOPROC_DEBUG_DUMP
999}
1000
1001TEST_F(ApmTest, Process) {
1002  GOOGLE_PROTOBUF_VERIFY_VERSION;
1003  webrtc::audioproc::OutputData output_data;
1004
1005  if (!write_output_data) {
1006    ReadMessageLiteFromFile(output_filename, &output_data);
1007  } else {
1008    // We don't have a file; add the required tests to the protobuf.
1009    // TODO(ajm): vary the output channels as well?
1010    const int channels[] = {1, 2};
1011    const size_t channels_size = sizeof(channels) / sizeof(*channels);
1012#if defined(WEBRTC_APM_UNIT_TEST_FIXED_PROFILE)
1013    // AECM doesn't support super-wb.
1014    const int sample_rates[] = {8000, 16000};
1015#elif defined(WEBRTC_APM_UNIT_TEST_FLOAT_PROFILE)
1016    const int sample_rates[] = {8000, 16000, 32000};
1017#endif
1018    const size_t sample_rates_size = sizeof(sample_rates) / sizeof(*sample_rates);
1019    for (size_t i = 0; i < channels_size; i++) {
1020      for (size_t j = 0; j < channels_size; j++) {
1021        for (size_t k = 0; k < sample_rates_size; k++) {
1022          webrtc::audioproc::Test* test = output_data.add_test();
1023          test->set_num_reverse_channels(channels[i]);
1024          test->set_num_input_channels(channels[j]);
1025          test->set_num_output_channels(channels[j]);
1026          test->set_sample_rate(sample_rates[k]);
1027        }
1028      }
1029    }
1030  }
1031
1032#if defined(WEBRTC_APM_UNIT_TEST_FIXED_PROFILE)
1033  EXPECT_EQ(apm_->kNoError, apm_->set_sample_rate_hz(16000));
1034  EXPECT_EQ(apm_->kNoError, apm_->echo_control_mobile()->Enable(true));
1035
1036  EXPECT_EQ(apm_->kNoError,
1037            apm_->gain_control()->set_mode(GainControl::kAdaptiveDigital));
1038  EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
1039#elif defined(WEBRTC_APM_UNIT_TEST_FLOAT_PROFILE)
1040  EXPECT_EQ(apm_->kNoError,
1041            apm_->echo_cancellation()->enable_drift_compensation(true));
1042  EXPECT_EQ(apm_->kNoError,
1043            apm_->echo_cancellation()->enable_metrics(true));
1044  EXPECT_EQ(apm_->kNoError,
1045            apm_->echo_cancellation()->enable_delay_logging(true));
1046  EXPECT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
1047
1048  EXPECT_EQ(apm_->kNoError,
1049            apm_->gain_control()->set_mode(GainControl::kAdaptiveAnalog));
1050  EXPECT_EQ(apm_->kNoError,
1051            apm_->gain_control()->set_analog_level_limits(0, 255));
1052  EXPECT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));
1053#endif
1054
1055  EXPECT_EQ(apm_->kNoError,
1056            apm_->high_pass_filter()->Enable(true));
1057
1058  EXPECT_EQ(apm_->kNoError,
1059            apm_->level_estimator()->Enable(true));
1060
1061  EXPECT_EQ(apm_->kNoError,
1062            apm_->noise_suppression()->Enable(true));
1063
1064  EXPECT_EQ(apm_->kNoError,
1065            apm_->voice_detection()->Enable(true));
1066
1067  for (int i = 0; i < output_data.test_size(); i++) {
1068    printf("Running test %d of %d...\n", i + 1, output_data.test_size());
1069
1070    webrtc::audioproc::Test* test = output_data.mutable_test(i);
1071    const int samples_per_channel = test->sample_rate() / 100;
1072    revframe_->_payloadDataLengthInSamples = samples_per_channel;
1073    revframe_->_audioChannel = test->num_reverse_channels();
1074    revframe_->_frequencyInHz = test->sample_rate();
1075    frame_->_payloadDataLengthInSamples = samples_per_channel;
1076    frame_->_audioChannel = test->num_input_channels();
1077    frame_->_frequencyInHz = test->sample_rate();
1078
1079    EXPECT_EQ(apm_->kNoError, apm_->Initialize());
1080    ASSERT_EQ(apm_->kNoError, apm_->set_sample_rate_hz(test->sample_rate()));
1081    ASSERT_EQ(apm_->kNoError, apm_->set_num_channels(frame_->_audioChannel,
1082                                                     frame_->_audioChannel));
1083    ASSERT_EQ(apm_->kNoError,
1084        apm_->set_num_reverse_channels(revframe_->_audioChannel));
1085
1086    int frame_count = 0;
1087    int has_echo_count = 0;
1088    int has_voice_count = 0;
1089    int is_saturated_count = 0;
1090    int analog_level = 127;
1091    int analog_level_average = 0;
1092    int max_output_average = 0;
1093
1094    while (1) {
1095      // Read far-end frame
1096      const size_t frame_size = samples_per_channel * 2;
1097      size_t read_count = fread(revframe_->_payloadData,
1098                                sizeof(int16_t),
1099                                frame_size,
1100                                far_file_);
1101      if (read_count != frame_size) {
1102        // Check that the file really ended.
1103        ASSERT_NE(0, feof(far_file_));
1104        break; // This is expected.
1105      }
1106
1107      if (revframe_->_audioChannel == 1) {
1108        MixStereoToMono(revframe_->_payloadData, revframe_->_payloadData,
1109                        samples_per_channel);
1110      }
1111
1112      EXPECT_EQ(apm_->kNoError, apm_->AnalyzeReverseStream(revframe_));
1113
1114      EXPECT_EQ(apm_->kNoError, apm_->set_stream_delay_ms(0));
1115      EXPECT_EQ(apm_->kNoError,
1116          apm_->echo_cancellation()->set_stream_drift_samples(0));
1117      EXPECT_EQ(apm_->kNoError,
1118          apm_->gain_control()->set_stream_analog_level(analog_level));
1119
1120      // Read near-end frame
1121      read_count = fread(frame_->_payloadData,
1122                         sizeof(int16_t),
1123                         frame_size,
1124                         near_file_);
1125      if (read_count != frame_size) {
1126        // Check that the file really ended.
1127        ASSERT_NE(0, feof(near_file_));
1128        break; // This is expected.
1129      }
1130
1131      if (frame_->_audioChannel == 1) {
1132        MixStereoToMono(frame_->_payloadData, frame_->_payloadData,
1133                        samples_per_channel);
1134      }
1135      frame_->_vadActivity = AudioFrame::kVadUnknown;
1136
1137      EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_));
1138
1139      max_output_average += MaxAudioFrame(*frame_);
1140
1141      if (apm_->echo_cancellation()->stream_has_echo()) {
1142        has_echo_count++;
1143      }
1144
1145      analog_level = apm_->gain_control()->stream_analog_level();
1146      analog_level_average += analog_level;
1147      if (apm_->gain_control()->stream_is_saturated()) {
1148        is_saturated_count++;
1149      }
1150      if (apm_->voice_detection()->stream_has_voice()) {
1151        has_voice_count++;
1152        EXPECT_EQ(AudioFrame::kVadActive, frame_->_vadActivity);
1153      } else {
1154        EXPECT_EQ(AudioFrame::kVadPassive, frame_->_vadActivity);
1155      }
1156
1157      frame_count++;
1158    }
1159    max_output_average /= frame_count;
1160    analog_level_average /= frame_count;
1161
1162#if defined(WEBRTC_APM_UNIT_TEST_FLOAT_PROFILE)
1163    EchoCancellation::Metrics echo_metrics;
1164    EXPECT_EQ(apm_->kNoError,
1165              apm_->echo_cancellation()->GetMetrics(&echo_metrics));
1166    int median = 0;
1167    int std = 0;
1168    EXPECT_EQ(apm_->kNoError,
1169              apm_->echo_cancellation()->GetDelayMetrics(&median, &std));
1170
1171    int rms_level = apm_->level_estimator()->RMS();
1172    EXPECT_LE(0, rms_level);
1173    EXPECT_GE(127, rms_level);
1174#endif
1175
1176    if (!write_output_data) {
1177      EXPECT_EQ(test->has_echo_count(), has_echo_count);
1178      EXPECT_EQ(test->has_voice_count(), has_voice_count);
1179      EXPECT_EQ(test->is_saturated_count(), is_saturated_count);
1180
1181      EXPECT_EQ(test->analog_level_average(), analog_level_average);
1182      EXPECT_EQ(test->max_output_average(), max_output_average);
1183
1184#if defined(WEBRTC_APM_UNIT_TEST_FLOAT_PROFILE)
1185      webrtc::audioproc::Test::EchoMetrics reference =
1186          test->echo_metrics();
1187      TestStats(echo_metrics.residual_echo_return_loss,
1188                reference.residual_echo_return_loss());
1189      TestStats(echo_metrics.echo_return_loss,
1190                reference.echo_return_loss());
1191      TestStats(echo_metrics.echo_return_loss_enhancement,
1192                reference.echo_return_loss_enhancement());
1193      TestStats(echo_metrics.a_nlp,
1194                reference.a_nlp());
1195
1196      webrtc::audioproc::Test::DelayMetrics reference_delay =
1197          test->delay_metrics();
1198      EXPECT_EQ(reference_delay.median(), median);
1199      EXPECT_EQ(reference_delay.std(), std);
1200
1201      EXPECT_EQ(test->rms_level(), rms_level);
1202#endif
1203    } else {
1204      test->set_has_echo_count(has_echo_count);
1205      test->set_has_voice_count(has_voice_count);
1206      test->set_is_saturated_count(is_saturated_count);
1207
1208      test->set_analog_level_average(analog_level_average);
1209      test->set_max_output_average(max_output_average);
1210
1211#if defined(WEBRTC_APM_UNIT_TEST_FLOAT_PROFILE)
1212      webrtc::audioproc::Test::EchoMetrics* message =
1213          test->mutable_echo_metrics();
1214      WriteStatsMessage(echo_metrics.residual_echo_return_loss,
1215                        message->mutable_residual_echo_return_loss());
1216      WriteStatsMessage(echo_metrics.echo_return_loss,
1217                        message->mutable_echo_return_loss());
1218      WriteStatsMessage(echo_metrics.echo_return_loss_enhancement,
1219                        message->mutable_echo_return_loss_enhancement());
1220      WriteStatsMessage(echo_metrics.a_nlp,
1221                        message->mutable_a_nlp());
1222
1223      webrtc::audioproc::Test::DelayMetrics* message_delay =
1224          test->mutable_delay_metrics();
1225      message_delay->set_median(median);
1226      message_delay->set_std(std);
1227
1228      test->set_rms_level(rms_level);
1229#endif
1230    }
1231
1232    rewind(far_file_);
1233    rewind(near_file_);
1234  }
1235
1236  if (write_output_data) {
1237    WriteMessageLiteToFile(output_filename, output_data);
1238  }
1239}
1240}  // namespace
1241
1242int main(int argc, char** argv) {
1243  ::testing::InitGoogleTest(&argc, argv);
1244
1245  for (int i = 1; i < argc; i++) {
1246    if (strcmp(argv[i], "--write_output_data") == 0) {
1247      write_output_data = true;
1248    }
1249  }
1250
1251  int err = RUN_ALL_TESTS();
1252
1253  // Optional, but removes memory leak noise from Valgrind.
1254  google::protobuf::ShutdownProtobufLibrary();
1255  return err;
1256}
1257