1 /* 2 * Copyright (c) 2015 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 <algorithm> 12 #include <limits> 13 #include <list> 14 #include <numeric> 15 #include <string> 16 #include <vector> 17 18 #include "testing/gmock/include/gmock/gmock.h" 19 #include "testing/gtest/include/gtest/gtest.h" 20 #include "webrtc/base/arraysize.h" 21 #include "webrtc/base/criticalsection.h" 22 #include "webrtc/base/format_macros.h" 23 #include "webrtc/base/scoped_ptr.h" 24 #include "webrtc/base/scoped_ref_ptr.h" 25 #include "webrtc/modules/audio_device/android/audio_common.h" 26 #include "webrtc/modules/audio_device/android/audio_manager.h" 27 #include "webrtc/modules/audio_device/android/build_info.h" 28 #include "webrtc/modules/audio_device/android/ensure_initialized.h" 29 #include "webrtc/modules/audio_device/audio_device_impl.h" 30 #include "webrtc/modules/audio_device/include/audio_device.h" 31 #include "webrtc/system_wrappers/include/clock.h" 32 #include "webrtc/system_wrappers/include/event_wrapper.h" 33 #include "webrtc/system_wrappers/include/sleep.h" 34 #include "webrtc/test/testsupport/fileutils.h" 35 36 using std::cout; 37 using std::endl; 38 using ::testing::_; 39 using ::testing::AtLeast; 40 using ::testing::Gt; 41 using ::testing::Invoke; 42 using ::testing::NiceMock; 43 using ::testing::NotNull; 44 using ::testing::Return; 45 using ::testing::TestWithParam; 46 47 // #define ENABLE_DEBUG_PRINTF 48 #ifdef ENABLE_DEBUG_PRINTF 49 #define PRINTD(...) fprintf(stderr, __VA_ARGS__); 50 #else 51 #define PRINTD(...) ((void)0) 52 #endif 53 #define PRINT(...) fprintf(stderr, __VA_ARGS__); 54 55 namespace webrtc { 56 57 // Number of callbacks (input or output) the tests waits for before we set 58 // an event indicating that the test was OK. 59 static const size_t kNumCallbacks = 10; 60 // Max amount of time we wait for an event to be set while counting callbacks. 61 static const int kTestTimeOutInMilliseconds = 10 * 1000; 62 // Average number of audio callbacks per second assuming 10ms packet size. 63 static const size_t kNumCallbacksPerSecond = 100; 64 // Play out a test file during this time (unit is in seconds). 65 static const int kFilePlayTimeInSec = 5; 66 static const size_t kBitsPerSample = 16; 67 static const size_t kBytesPerSample = kBitsPerSample / 8; 68 // Run the full-duplex test during this time (unit is in seconds). 69 // Note that first |kNumIgnoreFirstCallbacks| are ignored. 70 static const int kFullDuplexTimeInSec = 5; 71 // Wait for the callback sequence to stabilize by ignoring this amount of the 72 // initial callbacks (avoids initial FIFO access). 73 // Only used in the RunPlayoutAndRecordingInFullDuplex test. 74 static const size_t kNumIgnoreFirstCallbacks = 50; 75 // Sets the number of impulses per second in the latency test. 76 static const int kImpulseFrequencyInHz = 1; 77 // Length of round-trip latency measurements. Number of transmitted impulses 78 // is kImpulseFrequencyInHz * kMeasureLatencyTimeInSec - 1. 79 static const int kMeasureLatencyTimeInSec = 11; 80 // Utilized in round-trip latency measurements to avoid capturing noise samples. 81 static const int kImpulseThreshold = 1000; 82 static const char kTag[] = "[..........] "; 83 84 enum TransportType { 85 kPlayout = 0x1, 86 kRecording = 0x2, 87 }; 88 89 // Interface for processing the audio stream. Real implementations can e.g. 90 // run audio in loopback, read audio from a file or perform latency 91 // measurements. 92 class AudioStreamInterface { 93 public: 94 virtual void Write(const void* source, size_t num_frames) = 0; 95 virtual void Read(void* destination, size_t num_frames) = 0; 96 protected: 97 virtual ~AudioStreamInterface() {} 98 }; 99 100 // Reads audio samples from a PCM file where the file is stored in memory at 101 // construction. 102 class FileAudioStream : public AudioStreamInterface { 103 public: 104 FileAudioStream( 105 size_t num_callbacks, const std::string& file_name, int sample_rate) 106 : file_size_in_bytes_(0), 107 sample_rate_(sample_rate), 108 file_pos_(0) { 109 file_size_in_bytes_ = test::GetFileSize(file_name); 110 sample_rate_ = sample_rate; 111 EXPECT_GE(file_size_in_callbacks(), num_callbacks) 112 << "Size of test file is not large enough to last during the test."; 113 const size_t num_16bit_samples = 114 test::GetFileSize(file_name) / kBytesPerSample; 115 file_.reset(new int16_t[num_16bit_samples]); 116 FILE* audio_file = fopen(file_name.c_str(), "rb"); 117 EXPECT_NE(audio_file, nullptr); 118 size_t num_samples_read = fread( 119 file_.get(), sizeof(int16_t), num_16bit_samples, audio_file); 120 EXPECT_EQ(num_samples_read, num_16bit_samples); 121 fclose(audio_file); 122 } 123 124 // AudioStreamInterface::Write() is not implemented. 125 void Write(const void* source, size_t num_frames) override {} 126 127 // Read samples from file stored in memory (at construction) and copy 128 // |num_frames| (<=> 10ms) to the |destination| byte buffer. 129 void Read(void* destination, size_t num_frames) override { 130 memcpy(destination, 131 static_cast<int16_t*> (&file_[file_pos_]), 132 num_frames * sizeof(int16_t)); 133 file_pos_ += num_frames; 134 } 135 136 int file_size_in_seconds() const { 137 return static_cast<int>( 138 file_size_in_bytes_ / (kBytesPerSample * sample_rate_)); 139 } 140 size_t file_size_in_callbacks() const { 141 return file_size_in_seconds() * kNumCallbacksPerSecond; 142 } 143 144 private: 145 size_t file_size_in_bytes_; 146 int sample_rate_; 147 rtc::scoped_ptr<int16_t[]> file_; 148 size_t file_pos_; 149 }; 150 151 // Simple first in first out (FIFO) class that wraps a list of 16-bit audio 152 // buffers of fixed size and allows Write and Read operations. The idea is to 153 // store recorded audio buffers (using Write) and then read (using Read) these 154 // stored buffers with as short delay as possible when the audio layer needs 155 // data to play out. The number of buffers in the FIFO will stabilize under 156 // normal conditions since there will be a balance between Write and Read calls. 157 // The container is a std::list container and access is protected with a lock 158 // since both sides (playout and recording) are driven by its own thread. 159 class FifoAudioStream : public AudioStreamInterface { 160 public: 161 explicit FifoAudioStream(size_t frames_per_buffer) 162 : frames_per_buffer_(frames_per_buffer), 163 bytes_per_buffer_(frames_per_buffer_ * sizeof(int16_t)), 164 fifo_(new AudioBufferList), 165 largest_size_(0), 166 total_written_elements_(0), 167 write_count_(0) { 168 EXPECT_NE(fifo_.get(), nullptr); 169 } 170 171 ~FifoAudioStream() { 172 Flush(); 173 } 174 175 // Allocate new memory, copy |num_frames| samples from |source| into memory 176 // and add pointer to the memory location to end of the list. 177 // Increases the size of the FIFO by one element. 178 void Write(const void* source, size_t num_frames) override { 179 ASSERT_EQ(num_frames, frames_per_buffer_); 180 PRINTD("+"); 181 if (write_count_++ < kNumIgnoreFirstCallbacks) { 182 return; 183 } 184 int16_t* memory = new int16_t[frames_per_buffer_]; 185 memcpy(static_cast<int16_t*> (&memory[0]), 186 source, 187 bytes_per_buffer_); 188 rtc::CritScope lock(&lock_); 189 fifo_->push_back(memory); 190 const size_t size = fifo_->size(); 191 if (size > largest_size_) { 192 largest_size_ = size; 193 PRINTD("(%" PRIuS ")", largest_size_); 194 } 195 total_written_elements_ += size; 196 } 197 198 // Read pointer to data buffer from front of list, copy |num_frames| of stored 199 // data into |destination| and delete the utilized memory allocation. 200 // Decreases the size of the FIFO by one element. 201 void Read(void* destination, size_t num_frames) override { 202 ASSERT_EQ(num_frames, frames_per_buffer_); 203 PRINTD("-"); 204 rtc::CritScope lock(&lock_); 205 if (fifo_->empty()) { 206 memset(destination, 0, bytes_per_buffer_); 207 } else { 208 int16_t* memory = fifo_->front(); 209 fifo_->pop_front(); 210 memcpy(destination, 211 static_cast<int16_t*> (&memory[0]), 212 bytes_per_buffer_); 213 delete memory; 214 } 215 } 216 217 size_t size() const { 218 return fifo_->size(); 219 } 220 221 size_t largest_size() const { 222 return largest_size_; 223 } 224 225 size_t average_size() const { 226 return (total_written_elements_ == 0) ? 0.0 : 0.5 + static_cast<float> ( 227 total_written_elements_) / (write_count_ - kNumIgnoreFirstCallbacks); 228 } 229 230 private: 231 void Flush() { 232 for (auto it = fifo_->begin(); it != fifo_->end(); ++it) { 233 delete *it; 234 } 235 fifo_->clear(); 236 } 237 238 using AudioBufferList = std::list<int16_t*>; 239 rtc::CriticalSection lock_; 240 const size_t frames_per_buffer_; 241 const size_t bytes_per_buffer_; 242 rtc::scoped_ptr<AudioBufferList> fifo_; 243 size_t largest_size_; 244 size_t total_written_elements_; 245 size_t write_count_; 246 }; 247 248 // Inserts periodic impulses and measures the latency between the time of 249 // transmission and time of receiving the same impulse. 250 // Usage requires a special hardware called Audio Loopback Dongle. 251 // See http://source.android.com/devices/audio/loopback.html for details. 252 class LatencyMeasuringAudioStream : public AudioStreamInterface { 253 public: 254 explicit LatencyMeasuringAudioStream(size_t frames_per_buffer) 255 : clock_(Clock::GetRealTimeClock()), 256 frames_per_buffer_(frames_per_buffer), 257 bytes_per_buffer_(frames_per_buffer_ * sizeof(int16_t)), 258 play_count_(0), 259 rec_count_(0), 260 pulse_time_(0) { 261 } 262 263 // Insert periodic impulses in first two samples of |destination|. 264 void Read(void* destination, size_t num_frames) override { 265 ASSERT_EQ(num_frames, frames_per_buffer_); 266 if (play_count_ == 0) { 267 PRINT("["); 268 } 269 play_count_++; 270 memset(destination, 0, bytes_per_buffer_); 271 if (play_count_ % (kNumCallbacksPerSecond / kImpulseFrequencyInHz) == 0) { 272 if (pulse_time_ == 0) { 273 pulse_time_ = clock_->TimeInMilliseconds(); 274 } 275 PRINT("."); 276 const int16_t impulse = std::numeric_limits<int16_t>::max(); 277 int16_t* ptr16 = static_cast<int16_t*> (destination); 278 for (size_t i = 0; i < 2; ++i) { 279 ptr16[i] = impulse; 280 } 281 } 282 } 283 284 // Detect received impulses in |source|, derive time between transmission and 285 // detection and add the calculated delay to list of latencies. 286 void Write(const void* source, size_t num_frames) override { 287 ASSERT_EQ(num_frames, frames_per_buffer_); 288 rec_count_++; 289 if (pulse_time_ == 0) { 290 // Avoid detection of new impulse response until a new impulse has 291 // been transmitted (sets |pulse_time_| to value larger than zero). 292 return; 293 } 294 const int16_t* ptr16 = static_cast<const int16_t*> (source); 295 std::vector<int16_t> vec(ptr16, ptr16 + num_frames); 296 // Find max value in the audio buffer. 297 int max = *std::max_element(vec.begin(), vec.end()); 298 // Find index (element position in vector) of the max element. 299 int index_of_max = std::distance(vec.begin(), 300 std::find(vec.begin(), vec.end(), 301 max)); 302 if (max > kImpulseThreshold) { 303 PRINTD("(%d,%d)", max, index_of_max); 304 int64_t now_time = clock_->TimeInMilliseconds(); 305 int extra_delay = IndexToMilliseconds(static_cast<double> (index_of_max)); 306 PRINTD("[%d]", static_cast<int> (now_time - pulse_time_)); 307 PRINTD("[%d]", extra_delay); 308 // Total latency is the difference between transmit time and detection 309 // tome plus the extra delay within the buffer in which we detected the 310 // received impulse. It is transmitted at sample 0 but can be received 311 // at sample N where N > 0. The term |extra_delay| accounts for N and it 312 // is a value between 0 and 10ms. 313 latencies_.push_back(now_time - pulse_time_ + extra_delay); 314 pulse_time_ = 0; 315 } else { 316 PRINTD("-"); 317 } 318 } 319 320 size_t num_latency_values() const { 321 return latencies_.size(); 322 } 323 324 int min_latency() const { 325 if (latencies_.empty()) 326 return 0; 327 return *std::min_element(latencies_.begin(), latencies_.end()); 328 } 329 330 int max_latency() const { 331 if (latencies_.empty()) 332 return 0; 333 return *std::max_element(latencies_.begin(), latencies_.end()); 334 } 335 336 int average_latency() const { 337 if (latencies_.empty()) 338 return 0; 339 return 0.5 + static_cast<double> ( 340 std::accumulate(latencies_.begin(), latencies_.end(), 0)) / 341 latencies_.size(); 342 } 343 344 void PrintResults() const { 345 PRINT("] "); 346 for (auto it = latencies_.begin(); it != latencies_.end(); ++it) { 347 PRINT("%d ", *it); 348 } 349 PRINT("\n"); 350 PRINT("%s[min, max, avg]=[%d, %d, %d] ms\n", kTag, 351 min_latency(), max_latency(), average_latency()); 352 } 353 354 int IndexToMilliseconds(double index) const { 355 return static_cast<int>(10.0 * (index / frames_per_buffer_) + 0.5); 356 } 357 358 private: 359 Clock* clock_; 360 const size_t frames_per_buffer_; 361 const size_t bytes_per_buffer_; 362 size_t play_count_; 363 size_t rec_count_; 364 int64_t pulse_time_; 365 std::vector<int> latencies_; 366 }; 367 368 // Mocks the AudioTransport object and proxies actions for the two callbacks 369 // (RecordedDataIsAvailable and NeedMorePlayData) to different implementations 370 // of AudioStreamInterface. 371 class MockAudioTransport : public AudioTransport { 372 public: 373 explicit MockAudioTransport(int type) 374 : num_callbacks_(0), 375 type_(type), 376 play_count_(0), 377 rec_count_(0), 378 audio_stream_(nullptr) {} 379 380 virtual ~MockAudioTransport() {} 381 382 MOCK_METHOD10(RecordedDataIsAvailable, 383 int32_t(const void* audioSamples, 384 const size_t nSamples, 385 const size_t nBytesPerSample, 386 const size_t nChannels, 387 const uint32_t samplesPerSec, 388 const uint32_t totalDelayMS, 389 const int32_t clockDrift, 390 const uint32_t currentMicLevel, 391 const bool keyPressed, 392 uint32_t& newMicLevel)); 393 MOCK_METHOD8(NeedMorePlayData, 394 int32_t(const size_t nSamples, 395 const size_t nBytesPerSample, 396 const size_t nChannels, 397 const uint32_t samplesPerSec, 398 void* audioSamples, 399 size_t& nSamplesOut, 400 int64_t* elapsed_time_ms, 401 int64_t* ntp_time_ms)); 402 403 // Set default actions of the mock object. We are delegating to fake 404 // implementations (of AudioStreamInterface) here. 405 void HandleCallbacks(EventWrapper* test_is_done, 406 AudioStreamInterface* audio_stream, 407 int num_callbacks) { 408 test_is_done_ = test_is_done; 409 audio_stream_ = audio_stream; 410 num_callbacks_ = num_callbacks; 411 if (play_mode()) { 412 ON_CALL(*this, NeedMorePlayData(_, _, _, _, _, _, _, _)) 413 .WillByDefault( 414 Invoke(this, &MockAudioTransport::RealNeedMorePlayData)); 415 } 416 if (rec_mode()) { 417 ON_CALL(*this, RecordedDataIsAvailable(_, _, _, _, _, _, _, _, _, _)) 418 .WillByDefault( 419 Invoke(this, &MockAudioTransport::RealRecordedDataIsAvailable)); 420 } 421 } 422 423 int32_t RealRecordedDataIsAvailable(const void* audioSamples, 424 const size_t nSamples, 425 const size_t nBytesPerSample, 426 const size_t nChannels, 427 const uint32_t samplesPerSec, 428 const uint32_t totalDelayMS, 429 const int32_t clockDrift, 430 const uint32_t currentMicLevel, 431 const bool keyPressed, 432 uint32_t& newMicLevel) { 433 EXPECT_TRUE(rec_mode()) << "No test is expecting these callbacks."; 434 rec_count_++; 435 // Process the recorded audio stream if an AudioStreamInterface 436 // implementation exists. 437 if (audio_stream_) { 438 audio_stream_->Write(audioSamples, nSamples); 439 } 440 if (ReceivedEnoughCallbacks()) { 441 test_is_done_->Set(); 442 } 443 return 0; 444 } 445 446 int32_t RealNeedMorePlayData(const size_t nSamples, 447 const size_t nBytesPerSample, 448 const size_t nChannels, 449 const uint32_t samplesPerSec, 450 void* audioSamples, 451 size_t& nSamplesOut, 452 int64_t* elapsed_time_ms, 453 int64_t* ntp_time_ms) { 454 EXPECT_TRUE(play_mode()) << "No test is expecting these callbacks."; 455 play_count_++; 456 nSamplesOut = nSamples; 457 // Read (possibly processed) audio stream samples to be played out if an 458 // AudioStreamInterface implementation exists. 459 if (audio_stream_) { 460 audio_stream_->Read(audioSamples, nSamples); 461 } 462 if (ReceivedEnoughCallbacks()) { 463 test_is_done_->Set(); 464 } 465 return 0; 466 } 467 468 bool ReceivedEnoughCallbacks() { 469 bool recording_done = false; 470 if (rec_mode()) 471 recording_done = rec_count_ >= num_callbacks_; 472 else 473 recording_done = true; 474 475 bool playout_done = false; 476 if (play_mode()) 477 playout_done = play_count_ >= num_callbacks_; 478 else 479 playout_done = true; 480 481 return recording_done && playout_done; 482 } 483 484 bool play_mode() const { return type_ & kPlayout; } 485 bool rec_mode() const { return type_ & kRecording; } 486 487 private: 488 EventWrapper* test_is_done_; 489 size_t num_callbacks_; 490 int type_; 491 size_t play_count_; 492 size_t rec_count_; 493 AudioStreamInterface* audio_stream_; 494 rtc::scoped_ptr<LatencyMeasuringAudioStream> latency_audio_stream_; 495 }; 496 497 // AudioDeviceTest test fixture. 498 class AudioDeviceTest : public ::testing::Test { 499 protected: 500 AudioDeviceTest() 501 : test_is_done_(EventWrapper::Create()) { 502 // One-time initialization of JVM and application context. Ensures that we 503 // can do calls between C++ and Java. Initializes both Java and OpenSL ES 504 // implementations. 505 webrtc::audiodevicemodule::EnsureInitialized(); 506 // Creates an audio device using a default audio layer. 507 audio_device_ = CreateAudioDevice(AudioDeviceModule::kPlatformDefaultAudio); 508 EXPECT_NE(audio_device_.get(), nullptr); 509 EXPECT_EQ(0, audio_device_->Init()); 510 playout_parameters_ = audio_manager()->GetPlayoutAudioParameters(); 511 record_parameters_ = audio_manager()->GetRecordAudioParameters(); 512 build_info_.reset(new BuildInfo()); 513 } 514 virtual ~AudioDeviceTest() { 515 EXPECT_EQ(0, audio_device_->Terminate()); 516 } 517 518 int playout_sample_rate() const { 519 return playout_parameters_.sample_rate(); 520 } 521 int record_sample_rate() const { 522 return record_parameters_.sample_rate(); 523 } 524 size_t playout_channels() const { 525 return playout_parameters_.channels(); 526 } 527 size_t record_channels() const { 528 return record_parameters_.channels(); 529 } 530 size_t playout_frames_per_10ms_buffer() const { 531 return playout_parameters_.frames_per_10ms_buffer(); 532 } 533 size_t record_frames_per_10ms_buffer() const { 534 return record_parameters_.frames_per_10ms_buffer(); 535 } 536 537 int total_delay_ms() const { 538 return audio_manager()->GetDelayEstimateInMilliseconds(); 539 } 540 541 rtc::scoped_refptr<AudioDeviceModule> audio_device() const { 542 return audio_device_; 543 } 544 545 AudioDeviceModuleImpl* audio_device_impl() const { 546 return static_cast<AudioDeviceModuleImpl*>(audio_device_.get()); 547 } 548 549 AudioManager* audio_manager() const { 550 return audio_device_impl()->GetAndroidAudioManagerForTest(); 551 } 552 553 AudioManager* GetAudioManager(AudioDeviceModule* adm) const { 554 return static_cast<AudioDeviceModuleImpl*>(adm)-> 555 GetAndroidAudioManagerForTest(); 556 } 557 558 AudioDeviceBuffer* audio_device_buffer() const { 559 return audio_device_impl()->GetAudioDeviceBuffer(); 560 } 561 562 rtc::scoped_refptr<AudioDeviceModule> CreateAudioDevice( 563 AudioDeviceModule::AudioLayer audio_layer) { 564 rtc::scoped_refptr<AudioDeviceModule> module( 565 AudioDeviceModuleImpl::Create(0, audio_layer)); 566 return module; 567 } 568 569 // Returns file name relative to the resource root given a sample rate. 570 std::string GetFileName(int sample_rate) { 571 EXPECT_TRUE(sample_rate == 48000 || sample_rate == 44100); 572 char fname[64]; 573 snprintf(fname, 574 sizeof(fname), 575 "audio_device/audio_short%d", 576 sample_rate / 1000); 577 std::string file_name(webrtc::test::ResourcePath(fname, "pcm")); 578 EXPECT_TRUE(test::FileExists(file_name)); 579 #ifdef ENABLE_PRINTF 580 PRINT("file name: %s\n", file_name.c_str()); 581 const size_t bytes = test::GetFileSize(file_name); 582 PRINT("file size: %" PRIuS " [bytes]\n", bytes); 583 PRINT("file size: %" PRIuS " [samples]\n", bytes / kBytesPerSample); 584 const int seconds = 585 static_cast<int>(bytes / (sample_rate * kBytesPerSample)); 586 PRINT("file size: %d [secs]\n", seconds); 587 PRINT("file size: %" PRIuS " [callbacks]\n", 588 seconds * kNumCallbacksPerSecond); 589 #endif 590 return file_name; 591 } 592 593 AudioDeviceModule::AudioLayer GetActiveAudioLayer() const { 594 AudioDeviceModule::AudioLayer audio_layer; 595 EXPECT_EQ(0, audio_device()->ActiveAudioLayer(&audio_layer)); 596 return audio_layer; 597 } 598 599 int TestDelayOnAudioLayer( 600 const AudioDeviceModule::AudioLayer& layer_to_test) { 601 rtc::scoped_refptr<AudioDeviceModule> audio_device; 602 audio_device = CreateAudioDevice(layer_to_test); 603 EXPECT_NE(audio_device.get(), nullptr); 604 AudioManager* audio_manager = GetAudioManager(audio_device.get()); 605 EXPECT_NE(audio_manager, nullptr); 606 return audio_manager->GetDelayEstimateInMilliseconds(); 607 } 608 609 AudioDeviceModule::AudioLayer TestActiveAudioLayer( 610 const AudioDeviceModule::AudioLayer& layer_to_test) { 611 rtc::scoped_refptr<AudioDeviceModule> audio_device; 612 audio_device = CreateAudioDevice(layer_to_test); 613 EXPECT_NE(audio_device.get(), nullptr); 614 AudioDeviceModule::AudioLayer active; 615 EXPECT_EQ(0, audio_device->ActiveAudioLayer(&active)); 616 return active; 617 } 618 619 bool DisableTestForThisDevice(const std::string& model) { 620 return (build_info_->GetDeviceModel() == model); 621 } 622 623 // Volume control is currently only supported for the Java output audio layer. 624 // For OpenSL ES, the internal stream volume is always on max level and there 625 // is no need for this test to set it to max. 626 bool AudioLayerSupportsVolumeControl() const { 627 return GetActiveAudioLayer() == AudioDeviceModule::kAndroidJavaAudio; 628 } 629 630 void SetMaxPlayoutVolume() { 631 if (!AudioLayerSupportsVolumeControl()) 632 return; 633 uint32_t max_volume; 634 EXPECT_EQ(0, audio_device()->MaxSpeakerVolume(&max_volume)); 635 EXPECT_EQ(0, audio_device()->SetSpeakerVolume(max_volume)); 636 } 637 638 void DisableBuiltInAECIfAvailable() { 639 if (audio_device()->BuiltInAECIsAvailable()) { 640 EXPECT_EQ(0, audio_device()->EnableBuiltInAEC(false)); 641 } 642 } 643 644 void StartPlayout() { 645 EXPECT_FALSE(audio_device()->PlayoutIsInitialized()); 646 EXPECT_FALSE(audio_device()->Playing()); 647 EXPECT_EQ(0, audio_device()->InitPlayout()); 648 EXPECT_TRUE(audio_device()->PlayoutIsInitialized()); 649 EXPECT_EQ(0, audio_device()->StartPlayout()); 650 EXPECT_TRUE(audio_device()->Playing()); 651 } 652 653 void StopPlayout() { 654 EXPECT_EQ(0, audio_device()->StopPlayout()); 655 EXPECT_FALSE(audio_device()->Playing()); 656 EXPECT_FALSE(audio_device()->PlayoutIsInitialized()); 657 } 658 659 void StartRecording() { 660 EXPECT_FALSE(audio_device()->RecordingIsInitialized()); 661 EXPECT_FALSE(audio_device()->Recording()); 662 EXPECT_EQ(0, audio_device()->InitRecording()); 663 EXPECT_TRUE(audio_device()->RecordingIsInitialized()); 664 EXPECT_EQ(0, audio_device()->StartRecording()); 665 EXPECT_TRUE(audio_device()->Recording()); 666 } 667 668 void StopRecording() { 669 EXPECT_EQ(0, audio_device()->StopRecording()); 670 EXPECT_FALSE(audio_device()->Recording()); 671 } 672 673 int GetMaxSpeakerVolume() const { 674 uint32_t max_volume(0); 675 EXPECT_EQ(0, audio_device()->MaxSpeakerVolume(&max_volume)); 676 return max_volume; 677 } 678 679 int GetMinSpeakerVolume() const { 680 uint32_t min_volume(0); 681 EXPECT_EQ(0, audio_device()->MinSpeakerVolume(&min_volume)); 682 return min_volume; 683 } 684 685 int GetSpeakerVolume() const { 686 uint32_t volume(0); 687 EXPECT_EQ(0, audio_device()->SpeakerVolume(&volume)); 688 return volume; 689 } 690 691 rtc::scoped_ptr<EventWrapper> test_is_done_; 692 rtc::scoped_refptr<AudioDeviceModule> audio_device_; 693 AudioParameters playout_parameters_; 694 AudioParameters record_parameters_; 695 rtc::scoped_ptr<BuildInfo> build_info_; 696 }; 697 698 TEST_F(AudioDeviceTest, ConstructDestruct) { 699 // Using the test fixture to create and destruct the audio device module. 700 } 701 702 // We always ask for a default audio layer when the ADM is constructed. But the 703 // ADM will then internally set the best suitable combination of audio layers, 704 // for input and output based on if low-latency output audio in combination 705 // with OpenSL ES is supported or not. This test ensures that the correct 706 // selection is done. 707 TEST_F(AudioDeviceTest, VerifyDefaultAudioLayer) { 708 const AudioDeviceModule::AudioLayer audio_layer = GetActiveAudioLayer(); 709 bool low_latency_output = audio_manager()->IsLowLatencyPlayoutSupported(); 710 AudioDeviceModule::AudioLayer expected_audio_layer = low_latency_output ? 711 AudioDeviceModule::kAndroidJavaInputAndOpenSLESOutputAudio : 712 AudioDeviceModule::kAndroidJavaAudio; 713 EXPECT_EQ(expected_audio_layer, audio_layer); 714 } 715 716 // Verify that it is possible to explicitly create the two types of supported 717 // ADMs. These two tests overrides the default selection of native audio layer 718 // by ignoring if the device supports low-latency output or not. 719 TEST_F(AudioDeviceTest, CorrectAudioLayerIsUsedForCombinedJavaOpenSLCombo) { 720 AudioDeviceModule::AudioLayer expected_layer = 721 AudioDeviceModule::kAndroidJavaInputAndOpenSLESOutputAudio; 722 AudioDeviceModule::AudioLayer active_layer = TestActiveAudioLayer( 723 expected_layer); 724 EXPECT_EQ(expected_layer, active_layer); 725 } 726 727 TEST_F(AudioDeviceTest, CorrectAudioLayerIsUsedForJavaInBothDirections) { 728 AudioDeviceModule::AudioLayer expected_layer = 729 AudioDeviceModule::kAndroidJavaAudio; 730 AudioDeviceModule::AudioLayer active_layer = TestActiveAudioLayer( 731 expected_layer); 732 EXPECT_EQ(expected_layer, active_layer); 733 } 734 735 // The Android ADM supports two different delay reporting modes. One for the 736 // low-latency output path (in combination with OpenSL ES), and one for the 737 // high-latency output path (Java backends in both directions). These two tests 738 // verifies that the audio manager reports correct delay estimate given the 739 // selected audio layer. Note that, this delay estimate will only be utilized 740 // if the HW AEC is disabled. 741 TEST_F(AudioDeviceTest, UsesCorrectDelayEstimateForHighLatencyOutputPath) { 742 EXPECT_EQ(kHighLatencyModeDelayEstimateInMilliseconds, 743 TestDelayOnAudioLayer(AudioDeviceModule::kAndroidJavaAudio)); 744 } 745 746 TEST_F(AudioDeviceTest, UsesCorrectDelayEstimateForLowLatencyOutputPath) { 747 EXPECT_EQ(kLowLatencyModeDelayEstimateInMilliseconds, 748 TestDelayOnAudioLayer( 749 AudioDeviceModule::kAndroidJavaInputAndOpenSLESOutputAudio)); 750 } 751 752 // Ensure that the ADM internal audio device buffer is configured to use the 753 // correct set of parameters. 754 TEST_F(AudioDeviceTest, VerifyAudioDeviceBufferParameters) { 755 EXPECT_EQ(playout_parameters_.sample_rate(), 756 audio_device_buffer()->PlayoutSampleRate()); 757 EXPECT_EQ(record_parameters_.sample_rate(), 758 audio_device_buffer()->RecordingSampleRate()); 759 EXPECT_EQ(playout_parameters_.channels(), 760 audio_device_buffer()->PlayoutChannels()); 761 EXPECT_EQ(record_parameters_.channels(), 762 audio_device_buffer()->RecordingChannels()); 763 } 764 765 766 TEST_F(AudioDeviceTest, InitTerminate) { 767 // Initialization is part of the test fixture. 768 EXPECT_TRUE(audio_device()->Initialized()); 769 EXPECT_EQ(0, audio_device()->Terminate()); 770 EXPECT_FALSE(audio_device()->Initialized()); 771 } 772 773 TEST_F(AudioDeviceTest, Devices) { 774 // Device enumeration is not supported. Verify fixed values only. 775 EXPECT_EQ(1, audio_device()->PlayoutDevices()); 776 EXPECT_EQ(1, audio_device()->RecordingDevices()); 777 } 778 779 TEST_F(AudioDeviceTest, SpeakerVolumeShouldBeAvailable) { 780 // The OpenSL ES output audio path does not support volume control. 781 if (!AudioLayerSupportsVolumeControl()) 782 return; 783 bool available; 784 EXPECT_EQ(0, audio_device()->SpeakerVolumeIsAvailable(&available)); 785 EXPECT_TRUE(available); 786 } 787 788 TEST_F(AudioDeviceTest, MaxSpeakerVolumeIsPositive) { 789 // The OpenSL ES output audio path does not support volume control. 790 if (!AudioLayerSupportsVolumeControl()) 791 return; 792 StartPlayout(); 793 EXPECT_GT(GetMaxSpeakerVolume(), 0); 794 StopPlayout(); 795 } 796 797 TEST_F(AudioDeviceTest, MinSpeakerVolumeIsZero) { 798 // The OpenSL ES output audio path does not support volume control. 799 if (!AudioLayerSupportsVolumeControl()) 800 return; 801 EXPECT_EQ(GetMinSpeakerVolume(), 0); 802 } 803 804 TEST_F(AudioDeviceTest, DefaultSpeakerVolumeIsWithinMinMax) { 805 // The OpenSL ES output audio path does not support volume control. 806 if (!AudioLayerSupportsVolumeControl()) 807 return; 808 const int default_volume = GetSpeakerVolume(); 809 EXPECT_GE(default_volume, GetMinSpeakerVolume()); 810 EXPECT_LE(default_volume, GetMaxSpeakerVolume()); 811 } 812 813 TEST_F(AudioDeviceTest, SetSpeakerVolumeActuallySetsVolume) { 814 // The OpenSL ES output audio path does not support volume control. 815 if (!AudioLayerSupportsVolumeControl()) 816 return; 817 const int default_volume = GetSpeakerVolume(); 818 const int max_volume = GetMaxSpeakerVolume(); 819 EXPECT_EQ(0, audio_device()->SetSpeakerVolume(max_volume)); 820 int new_volume = GetSpeakerVolume(); 821 EXPECT_EQ(new_volume, max_volume); 822 EXPECT_EQ(0, audio_device()->SetSpeakerVolume(default_volume)); 823 } 824 825 // Tests that playout can be initiated, started and stopped. No audio callback 826 // is registered in this test. 827 // Flaky on our trybots makes this test unusable. 828 // https://code.google.com/p/webrtc/issues/detail?id=5046 829 TEST_F(AudioDeviceTest, DISABLED_StartStopPlayout) { 830 StartPlayout(); 831 StopPlayout(); 832 StartPlayout(); 833 StopPlayout(); 834 } 835 836 // Tests that recording can be initiated, started and stopped. No audio callback 837 // is registered in this test. 838 TEST_F(AudioDeviceTest, StartStopRecording) { 839 StartRecording(); 840 StopRecording(); 841 StartRecording(); 842 StopRecording(); 843 } 844 845 // Verify that calling StopPlayout() will leave us in an uninitialized state 846 // which will require a new call to InitPlayout(). This test does not call 847 // StartPlayout() while being uninitialized since doing so will hit a 848 // RTC_DCHECK. 849 TEST_F(AudioDeviceTest, StopPlayoutRequiresInitToRestart) { 850 EXPECT_EQ(0, audio_device()->InitPlayout()); 851 EXPECT_EQ(0, audio_device()->StartPlayout()); 852 EXPECT_EQ(0, audio_device()->StopPlayout()); 853 EXPECT_FALSE(audio_device()->PlayoutIsInitialized()); 854 } 855 856 // Start playout and verify that the native audio layer starts asking for real 857 // audio samples to play out using the NeedMorePlayData callback. 858 TEST_F(AudioDeviceTest, StartPlayoutVerifyCallbacks) { 859 MockAudioTransport mock(kPlayout); 860 mock.HandleCallbacks(test_is_done_.get(), nullptr, kNumCallbacks); 861 EXPECT_CALL(mock, NeedMorePlayData(playout_frames_per_10ms_buffer(), 862 kBytesPerSample, 863 playout_channels(), 864 playout_sample_rate(), 865 NotNull(), 866 _, _, _)) 867 .Times(AtLeast(kNumCallbacks)); 868 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); 869 StartPlayout(); 870 test_is_done_->Wait(kTestTimeOutInMilliseconds); 871 StopPlayout(); 872 } 873 874 // Start recording and verify that the native audio layer starts feeding real 875 // audio samples via the RecordedDataIsAvailable callback. 876 TEST_F(AudioDeviceTest, StartRecordingVerifyCallbacks) { 877 MockAudioTransport mock(kRecording); 878 mock.HandleCallbacks(test_is_done_.get(), nullptr, kNumCallbacks); 879 EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(), 880 record_frames_per_10ms_buffer(), 881 kBytesPerSample, 882 record_channels(), 883 record_sample_rate(), 884 total_delay_ms(), 885 0, 886 0, 887 false, 888 _)) 889 .Times(AtLeast(kNumCallbacks)); 890 891 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); 892 StartRecording(); 893 test_is_done_->Wait(kTestTimeOutInMilliseconds); 894 StopRecording(); 895 } 896 897 898 // Start playout and recording (full-duplex audio) and verify that audio is 899 // active in both directions. 900 TEST_F(AudioDeviceTest, StartPlayoutAndRecordingVerifyCallbacks) { 901 MockAudioTransport mock(kPlayout | kRecording); 902 mock.HandleCallbacks(test_is_done_.get(), nullptr, kNumCallbacks); 903 EXPECT_CALL(mock, NeedMorePlayData(playout_frames_per_10ms_buffer(), 904 kBytesPerSample, 905 playout_channels(), 906 playout_sample_rate(), 907 NotNull(), 908 _, _, _)) 909 .Times(AtLeast(kNumCallbacks)); 910 EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(), 911 record_frames_per_10ms_buffer(), 912 kBytesPerSample, 913 record_channels(), 914 record_sample_rate(), 915 total_delay_ms(), 916 0, 917 0, 918 false, 919 _)) 920 .Times(AtLeast(kNumCallbacks)); 921 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); 922 StartPlayout(); 923 StartRecording(); 924 test_is_done_->Wait(kTestTimeOutInMilliseconds); 925 StopRecording(); 926 StopPlayout(); 927 } 928 929 // Start playout and read audio from an external PCM file when the audio layer 930 // asks for data to play out. Real audio is played out in this test but it does 931 // not contain any explicit verification that the audio quality is perfect. 932 TEST_F(AudioDeviceTest, RunPlayoutWithFileAsSource) { 933 // TODO(henrika): extend test when mono output is supported. 934 EXPECT_EQ(1u, playout_channels()); 935 NiceMock<MockAudioTransport> mock(kPlayout); 936 const int num_callbacks = kFilePlayTimeInSec * kNumCallbacksPerSecond; 937 std::string file_name = GetFileName(playout_sample_rate()); 938 rtc::scoped_ptr<FileAudioStream> file_audio_stream( 939 new FileAudioStream(num_callbacks, file_name, playout_sample_rate())); 940 mock.HandleCallbacks(test_is_done_.get(), 941 file_audio_stream.get(), 942 num_callbacks); 943 // SetMaxPlayoutVolume(); 944 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); 945 StartPlayout(); 946 test_is_done_->Wait(kTestTimeOutInMilliseconds); 947 StopPlayout(); 948 } 949 950 // Start playout and recording and store recorded data in an intermediate FIFO 951 // buffer from which the playout side then reads its samples in the same order 952 // as they were stored. Under ideal circumstances, a callback sequence would 953 // look like: ...+-+-+-+-+-+-+-..., where '+' means 'packet recorded' and '-' 954 // means 'packet played'. Under such conditions, the FIFO would only contain 955 // one packet on average. However, under more realistic conditions, the size 956 // of the FIFO will vary more due to an unbalance between the two sides. 957 // This test tries to verify that the device maintains a balanced callback- 958 // sequence by running in loopback for ten seconds while measuring the size 959 // (max and average) of the FIFO. The size of the FIFO is increased by the 960 // recording side and decreased by the playout side. 961 // TODO(henrika): tune the final test parameters after running tests on several 962 // different devices. 963 TEST_F(AudioDeviceTest, RunPlayoutAndRecordingInFullDuplex) { 964 EXPECT_EQ(record_channels(), playout_channels()); 965 EXPECT_EQ(record_sample_rate(), playout_sample_rate()); 966 NiceMock<MockAudioTransport> mock(kPlayout | kRecording); 967 rtc::scoped_ptr<FifoAudioStream> fifo_audio_stream( 968 new FifoAudioStream(playout_frames_per_10ms_buffer())); 969 mock.HandleCallbacks(test_is_done_.get(), 970 fifo_audio_stream.get(), 971 kFullDuplexTimeInSec * kNumCallbacksPerSecond); 972 SetMaxPlayoutVolume(); 973 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); 974 StartRecording(); 975 StartPlayout(); 976 test_is_done_->Wait(std::max(kTestTimeOutInMilliseconds, 977 1000 * kFullDuplexTimeInSec)); 978 StopPlayout(); 979 StopRecording(); 980 EXPECT_LE(fifo_audio_stream->average_size(), 10u); 981 EXPECT_LE(fifo_audio_stream->largest_size(), 20u); 982 } 983 984 // Measures loopback latency and reports the min, max and average values for 985 // a full duplex audio session. 986 // The latency is measured like so: 987 // - Insert impulses periodically on the output side. 988 // - Detect the impulses on the input side. 989 // - Measure the time difference between the transmit time and receive time. 990 // - Store time differences in a vector and calculate min, max and average. 991 // This test requires a special hardware called Audio Loopback Dongle. 992 // See http://source.android.com/devices/audio/loopback.html for details. 993 TEST_F(AudioDeviceTest, DISABLED_MeasureLoopbackLatency) { 994 EXPECT_EQ(record_channels(), playout_channels()); 995 EXPECT_EQ(record_sample_rate(), playout_sample_rate()); 996 NiceMock<MockAudioTransport> mock(kPlayout | kRecording); 997 rtc::scoped_ptr<LatencyMeasuringAudioStream> latency_audio_stream( 998 new LatencyMeasuringAudioStream(playout_frames_per_10ms_buffer())); 999 mock.HandleCallbacks(test_is_done_.get(), 1000 latency_audio_stream.get(), 1001 kMeasureLatencyTimeInSec * kNumCallbacksPerSecond); 1002 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); 1003 SetMaxPlayoutVolume(); 1004 DisableBuiltInAECIfAvailable(); 1005 StartRecording(); 1006 StartPlayout(); 1007 test_is_done_->Wait(std::max(kTestTimeOutInMilliseconds, 1008 1000 * kMeasureLatencyTimeInSec)); 1009 StopPlayout(); 1010 StopRecording(); 1011 // Verify that the correct number of transmitted impulses are detected. 1012 EXPECT_EQ(latency_audio_stream->num_latency_values(), 1013 static_cast<size_t>( 1014 kImpulseFrequencyInHz * kMeasureLatencyTimeInSec - 1)); 1015 latency_audio_stream->PrintResults(); 1016 } 1017 1018 } // namespace webrtc 1019