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