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