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