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