blob: 0479a0b2e20aa9eb3132bd11b98d65fe939e7b5a [file] [log] [blame]
henrikaf2f91fa2017-03-17 04:26:22 -07001/*
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
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "modules/audio_device/include/audio_device.h"
12
henrika714e5cd2017-04-20 08:03:11 -070013#include <algorithm>
henrikaf2f91fa2017-03-17 04:26:22 -070014#include <cstring>
Danil Chapovalovb9f69022019-10-21 09:19:10 +020015#include <list>
henrikaec9c7452018-06-08 16:10:03 +020016#include <memory>
henrika714e5cd2017-04-20 08:03:11 -070017#include <numeric>
henrikaf2f91fa2017-03-17 04:26:22 -070018
Danil Chapovalov196100e2018-06-21 10:17:24 +020019#include "absl/types/optional.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "api/array_view.h"
Mirko Bonadeid9708072019-01-25 20:26:48 +010021#include "api/scoped_refptr.h"
Danil Chapovalov1c41be62019-04-01 09:16:12 +020022#include "api/task_queue/default_task_queue_factory.h"
23#include "api/task_queue/task_queue_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "modules/audio_device/audio_device_impl.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "modules/audio_device/include/mock_audio_transport.h"
henrika351173c2019-11-18 17:36:08 +010026#include "rtc_base/arraysize.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020027#include "rtc_base/buffer.h"
Steve Anton10542f22019-01-11 09:11:00 -080028#include "rtc_base/critical_section.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020029#include "rtc_base/event.h"
30#include "rtc_base/logging.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010031#include "rtc_base/numerics/safe_conversions.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020032#include "rtc_base/race_checker.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020033#include "rtc_base/thread_annotations.h"
34#include "rtc_base/thread_checker.h"
Steve Anton10542f22019-01-11 09:11:00 -080035#include "rtc_base/time_utils.h"
henrika5b6afc02018-09-05 14:34:40 +020036#include "system_wrappers/include/sleep.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020037#include "test/gmock.h"
38#include "test/gtest.h"
henrikaec9c7452018-06-08 16:10:03 +020039#ifdef WEBRTC_WIN
40#include "modules/audio_device/include/audio_device_factory.h"
41#include "modules/audio_device/win/core_audio_utility_win.h"
42#endif
henrikaf2f91fa2017-03-17 04:26:22 -070043
44using ::testing::_;
45using ::testing::AtLeast;
46using ::testing::Ge;
47using ::testing::Invoke;
Jonas Olssona4d87372019-07-05 19:08:33 +020048using ::testing::Mock;
henrikaf2f91fa2017-03-17 04:26:22 -070049using ::testing::NiceMock;
50using ::testing::NotNull;
51
52namespace webrtc {
53namespace {
54
henrika5773ad32018-09-21 14:53:10 +020055// 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
henrikae24991d2017-04-06 01:14:23 -070063// #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
Yves Gerey1afe6572019-07-18 22:01:09 +020071// Don't run these tests if audio-related requirements are not met.
Yves Gereyee0550c2019-07-17 21:41:59 +020072#define SKIP_TEST_IF_NOT(requirements_satisfied) \
73 do { \
74 if (!requirements_satisfied) { \
75 GTEST_SKIP() << "Skipped. No audio device found."; \
76 } \
henrikaf2f91fa2017-03-17 04:26:22 -070077 } while (false)
henrikaf2f91fa2017-03-17 04:26:22 -070078
79// Number of callbacks (input or output) the tests waits for before we set
80// an event indicating that the test was OK.
henrikae24991d2017-04-06 01:14:23 -070081static constexpr size_t kNumCallbacks = 10;
henrikaf2f91fa2017-03-17 04:26:22 -070082// Max amount of time we wait for an event to be set while counting callbacks.
henrika714e5cd2017-04-20 08:03:11 -070083static constexpr size_t kTestTimeOutInMilliseconds = 10 * 1000;
henrikae24991d2017-04-06 01:14:23 -070084// Average number of audio callbacks per second assuming 10ms packet size.
85static constexpr size_t kNumCallbacksPerSecond = 100;
86// Run the full-duplex test during this time (unit is in seconds).
henrika714e5cd2017-04-20 08:03:11 -070087static constexpr size_t kFullDuplexTimeInSec = 5;
88// Length of round-trip latency measurements. Number of deteced impulses
89// shall be kImpulseFrequencyInHz * kMeasureLatencyTimeInSec - 1 since the
90// last transmitted pulse is not used.
91static constexpr size_t kMeasureLatencyTimeInSec = 10;
92// Sets the number of impulses per second in the latency test.
93static constexpr size_t kImpulseFrequencyInHz = 1;
94// Utilized in round-trip latency measurements to avoid capturing noise samples.
95static constexpr int kImpulseThreshold = 1000;
henrikaf2f91fa2017-03-17 04:26:22 -070096
97enum class TransportType {
98 kInvalid,
99 kPlay,
100 kRecord,
101 kPlayAndRecord,
102};
henrikae24991d2017-04-06 01:14:23 -0700103
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.
107class AudioStream {
108 public:
henrikaeb98c722018-03-20 12:54:07 +0100109 virtual void Write(rtc::ArrayView<const int16_t> source) = 0;
110 virtual void Read(rtc::ArrayView<int16_t> destination) = 0;
henrikae24991d2017-04-06 01:14:23 -0700111
112 virtual ~AudioStream() = default;
113};
114
henrika714e5cd2017-04-20 08:03:11 -0700115// 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.
118int 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
henrikaf2f91fa2017-03-17 04:26:22 -0700123} // namespace
124
henrikae24991d2017-04-06 01:14:23 -0700125// 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
henrikac7d93582018-09-14 15:37:34 +0200134// change over time and that both sides will in most cases use the same size.
henrikae24991d2017-04-06 01:14:23 -0700135class FifoAudioStream : public AudioStream {
136 public:
henrikaeb98c722018-03-20 12:54:07 +0100137 void Write(rtc::ArrayView<const int16_t> source) override {
henrikae24991d2017-04-06 01:14:23 -0700138 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
139 const size_t size = [&] {
140 rtc::CritScope 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) {
henrikad8c6ec42019-07-18 15:17:28 +0200149 PRINTD(".");
henrikae24991d2017-04-06 01:14:23 -0700150 }
151 written_elements_ += size;
152 }
153
henrikaeb98c722018-03-20 12:54:07 +0100154 void Read(rtc::ArrayView<int16_t> destination) override {
henrikae24991d2017-04-06 01:14:23 -0700155 rtc::CritScope lock(&lock_);
156 if (fifo_.empty()) {
157 std::fill(destination.begin(), destination.end(), 0);
158 } else {
159 const Buffer16& buffer = fifo_.front();
henrikac7d93582018-09-14 15:37:34 +0200160 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_NOTREACHED() << "Required conversion is not support";
180 }
henrikae24991d2017-04-06 01:14:23 -0700181 fifo_.pop_front();
182 }
183 }
184
185 size_t size() const {
186 rtc::CritScope lock(&lock_);
187 return fifo_.size();
188 }
189
190 size_t max_size() const {
191 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
192 return max_size_;
193 }
194
195 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 rtc::CriticalSection lock_;
203 rtc::RaceChecker race_checker_;
204
danilchap56359be2017-09-07 07:53:45 -0700205 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;
henrikae24991d2017-04-06 01:14:23 -0700209};
210
henrika714e5cd2017-04-20 08:03:11 -0700211// Inserts periodic impulses and measures the latency between the time of
212// transmission and time of receiving the same impulse.
213class LatencyAudioStream : public AudioStream {
214 public:
215 LatencyAudioStream() {
216 // Delay thread checkers from being initialized until first callback from
217 // respective thread.
Sebastian Janssonc01367d2019-04-08 15:20:44 +0200218 read_thread_checker_.Detach();
219 write_thread_checker_.Detach();
henrika714e5cd2017-04-20 08:03:11 -0700220 }
221
222 // Insert periodic impulses in first two samples of |destination|.
henrikaeb98c722018-03-20 12:54:07 +0100223 void Read(rtc::ArrayView<int16_t> destination) override {
henrika714e5cd2017-04-20 08:03:11 -0700224 RTC_DCHECK_RUN_ON(&read_thread_checker_);
henrika714e5cd2017-04-20 08:03:11 -0700225 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 rtc::CritScope lock(&lock_);
234 if (!pulse_time_) {
Oskar Sundbom6ad9f262017-11-16 10:53:39 +0100235 pulse_time_ = rtc::TimeMillis();
henrika714e5cd2017-04-20 08:03:11 -0700236 }
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.
henrikaeb98c722018-03-20 12:54:07 +0100245 void Write(rtc::ArrayView<const int16_t> source) override {
henrika714e5cd2017-04-20 08:03:11 -0700246 RTC_DCHECK_RUN_ON(&write_thread_checker_);
247 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
248 rtc::CritScope 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
279 size_t num_latency_values() const {
280 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
281 return latencies_.size();
282 }
283
284 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
291 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
298 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
307 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 rtc::CriticalSection lock_;
319 rtc::RaceChecker race_checker_;
320 rtc::ThreadChecker read_thread_checker_;
321 rtc::ThreadChecker write_thread_checker_;
322
Danil Chapovalov196100e2018-06-21 10:17:24 +0200323 absl::optional<int64_t> pulse_time_ RTC_GUARDED_BY(lock_);
danilchap56359be2017-09-07 07:53:45 -0700324 std::vector<int> latencies_ RTC_GUARDED_BY(race_checker_);
Niels Möller1e062892018-02-07 10:18:32 +0100325 size_t read_count_ RTC_GUARDED_BY(read_thread_checker_) = 0;
326 size_t write_count_ RTC_GUARDED_BY(write_thread_checker_) = 0;
henrika714e5cd2017-04-20 08:03:11 -0700327};
328
henrikaf2f91fa2017-03-17 04:26:22 -0700329// Mocks the AudioTransport object and proxies actions for the two callbacks
330// (RecordedDataIsAvailable and NeedMorePlayData) to different implementations
331// of AudioStreamInterface.
332class MockAudioTransport : public test::MockAudioTransport {
333 public:
334 explicit MockAudioTransport(TransportType type) : type_(type) {}
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.
henrikae24991d2017-04-06 01:14:23 -0700341 void HandleCallbacks(rtc::Event* event,
342 AudioStream* audio_stream,
343 int num_callbacks) {
henrikaf2f91fa2017-03-17 04:26:22 -0700344 event_ = event;
henrikae24991d2017-04-06 01:14:23 -0700345 audio_stream_ = audio_stream;
henrikaf2f91fa2017-03-17 04:26:22 -0700346 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
henrika5b6afc02018-09-05 14:34:40 +0200359 // 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().
363 void HandleCallbacks(AudioStream* audio_stream) {
364 HandleCallbacks(nullptr, audio_stream, 0);
365 }
366
henrikaf2f91fa2017-03-17 04:26:22 -0700367 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.";
henrikaf2f91fa2017-03-17 04:26:22 -0700378 // 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 }
henrika78e0ac12018-09-27 16:23:21 +0200392 {
393 rtc::CritScope lock(&lock_);
394 rec_count_++;
395 }
henrikae24991d2017-04-06 01:14:23 -0700396 // 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),
henrikaeb98c722018-03-20 12:54:07 +0100400 samples_per_channel * channels));
henrikae24991d2017-04-06 01:14:23 -0700401 }
henrikaf2f91fa2017-03-17 04:26:22 -0700402 // Signal the event after given amount of callbacks.
henrika5b6afc02018-09-05 14:34:40 +0200403 if (event_ && ReceivedEnoughCallbacks()) {
henrikaf2f91fa2017-03-17 04:26:22 -0700404 event_->Set();
405 }
406 return 0;
407 }
408
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,
henrikaeb98c722018-03-20 12:54:07 +0100414 size_t& samples_out,
henrikaf2f91fa2017-03-17 04:26:22 -0700415 int64_t* elapsed_time_ms,
416 int64_t* ntp_time_ms) {
417 EXPECT_TRUE(play_mode()) << "No test is expecting these callbacks.";
henrikaf2f91fa2017-03-17 04:26:22 -0700418 // 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 }
henrika78e0ac12018-09-27 16:23:21 +0200432 {
433 rtc::CritScope lock(&lock_);
434 play_count_++;
435 }
henrikaeb98c722018-03-20 12:54:07 +0100436 samples_out = samples_per_channel * channels;
henrikae24991d2017-04-06 01:14:23 -0700437 // Read audio data from audio stream object if one has been injected.
438 if (audio_stream_) {
henrikaeb98c722018-03-20 12:54:07 +0100439 audio_stream_->Read(rtc::MakeArrayView(
440 static_cast<int16_t*>(audio_buffer), samples_per_channel * channels));
henrikae24991d2017-04-06 01:14:23 -0700441 } 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 }
henrikaf2f91fa2017-03-17 04:26:22 -0700446 // Signal the event after given amount of callbacks.
henrika5b6afc02018-09-05 14:34:40 +0200447 if (event_ && ReceivedEnoughCallbacks()) {
henrikaf2f91fa2017-03-17 04:26:22 -0700448 event_->Set();
449 }
450 return 0;
451 }
452
453 bool ReceivedEnoughCallbacks() {
454 bool recording_done = false;
455 if (rec_mode()) {
henrika78e0ac12018-09-27 16:23:21 +0200456 rtc::CritScope lock(&lock_);
henrikaf2f91fa2017-03-17 04:26:22 -0700457 recording_done = rec_count_ >= num_callbacks_;
458 } else {
459 recording_done = true;
460 }
461 bool playout_done = false;
462 if (play_mode()) {
henrika78e0ac12018-09-27 16:23:21 +0200463 rtc::CritScope lock(&lock_);
henrikaf2f91fa2017-03-17 04:26:22 -0700464 playout_done = play_count_ >= num_callbacks_;
465 } else {
466 playout_done = true;
467 }
468 return recording_done && playout_done;
469 }
470
471 bool play_mode() const {
472 return type_ == TransportType::kPlay ||
473 type_ == TransportType::kPlayAndRecord;
474 }
475
476 bool rec_mode() const {
477 return type_ == TransportType::kRecord ||
478 type_ == TransportType::kPlayAndRecord;
479 }
480
henrika5b6afc02018-09-05 14:34:40 +0200481 void ResetCallbackCounters() {
henrika78e0ac12018-09-27 16:23:21 +0200482 rtc::CritScope lock(&lock_);
henrika5b6afc02018-09-05 14:34:40 +0200483 if (play_mode()) {
484 play_count_ = 0;
485 }
486 if (rec_mode()) {
487 rec_count_ = 0;
488 }
489 }
490
henrikaf2f91fa2017-03-17 04:26:22 -0700491 private:
henrika78e0ac12018-09-27 16:23:21 +0200492 rtc::CriticalSection lock_;
henrikaf2f91fa2017-03-17 04:26:22 -0700493 TransportType type_ = TransportType::kInvalid;
494 rtc::Event* event_ = nullptr;
henrikae24991d2017-04-06 01:14:23 -0700495 AudioStream* audio_stream_ = nullptr;
henrikaf2f91fa2017-03-17 04:26:22 -0700496 size_t num_callbacks_ = 0;
henrika78e0ac12018-09-27 16:23:21 +0200497 size_t play_count_ RTC_GUARDED_BY(lock_) = 0;
498 size_t rec_count_ RTC_GUARDED_BY(lock_) = 0;
henrikaf2f91fa2017-03-17 04:26:22 -0700499 AudioParameters playout_parameters_;
500 AudioParameters record_parameters_;
501};
502
503// AudioDeviceTest test fixture.
Yves Gerey1afe6572019-07-18 22:01:09 +0200504
Yves Gereyff060ee2019-09-11 15:53:01 +0200505// 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
517class MAYBE_AudioDeviceTest
henrikaec9c7452018-06-08 16:10:03 +0200518 : public ::testing::TestWithParam<webrtc::AudioDeviceModule::AudioLayer> {
henrikaf2f91fa2017-03-17 04:26:22 -0700519 protected:
Yves Gereyff060ee2019-09-11 15:53:01 +0200520 MAYBE_AudioDeviceTest()
Danil Chapovalov1c41be62019-04-01 09:16:12 +0200521 : audio_layer_(GetParam()),
522 task_queue_factory_(CreateDefaultTaskQueueFactory()) {
henrikaf2f91fa2017-03-17 04:26:22 -0700523 rtc::LogMessage::LogToDebug(rtc::LS_INFO);
524 // Add extra logging fields here if needed for debugging.
henrikaec9c7452018-06-08 16:10:03 +0200525 rtc::LogMessage::LogTimestamps();
526 rtc::LogMessage::LogThreads();
527 audio_device_ = CreateAudioDevice();
henrikaf2f91fa2017-03-17 04:26:22 -0700528 EXPECT_NE(audio_device_.get(), nullptr);
529 AudioDeviceModule::AudioLayer audio_layer;
maxmorin33bf69a2017-03-23 04:06:53 -0700530 int got_platform_audio_layer =
531 audio_device_->ActiveAudioLayer(&audio_layer);
henrika919dc2e2017-10-12 14:24:55 +0200532 // First, ensure that a valid audio layer can be activated.
533 if (got_platform_audio_layer != 0) {
henrikaf2f91fa2017-03-17 04:26:22 -0700534 requirements_satisfied_ = false;
535 }
henrika919dc2e2017-10-12 14:24:55 +0200536 // Next, verify that the ADM can be initialized.
henrikaf2f91fa2017-03-17 04:26:22 -0700537 if (requirements_satisfied_) {
henrika919dc2e2017-10-12 14:24:55 +0200538 requirements_satisfied_ = (audio_device_->Init() == 0);
539 }
540 // Finally, ensure that at least one valid device exists in each direction.
541 if (requirements_satisfied_) {
henrikaf2f91fa2017-03-17 04:26:22 -0700542 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 }
henrikaf2f91fa2017-03-17 04:26:22 -0700547 if (requirements_satisfied_) {
henrika5773ad32018-09-21 14:53:10 +0200548 EXPECT_EQ(0, audio_device_->SetPlayoutDevice(AUDIO_DEVICE_ID));
henrikaf2f91fa2017-03-17 04:26:22 -0700549 EXPECT_EQ(0, audio_device_->InitSpeaker());
henrikaf2f91fa2017-03-17 04:26:22 -0700550 EXPECT_EQ(0, audio_device_->StereoPlayoutIsAvailable(&stereo_playout_));
551 EXPECT_EQ(0, audio_device_->SetStereoPlayout(stereo_playout_));
henrika5773ad32018-09-21 14:53:10 +0200552 EXPECT_EQ(0, audio_device_->SetRecordingDevice(AUDIO_DEVICE_ID));
553 EXPECT_EQ(0, audio_device_->InitMicrophone());
henrika0238ba82017-03-28 04:38:29 -0700554 // 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));
henrikaf2f91fa2017-03-17 04:26:22 -0700559 }
560 }
561
Yves Gereyb93a2452019-07-19 22:46:13 +0200562 // 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.
567 void PreTearDown() { EXPECT_EQ(0, audio_device_->Terminate()); }
568
Yves Gereyff060ee2019-09-11 15:53:01 +0200569 virtual ~MAYBE_AudioDeviceTest() {
henrikaf2f91fa2017-03-17 04:26:22 -0700570 if (audio_device_) {
571 EXPECT_EQ(0, audio_device_->Terminate());
572 }
573 }
574
575 bool requirements_satisfied() const { return requirements_satisfied_; }
576 rtc::Event* event() { return &event_; }
henrika5b6afc02018-09-05 14:34:40 +0200577 AudioDeviceModule::AudioLayer audio_layer() const { return audio_layer_; }
henrikaf2f91fa2017-03-17 04:26:22 -0700578
henrika5b6afc02018-09-05 14:34:40 +0200579 // 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.
582 const rtc::scoped_refptr<AudioDeviceModuleForTest>& audio_device() const {
henrikaf2f91fa2017-03-17 04:26:22 -0700583 return audio_device_;
584 }
585
henrika5b6afc02018-09-05 14:34:40 +0200586 rtc::scoped_refptr<AudioDeviceModuleForTest> CreateAudioDevice() {
henrikaec9c7452018-06-08 16:10:03 +0200587 // Use the default factory for kPlatformDefaultAudio and a special factory
henrika5b6afc02018-09-05 14:34:40 +0200588 // CreateWindowsCoreAudioAudioDeviceModuleForTest() for kWindowsCoreAudio2.
henrikaec9c7452018-06-08 16:10:03 +0200589 // 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) {
Danil Chapovalov1c41be62019-04-01 09:16:12 +0200592 return AudioDeviceModule::CreateForTest(audio_layer_,
593 task_queue_factory_.get());
henrikaec9c7452018-06-08 16:10:03 +0200594 } 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.
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200599 com_initializer_ = std::make_unique<webrtc_win::ScopedCOMInitializer>(
henrikaec9c7452018-06-08 16:10:03 +0200600 webrtc_win::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());
Danil Chapovalov1c41be62019-04-01 09:16:12 +0200604 return CreateWindowsCoreAudioAudioDeviceModuleForTest(
henrikad8c6ec42019-07-18 15:17:28 +0200605 task_queue_factory_.get(), true);
henrikaec9c7452018-06-08 16:10:03 +0200606#else
607 return nullptr;
608#endif
609 } else {
610 return nullptr;
611 }
612 }
613
henrikaf2f91fa2017-03-17 04:26:22 -0700614 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
622 void StopPlayout() {
623 EXPECT_EQ(0, audio_device()->StopPlayout());
624 EXPECT_FALSE(audio_device()->Playing());
625 EXPECT_FALSE(audio_device()->PlayoutIsInitialized());
626 }
627
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
636 void StopRecording() {
637 EXPECT_EQ(0, audio_device()->StopRecording());
638 EXPECT_FALSE(audio_device()->Recording());
639 EXPECT_FALSE(audio_device()->RecordingIsInitialized());
640 }
641
henrikaec9c7452018-06-08 16:10:03 +0200642 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
henrikaf2f91fa2017-03-17 04:26:22 -0700656 private:
henrikaec9c7452018-06-08 16:10:03 +0200657#ifdef WEBRTC_WIN
658 // Windows Core Audio based ADM needs to run on a COM initialized thread.
659 std::unique_ptr<webrtc_win::ScopedCOMInitializer> com_initializer_;
660#endif
661 AudioDeviceModule::AudioLayer audio_layer_;
Danil Chapovalov1c41be62019-04-01 09:16:12 +0200662 std::unique_ptr<TaskQueueFactory> task_queue_factory_;
henrikaf2f91fa2017-03-17 04:26:22 -0700663 bool requirements_satisfied_ = true;
664 rtc::Event event_;
henrika5b6afc02018-09-05 14:34:40 +0200665 rtc::scoped_refptr<AudioDeviceModuleForTest> audio_device_;
henrikaf2f91fa2017-03-17 04:26:22 -0700666 bool stereo_playout_ = false;
henrikaf2f91fa2017-03-17 04:26:22 -0700667};
668
henrikaec9c7452018-06-08 16:10:03 +0200669// Instead of using the test fixture, verify that the different factory methods
670// work as intended.
Yves Gereyff060ee2019-09-11 15:53:01 +0200671TEST(MAYBE_AudioDeviceTestWin, ConstructDestructWithFactory) {
Danil Chapovalov1c41be62019-04-01 09:16:12 +0200672 std::unique_ptr<TaskQueueFactory> task_queue_factory =
673 CreateDefaultTaskQueueFactory();
henrikaec9c7452018-06-08 16:10:03 +0200674 rtc::scoped_refptr<AudioDeviceModule> audio_device;
675 // The default factory should work for all platforms when a default ADM is
676 // requested.
Danil Chapovalov1c41be62019-04-01 09:16:12 +0200677 audio_device = AudioDeviceModule::Create(
678 AudioDeviceModule::kPlatformDefaultAudio, task_queue_factory.get());
henrikaec9c7452018-06-08 16:10:03 +0200679 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.
Danil Chapovalov1c41be62019-04-01 09:16:12 +0200686 audio_device = AudioDeviceModule::Create(
687 AudioDeviceModule::kWindowsCoreAudio2, task_queue_factory.get());
henrikaec9c7452018-06-08 16:10:03 +0200688 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 webrtc_win::ScopedCOMInitializer com_initializer(
695 webrtc_win::ScopedCOMInitializer::kMTA);
696 EXPECT_TRUE(com_initializer.Succeeded());
Danil Chapovalov1c41be62019-04-01 09:16:12 +0200697 audio_device =
698 CreateWindowsCoreAudioAudioDeviceModule(task_queue_factory.get());
henrikaec9c7452018-06-08 16:10:03 +0200699 EXPECT_TRUE(audio_device);
700 AudioDeviceModule::AudioLayer audio_layer;
701 EXPECT_EQ(0, audio_device->ActiveAudioLayer(&audio_layer));
702 EXPECT_EQ(audio_layer, AudioDeviceModule::kWindowsCoreAudio2);
703#endif
704}
henrikaf2f91fa2017-03-17 04:26:22 -0700705
henrikaec9c7452018-06-08 16:10:03 +0200706// Uses the test fixture to create, initialize and destruct the ADM.
Yves Gereyff060ee2019-09-11 15:53:01 +0200707TEST_P(MAYBE_AudioDeviceTest, ConstructDestructDefault) {}
henrikaec9c7452018-06-08 16:10:03 +0200708
Yves Gereyff060ee2019-09-11 15:53:01 +0200709TEST_P(MAYBE_AudioDeviceTest, InitTerminate) {
henrikaf2f91fa2017-03-17 04:26:22 -0700710 SKIP_TEST_IF_NOT(requirements_satisfied());
711 // Initialization is part of the test fixture.
712 EXPECT_TRUE(audio_device()->Initialized());
713 EXPECT_EQ(0, audio_device()->Terminate());
714 EXPECT_FALSE(audio_device()->Initialized());
715}
716
henrikaec9c7452018-06-08 16:10:03 +0200717// Enumerate all available and active output devices.
Yves Gereyff060ee2019-09-11 15:53:01 +0200718TEST_P(MAYBE_AudioDeviceTest, PlayoutDeviceNames) {
henrikaf2f91fa2017-03-17 04:26:22 -0700719 SKIP_TEST_IF_NOT(requirements_satisfied());
henrikaec9c7452018-06-08 16:10:03 +0200720 char device_name[kAdmMaxDeviceNameSize];
721 char unique_id[kAdmMaxGuidSize];
722 int num_devices = audio_device()->PlayoutDevices();
723 if (NewWindowsAudioDeviceModuleIsUsed()) {
724 num_devices += 2;
725 }
726 EXPECT_GT(num_devices, 0);
727 for (int i = 0; i < num_devices; ++i) {
728 EXPECT_EQ(0, audio_device()->PlayoutDeviceName(i, device_name, unique_id));
729 }
730 EXPECT_EQ(-1, audio_device()->PlayoutDeviceName(num_devices, device_name,
731 unique_id));
732}
733
734// Enumerate all available and active input devices.
Yves Gereyff060ee2019-09-11 15:53:01 +0200735TEST_P(MAYBE_AudioDeviceTest, RecordingDeviceNames) {
henrikaec9c7452018-06-08 16:10:03 +0200736 SKIP_TEST_IF_NOT(requirements_satisfied());
737 char device_name[kAdmMaxDeviceNameSize];
738 char unique_id[kAdmMaxGuidSize];
739 int num_devices = audio_device()->RecordingDevices();
740 if (NewWindowsAudioDeviceModuleIsUsed()) {
741 num_devices += 2;
742 }
743 EXPECT_GT(num_devices, 0);
744 for (int i = 0; i < num_devices; ++i) {
745 EXPECT_EQ(0,
746 audio_device()->RecordingDeviceName(i, device_name, unique_id));
747 }
748 EXPECT_EQ(-1, audio_device()->RecordingDeviceName(num_devices, device_name,
749 unique_id));
750}
751
752// Counts number of active output devices and ensure that all can be selected.
Yves Gereyff060ee2019-09-11 15:53:01 +0200753TEST_P(MAYBE_AudioDeviceTest, SetPlayoutDevice) {
henrikaec9c7452018-06-08 16:10:03 +0200754 SKIP_TEST_IF_NOT(requirements_satisfied());
755 int num_devices = audio_device()->PlayoutDevices();
756 if (NewWindowsAudioDeviceModuleIsUsed()) {
757 num_devices += 2;
758 }
759 EXPECT_GT(num_devices, 0);
760 // Verify that all available playout devices can be set (not enabled yet).
761 for (int i = 0; i < num_devices; ++i) {
762 EXPECT_EQ(0, audio_device()->SetPlayoutDevice(i));
763 }
764 EXPECT_EQ(-1, audio_device()->SetPlayoutDevice(num_devices));
765#ifdef WEBRTC_WIN
766 // On Windows, verify the alternative method where the user can select device
767 // by role.
768 EXPECT_EQ(
769 0, audio_device()->SetPlayoutDevice(AudioDeviceModule::kDefaultDevice));
770 EXPECT_EQ(0, audio_device()->SetPlayoutDevice(
771 AudioDeviceModule::kDefaultCommunicationDevice));
772#endif
773}
774
775// Counts number of active input devices and ensure that all can be selected.
Yves Gereyff060ee2019-09-11 15:53:01 +0200776TEST_P(MAYBE_AudioDeviceTest, SetRecordingDevice) {
henrikaec9c7452018-06-08 16:10:03 +0200777 SKIP_TEST_IF_NOT(requirements_satisfied());
778 int num_devices = audio_device()->RecordingDevices();
779 if (NewWindowsAudioDeviceModuleIsUsed()) {
780 num_devices += 2;
781 }
782 EXPECT_GT(num_devices, 0);
783 // Verify that all available recording devices can be set (not enabled yet).
784 for (int i = 0; i < num_devices; ++i) {
785 EXPECT_EQ(0, audio_device()->SetRecordingDevice(i));
786 }
787 EXPECT_EQ(-1, audio_device()->SetRecordingDevice(num_devices));
788#ifdef WEBRTC_WIN
789 // On Windows, verify the alternative method where the user can select device
790 // by role.
791 EXPECT_EQ(
792 0, audio_device()->SetRecordingDevice(AudioDeviceModule::kDefaultDevice));
793 EXPECT_EQ(0, audio_device()->SetRecordingDevice(
794 AudioDeviceModule::kDefaultCommunicationDevice));
795#endif
796}
797
798// Tests Start/Stop playout without any registered audio callback.
Yves Gereyff060ee2019-09-11 15:53:01 +0200799TEST_P(MAYBE_AudioDeviceTest, StartStopPlayout) {
henrikaec9c7452018-06-08 16:10:03 +0200800 SKIP_TEST_IF_NOT(requirements_satisfied());
henrikaf2f91fa2017-03-17 04:26:22 -0700801 StartPlayout();
802 StopPlayout();
803}
804
805// Tests Start/Stop recording without any registered audio callback.
Yves Gereyff060ee2019-09-11 15:53:01 +0200806TEST_P(MAYBE_AudioDeviceTest, StartStopRecording) {
henrikaf2f91fa2017-03-17 04:26:22 -0700807 SKIP_TEST_IF_NOT(requirements_satisfied());
808 StartRecording();
809 StopRecording();
henrikaf2f91fa2017-03-17 04:26:22 -0700810}
811
henrika351173c2019-11-18 17:36:08 +0100812// Tests Start/Stop playout for all available input devices to ensure that
813// the selected device can be created and used as intended.
814TEST_P(MAYBE_AudioDeviceTest, StartStopPlayoutWithRealDevice) {
815 SKIP_TEST_IF_NOT(requirements_satisfied());
816 int num_devices = audio_device()->PlayoutDevices();
817 if (NewWindowsAudioDeviceModuleIsUsed()) {
818 num_devices += 2;
819 }
820 EXPECT_GT(num_devices, 0);
821 // Verify that all available playout devices can be set and used.
822 for (int i = 0; i < num_devices; ++i) {
823 EXPECT_EQ(0, audio_device()->SetPlayoutDevice(i));
824 StartPlayout();
825 StopPlayout();
826 }
827#ifdef WEBRTC_WIN
828 AudioDeviceModule::WindowsDeviceType device_role[] = {
829 AudioDeviceModule::kDefaultDevice,
830 AudioDeviceModule::kDefaultCommunicationDevice};
831 for (size_t i = 0; i < arraysize(device_role); ++i) {
832 EXPECT_EQ(0, audio_device()->SetPlayoutDevice(device_role[i]));
833 StartPlayout();
834 StopPlayout();
835 }
836#endif
837}
838
839// Tests Start/Stop recording for all available input devices to ensure that
840// the selected device can be created and used as intended.
841TEST_P(MAYBE_AudioDeviceTest, StartStopRecordingWithRealDevice) {
842 SKIP_TEST_IF_NOT(requirements_satisfied());
843 int num_devices = audio_device()->RecordingDevices();
844 if (NewWindowsAudioDeviceModuleIsUsed()) {
845 num_devices += 2;
846 }
847 EXPECT_GT(num_devices, 0);
848 // Verify that all available recording devices can be set and used.
849 for (int i = 0; i < num_devices; ++i) {
850 EXPECT_EQ(0, audio_device()->SetRecordingDevice(i));
851 StartRecording();
852 StopRecording();
853 }
854#ifdef WEBRTC_WIN
855 AudioDeviceModule::WindowsDeviceType device_role[] = {
856 AudioDeviceModule::kDefaultDevice,
857 AudioDeviceModule::kDefaultCommunicationDevice};
858 for (size_t i = 0; i < arraysize(device_role); ++i) {
859 EXPECT_EQ(0, audio_device()->SetRecordingDevice(device_role[i]));
860 StartRecording();
861 StopRecording();
862 }
863#endif
864}
865
henrika6b3e1a22017-09-25 16:34:30 +0200866// Tests Init/Stop/Init recording without any registered audio callback.
867// See https://bugs.chromium.org/p/webrtc/issues/detail?id=8041 for details
868// on why this test is useful.
Yves Gereyff060ee2019-09-11 15:53:01 +0200869TEST_P(MAYBE_AudioDeviceTest, InitStopInitRecording) {
henrika6b3e1a22017-09-25 16:34:30 +0200870 SKIP_TEST_IF_NOT(requirements_satisfied());
871 EXPECT_EQ(0, audio_device()->InitRecording());
872 EXPECT_TRUE(audio_device()->RecordingIsInitialized());
873 StopRecording();
874 EXPECT_EQ(0, audio_device()->InitRecording());
875 StopRecording();
876}
877
henrikad4049462019-07-12 13:37:11 +0200878// Verify that additional attempts to initialize or start recording while
879// already being active works. Additional calls should just be ignored.
Yves Gereyff060ee2019-09-11 15:53:01 +0200880TEST_P(MAYBE_AudioDeviceTest, StartInitRecording) {
henrikad4049462019-07-12 13:37:11 +0200881 SKIP_TEST_IF_NOT(requirements_satisfied());
882 StartRecording();
883 // An additional attempt to initialize at this stage should be ignored.
884 EXPECT_EQ(0, audio_device()->InitRecording());
885 // Same for additional request to start recording while already active.
886 EXPECT_EQ(0, audio_device()->StartRecording());
887 StopRecording();
888}
889
890// Verify that additional attempts to initialize or start playou while
891// already being active works. Additional calls should just be ignored.
Yves Gereyff060ee2019-09-11 15:53:01 +0200892TEST_P(MAYBE_AudioDeviceTest, StartInitPlayout) {
henrikad4049462019-07-12 13:37:11 +0200893 SKIP_TEST_IF_NOT(requirements_satisfied());
894 StartPlayout();
895 // An additional attempt to initialize at this stage should be ignored.
896 EXPECT_EQ(0, audio_device()->InitPlayout());
897 // Same for additional request to start playout while already active.
898 EXPECT_EQ(0, audio_device()->StartPlayout());
899 StopPlayout();
900}
901
henrika6b3e1a22017-09-25 16:34:30 +0200902// Tests Init/Stop/Init recording while playout is active.
Yves Gereyff060ee2019-09-11 15:53:01 +0200903TEST_P(MAYBE_AudioDeviceTest, InitStopInitRecordingWhilePlaying) {
henrika6b3e1a22017-09-25 16:34:30 +0200904 SKIP_TEST_IF_NOT(requirements_satisfied());
905 StartPlayout();
906 EXPECT_EQ(0, audio_device()->InitRecording());
907 EXPECT_TRUE(audio_device()->RecordingIsInitialized());
908 StopRecording();
909 EXPECT_EQ(0, audio_device()->InitRecording());
910 StopRecording();
911 StopPlayout();
912}
913
914// Tests Init/Stop/Init playout without any registered audio callback.
Yves Gereyff060ee2019-09-11 15:53:01 +0200915TEST_P(MAYBE_AudioDeviceTest, InitStopInitPlayout) {
henrika6b3e1a22017-09-25 16:34:30 +0200916 SKIP_TEST_IF_NOT(requirements_satisfied());
917 EXPECT_EQ(0, audio_device()->InitPlayout());
918 EXPECT_TRUE(audio_device()->PlayoutIsInitialized());
919 StopPlayout();
920 EXPECT_EQ(0, audio_device()->InitPlayout());
921 StopPlayout();
922}
923
924// Tests Init/Stop/Init playout while recording is active.
Yves Gereyff060ee2019-09-11 15:53:01 +0200925TEST_P(MAYBE_AudioDeviceTest, InitStopInitPlayoutWhileRecording) {
henrika6b3e1a22017-09-25 16:34:30 +0200926 SKIP_TEST_IF_NOT(requirements_satisfied());
927 StartRecording();
928 EXPECT_EQ(0, audio_device()->InitPlayout());
929 EXPECT_TRUE(audio_device()->PlayoutIsInitialized());
930 StopPlayout();
931 EXPECT_EQ(0, audio_device()->InitPlayout());
932 StopPlayout();
933 StopRecording();
934}
935
henrika5b6afc02018-09-05 14:34:40 +0200936// TODO(henrika): restart without intermediate destruction is currently only
937// supported on Windows.
938#ifdef WEBRTC_WIN
939// Tests Start/Stop playout followed by a second session (emulates a restart
940// triggered by a user using public APIs).
Yves Gereyff060ee2019-09-11 15:53:01 +0200941TEST_P(MAYBE_AudioDeviceTest, StartStopPlayoutWithExternalRestart) {
henrika5b6afc02018-09-05 14:34:40 +0200942 SKIP_TEST_IF_NOT(requirements_satisfied());
943 StartPlayout();
944 StopPlayout();
945 // Restart playout without destroying the ADM in between. Ensures that we
946 // support: Init(), Start(), Stop(), Init(), Start(), Stop().
947 StartPlayout();
948 StopPlayout();
949}
950
951// Tests Start/Stop recording followed by a second session (emulates a restart
952// triggered by a user using public APIs).
Yves Gereyff060ee2019-09-11 15:53:01 +0200953TEST_P(MAYBE_AudioDeviceTest, StartStopRecordingWithExternalRestart) {
henrika5b6afc02018-09-05 14:34:40 +0200954 SKIP_TEST_IF_NOT(requirements_satisfied());
955 StartRecording();
956 StopRecording();
957 // Restart recording without destroying the ADM in between. Ensures that we
958 // support: Init(), Start(), Stop(), Init(), Start(), Stop().
959 StartRecording();
960 StopRecording();
961}
962
963// Tests Start/Stop playout followed by a second session (emulates a restart
964// triggered by an internal callback e.g. corresponding to a device switch).
965// Note that, internal restart is only supported in combination with the latest
966// Windows ADM.
Yves Gereyff060ee2019-09-11 15:53:01 +0200967TEST_P(MAYBE_AudioDeviceTest, StartStopPlayoutWithInternalRestart) {
henrika5b6afc02018-09-05 14:34:40 +0200968 SKIP_TEST_IF_NOT(requirements_satisfied());
969 if (audio_layer() != AudioDeviceModule::kWindowsCoreAudio2) {
970 return;
971 }
972 MockAudioTransport mock(TransportType::kPlay);
973 mock.HandleCallbacks(event(), nullptr, kNumCallbacks);
974 EXPECT_CALL(mock, NeedMorePlayData(_, _, _, _, NotNull(), _, _, _))
975 .Times(AtLeast(kNumCallbacks));
976 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
977 StartPlayout();
978 event()->Wait(kTestTimeOutInMilliseconds);
979 EXPECT_TRUE(audio_device()->Playing());
980 // Restart playout but without stopping the internal audio thread.
981 // This procedure uses a non-public test API and it emulates what happens
982 // inside the ADM when e.g. a device is removed.
983 EXPECT_EQ(0, audio_device()->RestartPlayoutInternally());
984
985 // Run basic tests of public APIs while a restart attempt is active.
986 // These calls should now be very thin and not trigger any new actions.
987 EXPECT_EQ(-1, audio_device()->StopPlayout());
988 EXPECT_TRUE(audio_device()->Playing());
989 EXPECT_TRUE(audio_device()->PlayoutIsInitialized());
990 EXPECT_EQ(0, audio_device()->InitPlayout());
991 EXPECT_EQ(0, audio_device()->StartPlayout());
992
993 // Wait until audio has restarted and a new sequence of audio callbacks
994 // becomes active.
995 // TODO(henrika): is it possible to verify that the internal state transition
996 // is Stop->Init->Start?
997 ASSERT_TRUE(Mock::VerifyAndClearExpectations(&mock));
998 mock.ResetCallbackCounters();
999 EXPECT_CALL(mock, NeedMorePlayData(_, _, _, _, NotNull(), _, _, _))
1000 .Times(AtLeast(kNumCallbacks));
1001 event()->Wait(kTestTimeOutInMilliseconds);
1002 EXPECT_TRUE(audio_device()->Playing());
1003 // Stop playout and the audio thread after successful internal restart.
1004 StopPlayout();
Yves Gereyb93a2452019-07-19 22:46:13 +02001005 PreTearDown();
henrika5b6afc02018-09-05 14:34:40 +02001006}
1007
1008// Tests Start/Stop recording followed by a second session (emulates a restart
1009// triggered by an internal callback e.g. corresponding to a device switch).
1010// Note that, internal restart is only supported in combination with the latest
1011// Windows ADM.
Yves Gereyff060ee2019-09-11 15:53:01 +02001012TEST_P(MAYBE_AudioDeviceTest, StartStopRecordingWithInternalRestart) {
henrika5b6afc02018-09-05 14:34:40 +02001013 SKIP_TEST_IF_NOT(requirements_satisfied());
1014 if (audio_layer() != AudioDeviceModule::kWindowsCoreAudio2) {
1015 return;
1016 }
1017 MockAudioTransport mock(TransportType::kRecord);
1018 mock.HandleCallbacks(event(), nullptr, kNumCallbacks);
1019 EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(), _, _, _, _, Ge(0u), 0, _,
1020 false, _))
1021 .Times(AtLeast(kNumCallbacks));
1022 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
1023 StartRecording();
1024 event()->Wait(kTestTimeOutInMilliseconds);
1025 EXPECT_TRUE(audio_device()->Recording());
1026 // Restart recording but without stopping the internal audio thread.
1027 // This procedure uses a non-public test API and it emulates what happens
1028 // inside the ADM when e.g. a device is removed.
1029 EXPECT_EQ(0, audio_device()->RestartRecordingInternally());
1030
1031 // Run basic tests of public APIs while a restart attempt is active.
1032 // These calls should now be very thin and not trigger any new actions.
1033 EXPECT_EQ(-1, audio_device()->StopRecording());
1034 EXPECT_TRUE(audio_device()->Recording());
1035 EXPECT_TRUE(audio_device()->RecordingIsInitialized());
1036 EXPECT_EQ(0, audio_device()->InitRecording());
1037 EXPECT_EQ(0, audio_device()->StartRecording());
1038
1039 // Wait until audio has restarted and a new sequence of audio callbacks
1040 // becomes active.
1041 // TODO(henrika): is it possible to verify that the internal state transition
1042 // is Stop->Init->Start?
1043 ASSERT_TRUE(Mock::VerifyAndClearExpectations(&mock));
1044 mock.ResetCallbackCounters();
1045 EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(), _, _, _, _, Ge(0u), 0, _,
1046 false, _))
1047 .Times(AtLeast(kNumCallbacks));
1048 event()->Wait(kTestTimeOutInMilliseconds);
1049 EXPECT_TRUE(audio_device()->Recording());
1050 // Stop recording and the audio thread after successful internal restart.
1051 StopRecording();
Yves Gereyb93a2452019-07-19 22:46:13 +02001052 PreTearDown();
henrika5b6afc02018-09-05 14:34:40 +02001053}
1054#endif // #ifdef WEBRTC_WIN
1055
henrikaf2f91fa2017-03-17 04:26:22 -07001056// Start playout and verify that the native audio layer starts asking for real
1057// audio samples to play out using the NeedMorePlayData() callback.
1058// Note that we can't add expectations on audio parameters in EXPECT_CALL
1059// since parameter are not provided in the each callback. We therefore test and
1060// verify the parameters in the fake audio transport implementation instead.
Yves Gereyff060ee2019-09-11 15:53:01 +02001061TEST_P(MAYBE_AudioDeviceTest, StartPlayoutVerifyCallbacks) {
henrikaf2f91fa2017-03-17 04:26:22 -07001062 SKIP_TEST_IF_NOT(requirements_satisfied());
1063 MockAudioTransport mock(TransportType::kPlay);
henrikae24991d2017-04-06 01:14:23 -07001064 mock.HandleCallbacks(event(), nullptr, kNumCallbacks);
henrikaf2f91fa2017-03-17 04:26:22 -07001065 EXPECT_CALL(mock, NeedMorePlayData(_, _, _, _, NotNull(), _, _, _))
1066 .Times(AtLeast(kNumCallbacks));
1067 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
1068 StartPlayout();
1069 event()->Wait(kTestTimeOutInMilliseconds);
1070 StopPlayout();
Yves Gerey412282a2019-07-22 21:15:22 +02001071 PreTearDown();
henrikaf2f91fa2017-03-17 04:26:22 -07001072}
1073
Yves Gerey704c8c42019-08-13 22:32:46 +02001074// Don't run these tests in combination with sanitizers.
1075// They are already flaky *without* sanitizers.
1076// Sanitizers seem to increase flakiness (which brings noise),
1077// without reporting anything.
1078// TODO(webrtc:10867): Re-enable when flakiness fixed.
1079#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
1080 defined(THREAD_SANITIZER)
1081#define MAYBE_StartRecordingVerifyCallbacks \
1082 DISABLED_StartRecordingVerifyCallbacks
1083#define MAYBE_StartPlayoutAndRecordingVerifyCallbacks \
1084 DISABLED_StartPlayoutAndRecordingVerifyCallbacks
1085#else
1086#define MAYBE_StartRecordingVerifyCallbacks StartRecordingVerifyCallbacks
1087#define MAYBE_StartPlayoutAndRecordingVerifyCallbacks \
1088 StartPlayoutAndRecordingVerifyCallbacks
1089#endif
1090
henrikaf2f91fa2017-03-17 04:26:22 -07001091// Start recording and verify that the native audio layer starts providing real
1092// audio samples using the RecordedDataIsAvailable() callback.
Yves Gereyff060ee2019-09-11 15:53:01 +02001093TEST_P(MAYBE_AudioDeviceTest, MAYBE_StartRecordingVerifyCallbacks) {
henrikaf2f91fa2017-03-17 04:26:22 -07001094 SKIP_TEST_IF_NOT(requirements_satisfied());
1095 MockAudioTransport mock(TransportType::kRecord);
henrikae24991d2017-04-06 01:14:23 -07001096 mock.HandleCallbacks(event(), nullptr, kNumCallbacks);
henrikaf2f91fa2017-03-17 04:26:22 -07001097 EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(), _, _, _, _, Ge(0u), 0, _,
1098 false, _))
1099 .Times(AtLeast(kNumCallbacks));
1100 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
1101 StartRecording();
1102 event()->Wait(kTestTimeOutInMilliseconds);
1103 StopRecording();
Yves Gereyb93a2452019-07-19 22:46:13 +02001104 PreTearDown();
henrikaf2f91fa2017-03-17 04:26:22 -07001105}
1106
1107// Start playout and recording (full-duplex audio) and verify that audio is
1108// active in both directions.
Yves Gereyff060ee2019-09-11 15:53:01 +02001109TEST_P(MAYBE_AudioDeviceTest, MAYBE_StartPlayoutAndRecordingVerifyCallbacks) {
henrikaf2f91fa2017-03-17 04:26:22 -07001110 SKIP_TEST_IF_NOT(requirements_satisfied());
1111 MockAudioTransport mock(TransportType::kPlayAndRecord);
henrikae24991d2017-04-06 01:14:23 -07001112 mock.HandleCallbacks(event(), nullptr, kNumCallbacks);
henrikaf2f91fa2017-03-17 04:26:22 -07001113 EXPECT_CALL(mock, NeedMorePlayData(_, _, _, _, NotNull(), _, _, _))
1114 .Times(AtLeast(kNumCallbacks));
1115 EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(), _, _, _, _, Ge(0u), 0, _,
1116 false, _))
1117 .Times(AtLeast(kNumCallbacks));
1118 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
1119 StartPlayout();
1120 StartRecording();
1121 event()->Wait(kTestTimeOutInMilliseconds);
1122 StopRecording();
1123 StopPlayout();
Yves Gereyb93a2452019-07-19 22:46:13 +02001124 PreTearDown();
henrikaf2f91fa2017-03-17 04:26:22 -07001125}
1126
henrikae24991d2017-04-06 01:14:23 -07001127// Start playout and recording and store recorded data in an intermediate FIFO
1128// buffer from which the playout side then reads its samples in the same order
1129// as they were stored. Under ideal circumstances, a callback sequence would
1130// look like: ...+-+-+-+-+-+-+-..., where '+' means 'packet recorded' and '-'
1131// means 'packet played'. Under such conditions, the FIFO would contain max 1,
1132// with an average somewhere in (0,1) depending on how long the packets are
1133// buffered. However, under more realistic conditions, the size
1134// of the FIFO will vary more due to an unbalance between the two sides.
1135// This test tries to verify that the device maintains a balanced callback-
1136// sequence by running in loopback for a few seconds while measuring the size
1137// (max and average) of the FIFO. The size of the FIFO is increased by the
1138// recording side and decreased by the playout side.
Yves Gereyff060ee2019-09-11 15:53:01 +02001139TEST_P(MAYBE_AudioDeviceTest, RunPlayoutAndRecordingInFullDuplex) {
henrikae24991d2017-04-06 01:14:23 -07001140 SKIP_TEST_IF_NOT(requirements_satisfied());
1141 NiceMock<MockAudioTransport> mock(TransportType::kPlayAndRecord);
1142 FifoAudioStream audio_stream;
1143 mock.HandleCallbacks(event(), &audio_stream,
1144 kFullDuplexTimeInSec * kNumCallbacksPerSecond);
1145 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
henrikaeb98c722018-03-20 12:54:07 +01001146 // Run both sides using the same channel configuration to avoid conversions
1147 // between mono/stereo while running in full duplex mode. Also, some devices
1148 // (mainly on Windows) do not support mono.
1149 EXPECT_EQ(0, audio_device()->SetStereoPlayout(true));
1150 EXPECT_EQ(0, audio_device()->SetStereoRecording(true));
Gustaf Ullberg102b7282019-06-03 15:03:02 +02001151 // Mute speakers to prevent howling.
1152 EXPECT_EQ(0, audio_device()->SetSpeakerVolume(0));
henrikae24991d2017-04-06 01:14:23 -07001153 StartPlayout();
1154 StartRecording();
henrika714e5cd2017-04-20 08:03:11 -07001155 event()->Wait(static_cast<int>(
1156 std::max(kTestTimeOutInMilliseconds, 1000 * kFullDuplexTimeInSec)));
henrikae24991d2017-04-06 01:14:23 -07001157 StopRecording();
1158 StopPlayout();
Yves Gerey412282a2019-07-22 21:15:22 +02001159 // Avoid concurrent access to audio_stream.
1160 PreTearDown();
henrikae24991d2017-04-06 01:14:23 -07001161 // This thresholds is set rather high to accommodate differences in hardware
1162 // in several devices. The main idea is to capture cases where a very large
henrikab6ca7212017-10-06 12:47:52 +02001163 // latency is built up. See http://bugs.webrtc.org/7744 for examples on
1164 // bots where relatively large average latencies can happen.
1165 EXPECT_LE(audio_stream.average_size(), 25u);
henrikae24991d2017-04-06 01:14:23 -07001166 PRINT("\n");
1167}
1168
henrika5b6afc02018-09-05 14:34:40 +02001169// Runs audio in full duplex until user hits Enter. Intended as a manual test
1170// to ensure that the audio quality is good and that real device switches works
1171// as intended.
Yves Gereyff060ee2019-09-11 15:53:01 +02001172TEST_P(MAYBE_AudioDeviceTest,
henrika5b6afc02018-09-05 14:34:40 +02001173 DISABLED_RunPlayoutAndRecordingInFullDuplexAndWaitForEnterKey) {
1174 SKIP_TEST_IF_NOT(requirements_satisfied());
1175 if (audio_layer() != AudioDeviceModule::kWindowsCoreAudio2) {
1176 return;
1177 }
1178 NiceMock<MockAudioTransport> mock(TransportType::kPlayAndRecord);
1179 FifoAudioStream audio_stream;
1180 mock.HandleCallbacks(&audio_stream);
1181 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
1182 EXPECT_EQ(0, audio_device()->SetStereoPlayout(true));
1183 EXPECT_EQ(0, audio_device()->SetStereoRecording(true));
1184 // Ensure that the sample rate for both directions are identical so that we
1185 // always can listen to our own voice. Will lead to rate conversion (and
1186 // higher latency) if the native sample rate is not 48kHz.
1187 EXPECT_EQ(0, audio_device()->SetPlayoutSampleRate(48000));
1188 EXPECT_EQ(0, audio_device()->SetRecordingSampleRate(48000));
1189 StartPlayout();
1190 StartRecording();
1191 do {
1192 PRINT("Loopback audio is active at 48kHz. Press Enter to stop.\n");
1193 } while (getchar() != '\n');
1194 StopRecording();
1195 StopPlayout();
Yves Gereyb93a2452019-07-19 22:46:13 +02001196 PreTearDown();
henrika5b6afc02018-09-05 14:34:40 +02001197}
1198
henrika714e5cd2017-04-20 08:03:11 -07001199// Measures loopback latency and reports the min, max and average values for
1200// a full duplex audio session.
1201// The latency is measured like so:
1202// - Insert impulses periodically on the output side.
1203// - Detect the impulses on the input side.
1204// - Measure the time difference between the transmit time and receive time.
1205// - Store time differences in a vector and calculate min, max and average.
1206// This test needs the '--gtest_also_run_disabled_tests' flag to run and also
1207// some sort of audio feedback loop. E.g. a headset where the mic is placed
1208// close to the speaker to ensure highest possible echo. It is also recommended
1209// to run the test at highest possible output volume.
Yves Gereyff060ee2019-09-11 15:53:01 +02001210TEST_P(MAYBE_AudioDeviceTest, DISABLED_MeasureLoopbackLatency) {
henrika714e5cd2017-04-20 08:03:11 -07001211 SKIP_TEST_IF_NOT(requirements_satisfied());
1212 NiceMock<MockAudioTransport> mock(TransportType::kPlayAndRecord);
1213 LatencyAudioStream audio_stream;
1214 mock.HandleCallbacks(event(), &audio_stream,
1215 kMeasureLatencyTimeInSec * kNumCallbacksPerSecond);
1216 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
henrikaeb98c722018-03-20 12:54:07 +01001217 EXPECT_EQ(0, audio_device()->SetStereoPlayout(true));
1218 EXPECT_EQ(0, audio_device()->SetStereoRecording(true));
henrika714e5cd2017-04-20 08:03:11 -07001219 StartPlayout();
1220 StartRecording();
1221 event()->Wait(static_cast<int>(
1222 std::max(kTestTimeOutInMilliseconds, 1000 * kMeasureLatencyTimeInSec)));
1223 StopRecording();
1224 StopPlayout();
Yves Gerey412282a2019-07-22 21:15:22 +02001225 // Avoid concurrent access to audio_stream.
1226 PreTearDown();
henrikac7d93582018-09-14 15:37:34 +02001227 // Verify that a sufficient number of transmitted impulses are detected.
1228 EXPECT_GE(audio_stream.num_latency_values(),
henrika714e5cd2017-04-20 08:03:11 -07001229 static_cast<size_t>(
henrikac7d93582018-09-14 15:37:34 +02001230 kImpulseFrequencyInHz * kMeasureLatencyTimeInSec - 2));
henrika714e5cd2017-04-20 08:03:11 -07001231 // Print out min, max and average delay values for debugging purposes.
1232 audio_stream.PrintResults();
1233}
1234
henrikaec9c7452018-06-08 16:10:03 +02001235#ifdef WEBRTC_WIN
1236// Test two different audio layers (or rather two different Core Audio
1237// implementations) for Windows.
Mirko Bonadeic84f6612019-01-31 12:20:57 +01001238INSTANTIATE_TEST_SUITE_P(
henrikaec9c7452018-06-08 16:10:03 +02001239 AudioLayerWin,
Yves Gereyff060ee2019-09-11 15:53:01 +02001240 MAYBE_AudioDeviceTest,
henrikaec9c7452018-06-08 16:10:03 +02001241 ::testing::Values(AudioDeviceModule::kPlatformDefaultAudio,
1242 AudioDeviceModule::kWindowsCoreAudio2));
1243#else
1244// For all platforms but Windows, only test the default audio layer.
Mirko Bonadeic84f6612019-01-31 12:20:57 +01001245INSTANTIATE_TEST_SUITE_P(
henrikaec9c7452018-06-08 16:10:03 +02001246 AudioLayer,
Yves Gereyff060ee2019-09-11 15:53:01 +02001247 MAYBE_AudioDeviceTest,
henrikaec9c7452018-06-08 16:10:03 +02001248 ::testing::Values(AudioDeviceModule::kPlatformDefaultAudio));
1249#endif
1250
henrikaf2f91fa2017-03-17 04:26:22 -07001251} // namespace webrtc