audio_device_unittest.cc (49467B)
1 /* 2 * Copyright (c) 2017 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 "api/audio/audio_device.h" 12 13 #include <algorithm> 14 #include <cstdint> 15 #include <cstdio> 16 #include <cstring> 17 #include <limits> 18 #include <list> 19 #include <numeric> 20 #include <optional> 21 #include <vector> 22 23 #include "api/array_view.h" 24 #include "api/audio/audio_device_defines.h" 25 #include "api/audio/create_audio_device_module.h" 26 #include "api/environment/environment.h" 27 #include "api/environment/environment_factory.h" 28 #include "api/scoped_refptr.h" 29 #include "api/sequence_checker.h" 30 #include "api/units/time_delta.h" 31 #include "modules/audio_device/audio_device_impl.h" 32 #include "modules/audio_device/include/mock_audio_transport.h" 33 #include "rtc_base/buffer.h" 34 #include "rtc_base/checks.h" 35 #include "rtc_base/event.h" 36 #include "rtc_base/logging.h" 37 #include "rtc_base/numerics/safe_conversions.h" 38 #include "rtc_base/race_checker.h" 39 #include "rtc_base/synchronization/mutex.h" 40 #include "rtc_base/thread_annotations.h" 41 #include "rtc_base/time_utils.h" 42 #include "test/gmock.h" 43 #include "test/gtest.h" 44 45 #ifdef WEBRTC_WIN 46 #include "modules/audio_device/include/audio_device_factory.h" 47 #include "modules/audio_device/win/core_audio_utility_win.h" 48 #include "rtc_base/win/scoped_com_initializer.h" 49 #endif // WEBRTC_WIN 50 51 using ::testing::_; 52 using ::testing::AtLeast; 53 using ::testing::Ge; 54 using ::testing::Invoke; 55 using ::testing::Mock; 56 using ::testing::NiceMock; 57 using ::testing::NotNull; 58 59 namespace webrtc { 60 namespace { 61 62 // Using a #define for AUDIO_DEVICE since we will call *different* versions of 63 // the ADM functions, depending on the ID type. 64 #if defined(WEBRTC_WIN) 65 #define AUDIO_DEVICE_ID (AudioDeviceModule::WindowsDeviceType::kDefaultDevice) 66 #else 67 #define AUDIO_DEVICE_ID (0u) 68 #endif // defined(WEBRTC_WIN) 69 70 // #define ENABLE_DEBUG_PRINTF 71 #ifdef ENABLE_DEBUG_PRINTF 72 #define PRINTD(...) fprintf(stderr, __VA_ARGS__); 73 #else 74 #define PRINTD(...) ((void)0) 75 #endif 76 #define PRINT(...) fprintf(stderr, __VA_ARGS__); 77 78 // Don't run these tests if audio-related requirements are not met. 79 #define SKIP_TEST_IF_NOT(requirements_satisfied) \ 80 do { \ 81 if (!requirements_satisfied) { \ 82 GTEST_SKIP() << "Skipped. No audio device found."; \ 83 } \ 84 } while (false) 85 86 // Number of callbacks (input or output) the tests waits for before we set 87 // an event indicating that the test was OK. 88 constexpr size_t kNumCallbacks = 10; 89 // Max amount of time we wait for an event to be set while counting callbacks. 90 constexpr TimeDelta kTestTimeOut = TimeDelta::Seconds(10); 91 // Average number of audio callbacks per second assuming 10ms packet size. 92 constexpr size_t kNumCallbacksPerSecond = 100; 93 // Run the full-duplex test during this time (unit is in seconds). 94 constexpr TimeDelta kFullDuplexTime = TimeDelta::Seconds(5); 95 // Length of round-trip latency measurements. Number of deteced impulses 96 // shall be kImpulseFrequencyInHz * kMeasureLatencyTime - 1 since the 97 // last transmitted pulse is not used. 98 constexpr TimeDelta kMeasureLatencyTime = TimeDelta::Seconds(10); 99 // Sets the number of impulses per second in the latency test. 100 constexpr size_t kImpulseFrequencyInHz = 1; 101 // Utilized in round-trip latency measurements to avoid capturing noise samples. 102 constexpr int kImpulseThreshold = 1000; 103 104 enum class TransportType { 105 kInvalid, 106 kPlay, 107 kRecord, 108 kPlayAndRecord, 109 }; 110 111 // Interface for processing the audio stream. Real implementations can e.g. 112 // run audio in loopback, read audio from a file or perform latency 113 // measurements. 114 class AudioStream { 115 public: 116 virtual void Write(ArrayView<const int16_t> source) = 0; 117 virtual void Read(ArrayView<int16_t> destination) = 0; 118 119 virtual ~AudioStream() = default; 120 }; 121 122 // Converts index corresponding to position within a 10ms buffer into a 123 // delay value in milliseconds. 124 // Example: index=240, frames_per_10ms_buffer=480 => 5ms as output. 125 int IndexToMilliseconds(size_t index, size_t frames_per_10ms_buffer) { 126 return checked_cast<int>( 127 10.0 * (static_cast<double>(index) / frames_per_10ms_buffer) + 0.5); 128 } 129 130 } // namespace 131 132 // Simple first in first out (FIFO) class that wraps a list of 16-bit audio 133 // buffers of fixed size and allows Write and Read operations. The idea is to 134 // store recorded audio buffers (using Write) and then read (using Read) these 135 // stored buffers with as short delay as possible when the audio layer needs 136 // data to play out. The number of buffers in the FIFO will stabilize under 137 // normal conditions since there will be a balance between Write and Read calls. 138 // The container is a std::list container and access is protected with a lock 139 // since both sides (playout and recording) are driven by its own thread. 140 // Note that, we know by design that the size of the audio buffer will not 141 // change over time and that both sides will in most cases use the same size. 142 class FifoAudioStream : public AudioStream { 143 public: 144 void Write(ArrayView<const int16_t> source) override { 145 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); 146 const size_t size = [&] { 147 MutexLock lock(&lock_); 148 fifo_.push_back(Buffer16(source.data(), source.size())); 149 return fifo_.size(); 150 }(); 151 if (size > max_size_) { 152 max_size_ = size; 153 } 154 // Add marker once per second to signal that audio is active. 155 if (write_count_++ % 100 == 0) { 156 PRINTD("."); 157 } 158 written_elements_ += size; 159 } 160 161 void Read(ArrayView<int16_t> destination) override { 162 MutexLock lock(&lock_); 163 if (fifo_.empty()) { 164 std::fill(destination.begin(), destination.end(), 0); 165 } else { 166 const Buffer16& buffer = fifo_.front(); 167 if (buffer.size() == destination.size()) { 168 // Default case where input and output uses same sample rate and 169 // channel configuration. No conversion is needed. 170 std::copy(buffer.begin(), buffer.end(), destination.begin()); 171 } else if (destination.size() == 2 * buffer.size()) { 172 // Recorded input signal in `buffer` is in mono. Do channel upmix to 173 // match stereo output (1 -> 2). 174 for (size_t i = 0; i < buffer.size(); ++i) { 175 destination[2 * i] = buffer[i]; 176 destination[2 * i + 1] = buffer[i]; 177 } 178 } else if (buffer.size() == 2 * destination.size()) { 179 // Recorded input signal in `buffer` is in stereo. Do channel downmix 180 // to match mono output (2 -> 1). 181 for (size_t i = 0; i < destination.size(); ++i) { 182 destination[i] = 183 (static_cast<int32_t>(buffer[2 * i]) + buffer[2 * i + 1]) / 2; 184 } 185 } else { 186 RTC_DCHECK_NOTREACHED() << "Required conversion is not support"; 187 } 188 fifo_.pop_front(); 189 } 190 } 191 192 size_t size() const { 193 MutexLock lock(&lock_); 194 return fifo_.size(); 195 } 196 197 size_t max_size() const { 198 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); 199 return max_size_; 200 } 201 202 size_t average_size() const { 203 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); 204 return 0.5 + static_cast<float>(written_elements_ / write_count_); 205 } 206 207 using Buffer16 = BufferT<int16_t>; 208 209 mutable Mutex lock_; 210 RaceChecker race_checker_; 211 212 std::list<Buffer16> fifo_ RTC_GUARDED_BY(lock_); 213 size_t write_count_ RTC_GUARDED_BY(race_checker_) = 0; 214 size_t max_size_ RTC_GUARDED_BY(race_checker_) = 0; 215 size_t written_elements_ RTC_GUARDED_BY(race_checker_) = 0; 216 }; 217 218 // Inserts periodic impulses and measures the latency between the time of 219 // transmission and time of receiving the same impulse. 220 class LatencyAudioStream : public AudioStream { 221 public: 222 LatencyAudioStream() { 223 // Delay thread checkers from being initialized until first callback from 224 // respective thread. 225 read_thread_checker_.Detach(); 226 write_thread_checker_.Detach(); 227 } 228 229 // Insert periodic impulses in first two samples of `destination`. 230 void Read(ArrayView<int16_t> destination) override { 231 RTC_DCHECK_RUN_ON(&read_thread_checker_); 232 if (read_count_ == 0) { 233 PRINT("["); 234 } 235 read_count_++; 236 std::fill(destination.begin(), destination.end(), 0); 237 if (read_count_ % (kNumCallbacksPerSecond / kImpulseFrequencyInHz) == 0) { 238 PRINT("."); 239 { 240 MutexLock lock(&lock_); 241 if (!pulse_time_) { 242 pulse_time_ = TimeMillis(); 243 } 244 } 245 constexpr int16_t impulse = std::numeric_limits<int16_t>::max(); 246 std::fill_n(destination.begin(), 2, impulse); 247 } 248 } 249 250 // Detect received impulses in `source`, derive time between transmission and 251 // detection and add the calculated delay to list of latencies. 252 void Write(ArrayView<const int16_t> source) override { 253 RTC_DCHECK_RUN_ON(&write_thread_checker_); 254 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); 255 MutexLock lock(&lock_); 256 write_count_++; 257 if (!pulse_time_) { 258 // Avoid detection of new impulse response until a new impulse has 259 // been transmitted (sets `pulse_time_` to value larger than zero). 260 return; 261 } 262 // Find index (element position in vector) of the max element. 263 const size_t index_of_max = 264 std::max_element(source.begin(), source.end()) - source.begin(); 265 // Derive time between transmitted pulse and received pulse if the level 266 // is high enough (removes noise). 267 const size_t max = source[index_of_max]; 268 if (max > kImpulseThreshold) { 269 PRINTD("(%zu, %zu)", max, index_of_max); 270 int64_t now_time = TimeMillis(); 271 int extra_delay = IndexToMilliseconds(index_of_max, source.size()); 272 PRINTD("[%d]", checked_cast<int>(now_time - pulse_time_)); 273 PRINTD("[%d]", extra_delay); 274 // Total latency is the difference between transmit time and detection 275 // tome plus the extra delay within the buffer in which we detected the 276 // received impulse. It is transmitted at sample 0 but can be received 277 // at sample N where N > 0. The term `extra_delay` accounts for N and it 278 // is a value between 0 and 10ms. 279 latencies_.push_back(now_time - *pulse_time_ + extra_delay); 280 pulse_time_.reset(); 281 } else { 282 PRINTD("-"); 283 } 284 } 285 286 size_t num_latency_values() const { 287 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); 288 return latencies_.size(); 289 } 290 291 int min_latency() const { 292 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); 293 if (latencies_.empty()) 294 return 0; 295 return *std::min_element(latencies_.begin(), latencies_.end()); 296 } 297 298 int max_latency() const { 299 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); 300 if (latencies_.empty()) 301 return 0; 302 return *std::max_element(latencies_.begin(), latencies_.end()); 303 } 304 305 int average_latency() const { 306 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); 307 if (latencies_.empty()) 308 return 0; 309 return 0.5 + static_cast<double>( 310 std::accumulate(latencies_.begin(), latencies_.end(), 0)) / 311 latencies_.size(); 312 } 313 314 void PrintResults() const { 315 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_); 316 PRINT("] "); 317 for (auto it = latencies_.begin(); it != latencies_.end(); ++it) { 318 PRINTD("%d ", *it); 319 } 320 PRINT("\n"); 321 PRINT("[..........] [min, max, avg]=[%d, %d, %d] ms\n", min_latency(), 322 max_latency(), average_latency()); 323 } 324 325 Mutex lock_; 326 RaceChecker race_checker_; 327 SequenceChecker read_thread_checker_; 328 SequenceChecker write_thread_checker_; 329 330 std::optional<int64_t> pulse_time_ RTC_GUARDED_BY(lock_); 331 std::vector<int> latencies_ RTC_GUARDED_BY(race_checker_); 332 size_t read_count_ RTC_GUARDED_BY(read_thread_checker_) = 0; 333 size_t write_count_ RTC_GUARDED_BY(write_thread_checker_) = 0; 334 }; 335 336 // Mocks the AudioTransport object and proxies actions for the two callbacks 337 // (RecordedDataIsAvailable and NeedMorePlayData) to different implementations 338 // of AudioStreamInterface. 339 class MockAudioTransport : public test::MockAudioTransport { 340 public: 341 explicit MockAudioTransport(TransportType type) : type_(type) {} 342 ~MockAudioTransport() override {} 343 344 // Set default actions of the mock object. We are delegating to fake 345 // implementation where the number of callbacks is counted and an event 346 // is set after a certain number of callbacks. Audio parameters are also 347 // checked. 348 void HandleCallbacks(Event* event, 349 AudioStream* audio_stream, 350 int num_callbacks) { 351 event_ = event; 352 audio_stream_ = audio_stream; 353 num_callbacks_ = num_callbacks; 354 if (play_mode()) { 355 ON_CALL(*this, NeedMorePlayData(_, _, _, _, _, _, _, _)) 356 .WillByDefault( 357 Invoke(this, &MockAudioTransport::RealNeedMorePlayData)); 358 } 359 if (rec_mode()) { 360 ON_CALL(*this, RecordedDataIsAvailable(_, _, _, _, _, _, _, _, _, _)) 361 .WillByDefault( 362 Invoke(this, &MockAudioTransport::RealRecordedDataIsAvailable)); 363 } 364 } 365 366 // Special constructor used in manual tests where the user wants to run audio 367 // until e.g. a keyboard key is pressed. The event flag is set to nullptr by 368 // default since it is up to the user to stop the test. See e.g. 369 // DISABLED_RunPlayoutAndRecordingInFullDuplexAndWaitForEnterKey(). 370 void HandleCallbacks(AudioStream* audio_stream) { 371 HandleCallbacks(nullptr, audio_stream, 0); 372 } 373 374 int32_t RealRecordedDataIsAvailable(const void* audio_buffer, 375 const size_t samples_per_channel, 376 const size_t bytes_per_frame, 377 const size_t channels, 378 const uint32_t sample_rate, 379 const uint32_t /* total_delay_ms */, 380 const int32_t /* clock_drift */, 381 const uint32_t /* current_mic_level */, 382 const bool /* typing_status */, 383 uint32_t& /* new_mic_level */) { 384 EXPECT_TRUE(rec_mode()) << "No test is expecting these callbacks."; 385 // Store audio parameters once in the first callback. For all other 386 // callbacks, verify that the provided audio parameters are maintained and 387 // that each callback corresponds to 10ms for any given sample rate. 388 if (!record_parameters_.is_complete()) { 389 record_parameters_.reset(sample_rate, channels, samples_per_channel); 390 } else { 391 EXPECT_EQ(samples_per_channel, record_parameters_.frames_per_buffer()); 392 EXPECT_EQ(bytes_per_frame, record_parameters_.GetBytesPerFrame()); 393 EXPECT_EQ(channels, record_parameters_.channels()); 394 EXPECT_EQ(static_cast<int>(sample_rate), 395 record_parameters_.sample_rate()); 396 EXPECT_EQ(samples_per_channel, 397 record_parameters_.frames_per_10ms_buffer()); 398 } 399 { 400 MutexLock lock(&lock_); 401 rec_count_++; 402 } 403 // Write audio data to audio stream object if one has been injected. 404 if (audio_stream_) { 405 audio_stream_->Write( 406 MakeArrayView(static_cast<const int16_t*>(audio_buffer), 407 samples_per_channel * channels)); 408 } 409 // Signal the event after given amount of callbacks. 410 if (event_ && ReceivedEnoughCallbacks()) { 411 event_->Set(); 412 } 413 return 0; 414 } 415 416 int32_t RealNeedMorePlayData(const size_t samples_per_channel, 417 const size_t bytes_per_frame, 418 const size_t channels, 419 const uint32_t sample_rate, 420 void* audio_buffer, 421 size_t& samples_out, 422 int64_t* /* elapsed_time_ms */, 423 int64_t* /* ntp_time_ms */) { 424 EXPECT_TRUE(play_mode()) << "No test is expecting these callbacks."; 425 // Store audio parameters once in the first callback. For all other 426 // callbacks, verify that the provided audio parameters are maintained and 427 // that each callback corresponds to 10ms for any given sample rate. 428 if (!playout_parameters_.is_complete()) { 429 playout_parameters_.reset(sample_rate, channels, samples_per_channel); 430 } else { 431 EXPECT_EQ(samples_per_channel, playout_parameters_.frames_per_buffer()); 432 EXPECT_EQ(bytes_per_frame, playout_parameters_.GetBytesPerFrame()); 433 EXPECT_EQ(channels, playout_parameters_.channels()); 434 EXPECT_EQ(static_cast<int>(sample_rate), 435 playout_parameters_.sample_rate()); 436 EXPECT_EQ(samples_per_channel, 437 playout_parameters_.frames_per_10ms_buffer()); 438 } 439 { 440 MutexLock lock(&lock_); 441 play_count_++; 442 } 443 samples_out = samples_per_channel * channels; 444 // Read audio data from audio stream object if one has been injected. 445 if (audio_stream_) { 446 audio_stream_->Read(MakeArrayView(static_cast<int16_t*>(audio_buffer), 447 samples_per_channel * channels)); 448 } else { 449 // Fill the audio buffer with zeros to avoid disturbing audio. 450 const size_t num_bytes = samples_per_channel * bytes_per_frame; 451 std::memset(audio_buffer, 0, num_bytes); 452 } 453 // Signal the event after given amount of callbacks. 454 if (event_ && ReceivedEnoughCallbacks()) { 455 event_->Set(); 456 } 457 return 0; 458 } 459 460 bool ReceivedEnoughCallbacks() { 461 bool recording_done = false; 462 if (rec_mode()) { 463 MutexLock lock(&lock_); 464 recording_done = rec_count_ >= num_callbacks_; 465 } else { 466 recording_done = true; 467 } 468 bool playout_done = false; 469 if (play_mode()) { 470 MutexLock lock(&lock_); 471 playout_done = play_count_ >= num_callbacks_; 472 } else { 473 playout_done = true; 474 } 475 return recording_done && playout_done; 476 } 477 478 bool play_mode() const { 479 return type_ == TransportType::kPlay || 480 type_ == TransportType::kPlayAndRecord; 481 } 482 483 bool rec_mode() const { 484 return type_ == TransportType::kRecord || 485 type_ == TransportType::kPlayAndRecord; 486 } 487 488 void ResetCallbackCounters() { 489 MutexLock lock(&lock_); 490 if (play_mode()) { 491 play_count_ = 0; 492 } 493 if (rec_mode()) { 494 rec_count_ = 0; 495 } 496 } 497 498 private: 499 Mutex lock_; 500 TransportType type_ = TransportType::kInvalid; 501 Event* event_ = nullptr; 502 AudioStream* audio_stream_ = nullptr; 503 size_t num_callbacks_ = 0; 504 size_t play_count_ RTC_GUARDED_BY(lock_) = 0; 505 size_t rec_count_ RTC_GUARDED_BY(lock_) = 0; 506 AudioParameters playout_parameters_; 507 AudioParameters record_parameters_; 508 }; 509 510 // AudioDeviceTest test fixture. 511 512 // bugs.webrtc.org/9808 513 // Both the tests and the code under test are very old, unstaffed and not 514 // a part of webRTC stack. 515 // Here sanitizers make the tests hang, without providing usefull report. 516 // So we are just disabling them, without intention to re-enable them. 517 #if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \ 518 defined(THREAD_SANITIZER) || defined(UNDEFINED_SANITIZER) 519 #define MAYBE_AudioDeviceTest DISABLED_AudioDeviceTest 520 #else 521 #define MAYBE_AudioDeviceTest AudioDeviceTest 522 #endif 523 524 class MAYBE_AudioDeviceTest 525 : public ::testing::TestWithParam<AudioDeviceModule::AudioLayer> { 526 protected: 527 MAYBE_AudioDeviceTest() 528 : audio_layer_(GetParam()), env_(CreateEnvironment()) { 529 LogMessage::LogToDebug(LS_INFO); 530 // Add extra logging fields here if needed for debugging. 531 LogMessage::LogTimestamps(); 532 LogMessage::LogThreads(); 533 audio_device_ = CreateAudioDevice(); 534 EXPECT_NE(audio_device_.get(), nullptr); 535 AudioDeviceModule::AudioLayer audio_layer; 536 int got_platform_audio_layer = 537 audio_device_->ActiveAudioLayer(&audio_layer); 538 // First, ensure that a valid audio layer can be activated. 539 if (got_platform_audio_layer != 0) { 540 requirements_satisfied_ = false; 541 } 542 // Next, verify that the ADM can be initialized. 543 if (requirements_satisfied_) { 544 requirements_satisfied_ = (audio_device_->Init() == 0); 545 } 546 // Finally, ensure that at least one valid device exists in each direction. 547 if (requirements_satisfied_) { 548 const int16_t num_playout_devices = audio_device_->PlayoutDevices(); 549 const int16_t num_record_devices = audio_device_->RecordingDevices(); 550 requirements_satisfied_ = 551 num_playout_devices > 0 && num_record_devices > 0; 552 } 553 if (requirements_satisfied_) { 554 EXPECT_EQ(0, audio_device_->SetPlayoutDevice(AUDIO_DEVICE_ID)); 555 EXPECT_EQ(0, audio_device_->InitSpeaker()); 556 EXPECT_EQ(0, audio_device_->StereoPlayoutIsAvailable(&stereo_playout_)); 557 EXPECT_EQ(0, audio_device_->SetStereoPlayout(stereo_playout_)); 558 EXPECT_EQ(0, audio_device_->SetRecordingDevice(AUDIO_DEVICE_ID)); 559 EXPECT_EQ(0, audio_device_->InitMicrophone()); 560 // Avoid asking for input stereo support and always record in mono 561 // since asking can cause issues in combination with remote desktop. 562 // See https://bugs.chromium.org/p/webrtc/issues/detail?id=7397 for 563 // details. 564 EXPECT_EQ(0, audio_device_->SetStereoRecording(false)); 565 } 566 } 567 568 // This is needed by all tests using MockAudioTransport, 569 // since there is no way to unregister it. 570 // Without Terminate(), audio_device would still accesses 571 // the destructed mock via "webrtc_audio_module_rec_thread". 572 // An alternative would be for the mock to outlive audio_device. 573 void PreTearDown() { EXPECT_EQ(0, audio_device_->Terminate()); } 574 575 ~MAYBE_AudioDeviceTest() override { 576 if (audio_device_) { 577 EXPECT_EQ(0, audio_device_->Terminate()); 578 } 579 } 580 581 bool requirements_satisfied() const { return requirements_satisfied_; } 582 Event* event() { return &event_; } 583 AudioDeviceModule::AudioLayer audio_layer() const { return audio_layer_; } 584 585 // AudioDeviceModuleForTest extends the default ADM interface with some extra 586 // test methods. Intended for usage in tests only and requires a unique 587 // factory method. See CreateAudioDevice() for details. 588 const scoped_refptr<AudioDeviceModuleForTest>& audio_device() const { 589 return audio_device_; 590 } 591 592 scoped_refptr<AudioDeviceModuleForTest> CreateAudioDevice() { 593 // Use the default factory for kPlatformDefaultAudio and a special factory 594 // CreateWindowsCoreAudioAudioDeviceModuleForTest() for kWindowsCoreAudio2. 595 // The value of `audio_layer_` is set at construction by GetParam() and two 596 // different layers are tested on Windows only. 597 if (audio_layer_ == AudioDeviceModule::kPlatformDefaultAudio) { 598 return AudioDeviceModuleImpl::Create(env_, audio_layer_); 599 } else if (audio_layer_ == AudioDeviceModule::kWindowsCoreAudio2) { 600 #ifdef WEBRTC_WIN 601 // We must initialize the COM library on a thread before we calling any of 602 // the library functions. All COM functions in the ADM will return 603 // CO_E_NOTINITIALIZED otherwise. 604 com_initializer_ = 605 std::make_unique<ScopedCOMInitializer>(ScopedCOMInitializer::kMTA); 606 EXPECT_TRUE(com_initializer_->Succeeded()); 607 EXPECT_TRUE(webrtc_win::core_audio_utility::IsSupported()); 608 EXPECT_TRUE(webrtc_win::core_audio_utility::IsMMCSSSupported()); 609 return CreateWindowsCoreAudioAudioDeviceModuleForTest(env_, true); 610 #else 611 return nullptr; 612 #endif 613 } else { 614 return nullptr; 615 } 616 } 617 618 void StartPlayout() { 619 EXPECT_FALSE(audio_device()->Playing()); 620 EXPECT_EQ(0, audio_device()->InitPlayout()); 621 EXPECT_TRUE(audio_device()->PlayoutIsInitialized()); 622 EXPECT_EQ(0, audio_device()->StartPlayout()); 623 EXPECT_TRUE(audio_device()->Playing()); 624 } 625 626 void StopPlayout() { 627 EXPECT_EQ(0, audio_device()->StopPlayout()); 628 EXPECT_FALSE(audio_device()->Playing()); 629 EXPECT_FALSE(audio_device()->PlayoutIsInitialized()); 630 } 631 632 void StartRecording() { 633 EXPECT_FALSE(audio_device()->Recording()); 634 EXPECT_EQ(0, audio_device()->InitRecording()); 635 EXPECT_TRUE(audio_device()->RecordingIsInitialized()); 636 EXPECT_EQ(0, audio_device()->StartRecording()); 637 EXPECT_TRUE(audio_device()->Recording()); 638 } 639 640 void StopRecording() { 641 EXPECT_EQ(0, audio_device()->StopRecording()); 642 EXPECT_FALSE(audio_device()->Recording()); 643 EXPECT_FALSE(audio_device()->RecordingIsInitialized()); 644 } 645 646 bool NewWindowsAudioDeviceModuleIsUsed() { 647 #ifdef WEBRTC_WIN 648 AudioDeviceModule::AudioLayer audio_layer; 649 EXPECT_EQ(0, audio_device()->ActiveAudioLayer(&audio_layer)); 650 if (audio_layer == AudioDeviceModule::kWindowsCoreAudio2) { 651 // Default device is always added as first element in the list and the 652 // default communication device as the second element. Hence, the list 653 // contains two extra elements in this case. 654 return true; 655 } 656 #endif 657 return false; 658 } 659 660 private: 661 #ifdef WEBRTC_WIN 662 // Windows Core Audio based ADM needs to run on a COM initialized thread. 663 std::unique_ptr<ScopedCOMInitializer> com_initializer_; 664 #endif 665 AudioDeviceModule::AudioLayer audio_layer_; 666 const Environment env_; 667 bool requirements_satisfied_ = true; 668 Event event_; 669 scoped_refptr<AudioDeviceModuleForTest> audio_device_; 670 bool stereo_playout_ = false; 671 }; 672 673 // Instead of using the test fixture, verify that the different factory methods 674 // work as intended. 675 TEST(MAYBE_AudioDeviceTestWin, ConstructDestructWithFactory) { 676 const Environment env = CreateEnvironment(); 677 scoped_refptr<AudioDeviceModule> audio_device; 678 // The default environment should work for all platforms when a default ADM is 679 // requested. 680 audio_device = 681 CreateAudioDeviceModule(env, AudioDeviceModule::kPlatformDefaultAudio); 682 EXPECT_TRUE(audio_device); 683 audio_device = nullptr; 684 #ifdef WEBRTC_WIN 685 // For Windows, the old factory method creates an ADM where the platform- 686 // specific parts are implemented by an AudioDeviceGeneric object. Verify 687 // that the old factory can't be used in combination with the latest audio 688 // layer AudioDeviceModule::kWindowsCoreAudio2. 689 audio_device = 690 CreateAudioDeviceModule(env, AudioDeviceModule::kWindowsCoreAudio2); 691 EXPECT_FALSE(audio_device); 692 audio_device = nullptr; 693 // Instead, ensure that the new dedicated factory method called 694 // CreateWindowsCoreAudioAudioDeviceModule() can be used on Windows and that 695 // it sets the audio layer to kWindowsCoreAudio2 implicitly. Note that, the 696 // new ADM for Windows must be created on a COM thread. 697 ScopedCOMInitializer com_initializer(ScopedCOMInitializer::kMTA); 698 EXPECT_TRUE(com_initializer.Succeeded()); 699 audio_device = CreateWindowsCoreAudioAudioDeviceModule(env); 700 EXPECT_TRUE(audio_device); 701 AudioDeviceModule::AudioLayer audio_layer; 702 EXPECT_EQ(0, audio_device->ActiveAudioLayer(&audio_layer)); 703 EXPECT_EQ(audio_layer, AudioDeviceModule::kWindowsCoreAudio2); 704 #endif 705 } 706 707 // Uses the test fixture to create, initialize and destruct the ADM. 708 TEST_P(MAYBE_AudioDeviceTest, ConstructDestructDefault) {} 709 710 TEST_P(MAYBE_AudioDeviceTest, InitTerminate) { 711 SKIP_TEST_IF_NOT(requirements_satisfied()); 712 // Initialization is part of the test fixture. 713 EXPECT_TRUE(audio_device()->Initialized()); 714 EXPECT_EQ(0, audio_device()->Terminate()); 715 EXPECT_FALSE(audio_device()->Initialized()); 716 } 717 718 // Enumerate all available and active output devices. 719 TEST_P(MAYBE_AudioDeviceTest, PlayoutDeviceNames) { 720 SKIP_TEST_IF_NOT(requirements_satisfied()); 721 char device_name[kAdmMaxDeviceNameSize]; 722 char unique_id[kAdmMaxGuidSize]; 723 int num_devices = audio_device()->PlayoutDevices(); 724 if (NewWindowsAudioDeviceModuleIsUsed()) { 725 num_devices += 2; 726 } 727 EXPECT_GT(num_devices, 0); 728 for (int i = 0; i < num_devices; ++i) { 729 EXPECT_EQ(0, audio_device()->PlayoutDeviceName(i, device_name, unique_id)); 730 } 731 EXPECT_EQ(-1, audio_device()->PlayoutDeviceName(num_devices, device_name, 732 unique_id)); 733 } 734 735 // Enumerate all available and active input devices. 736 TEST_P(MAYBE_AudioDeviceTest, RecordingDeviceNames) { 737 SKIP_TEST_IF_NOT(requirements_satisfied()); 738 char device_name[kAdmMaxDeviceNameSize]; 739 char unique_id[kAdmMaxGuidSize]; 740 int num_devices = audio_device()->RecordingDevices(); 741 if (NewWindowsAudioDeviceModuleIsUsed()) { 742 num_devices += 2; 743 } 744 EXPECT_GT(num_devices, 0); 745 for (int i = 0; i < num_devices; ++i) { 746 EXPECT_EQ(0, 747 audio_device()->RecordingDeviceName(i, device_name, unique_id)); 748 } 749 EXPECT_EQ(-1, audio_device()->RecordingDeviceName(num_devices, device_name, 750 unique_id)); 751 } 752 753 // Counts number of active output devices and ensure that all can be selected. 754 TEST_P(MAYBE_AudioDeviceTest, SetPlayoutDevice) { 755 SKIP_TEST_IF_NOT(requirements_satisfied()); 756 int num_devices = audio_device()->PlayoutDevices(); 757 if (NewWindowsAudioDeviceModuleIsUsed()) { 758 num_devices += 2; 759 } 760 EXPECT_GT(num_devices, 0); 761 // Verify that all available playout devices can be set (not enabled yet). 762 for (int i = 0; i < num_devices; ++i) { 763 EXPECT_EQ(0, audio_device()->SetPlayoutDevice(i)); 764 } 765 EXPECT_EQ(-1, audio_device()->SetPlayoutDevice(num_devices)); 766 #ifdef WEBRTC_WIN 767 // On Windows, verify the alternative method where the user can select device 768 // by role. 769 EXPECT_EQ( 770 0, audio_device()->SetPlayoutDevice(AudioDeviceModule::kDefaultDevice)); 771 EXPECT_EQ(0, audio_device()->SetPlayoutDevice( 772 AudioDeviceModule::kDefaultCommunicationDevice)); 773 #endif 774 } 775 776 // Counts number of active input devices and ensure that all can be selected. 777 TEST_P(MAYBE_AudioDeviceTest, SetRecordingDevice) { 778 SKIP_TEST_IF_NOT(requirements_satisfied()); 779 int num_devices = audio_device()->RecordingDevices(); 780 if (NewWindowsAudioDeviceModuleIsUsed()) { 781 num_devices += 2; 782 } 783 EXPECT_GT(num_devices, 0); 784 // Verify that all available recording devices can be set (not enabled yet). 785 for (int i = 0; i < num_devices; ++i) { 786 EXPECT_EQ(0, audio_device()->SetRecordingDevice(i)); 787 } 788 EXPECT_EQ(-1, audio_device()->SetRecordingDevice(num_devices)); 789 #ifdef WEBRTC_WIN 790 // On Windows, verify the alternative method where the user can select device 791 // by role. 792 EXPECT_EQ( 793 0, audio_device()->SetRecordingDevice(AudioDeviceModule::kDefaultDevice)); 794 EXPECT_EQ(0, audio_device()->SetRecordingDevice( 795 AudioDeviceModule::kDefaultCommunicationDevice)); 796 #endif 797 } 798 799 // Tests Start/Stop playout without any registered audio callback. 800 TEST_P(MAYBE_AudioDeviceTest, StartStopPlayout) { 801 SKIP_TEST_IF_NOT(requirements_satisfied()); 802 StartPlayout(); 803 StopPlayout(); 804 } 805 806 // Tests Start/Stop recording without any registered audio callback. 807 TEST_P(MAYBE_AudioDeviceTest, StartStopRecording) { 808 SKIP_TEST_IF_NOT(requirements_satisfied()); 809 StartRecording(); 810 StopRecording(); 811 } 812 813 // Tests Start/Stop playout for all available input devices to ensure that 814 // the selected device can be created and used as intended. 815 TEST_P(MAYBE_AudioDeviceTest, StartStopPlayoutWithRealDevice) { 816 SKIP_TEST_IF_NOT(requirements_satisfied()); 817 int num_devices = audio_device()->PlayoutDevices(); 818 if (NewWindowsAudioDeviceModuleIsUsed()) { 819 num_devices += 2; 820 } 821 EXPECT_GT(num_devices, 0); 822 // Verify that all available playout devices can be set and used. 823 for (int i = 0; i < num_devices; ++i) { 824 EXPECT_EQ(0, audio_device()->SetPlayoutDevice(i)); 825 StartPlayout(); 826 StopPlayout(); 827 } 828 #ifdef WEBRTC_WIN 829 AudioDeviceModule::WindowsDeviceType device_role[] = { 830 AudioDeviceModule::kDefaultDevice, 831 AudioDeviceModule::kDefaultCommunicationDevice}; 832 for (AudioDeviceModule::WindowsDeviceType device_type : device_role) { 833 EXPECT_EQ(0, audio_device()->SetPlayoutDevice(device_type)); 834 StartPlayout(); 835 StopPlayout(); 836 } 837 #endif 838 } 839 840 // Tests Start/Stop recording for all available input devices to ensure that 841 // the selected device can be created and used as intended. 842 TEST_P(MAYBE_AudioDeviceTest, StartStopRecordingWithRealDevice) { 843 SKIP_TEST_IF_NOT(requirements_satisfied()); 844 int num_devices = audio_device()->RecordingDevices(); 845 if (NewWindowsAudioDeviceModuleIsUsed()) { 846 num_devices += 2; 847 } 848 EXPECT_GT(num_devices, 0); 849 // Verify that all available recording devices can be set and used. 850 for (int i = 0; i < num_devices; ++i) { 851 EXPECT_EQ(0, audio_device()->SetRecordingDevice(i)); 852 StartRecording(); 853 StopRecording(); 854 } 855 #ifdef WEBRTC_WIN 856 AudioDeviceModule::WindowsDeviceType device_role[] = { 857 AudioDeviceModule::kDefaultDevice, 858 AudioDeviceModule::kDefaultCommunicationDevice}; 859 for (AudioDeviceModule::WindowsDeviceType device_type : device_role) { 860 EXPECT_EQ(0, audio_device()->SetRecordingDevice(device_type)); 861 StartRecording(); 862 StopRecording(); 863 } 864 #endif 865 } 866 867 // Tests Init/Stop/Init recording without any registered audio callback. 868 // See https://bugs.chromium.org/p/webrtc/issues/detail?id=8041 for details 869 // on why this test is useful. 870 TEST_P(MAYBE_AudioDeviceTest, InitStopInitRecording) { 871 SKIP_TEST_IF_NOT(requirements_satisfied()); 872 EXPECT_EQ(0, audio_device()->InitRecording()); 873 EXPECT_TRUE(audio_device()->RecordingIsInitialized()); 874 StopRecording(); 875 EXPECT_EQ(0, audio_device()->InitRecording()); 876 StopRecording(); 877 } 878 879 // Verify that additional attempts to initialize or start recording while 880 // already being active works. Additional calls should just be ignored. 881 TEST_P(MAYBE_AudioDeviceTest, StartInitRecording) { 882 SKIP_TEST_IF_NOT(requirements_satisfied()); 883 StartRecording(); 884 // An additional attempt to initialize at this stage should be ignored. 885 EXPECT_EQ(0, audio_device()->InitRecording()); 886 // Same for additional request to start recording while already active. 887 EXPECT_EQ(0, audio_device()->StartRecording()); 888 StopRecording(); 889 } 890 891 // Verify that additional attempts to initialize or start playou while 892 // already being active works. Additional calls should just be ignored. 893 TEST_P(MAYBE_AudioDeviceTest, StartInitPlayout) { 894 SKIP_TEST_IF_NOT(requirements_satisfied()); 895 StartPlayout(); 896 // An additional attempt to initialize at this stage should be ignored. 897 EXPECT_EQ(0, audio_device()->InitPlayout()); 898 // Same for additional request to start playout while already active. 899 EXPECT_EQ(0, audio_device()->StartPlayout()); 900 StopPlayout(); 901 } 902 903 // Tests Init/Stop/Init recording while playout is active. 904 TEST_P(MAYBE_AudioDeviceTest, InitStopInitRecordingWhilePlaying) { 905 SKIP_TEST_IF_NOT(requirements_satisfied()); 906 StartPlayout(); 907 EXPECT_EQ(0, audio_device()->InitRecording()); 908 EXPECT_TRUE(audio_device()->RecordingIsInitialized()); 909 StopRecording(); 910 EXPECT_EQ(0, audio_device()->InitRecording()); 911 StopRecording(); 912 StopPlayout(); 913 } 914 915 // Tests Init/Stop/Init playout without any registered audio callback. 916 TEST_P(MAYBE_AudioDeviceTest, InitStopInitPlayout) { 917 SKIP_TEST_IF_NOT(requirements_satisfied()); 918 EXPECT_EQ(0, audio_device()->InitPlayout()); 919 EXPECT_TRUE(audio_device()->PlayoutIsInitialized()); 920 StopPlayout(); 921 EXPECT_EQ(0, audio_device()->InitPlayout()); 922 StopPlayout(); 923 } 924 925 // Tests Init/Stop/Init playout while recording is active. 926 TEST_P(MAYBE_AudioDeviceTest, InitStopInitPlayoutWhileRecording) { 927 SKIP_TEST_IF_NOT(requirements_satisfied()); 928 StartRecording(); 929 EXPECT_EQ(0, audio_device()->InitPlayout()); 930 EXPECT_TRUE(audio_device()->PlayoutIsInitialized()); 931 StopPlayout(); 932 EXPECT_EQ(0, audio_device()->InitPlayout()); 933 StopPlayout(); 934 StopRecording(); 935 } 936 937 // TODO(henrika): restart without intermediate destruction is currently only 938 // supported on Windows. 939 #ifdef WEBRTC_WIN 940 // Tests Start/Stop playout followed by a second session (emulates a restart 941 // triggered by a user using public APIs). 942 TEST_P(MAYBE_AudioDeviceTest, StartStopPlayoutWithExternalRestart) { 943 SKIP_TEST_IF_NOT(requirements_satisfied()); 944 StartPlayout(); 945 StopPlayout(); 946 // Restart playout without destroying the ADM in between. Ensures that we 947 // support: Init(), Start(), Stop(), Init(), Start(), Stop(). 948 StartPlayout(); 949 StopPlayout(); 950 } 951 952 // Tests Start/Stop recording followed by a second session (emulates a restart 953 // triggered by a user using public APIs). 954 TEST_P(MAYBE_AudioDeviceTest, StartStopRecordingWithExternalRestart) { 955 SKIP_TEST_IF_NOT(requirements_satisfied()); 956 StartRecording(); 957 StopRecording(); 958 // Restart recording without destroying the ADM in between. Ensures that we 959 // support: Init(), Start(), Stop(), Init(), Start(), Stop(). 960 StartRecording(); 961 StopRecording(); 962 } 963 964 // Tests Start/Stop playout followed by a second session (emulates a restart 965 // triggered by an internal callback e.g. corresponding to a device switch). 966 // Note that, internal restart is only supported in combination with the latest 967 // Windows ADM. 968 TEST_P(MAYBE_AudioDeviceTest, StartStopPlayoutWithInternalRestart) { 969 SKIP_TEST_IF_NOT(requirements_satisfied()); 970 if (audio_layer() != AudioDeviceModule::kWindowsCoreAudio2) { 971 return; 972 } 973 MockAudioTransport mock(TransportType::kPlay); 974 mock.HandleCallbacks(event(), nullptr, kNumCallbacks); 975 EXPECT_CALL(mock, NeedMorePlayData(_, _, _, _, NotNull(), _, _, _)) 976 .Times(AtLeast(kNumCallbacks)); 977 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); 978 StartPlayout(); 979 event()->Wait(kTestTimeOut); 980 EXPECT_TRUE(audio_device()->Playing()); 981 // Restart playout but without stopping the internal audio thread. 982 // This procedure uses a non-public test API and it emulates what happens 983 // inside the ADM when e.g. a device is removed. 984 EXPECT_EQ(0, audio_device()->RestartPlayoutInternally()); 985 986 // Run basic tests of public APIs while a restart attempt is active. 987 // These calls should now be very thin and not trigger any new actions. 988 EXPECT_EQ(-1, audio_device()->StopPlayout()); 989 EXPECT_TRUE(audio_device()->Playing()); 990 EXPECT_TRUE(audio_device()->PlayoutIsInitialized()); 991 EXPECT_EQ(0, audio_device()->InitPlayout()); 992 EXPECT_EQ(0, audio_device()->StartPlayout()); 993 994 // Wait until audio has restarted and a new sequence of audio callbacks 995 // becomes active. 996 // TODO(henrika): is it possible to verify that the internal state transition 997 // is Stop->Init->Start? 998 ASSERT_TRUE(Mock::VerifyAndClearExpectations(&mock)); 999 mock.ResetCallbackCounters(); 1000 EXPECT_CALL(mock, NeedMorePlayData(_, _, _, _, NotNull(), _, _, _)) 1001 .Times(AtLeast(kNumCallbacks)); 1002 event()->Wait(kTestTimeOut); 1003 EXPECT_TRUE(audio_device()->Playing()); 1004 // Stop playout and the audio thread after successful internal restart. 1005 StopPlayout(); 1006 PreTearDown(); 1007 } 1008 1009 // Tests Start/Stop recording followed by a second session (emulates a restart 1010 // triggered by an internal callback e.g. corresponding to a device switch). 1011 // Note that, internal restart is only supported in combination with the latest 1012 // Windows ADM. 1013 TEST_P(MAYBE_AudioDeviceTest, StartStopRecordingWithInternalRestart) { 1014 SKIP_TEST_IF_NOT(requirements_satisfied()); 1015 if (audio_layer() != AudioDeviceModule::kWindowsCoreAudio2) { 1016 return; 1017 } 1018 MockAudioTransport mock(TransportType::kRecord); 1019 mock.HandleCallbacks(event(), nullptr, kNumCallbacks); 1020 EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(), _, _, _, _, Ge(0u), 0, _, 1021 false, _, _)) 1022 .Times(AtLeast(kNumCallbacks)); 1023 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); 1024 StartRecording(); 1025 event()->Wait(kTestTimeOut); 1026 EXPECT_TRUE(audio_device()->Recording()); 1027 // Restart recording but without stopping the internal audio thread. 1028 // This procedure uses a non-public test API and it emulates what happens 1029 // inside the ADM when e.g. a device is removed. 1030 EXPECT_EQ(0, audio_device()->RestartRecordingInternally()); 1031 1032 // Run basic tests of public APIs while a restart attempt is active. 1033 // These calls should now be very thin and not trigger any new actions. 1034 EXPECT_EQ(-1, audio_device()->StopRecording()); 1035 EXPECT_TRUE(audio_device()->Recording()); 1036 EXPECT_TRUE(audio_device()->RecordingIsInitialized()); 1037 EXPECT_EQ(0, audio_device()->InitRecording()); 1038 EXPECT_EQ(0, audio_device()->StartRecording()); 1039 1040 // Wait until audio has restarted and a new sequence of audio callbacks 1041 // becomes active. 1042 // TODO(henrika): is it possible to verify that the internal state transition 1043 // is Stop->Init->Start? 1044 ASSERT_TRUE(Mock::VerifyAndClearExpectations(&mock)); 1045 mock.ResetCallbackCounters(); 1046 EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(), _, _, _, _, Ge(0u), 0, _, 1047 false, _, _)) 1048 .Times(AtLeast(kNumCallbacks)); 1049 event()->Wait(kTestTimeOut); 1050 EXPECT_TRUE(audio_device()->Recording()); 1051 // Stop recording and the audio thread after successful internal restart. 1052 StopRecording(); 1053 PreTearDown(); 1054 } 1055 #endif // #ifdef WEBRTC_WIN 1056 1057 // Start playout and verify that the native audio layer starts asking for real 1058 // audio samples to play out using the NeedMorePlayData() callback. 1059 // Note that we can't add expectations on audio parameters in EXPECT_CALL 1060 // since parameter are not provided in the each callback. We therefore test and 1061 // verify the parameters in the fake audio transport implementation instead. 1062 TEST_P(MAYBE_AudioDeviceTest, StartPlayoutVerifyCallbacks) { 1063 SKIP_TEST_IF_NOT(requirements_satisfied()); 1064 MockAudioTransport mock(TransportType::kPlay); 1065 mock.HandleCallbacks(event(), nullptr, kNumCallbacks); 1066 EXPECT_CALL(mock, NeedMorePlayData(_, _, _, _, NotNull(), _, _, _)) 1067 .Times(AtLeast(kNumCallbacks)); 1068 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); 1069 StartPlayout(); 1070 event()->Wait(kTestTimeOut); 1071 StopPlayout(); 1072 PreTearDown(); 1073 } 1074 1075 // Don't run these tests in combination with sanitizers. 1076 // They are already flaky *without* sanitizers. 1077 // Sanitizers seem to increase flakiness (which brings noise), 1078 // without reporting anything. 1079 // TODO(webrtc:10867): Re-enable when flakiness fixed. 1080 #if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \ 1081 defined(THREAD_SANITIZER) 1082 #define MAYBE_StartRecordingVerifyCallbacks \ 1083 DISABLED_StartRecordingVerifyCallbacks 1084 #define MAYBE_StartPlayoutAndRecordingVerifyCallbacks \ 1085 DISABLED_StartPlayoutAndRecordingVerifyCallbacks 1086 #else 1087 #define MAYBE_StartRecordingVerifyCallbacks StartRecordingVerifyCallbacks 1088 #define MAYBE_StartPlayoutAndRecordingVerifyCallbacks \ 1089 StartPlayoutAndRecordingVerifyCallbacks 1090 #endif 1091 1092 // Start recording and verify that the native audio layer starts providing real 1093 // audio samples using the RecordedDataIsAvailable() callback. 1094 TEST_P(MAYBE_AudioDeviceTest, MAYBE_StartRecordingVerifyCallbacks) { 1095 SKIP_TEST_IF_NOT(requirements_satisfied()); 1096 MockAudioTransport mock(TransportType::kRecord); 1097 mock.HandleCallbacks(event(), nullptr, kNumCallbacks); 1098 EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(), _, _, _, _, Ge(0u), 0, _, 1099 false, _, _)) 1100 .Times(AtLeast(kNumCallbacks)); 1101 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); 1102 StartRecording(); 1103 event()->Wait(kTestTimeOut); 1104 StopRecording(); 1105 PreTearDown(); 1106 } 1107 1108 // Start playout and recording (full-duplex audio) and verify that audio is 1109 // active in both directions. 1110 TEST_P(MAYBE_AudioDeviceTest, MAYBE_StartPlayoutAndRecordingVerifyCallbacks) { 1111 SKIP_TEST_IF_NOT(requirements_satisfied()); 1112 MockAudioTransport mock(TransportType::kPlayAndRecord); 1113 mock.HandleCallbacks(event(), nullptr, kNumCallbacks); 1114 EXPECT_CALL(mock, NeedMorePlayData(_, _, _, _, NotNull(), _, _, _)) 1115 .Times(AtLeast(kNumCallbacks)); 1116 EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(), _, _, _, _, Ge(0u), 0, _, 1117 false, _, _)) 1118 .Times(AtLeast(kNumCallbacks)); 1119 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); 1120 StartPlayout(); 1121 StartRecording(); 1122 event()->Wait(kTestTimeOut); 1123 StopRecording(); 1124 StopPlayout(); 1125 PreTearDown(); 1126 } 1127 1128 // Start playout and recording and store recorded data in an intermediate FIFO 1129 // buffer from which the playout side then reads its samples in the same order 1130 // as they were stored. Under ideal circumstances, a callback sequence would 1131 // look like: ...+-+-+-+-+-+-+-..., where '+' means 'packet recorded' and '-' 1132 // means 'packet played'. Under such conditions, the FIFO would contain max 1, 1133 // with an average somewhere in (0,1) depending on how long the packets are 1134 // buffered. However, under more realistic conditions, the size 1135 // of the FIFO will vary more due to an unbalance between the two sides. 1136 // This test tries to verify that the device maintains a balanced callback- 1137 // sequence by running in loopback for a few seconds while measuring the size 1138 // (max and average) of the FIFO. The size of the FIFO is increased by the 1139 // recording side and decreased by the playout side. 1140 TEST_P(MAYBE_AudioDeviceTest, RunPlayoutAndRecordingInFullDuplex) { 1141 SKIP_TEST_IF_NOT(requirements_satisfied()); 1142 NiceMock<MockAudioTransport> mock(TransportType::kPlayAndRecord); 1143 FifoAudioStream audio_stream; 1144 mock.HandleCallbacks(event(), &audio_stream, 1145 kFullDuplexTime.seconds() * kNumCallbacksPerSecond); 1146 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); 1147 // Run both sides using the same channel configuration to avoid conversions 1148 // between mono/stereo while running in full duplex mode. Also, some devices 1149 // (mainly on Windows) do not support mono. 1150 EXPECT_EQ(0, audio_device()->SetStereoPlayout(true)); 1151 EXPECT_EQ(0, audio_device()->SetStereoRecording(true)); 1152 // Mute speakers to prevent howling. 1153 EXPECT_EQ(0, audio_device()->SetSpeakerVolume(0)); 1154 StartPlayout(); 1155 StartRecording(); 1156 event()->Wait(std::max(kTestTimeOut, kFullDuplexTime)); 1157 StopRecording(); 1158 StopPlayout(); 1159 PreTearDown(); 1160 } 1161 1162 // Runs audio in full duplex until user hits Enter. Intended as a manual test 1163 // to ensure that the audio quality is good and that real device switches works 1164 // as intended. 1165 TEST_P(MAYBE_AudioDeviceTest, 1166 DISABLED_RunPlayoutAndRecordingInFullDuplexAndWaitForEnterKey) { 1167 SKIP_TEST_IF_NOT(requirements_satisfied()); 1168 if (audio_layer() != AudioDeviceModule::kWindowsCoreAudio2) { 1169 return; 1170 } 1171 NiceMock<MockAudioTransport> mock(TransportType::kPlayAndRecord); 1172 FifoAudioStream audio_stream; 1173 mock.HandleCallbacks(&audio_stream); 1174 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); 1175 EXPECT_EQ(0, audio_device()->SetStereoPlayout(true)); 1176 EXPECT_EQ(0, audio_device()->SetStereoRecording(true)); 1177 // Ensure that the sample rate for both directions are identical so that we 1178 // always can listen to our own voice. Will lead to rate conversion (and 1179 // higher latency) if the native sample rate is not 48kHz. 1180 EXPECT_EQ(0, audio_device()->SetPlayoutSampleRate(48000)); 1181 EXPECT_EQ(0, audio_device()->SetRecordingSampleRate(48000)); 1182 StartPlayout(); 1183 StartRecording(); 1184 do { 1185 PRINT("Loopback audio is active at 48kHz. Press Enter to stop.\n"); 1186 } while (getchar() != '\n'); 1187 StopRecording(); 1188 StopPlayout(); 1189 PreTearDown(); 1190 } 1191 1192 // Measures loopback latency and reports the min, max and average values for 1193 // a full duplex audio session. 1194 // The latency is measured like so: 1195 // - Insert impulses periodically on the output side. 1196 // - Detect the impulses on the input side. 1197 // - Measure the time difference between the transmit time and receive time. 1198 // - Store time differences in a vector and calculate min, max and average. 1199 // This test needs the '--gtest_also_run_disabled_tests' flag to run and also 1200 // some sort of audio feedback loop. E.g. a headset where the mic is placed 1201 // close to the speaker to ensure highest possible echo. It is also recommended 1202 // to run the test at highest possible output volume. 1203 TEST_P(MAYBE_AudioDeviceTest, DISABLED_MeasureLoopbackLatency) { 1204 SKIP_TEST_IF_NOT(requirements_satisfied()); 1205 NiceMock<MockAudioTransport> mock(TransportType::kPlayAndRecord); 1206 LatencyAudioStream audio_stream; 1207 mock.HandleCallbacks(event(), &audio_stream, 1208 kMeasureLatencyTime.seconds() * kNumCallbacksPerSecond); 1209 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock)); 1210 EXPECT_EQ(0, audio_device()->SetStereoPlayout(true)); 1211 EXPECT_EQ(0, audio_device()->SetStereoRecording(true)); 1212 StartPlayout(); 1213 StartRecording(); 1214 event()->Wait(std::max(kTestTimeOut, kMeasureLatencyTime)); 1215 StopRecording(); 1216 StopPlayout(); 1217 // Avoid concurrent access to audio_stream. 1218 PreTearDown(); 1219 // Verify that a sufficient number of transmitted impulses are detected. 1220 EXPECT_GE(audio_stream.num_latency_values(), 1221 static_cast<size_t>( 1222 kImpulseFrequencyInHz * kMeasureLatencyTime.seconds() - 2)); 1223 // Print out min, max and average delay values for debugging purposes. 1224 audio_stream.PrintResults(); 1225 } 1226 1227 #ifdef WEBRTC_WIN 1228 // Test two different audio layers (or rather two different Core Audio 1229 // implementations) for Windows. 1230 INSTANTIATE_TEST_SUITE_P( 1231 AudioLayerWin, 1232 MAYBE_AudioDeviceTest, 1233 ::testing::Values(AudioDeviceModule::kPlatformDefaultAudio, 1234 AudioDeviceModule::kWindowsCoreAudio2)); 1235 #else 1236 // For all platforms but Windows, only test the default audio layer. 1237 INSTANTIATE_TEST_SUITE_P( 1238 AudioLayer, 1239 MAYBE_AudioDeviceTest, 1240 ::testing::Values(AudioDeviceModule::kPlatformDefaultAudio)); 1241 #endif 1242 1243 } // namespace webrtc