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