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