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