blob: c8cb4381582ef4d2830157e62a3542deb4080bca [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"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020028#include "rtc_base/event.h"
29#include "rtc_base/logging.h"
Karl Wiberge40468b2017-11-22 10:42:26 +010030#include "rtc_base/numerics/safe_conversions.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020031#include "rtc_base/race_checker.h"
Markus Handell5f612822020-07-08 10:13:20 +020032#include "rtc_base/synchronization/mutex.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"
Markus Handell5f612822020-07-08 10:13:20 +020042
henrikaec9c7452018-06-08 16:10:03 +020043#endif
henrikaf2f91fa2017-03-17 04:26:22 -070044
45using ::testing::_;
46using ::testing::AtLeast;
47using ::testing::Ge;
48using ::testing::Invoke;
Jonas Olssona4d87372019-07-05 19:08:33 +020049using ::testing::Mock;
henrikaf2f91fa2017-03-17 04:26:22 -070050using ::testing::NiceMock;
51using ::testing::NotNull;
52
53namespace webrtc {
54namespace {
55
henrika5773ad32018-09-21 14:53:10 +020056// Using a #define for AUDIO_DEVICE since we will call *different* versions of
57// the ADM functions, depending on the ID type.
58#if defined(WEBRTC_WIN)
59#define AUDIO_DEVICE_ID (AudioDeviceModule::WindowsDeviceType::kDefaultDevice)
60#else
61#define AUDIO_DEVICE_ID (0u)
62#endif // defined(WEBRTC_WIN)
63
henrikae24991d2017-04-06 01:14:23 -070064// #define ENABLE_DEBUG_PRINTF
65#ifdef ENABLE_DEBUG_PRINTF
66#define PRINTD(...) fprintf(stderr, __VA_ARGS__);
67#else
68#define PRINTD(...) ((void)0)
69#endif
70#define PRINT(...) fprintf(stderr, __VA_ARGS__);
71
Yves Gerey1afe6572019-07-18 22:01:09 +020072// Don't run these tests if audio-related requirements are not met.
Yves Gereyee0550c2019-07-17 21:41:59 +020073#define SKIP_TEST_IF_NOT(requirements_satisfied) \
74 do { \
75 if (!requirements_satisfied) { \
76 GTEST_SKIP() << "Skipped. No audio device found."; \
77 } \
henrikaf2f91fa2017-03-17 04:26:22 -070078 } while (false)
henrikaf2f91fa2017-03-17 04:26:22 -070079
80// Number of callbacks (input or output) the tests waits for before we set
81// an event indicating that the test was OK.
henrikae24991d2017-04-06 01:14:23 -070082static constexpr size_t kNumCallbacks = 10;
henrikaf2f91fa2017-03-17 04:26:22 -070083// Max amount of time we wait for an event to be set while counting callbacks.
henrika714e5cd2017-04-20 08:03:11 -070084static constexpr size_t kTestTimeOutInMilliseconds = 10 * 1000;
henrikae24991d2017-04-06 01:14:23 -070085// Average number of audio callbacks per second assuming 10ms packet size.
86static constexpr size_t kNumCallbacksPerSecond = 100;
87// Run the full-duplex test during this time (unit is in seconds).
henrika714e5cd2017-04-20 08:03:11 -070088static constexpr size_t kFullDuplexTimeInSec = 5;
89// Length of round-trip latency measurements. Number of deteced impulses
90// shall be kImpulseFrequencyInHz * kMeasureLatencyTimeInSec - 1 since the
91// last transmitted pulse is not used.
92static constexpr size_t kMeasureLatencyTimeInSec = 10;
93// Sets the number of impulses per second in the latency test.
94static constexpr size_t kImpulseFrequencyInHz = 1;
95// Utilized in round-trip latency measurements to avoid capturing noise samples.
96static constexpr int kImpulseThreshold = 1000;
henrikaf2f91fa2017-03-17 04:26:22 -070097
98enum class TransportType {
99 kInvalid,
100 kPlay,
101 kRecord,
102 kPlayAndRecord,
103};
henrikae24991d2017-04-06 01:14:23 -0700104
105// Interface for processing the audio stream. Real implementations can e.g.
106// run audio in loopback, read audio from a file or perform latency
107// measurements.
108class AudioStream {
109 public:
henrikaeb98c722018-03-20 12:54:07 +0100110 virtual void Write(rtc::ArrayView<const int16_t> source) = 0;
111 virtual void Read(rtc::ArrayView<int16_t> destination) = 0;
henrikae24991d2017-04-06 01:14:23 -0700112
113 virtual ~AudioStream() = default;
114};
115
henrika714e5cd2017-04-20 08:03:11 -0700116// Converts index corresponding to position within a 10ms buffer into a
117// delay value in milliseconds.
118// Example: index=240, frames_per_10ms_buffer=480 => 5ms as output.
119int IndexToMilliseconds(size_t index, size_t frames_per_10ms_buffer) {
120 return rtc::checked_cast<int>(
121 10.0 * (static_cast<double>(index) / frames_per_10ms_buffer) + 0.5);
122}
123
henrikaf2f91fa2017-03-17 04:26:22 -0700124} // namespace
125
henrikae24991d2017-04-06 01:14:23 -0700126// Simple first in first out (FIFO) class that wraps a list of 16-bit audio
127// buffers of fixed size and allows Write and Read operations. The idea is to
128// store recorded audio buffers (using Write) and then read (using Read) these
129// stored buffers with as short delay as possible when the audio layer needs
130// data to play out. The number of buffers in the FIFO will stabilize under
131// normal conditions since there will be a balance between Write and Read calls.
132// The container is a std::list container and access is protected with a lock
133// since both sides (playout and recording) are driven by its own thread.
134// Note that, we know by design that the size of the audio buffer will not
henrikac7d93582018-09-14 15:37:34 +0200135// change over time and that both sides will in most cases use the same size.
henrikae24991d2017-04-06 01:14:23 -0700136class FifoAudioStream : public AudioStream {
137 public:
henrikaeb98c722018-03-20 12:54:07 +0100138 void Write(rtc::ArrayView<const int16_t> source) override {
henrikae24991d2017-04-06 01:14:23 -0700139 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
140 const size_t size = [&] {
Markus Handell5f612822020-07-08 10:13:20 +0200141 MutexLock lock(&lock_);
henrikae24991d2017-04-06 01:14:23 -0700142 fifo_.push_back(Buffer16(source.data(), source.size()));
143 return fifo_.size();
144 }();
145 if (size > max_size_) {
146 max_size_ = size;
147 }
148 // Add marker once per second to signal that audio is active.
149 if (write_count_++ % 100 == 0) {
henrikad8c6ec42019-07-18 15:17:28 +0200150 PRINTD(".");
henrikae24991d2017-04-06 01:14:23 -0700151 }
152 written_elements_ += size;
153 }
154
henrikaeb98c722018-03-20 12:54:07 +0100155 void Read(rtc::ArrayView<int16_t> destination) override {
Markus Handell5f612822020-07-08 10:13:20 +0200156 MutexLock lock(&lock_);
henrikae24991d2017-04-06 01:14:23 -0700157 if (fifo_.empty()) {
158 std::fill(destination.begin(), destination.end(), 0);
159 } else {
160 const Buffer16& buffer = fifo_.front();
henrikac7d93582018-09-14 15:37:34 +0200161 if (buffer.size() == destination.size()) {
162 // Default case where input and output uses same sample rate and
163 // channel configuration. No conversion is needed.
164 std::copy(buffer.begin(), buffer.end(), destination.begin());
165 } else if (destination.size() == 2 * buffer.size()) {
166 // Recorded input signal in |buffer| is in mono. Do channel upmix to
167 // match stereo output (1 -> 2).
168 for (size_t i = 0; i < buffer.size(); ++i) {
169 destination[2 * i] = buffer[i];
170 destination[2 * i + 1] = buffer[i];
171 }
172 } else if (buffer.size() == 2 * destination.size()) {
173 // Recorded input signal in |buffer| is in stereo. Do channel downmix
174 // to match mono output (2 -> 1).
175 for (size_t i = 0; i < destination.size(); ++i) {
176 destination[i] =
177 (static_cast<int32_t>(buffer[2 * i]) + buffer[2 * i + 1]) / 2;
178 }
179 } else {
180 RTC_NOTREACHED() << "Required conversion is not support";
181 }
henrikae24991d2017-04-06 01:14:23 -0700182 fifo_.pop_front();
183 }
184 }
185
186 size_t size() const {
Markus Handell5f612822020-07-08 10:13:20 +0200187 MutexLock lock(&lock_);
henrikae24991d2017-04-06 01:14:23 -0700188 return fifo_.size();
189 }
190
191 size_t max_size() const {
192 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
193 return max_size_;
194 }
195
196 size_t average_size() const {
197 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
198 return 0.5 + static_cast<float>(written_elements_ / write_count_);
199 }
200
201 using Buffer16 = rtc::BufferT<int16_t>;
202
Markus Handell5f612822020-07-08 10:13:20 +0200203 mutable Mutex lock_;
henrikae24991d2017-04-06 01:14:23 -0700204 rtc::RaceChecker race_checker_;
205
danilchap56359be2017-09-07 07:53:45 -0700206 std::list<Buffer16> fifo_ RTC_GUARDED_BY(lock_);
207 size_t write_count_ RTC_GUARDED_BY(race_checker_) = 0;
208 size_t max_size_ RTC_GUARDED_BY(race_checker_) = 0;
209 size_t written_elements_ RTC_GUARDED_BY(race_checker_) = 0;
henrikae24991d2017-04-06 01:14:23 -0700210};
211
henrika714e5cd2017-04-20 08:03:11 -0700212// Inserts periodic impulses and measures the latency between the time of
213// transmission and time of receiving the same impulse.
214class LatencyAudioStream : public AudioStream {
215 public:
216 LatencyAudioStream() {
217 // Delay thread checkers from being initialized until first callback from
218 // respective thread.
Sebastian Janssonc01367d2019-04-08 15:20:44 +0200219 read_thread_checker_.Detach();
220 write_thread_checker_.Detach();
henrika714e5cd2017-04-20 08:03:11 -0700221 }
222
223 // Insert periodic impulses in first two samples of |destination|.
henrikaeb98c722018-03-20 12:54:07 +0100224 void Read(rtc::ArrayView<int16_t> destination) override {
henrika714e5cd2017-04-20 08:03:11 -0700225 RTC_DCHECK_RUN_ON(&read_thread_checker_);
henrika714e5cd2017-04-20 08:03:11 -0700226 if (read_count_ == 0) {
227 PRINT("[");
228 }
229 read_count_++;
230 std::fill(destination.begin(), destination.end(), 0);
231 if (read_count_ % (kNumCallbacksPerSecond / kImpulseFrequencyInHz) == 0) {
232 PRINT(".");
233 {
Markus Handell5f612822020-07-08 10:13:20 +0200234 MutexLock lock(&lock_);
henrika714e5cd2017-04-20 08:03:11 -0700235 if (!pulse_time_) {
Oskar Sundbom6ad9f262017-11-16 10:53:39 +0100236 pulse_time_ = rtc::TimeMillis();
henrika714e5cd2017-04-20 08:03:11 -0700237 }
238 }
239 constexpr int16_t impulse = std::numeric_limits<int16_t>::max();
240 std::fill_n(destination.begin(), 2, impulse);
241 }
242 }
243
244 // Detect received impulses in |source|, derive time between transmission and
245 // detection and add the calculated delay to list of latencies.
henrikaeb98c722018-03-20 12:54:07 +0100246 void Write(rtc::ArrayView<const int16_t> source) override {
henrika714e5cd2017-04-20 08:03:11 -0700247 RTC_DCHECK_RUN_ON(&write_thread_checker_);
248 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
Markus Handell5f612822020-07-08 10:13:20 +0200249 MutexLock lock(&lock_);
henrika714e5cd2017-04-20 08:03:11 -0700250 write_count_++;
251 if (!pulse_time_) {
252 // Avoid detection of new impulse response until a new impulse has
253 // been transmitted (sets |pulse_time_| to value larger than zero).
254 return;
255 }
256 // Find index (element position in vector) of the max element.
257 const size_t index_of_max =
258 std::max_element(source.begin(), source.end()) - source.begin();
259 // Derive time between transmitted pulse and received pulse if the level
260 // is high enough (removes noise).
261 const size_t max = source[index_of_max];
262 if (max > kImpulseThreshold) {
263 PRINTD("(%zu, %zu)", max, index_of_max);
264 int64_t now_time = rtc::TimeMillis();
265 int extra_delay = IndexToMilliseconds(index_of_max, source.size());
266 PRINTD("[%d]", rtc::checked_cast<int>(now_time - pulse_time_));
267 PRINTD("[%d]", extra_delay);
268 // Total latency is the difference between transmit time and detection
269 // tome plus the extra delay within the buffer in which we detected the
270 // received impulse. It is transmitted at sample 0 but can be received
271 // at sample N where N > 0. The term |extra_delay| accounts for N and it
272 // is a value between 0 and 10ms.
273 latencies_.push_back(now_time - *pulse_time_ + extra_delay);
274 pulse_time_.reset();
275 } else {
276 PRINTD("-");
277 }
278 }
279
280 size_t num_latency_values() const {
281 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
282 return latencies_.size();
283 }
284
285 int min_latency() const {
286 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
287 if (latencies_.empty())
288 return 0;
289 return *std::min_element(latencies_.begin(), latencies_.end());
290 }
291
292 int max_latency() const {
293 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
294 if (latencies_.empty())
295 return 0;
296 return *std::max_element(latencies_.begin(), latencies_.end());
297 }
298
299 int average_latency() const {
300 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
301 if (latencies_.empty())
302 return 0;
303 return 0.5 + static_cast<double>(
304 std::accumulate(latencies_.begin(), latencies_.end(), 0)) /
305 latencies_.size();
306 }
307
308 void PrintResults() const {
309 RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
310 PRINT("] ");
311 for (auto it = latencies_.begin(); it != latencies_.end(); ++it) {
312 PRINTD("%d ", *it);
313 }
314 PRINT("\n");
315 PRINT("[..........] [min, max, avg]=[%d, %d, %d] ms\n", min_latency(),
316 max_latency(), average_latency());
317 }
318
Markus Handell5f612822020-07-08 10:13:20 +0200319 Mutex lock_;
henrika714e5cd2017-04-20 08:03:11 -0700320 rtc::RaceChecker race_checker_;
321 rtc::ThreadChecker read_thread_checker_;
322 rtc::ThreadChecker write_thread_checker_;
323
Danil Chapovalov196100e2018-06-21 10:17:24 +0200324 absl::optional<int64_t> pulse_time_ RTC_GUARDED_BY(lock_);
danilchap56359be2017-09-07 07:53:45 -0700325 std::vector<int> latencies_ RTC_GUARDED_BY(race_checker_);
Niels Möller1e062892018-02-07 10:18:32 +0100326 size_t read_count_ RTC_GUARDED_BY(read_thread_checker_) = 0;
327 size_t write_count_ RTC_GUARDED_BY(write_thread_checker_) = 0;
henrika714e5cd2017-04-20 08:03:11 -0700328};
329
henrikaf2f91fa2017-03-17 04:26:22 -0700330// Mocks the AudioTransport object and proxies actions for the two callbacks
331// (RecordedDataIsAvailable and NeedMorePlayData) to different implementations
332// of AudioStreamInterface.
333class MockAudioTransport : public test::MockAudioTransport {
334 public:
335 explicit MockAudioTransport(TransportType type) : type_(type) {}
336 ~MockAudioTransport() {}
337
338 // Set default actions of the mock object. We are delegating to fake
339 // implementation where the number of callbacks is counted and an event
340 // is set after a certain number of callbacks. Audio parameters are also
341 // checked.
henrikae24991d2017-04-06 01:14:23 -0700342 void HandleCallbacks(rtc::Event* event,
343 AudioStream* audio_stream,
344 int num_callbacks) {
henrikaf2f91fa2017-03-17 04:26:22 -0700345 event_ = event;
henrikae24991d2017-04-06 01:14:23 -0700346 audio_stream_ = audio_stream;
henrikaf2f91fa2017-03-17 04:26:22 -0700347 num_callbacks_ = num_callbacks;
348 if (play_mode()) {
349 ON_CALL(*this, NeedMorePlayData(_, _, _, _, _, _, _, _))
350 .WillByDefault(
351 Invoke(this, &MockAudioTransport::RealNeedMorePlayData));
352 }
353 if (rec_mode()) {
354 ON_CALL(*this, RecordedDataIsAvailable(_, _, _, _, _, _, _, _, _, _))
355 .WillByDefault(
356 Invoke(this, &MockAudioTransport::RealRecordedDataIsAvailable));
357 }
358 }
359
henrika5b6afc02018-09-05 14:34:40 +0200360 // Special constructor used in manual tests where the user wants to run audio
361 // until e.g. a keyboard key is pressed. The event flag is set to nullptr by
362 // default since it is up to the user to stop the test. See e.g.
363 // DISABLED_RunPlayoutAndRecordingInFullDuplexAndWaitForEnterKey().
364 void HandleCallbacks(AudioStream* audio_stream) {
365 HandleCallbacks(nullptr, audio_stream, 0);
366 }
367
henrikaf2f91fa2017-03-17 04:26:22 -0700368 int32_t RealRecordedDataIsAvailable(const void* audio_buffer,
369 const size_t samples_per_channel,
370 const size_t bytes_per_frame,
371 const size_t channels,
372 const uint32_t sample_rate,
373 const uint32_t total_delay_ms,
374 const int32_t clock_drift,
375 const uint32_t current_mic_level,
376 const bool typing_status,
377 uint32_t& new_mic_level) {
378 EXPECT_TRUE(rec_mode()) << "No test is expecting these callbacks.";
henrikaf2f91fa2017-03-17 04:26:22 -0700379 // Store audio parameters once in the first callback. For all other
380 // callbacks, verify that the provided audio parameters are maintained and
381 // that each callback corresponds to 10ms for any given sample rate.
382 if (!record_parameters_.is_complete()) {
383 record_parameters_.reset(sample_rate, channels, samples_per_channel);
384 } else {
385 EXPECT_EQ(samples_per_channel, record_parameters_.frames_per_buffer());
386 EXPECT_EQ(bytes_per_frame, record_parameters_.GetBytesPerFrame());
387 EXPECT_EQ(channels, record_parameters_.channels());
388 EXPECT_EQ(static_cast<int>(sample_rate),
389 record_parameters_.sample_rate());
390 EXPECT_EQ(samples_per_channel,
391 record_parameters_.frames_per_10ms_buffer());
392 }
henrika78e0ac12018-09-27 16:23:21 +0200393 {
Markus Handell5f612822020-07-08 10:13:20 +0200394 MutexLock lock(&lock_);
henrika78e0ac12018-09-27 16:23:21 +0200395 rec_count_++;
396 }
henrikae24991d2017-04-06 01:14:23 -0700397 // Write audio data to audio stream object if one has been injected.
398 if (audio_stream_) {
399 audio_stream_->Write(
400 rtc::MakeArrayView(static_cast<const int16_t*>(audio_buffer),
henrikaeb98c722018-03-20 12:54:07 +0100401 samples_per_channel * channels));
henrikae24991d2017-04-06 01:14:23 -0700402 }
henrikaf2f91fa2017-03-17 04:26:22 -0700403 // Signal the event after given amount of callbacks.
henrika5b6afc02018-09-05 14:34:40 +0200404 if (event_ && ReceivedEnoughCallbacks()) {
henrikaf2f91fa2017-03-17 04:26:22 -0700405 event_->Set();
406 }
407 return 0;
408 }
409
410 int32_t RealNeedMorePlayData(const size_t samples_per_channel,
411 const size_t bytes_per_frame,
412 const size_t channels,
413 const uint32_t sample_rate,
414 void* audio_buffer,
henrikaeb98c722018-03-20 12:54:07 +0100415 size_t& samples_out,
henrikaf2f91fa2017-03-17 04:26:22 -0700416 int64_t* elapsed_time_ms,
417 int64_t* ntp_time_ms) {
418 EXPECT_TRUE(play_mode()) << "No test is expecting these callbacks.";
henrikaf2f91fa2017-03-17 04:26:22 -0700419 // Store audio parameters once in the first callback. For all other
420 // callbacks, verify that the provided audio parameters are maintained and
421 // that each callback corresponds to 10ms for any given sample rate.
422 if (!playout_parameters_.is_complete()) {
423 playout_parameters_.reset(sample_rate, channels, samples_per_channel);
424 } else {
425 EXPECT_EQ(samples_per_channel, playout_parameters_.frames_per_buffer());
426 EXPECT_EQ(bytes_per_frame, playout_parameters_.GetBytesPerFrame());
427 EXPECT_EQ(channels, playout_parameters_.channels());
428 EXPECT_EQ(static_cast<int>(sample_rate),
429 playout_parameters_.sample_rate());
430 EXPECT_EQ(samples_per_channel,
431 playout_parameters_.frames_per_10ms_buffer());
432 }
henrika78e0ac12018-09-27 16:23:21 +0200433 {
Markus Handell5f612822020-07-08 10:13:20 +0200434 MutexLock lock(&lock_);
henrika78e0ac12018-09-27 16:23:21 +0200435 play_count_++;
436 }
henrikaeb98c722018-03-20 12:54:07 +0100437 samples_out = samples_per_channel * channels;
henrikae24991d2017-04-06 01:14:23 -0700438 // Read audio data from audio stream object if one has been injected.
439 if (audio_stream_) {
henrikaeb98c722018-03-20 12:54:07 +0100440 audio_stream_->Read(rtc::MakeArrayView(
441 static_cast<int16_t*>(audio_buffer), samples_per_channel * channels));
henrikae24991d2017-04-06 01:14:23 -0700442 } else {
443 // Fill the audio buffer with zeros to avoid disturbing audio.
444 const size_t num_bytes = samples_per_channel * bytes_per_frame;
445 std::memset(audio_buffer, 0, num_bytes);
446 }
henrikaf2f91fa2017-03-17 04:26:22 -0700447 // Signal the event after given amount of callbacks.
henrika5b6afc02018-09-05 14:34:40 +0200448 if (event_ && ReceivedEnoughCallbacks()) {
henrikaf2f91fa2017-03-17 04:26:22 -0700449 event_->Set();
450 }
451 return 0;
452 }
453
454 bool ReceivedEnoughCallbacks() {
455 bool recording_done = false;
456 if (rec_mode()) {
Markus Handell5f612822020-07-08 10:13:20 +0200457 MutexLock lock(&lock_);
henrikaf2f91fa2017-03-17 04:26:22 -0700458 recording_done = rec_count_ >= num_callbacks_;
459 } else {
460 recording_done = true;
461 }
462 bool playout_done = false;
463 if (play_mode()) {
Markus Handell5f612822020-07-08 10:13:20 +0200464 MutexLock lock(&lock_);
henrikaf2f91fa2017-03-17 04:26:22 -0700465 playout_done = play_count_ >= num_callbacks_;
466 } else {
467 playout_done = true;
468 }
469 return recording_done && playout_done;
470 }
471
472 bool play_mode() const {
473 return type_ == TransportType::kPlay ||
474 type_ == TransportType::kPlayAndRecord;
475 }
476
477 bool rec_mode() const {
478 return type_ == TransportType::kRecord ||
479 type_ == TransportType::kPlayAndRecord;
480 }
481
henrika5b6afc02018-09-05 14:34:40 +0200482 void ResetCallbackCounters() {
Markus Handell5f612822020-07-08 10:13:20 +0200483 MutexLock lock(&lock_);
henrika5b6afc02018-09-05 14:34:40 +0200484 if (play_mode()) {
485 play_count_ = 0;
486 }
487 if (rec_mode()) {
488 rec_count_ = 0;
489 }
490 }
491
henrikaf2f91fa2017-03-17 04:26:22 -0700492 private:
Markus Handell5f612822020-07-08 10:13:20 +0200493 Mutex lock_;
henrikaf2f91fa2017-03-17 04:26:22 -0700494 TransportType type_ = TransportType::kInvalid;
495 rtc::Event* event_ = nullptr;
henrikae24991d2017-04-06 01:14:23 -0700496 AudioStream* audio_stream_ = nullptr;
henrikaf2f91fa2017-03-17 04:26:22 -0700497 size_t num_callbacks_ = 0;
henrika78e0ac12018-09-27 16:23:21 +0200498 size_t play_count_ RTC_GUARDED_BY(lock_) = 0;
499 size_t rec_count_ RTC_GUARDED_BY(lock_) = 0;
henrikaf2f91fa2017-03-17 04:26:22 -0700500 AudioParameters playout_parameters_;
501 AudioParameters record_parameters_;
502};
503
504// AudioDeviceTest test fixture.
Yves Gerey1afe6572019-07-18 22:01:09 +0200505
Yves Gereyff060ee2019-09-11 15:53:01 +0200506// bugs.webrtc.org/9808
507// Both the tests and the code under test are very old, unstaffed and not
508// a part of webRTC stack.
509// Here sanitizers make the tests hang, without providing usefull report.
510// So we are just disabling them, without intention to re-enable them.
511#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
512 defined(THREAD_SANITIZER) || defined(UNDEFINED_SANITIZER)
513#define MAYBE_AudioDeviceTest DISABLED_AudioDeviceTest
514#else
515#define MAYBE_AudioDeviceTest AudioDeviceTest
516#endif
517
518class MAYBE_AudioDeviceTest
henrikaec9c7452018-06-08 16:10:03 +0200519 : public ::testing::TestWithParam<webrtc::AudioDeviceModule::AudioLayer> {
henrikaf2f91fa2017-03-17 04:26:22 -0700520 protected:
Yves Gereyff060ee2019-09-11 15:53:01 +0200521 MAYBE_AudioDeviceTest()
Danil Chapovalov1c41be62019-04-01 09:16:12 +0200522 : audio_layer_(GetParam()),
523 task_queue_factory_(CreateDefaultTaskQueueFactory()) {
henrikaf2f91fa2017-03-17 04:26:22 -0700524 rtc::LogMessage::LogToDebug(rtc::LS_INFO);
525 // Add extra logging fields here if needed for debugging.
henrikaec9c7452018-06-08 16:10:03 +0200526 rtc::LogMessage::LogTimestamps();
527 rtc::LogMessage::LogThreads();
528 audio_device_ = CreateAudioDevice();
henrikaf2f91fa2017-03-17 04:26:22 -0700529 EXPECT_NE(audio_device_.get(), nullptr);
530 AudioDeviceModule::AudioLayer audio_layer;
maxmorin33bf69a2017-03-23 04:06:53 -0700531 int got_platform_audio_layer =
532 audio_device_->ActiveAudioLayer(&audio_layer);
henrika919dc2e2017-10-12 14:24:55 +0200533 // First, ensure that a valid audio layer can be activated.
534 if (got_platform_audio_layer != 0) {
henrikaf2f91fa2017-03-17 04:26:22 -0700535 requirements_satisfied_ = false;
536 }
henrika919dc2e2017-10-12 14:24:55 +0200537 // Next, verify that the ADM can be initialized.
henrikaf2f91fa2017-03-17 04:26:22 -0700538 if (requirements_satisfied_) {
henrika919dc2e2017-10-12 14:24:55 +0200539 requirements_satisfied_ = (audio_device_->Init() == 0);
540 }
541 // Finally, ensure that at least one valid device exists in each direction.
542 if (requirements_satisfied_) {
henrikaf2f91fa2017-03-17 04:26:22 -0700543 const int16_t num_playout_devices = audio_device_->PlayoutDevices();
544 const int16_t num_record_devices = audio_device_->RecordingDevices();
545 requirements_satisfied_ =
546 num_playout_devices > 0 && num_record_devices > 0;
547 }
henrikaf2f91fa2017-03-17 04:26:22 -0700548 if (requirements_satisfied_) {
henrika5773ad32018-09-21 14:53:10 +0200549 EXPECT_EQ(0, audio_device_->SetPlayoutDevice(AUDIO_DEVICE_ID));
henrikaf2f91fa2017-03-17 04:26:22 -0700550 EXPECT_EQ(0, audio_device_->InitSpeaker());
henrikaf2f91fa2017-03-17 04:26:22 -0700551 EXPECT_EQ(0, audio_device_->StereoPlayoutIsAvailable(&stereo_playout_));
552 EXPECT_EQ(0, audio_device_->SetStereoPlayout(stereo_playout_));
henrika5773ad32018-09-21 14:53:10 +0200553 EXPECT_EQ(0, audio_device_->SetRecordingDevice(AUDIO_DEVICE_ID));
554 EXPECT_EQ(0, audio_device_->InitMicrophone());
henrika0238ba82017-03-28 04:38:29 -0700555 // Avoid asking for input stereo support and always record in mono
556 // since asking can cause issues in combination with remote desktop.
557 // See https://bugs.chromium.org/p/webrtc/issues/detail?id=7397 for
558 // details.
559 EXPECT_EQ(0, audio_device_->SetStereoRecording(false));
henrikaf2f91fa2017-03-17 04:26:22 -0700560 }
561 }
562
Yves Gereyb93a2452019-07-19 22:46:13 +0200563 // This is needed by all tests using MockAudioTransport,
564 // since there is no way to unregister it.
565 // Without Terminate(), audio_device would still accesses
566 // the destructed mock via "webrtc_audio_module_rec_thread".
567 // An alternative would be for the mock to outlive audio_device.
568 void PreTearDown() { EXPECT_EQ(0, audio_device_->Terminate()); }
569
Yves Gereyff060ee2019-09-11 15:53:01 +0200570 virtual ~MAYBE_AudioDeviceTest() {
henrikaf2f91fa2017-03-17 04:26:22 -0700571 if (audio_device_) {
572 EXPECT_EQ(0, audio_device_->Terminate());
573 }
574 }
575
576 bool requirements_satisfied() const { return requirements_satisfied_; }
577 rtc::Event* event() { return &event_; }
henrika5b6afc02018-09-05 14:34:40 +0200578 AudioDeviceModule::AudioLayer audio_layer() const { return audio_layer_; }
henrikaf2f91fa2017-03-17 04:26:22 -0700579
henrika5b6afc02018-09-05 14:34:40 +0200580 // AudioDeviceModuleForTest extends the default ADM interface with some extra
581 // test methods. Intended for usage in tests only and requires a unique
582 // factory method. See CreateAudioDevice() for details.
583 const rtc::scoped_refptr<AudioDeviceModuleForTest>& audio_device() const {
henrikaf2f91fa2017-03-17 04:26:22 -0700584 return audio_device_;
585 }
586
henrika5b6afc02018-09-05 14:34:40 +0200587 rtc::scoped_refptr<AudioDeviceModuleForTest> CreateAudioDevice() {
henrikaec9c7452018-06-08 16:10:03 +0200588 // Use the default factory for kPlatformDefaultAudio and a special factory
henrika5b6afc02018-09-05 14:34:40 +0200589 // CreateWindowsCoreAudioAudioDeviceModuleForTest() for kWindowsCoreAudio2.
henrikaec9c7452018-06-08 16:10:03 +0200590 // The value of |audio_layer_| is set at construction by GetParam() and two
591 // different layers are tested on Windows only.
592 if (audio_layer_ == AudioDeviceModule::kPlatformDefaultAudio) {
Danil Chapovalov1c41be62019-04-01 09:16:12 +0200593 return AudioDeviceModule::CreateForTest(audio_layer_,
594 task_queue_factory_.get());
henrikaec9c7452018-06-08 16:10:03 +0200595 } else if (audio_layer_ == AudioDeviceModule::kWindowsCoreAudio2) {
596#ifdef WEBRTC_WIN
597 // We must initialize the COM library on a thread before we calling any of
598 // the library functions. All COM functions in the ADM will return
599 // CO_E_NOTINITIALIZED otherwise.
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200600 com_initializer_ = std::make_unique<webrtc_win::ScopedCOMInitializer>(
henrikaec9c7452018-06-08 16:10:03 +0200601 webrtc_win::ScopedCOMInitializer::kMTA);
602 EXPECT_TRUE(com_initializer_->Succeeded());
603 EXPECT_TRUE(webrtc_win::core_audio_utility::IsSupported());
604 EXPECT_TRUE(webrtc_win::core_audio_utility::IsMMCSSSupported());
Danil Chapovalov1c41be62019-04-01 09:16:12 +0200605 return CreateWindowsCoreAudioAudioDeviceModuleForTest(
henrikad8c6ec42019-07-18 15:17:28 +0200606 task_queue_factory_.get(), true);
henrikaec9c7452018-06-08 16:10:03 +0200607#else
608 return nullptr;
609#endif
610 } else {
611 return nullptr;
612 }
613 }
614
henrikaf2f91fa2017-03-17 04:26:22 -0700615 void StartPlayout() {
616 EXPECT_FALSE(audio_device()->Playing());
617 EXPECT_EQ(0, audio_device()->InitPlayout());
618 EXPECT_TRUE(audio_device()->PlayoutIsInitialized());
619 EXPECT_EQ(0, audio_device()->StartPlayout());
620 EXPECT_TRUE(audio_device()->Playing());
621 }
622
623 void StopPlayout() {
624 EXPECT_EQ(0, audio_device()->StopPlayout());
625 EXPECT_FALSE(audio_device()->Playing());
626 EXPECT_FALSE(audio_device()->PlayoutIsInitialized());
627 }
628
629 void StartRecording() {
630 EXPECT_FALSE(audio_device()->Recording());
631 EXPECT_EQ(0, audio_device()->InitRecording());
632 EXPECT_TRUE(audio_device()->RecordingIsInitialized());
633 EXPECT_EQ(0, audio_device()->StartRecording());
634 EXPECT_TRUE(audio_device()->Recording());
635 }
636
637 void StopRecording() {
638 EXPECT_EQ(0, audio_device()->StopRecording());
639 EXPECT_FALSE(audio_device()->Recording());
640 EXPECT_FALSE(audio_device()->RecordingIsInitialized());
641 }
642
henrikaec9c7452018-06-08 16:10:03 +0200643 bool NewWindowsAudioDeviceModuleIsUsed() {
644#ifdef WEBRTC_WIN
645 AudioDeviceModule::AudioLayer audio_layer;
646 EXPECT_EQ(0, audio_device()->ActiveAudioLayer(&audio_layer));
647 if (audio_layer == AudioDeviceModule::kWindowsCoreAudio2) {
648 // Default device is always added as first element in the list and the
649 // default communication device as the second element. Hence, the list
650 // contains two extra elements in this case.
651 return true;
652 }
653#endif
654 return false;
655 }
656
henrikaf2f91fa2017-03-17 04:26:22 -0700657 private:
henrikaec9c7452018-06-08 16:10:03 +0200658#ifdef WEBRTC_WIN
659 // Windows Core Audio based ADM needs to run on a COM initialized thread.
660 std::unique_ptr<webrtc_win::ScopedCOMInitializer> com_initializer_;
661#endif
662 AudioDeviceModule::AudioLayer audio_layer_;
Danil Chapovalov1c41be62019-04-01 09:16:12 +0200663 std::unique_ptr<TaskQueueFactory> task_queue_factory_;
henrikaf2f91fa2017-03-17 04:26:22 -0700664 bool requirements_satisfied_ = true;
665 rtc::Event event_;
henrika5b6afc02018-09-05 14:34:40 +0200666 rtc::scoped_refptr<AudioDeviceModuleForTest> audio_device_;
henrikaf2f91fa2017-03-17 04:26:22 -0700667 bool stereo_playout_ = false;
henrikaf2f91fa2017-03-17 04:26:22 -0700668};
669
henrikaec9c7452018-06-08 16:10:03 +0200670// Instead of using the test fixture, verify that the different factory methods
671// work as intended.
Yves Gereyff060ee2019-09-11 15:53:01 +0200672TEST(MAYBE_AudioDeviceTestWin, ConstructDestructWithFactory) {
Danil Chapovalov1c41be62019-04-01 09:16:12 +0200673 std::unique_ptr<TaskQueueFactory> task_queue_factory =
674 CreateDefaultTaskQueueFactory();
henrikaec9c7452018-06-08 16:10:03 +0200675 rtc::scoped_refptr<AudioDeviceModule> audio_device;
676 // The default factory should work for all platforms when a default ADM is
677 // requested.
Danil Chapovalov1c41be62019-04-01 09:16:12 +0200678 audio_device = AudioDeviceModule::Create(
679 AudioDeviceModule::kPlatformDefaultAudio, task_queue_factory.get());
henrikaec9c7452018-06-08 16:10:03 +0200680 EXPECT_TRUE(audio_device);
681 audio_device = nullptr;
682#ifdef WEBRTC_WIN
683 // For Windows, the old factory method creates an ADM where the platform-
684 // specific parts are implemented by an AudioDeviceGeneric object. Verify
685 // that the old factory can't be used in combination with the latest audio
686 // layer AudioDeviceModule::kWindowsCoreAudio2.
Danil Chapovalov1c41be62019-04-01 09:16:12 +0200687 audio_device = AudioDeviceModule::Create(
688 AudioDeviceModule::kWindowsCoreAudio2, task_queue_factory.get());
henrikaec9c7452018-06-08 16:10:03 +0200689 EXPECT_FALSE(audio_device);
690 audio_device = nullptr;
691 // Instead, ensure that the new dedicated factory method called
692 // CreateWindowsCoreAudioAudioDeviceModule() can be used on Windows and that
693 // it sets the audio layer to kWindowsCoreAudio2 implicitly. Note that, the
694 // new ADM for Windows must be created on a COM thread.
695 webrtc_win::ScopedCOMInitializer com_initializer(
696 webrtc_win::ScopedCOMInitializer::kMTA);
697 EXPECT_TRUE(com_initializer.Succeeded());
Danil Chapovalov1c41be62019-04-01 09:16:12 +0200698 audio_device =
699 CreateWindowsCoreAudioAudioDeviceModule(task_queue_factory.get());
henrikaec9c7452018-06-08 16:10:03 +0200700 EXPECT_TRUE(audio_device);
701 AudioDeviceModule::AudioLayer audio_layer;
702 EXPECT_EQ(0, audio_device->ActiveAudioLayer(&audio_layer));
703 EXPECT_EQ(audio_layer, AudioDeviceModule::kWindowsCoreAudio2);
704#endif
705}
henrikaf2f91fa2017-03-17 04:26:22 -0700706
henrikaec9c7452018-06-08 16:10:03 +0200707// Uses the test fixture to create, initialize and destruct the ADM.
Yves Gereyff060ee2019-09-11 15:53:01 +0200708TEST_P(MAYBE_AudioDeviceTest, ConstructDestructDefault) {}
henrikaec9c7452018-06-08 16:10:03 +0200709
Yves Gereyff060ee2019-09-11 15:53:01 +0200710TEST_P(MAYBE_AudioDeviceTest, InitTerminate) {
henrikaf2f91fa2017-03-17 04:26:22 -0700711 SKIP_TEST_IF_NOT(requirements_satisfied());
712 // Initialization is part of the test fixture.
713 EXPECT_TRUE(audio_device()->Initialized());
714 EXPECT_EQ(0, audio_device()->Terminate());
715 EXPECT_FALSE(audio_device()->Initialized());
716}
717
henrikaec9c7452018-06-08 16:10:03 +0200718// Enumerate all available and active output devices.
Yves Gereyff060ee2019-09-11 15:53:01 +0200719TEST_P(MAYBE_AudioDeviceTest, PlayoutDeviceNames) {
henrikaf2f91fa2017-03-17 04:26:22 -0700720 SKIP_TEST_IF_NOT(requirements_satisfied());
henrikaec9c7452018-06-08 16:10:03 +0200721 char device_name[kAdmMaxDeviceNameSize];
722 char unique_id[kAdmMaxGuidSize];
723 int num_devices = audio_device()->PlayoutDevices();
724 if (NewWindowsAudioDeviceModuleIsUsed()) {
725 num_devices += 2;
726 }
727 EXPECT_GT(num_devices, 0);
728 for (int i = 0; i < num_devices; ++i) {
729 EXPECT_EQ(0, audio_device()->PlayoutDeviceName(i, device_name, unique_id));
730 }
731 EXPECT_EQ(-1, audio_device()->PlayoutDeviceName(num_devices, device_name,
732 unique_id));
733}
734
735// Enumerate all available and active input devices.
Yves Gereyff060ee2019-09-11 15:53:01 +0200736TEST_P(MAYBE_AudioDeviceTest, RecordingDeviceNames) {
henrikaec9c7452018-06-08 16:10:03 +0200737 SKIP_TEST_IF_NOT(requirements_satisfied());
738 char device_name[kAdmMaxDeviceNameSize];
739 char unique_id[kAdmMaxGuidSize];
740 int num_devices = audio_device()->RecordingDevices();
741 if (NewWindowsAudioDeviceModuleIsUsed()) {
742 num_devices += 2;
743 }
744 EXPECT_GT(num_devices, 0);
745 for (int i = 0; i < num_devices; ++i) {
746 EXPECT_EQ(0,
747 audio_device()->RecordingDeviceName(i, device_name, unique_id));
748 }
749 EXPECT_EQ(-1, audio_device()->RecordingDeviceName(num_devices, device_name,
750 unique_id));
751}
752
753// Counts number of active output devices and ensure that all can be selected.
Yves Gereyff060ee2019-09-11 15:53:01 +0200754TEST_P(MAYBE_AudioDeviceTest, SetPlayoutDevice) {
henrikaec9c7452018-06-08 16:10:03 +0200755 SKIP_TEST_IF_NOT(requirements_satisfied());
756 int num_devices = audio_device()->PlayoutDevices();
757 if (NewWindowsAudioDeviceModuleIsUsed()) {
758 num_devices += 2;
759 }
760 EXPECT_GT(num_devices, 0);
761 // Verify that all available playout devices can be set (not enabled yet).
762 for (int i = 0; i < num_devices; ++i) {
763 EXPECT_EQ(0, audio_device()->SetPlayoutDevice(i));
764 }
765 EXPECT_EQ(-1, audio_device()->SetPlayoutDevice(num_devices));
766#ifdef WEBRTC_WIN
767 // On Windows, verify the alternative method where the user can select device
768 // by role.
769 EXPECT_EQ(
770 0, audio_device()->SetPlayoutDevice(AudioDeviceModule::kDefaultDevice));
771 EXPECT_EQ(0, audio_device()->SetPlayoutDevice(
772 AudioDeviceModule::kDefaultCommunicationDevice));
773#endif
774}
775
776// Counts number of active input devices and ensure that all can be selected.
Yves Gereyff060ee2019-09-11 15:53:01 +0200777TEST_P(MAYBE_AudioDeviceTest, SetRecordingDevice) {
henrikaec9c7452018-06-08 16:10:03 +0200778 SKIP_TEST_IF_NOT(requirements_satisfied());
779 int num_devices = audio_device()->RecordingDevices();
780 if (NewWindowsAudioDeviceModuleIsUsed()) {
781 num_devices += 2;
782 }
783 EXPECT_GT(num_devices, 0);
784 // Verify that all available recording devices can be set (not enabled yet).
785 for (int i = 0; i < num_devices; ++i) {
786 EXPECT_EQ(0, audio_device()->SetRecordingDevice(i));
787 }
788 EXPECT_EQ(-1, audio_device()->SetRecordingDevice(num_devices));
789#ifdef WEBRTC_WIN
790 // On Windows, verify the alternative method where the user can select device
791 // by role.
792 EXPECT_EQ(
793 0, audio_device()->SetRecordingDevice(AudioDeviceModule::kDefaultDevice));
794 EXPECT_EQ(0, audio_device()->SetRecordingDevice(
795 AudioDeviceModule::kDefaultCommunicationDevice));
796#endif
797}
798
799// Tests Start/Stop playout without any registered audio callback.
Yves Gereyff060ee2019-09-11 15:53:01 +0200800TEST_P(MAYBE_AudioDeviceTest, StartStopPlayout) {
henrikaec9c7452018-06-08 16:10:03 +0200801 SKIP_TEST_IF_NOT(requirements_satisfied());
henrikaf2f91fa2017-03-17 04:26:22 -0700802 StartPlayout();
803 StopPlayout();
804}
805
806// Tests Start/Stop recording without any registered audio callback.
Yves Gereyff060ee2019-09-11 15:53:01 +0200807TEST_P(MAYBE_AudioDeviceTest, StartStopRecording) {
henrikaf2f91fa2017-03-17 04:26:22 -0700808 SKIP_TEST_IF_NOT(requirements_satisfied());
809 StartRecording();
810 StopRecording();
henrikaf2f91fa2017-03-17 04:26:22 -0700811}
812
henrika351173c2019-11-18 17:36:08 +0100813// Tests Start/Stop playout for all available input devices to ensure that
814// the selected device can be created and used as intended.
815TEST_P(MAYBE_AudioDeviceTest, StartStopPlayoutWithRealDevice) {
816 SKIP_TEST_IF_NOT(requirements_satisfied());
817 int num_devices = audio_device()->PlayoutDevices();
818 if (NewWindowsAudioDeviceModuleIsUsed()) {
819 num_devices += 2;
820 }
821 EXPECT_GT(num_devices, 0);
822 // Verify that all available playout devices can be set and used.
823 for (int i = 0; i < num_devices; ++i) {
824 EXPECT_EQ(0, audio_device()->SetPlayoutDevice(i));
825 StartPlayout();
826 StopPlayout();
827 }
828#ifdef WEBRTC_WIN
829 AudioDeviceModule::WindowsDeviceType device_role[] = {
830 AudioDeviceModule::kDefaultDevice,
831 AudioDeviceModule::kDefaultCommunicationDevice};
832 for (size_t i = 0; i < arraysize(device_role); ++i) {
833 EXPECT_EQ(0, audio_device()->SetPlayoutDevice(device_role[i]));
834 StartPlayout();
835 StopPlayout();
836 }
837#endif
838}
839
840// Tests Start/Stop recording for all available input devices to ensure that
841// the selected device can be created and used as intended.
842TEST_P(MAYBE_AudioDeviceTest, StartStopRecordingWithRealDevice) {
843 SKIP_TEST_IF_NOT(requirements_satisfied());
844 int num_devices = audio_device()->RecordingDevices();
845 if (NewWindowsAudioDeviceModuleIsUsed()) {
846 num_devices += 2;
847 }
848 EXPECT_GT(num_devices, 0);
849 // Verify that all available recording devices can be set and used.
850 for (int i = 0; i < num_devices; ++i) {
851 EXPECT_EQ(0, audio_device()->SetRecordingDevice(i));
852 StartRecording();
853 StopRecording();
854 }
855#ifdef WEBRTC_WIN
856 AudioDeviceModule::WindowsDeviceType device_role[] = {
857 AudioDeviceModule::kDefaultDevice,
858 AudioDeviceModule::kDefaultCommunicationDevice};
859 for (size_t i = 0; i < arraysize(device_role); ++i) {
860 EXPECT_EQ(0, audio_device()->SetRecordingDevice(device_role[i]));
861 StartRecording();
862 StopRecording();
863 }
864#endif
865}
866
henrika6b3e1a22017-09-25 16:34:30 +0200867// Tests Init/Stop/Init recording without any registered audio callback.
868// See https://bugs.chromium.org/p/webrtc/issues/detail?id=8041 for details
869// on why this test is useful.
Yves Gereyff060ee2019-09-11 15:53:01 +0200870TEST_P(MAYBE_AudioDeviceTest, InitStopInitRecording) {
henrika6b3e1a22017-09-25 16:34:30 +0200871 SKIP_TEST_IF_NOT(requirements_satisfied());
872 EXPECT_EQ(0, audio_device()->InitRecording());
873 EXPECT_TRUE(audio_device()->RecordingIsInitialized());
874 StopRecording();
875 EXPECT_EQ(0, audio_device()->InitRecording());
876 StopRecording();
877}
878
henrikad4049462019-07-12 13:37:11 +0200879// Verify that additional attempts to initialize or start recording while
880// already being active works. Additional calls should just be ignored.
Yves Gereyff060ee2019-09-11 15:53:01 +0200881TEST_P(MAYBE_AudioDeviceTest, StartInitRecording) {
henrikad4049462019-07-12 13:37:11 +0200882 SKIP_TEST_IF_NOT(requirements_satisfied());
883 StartRecording();
884 // An additional attempt to initialize at this stage should be ignored.
885 EXPECT_EQ(0, audio_device()->InitRecording());
886 // Same for additional request to start recording while already active.
887 EXPECT_EQ(0, audio_device()->StartRecording());
888 StopRecording();
889}
890
891// Verify that additional attempts to initialize or start playou while
892// already being active works. Additional calls should just be ignored.
Yves Gereyff060ee2019-09-11 15:53:01 +0200893TEST_P(MAYBE_AudioDeviceTest, StartInitPlayout) {
henrikad4049462019-07-12 13:37:11 +0200894 SKIP_TEST_IF_NOT(requirements_satisfied());
895 StartPlayout();
896 // An additional attempt to initialize at this stage should be ignored.
897 EXPECT_EQ(0, audio_device()->InitPlayout());
898 // Same for additional request to start playout while already active.
899 EXPECT_EQ(0, audio_device()->StartPlayout());
900 StopPlayout();
901}
902
henrika6b3e1a22017-09-25 16:34:30 +0200903// Tests Init/Stop/Init recording while playout is active.
Yves Gereyff060ee2019-09-11 15:53:01 +0200904TEST_P(MAYBE_AudioDeviceTest, InitStopInitRecordingWhilePlaying) {
henrika6b3e1a22017-09-25 16:34:30 +0200905 SKIP_TEST_IF_NOT(requirements_satisfied());
906 StartPlayout();
907 EXPECT_EQ(0, audio_device()->InitRecording());
908 EXPECT_TRUE(audio_device()->RecordingIsInitialized());
909 StopRecording();
910 EXPECT_EQ(0, audio_device()->InitRecording());
911 StopRecording();
912 StopPlayout();
913}
914
915// Tests Init/Stop/Init playout without any registered audio callback.
Yves Gereyff060ee2019-09-11 15:53:01 +0200916TEST_P(MAYBE_AudioDeviceTest, InitStopInitPlayout) {
henrika6b3e1a22017-09-25 16:34:30 +0200917 SKIP_TEST_IF_NOT(requirements_satisfied());
918 EXPECT_EQ(0, audio_device()->InitPlayout());
919 EXPECT_TRUE(audio_device()->PlayoutIsInitialized());
920 StopPlayout();
921 EXPECT_EQ(0, audio_device()->InitPlayout());
922 StopPlayout();
923}
924
925// Tests Init/Stop/Init playout while recording is active.
Yves Gereyff060ee2019-09-11 15:53:01 +0200926TEST_P(MAYBE_AudioDeviceTest, InitStopInitPlayoutWhileRecording) {
henrika6b3e1a22017-09-25 16:34:30 +0200927 SKIP_TEST_IF_NOT(requirements_satisfied());
928 StartRecording();
929 EXPECT_EQ(0, audio_device()->InitPlayout());
930 EXPECT_TRUE(audio_device()->PlayoutIsInitialized());
931 StopPlayout();
932 EXPECT_EQ(0, audio_device()->InitPlayout());
933 StopPlayout();
934 StopRecording();
935}
936
henrika5b6afc02018-09-05 14:34:40 +0200937// TODO(henrika): restart without intermediate destruction is currently only
938// supported on Windows.
939#ifdef WEBRTC_WIN
940// Tests Start/Stop playout followed by a second session (emulates a restart
941// triggered by a user using public APIs).
Yves Gereyff060ee2019-09-11 15:53:01 +0200942TEST_P(MAYBE_AudioDeviceTest, StartStopPlayoutWithExternalRestart) {
henrika5b6afc02018-09-05 14:34:40 +0200943 SKIP_TEST_IF_NOT(requirements_satisfied());
944 StartPlayout();
945 StopPlayout();
946 // Restart playout without destroying the ADM in between. Ensures that we
947 // support: Init(), Start(), Stop(), Init(), Start(), Stop().
948 StartPlayout();
949 StopPlayout();
950}
951
952// Tests Start/Stop recording followed by a second session (emulates a restart
953// triggered by a user using public APIs).
Yves Gereyff060ee2019-09-11 15:53:01 +0200954TEST_P(MAYBE_AudioDeviceTest, StartStopRecordingWithExternalRestart) {
henrika5b6afc02018-09-05 14:34:40 +0200955 SKIP_TEST_IF_NOT(requirements_satisfied());
956 StartRecording();
957 StopRecording();
958 // Restart recording without destroying the ADM in between. Ensures that we
959 // support: Init(), Start(), Stop(), Init(), Start(), Stop().
960 StartRecording();
961 StopRecording();
962}
963
964// Tests Start/Stop playout followed by a second session (emulates a restart
965// triggered by an internal callback e.g. corresponding to a device switch).
966// Note that, internal restart is only supported in combination with the latest
967// Windows ADM.
Yves Gereyff060ee2019-09-11 15:53:01 +0200968TEST_P(MAYBE_AudioDeviceTest, StartStopPlayoutWithInternalRestart) {
henrika5b6afc02018-09-05 14:34:40 +0200969 SKIP_TEST_IF_NOT(requirements_satisfied());
970 if (audio_layer() != AudioDeviceModule::kWindowsCoreAudio2) {
971 return;
972 }
973 MockAudioTransport mock(TransportType::kPlay);
974 mock.HandleCallbacks(event(), nullptr, kNumCallbacks);
975 EXPECT_CALL(mock, NeedMorePlayData(_, _, _, _, NotNull(), _, _, _))
976 .Times(AtLeast(kNumCallbacks));
977 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
978 StartPlayout();
979 event()->Wait(kTestTimeOutInMilliseconds);
980 EXPECT_TRUE(audio_device()->Playing());
981 // Restart playout but without stopping the internal audio thread.
982 // This procedure uses a non-public test API and it emulates what happens
983 // inside the ADM when e.g. a device is removed.
984 EXPECT_EQ(0, audio_device()->RestartPlayoutInternally());
985
986 // Run basic tests of public APIs while a restart attempt is active.
987 // These calls should now be very thin and not trigger any new actions.
988 EXPECT_EQ(-1, audio_device()->StopPlayout());
989 EXPECT_TRUE(audio_device()->Playing());
990 EXPECT_TRUE(audio_device()->PlayoutIsInitialized());
991 EXPECT_EQ(0, audio_device()->InitPlayout());
992 EXPECT_EQ(0, audio_device()->StartPlayout());
993
994 // Wait until audio has restarted and a new sequence of audio callbacks
995 // becomes active.
996 // TODO(henrika): is it possible to verify that the internal state transition
997 // is Stop->Init->Start?
998 ASSERT_TRUE(Mock::VerifyAndClearExpectations(&mock));
999 mock.ResetCallbackCounters();
1000 EXPECT_CALL(mock, NeedMorePlayData(_, _, _, _, NotNull(), _, _, _))
1001 .Times(AtLeast(kNumCallbacks));
1002 event()->Wait(kTestTimeOutInMilliseconds);
1003 EXPECT_TRUE(audio_device()->Playing());
1004 // Stop playout and the audio thread after successful internal restart.
1005 StopPlayout();
Yves Gereyb93a2452019-07-19 22:46:13 +02001006 PreTearDown();
henrika5b6afc02018-09-05 14:34:40 +02001007}
1008
1009// Tests Start/Stop recording followed by a second session (emulates a restart
1010// triggered by an internal callback e.g. corresponding to a device switch).
1011// Note that, internal restart is only supported in combination with the latest
1012// Windows ADM.
Yves Gereyff060ee2019-09-11 15:53:01 +02001013TEST_P(MAYBE_AudioDeviceTest, StartStopRecordingWithInternalRestart) {
henrika5b6afc02018-09-05 14:34:40 +02001014 SKIP_TEST_IF_NOT(requirements_satisfied());
1015 if (audio_layer() != AudioDeviceModule::kWindowsCoreAudio2) {
1016 return;
1017 }
1018 MockAudioTransport mock(TransportType::kRecord);
1019 mock.HandleCallbacks(event(), nullptr, kNumCallbacks);
1020 EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(), _, _, _, _, Ge(0u), 0, _,
1021 false, _))
1022 .Times(AtLeast(kNumCallbacks));
1023 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
1024 StartRecording();
1025 event()->Wait(kTestTimeOutInMilliseconds);
1026 EXPECT_TRUE(audio_device()->Recording());
1027 // Restart recording but without stopping the internal audio thread.
1028 // This procedure uses a non-public test API and it emulates what happens
1029 // inside the ADM when e.g. a device is removed.
1030 EXPECT_EQ(0, audio_device()->RestartRecordingInternally());
1031
1032 // Run basic tests of public APIs while a restart attempt is active.
1033 // These calls should now be very thin and not trigger any new actions.
1034 EXPECT_EQ(-1, audio_device()->StopRecording());
1035 EXPECT_TRUE(audio_device()->Recording());
1036 EXPECT_TRUE(audio_device()->RecordingIsInitialized());
1037 EXPECT_EQ(0, audio_device()->InitRecording());
1038 EXPECT_EQ(0, audio_device()->StartRecording());
1039
1040 // Wait until audio has restarted and a new sequence of audio callbacks
1041 // becomes active.
1042 // TODO(henrika): is it possible to verify that the internal state transition
1043 // is Stop->Init->Start?
1044 ASSERT_TRUE(Mock::VerifyAndClearExpectations(&mock));
1045 mock.ResetCallbackCounters();
1046 EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(), _, _, _, _, Ge(0u), 0, _,
1047 false, _))
1048 .Times(AtLeast(kNumCallbacks));
1049 event()->Wait(kTestTimeOutInMilliseconds);
1050 EXPECT_TRUE(audio_device()->Recording());
1051 // Stop recording and the audio thread after successful internal restart.
1052 StopRecording();
Yves Gereyb93a2452019-07-19 22:46:13 +02001053 PreTearDown();
henrika5b6afc02018-09-05 14:34:40 +02001054}
1055#endif // #ifdef WEBRTC_WIN
1056
henrikaf2f91fa2017-03-17 04:26:22 -07001057// Start playout and verify that the native audio layer starts asking for real
1058// audio samples to play out using the NeedMorePlayData() callback.
1059// Note that we can't add expectations on audio parameters in EXPECT_CALL
1060// since parameter are not provided in the each callback. We therefore test and
1061// verify the parameters in the fake audio transport implementation instead.
Yves Gereyff060ee2019-09-11 15:53:01 +02001062TEST_P(MAYBE_AudioDeviceTest, StartPlayoutVerifyCallbacks) {
henrikaf2f91fa2017-03-17 04:26:22 -07001063 SKIP_TEST_IF_NOT(requirements_satisfied());
1064 MockAudioTransport mock(TransportType::kPlay);
henrikae24991d2017-04-06 01:14:23 -07001065 mock.HandleCallbacks(event(), nullptr, kNumCallbacks);
henrikaf2f91fa2017-03-17 04:26:22 -07001066 EXPECT_CALL(mock, NeedMorePlayData(_, _, _, _, NotNull(), _, _, _))
1067 .Times(AtLeast(kNumCallbacks));
1068 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
1069 StartPlayout();
1070 event()->Wait(kTestTimeOutInMilliseconds);
1071 StopPlayout();
Yves Gerey412282a2019-07-22 21:15:22 +02001072 PreTearDown();
henrikaf2f91fa2017-03-17 04:26:22 -07001073}
1074
Yves Gerey704c8c42019-08-13 22:32:46 +02001075// Don't run these tests in combination with sanitizers.
1076// They are already flaky *without* sanitizers.
1077// Sanitizers seem to increase flakiness (which brings noise),
1078// without reporting anything.
1079// TODO(webrtc:10867): Re-enable when flakiness fixed.
1080#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
1081 defined(THREAD_SANITIZER)
1082#define MAYBE_StartRecordingVerifyCallbacks \
1083 DISABLED_StartRecordingVerifyCallbacks
1084#define MAYBE_StartPlayoutAndRecordingVerifyCallbacks \
1085 DISABLED_StartPlayoutAndRecordingVerifyCallbacks
1086#else
1087#define MAYBE_StartRecordingVerifyCallbacks StartRecordingVerifyCallbacks
1088#define MAYBE_StartPlayoutAndRecordingVerifyCallbacks \
1089 StartPlayoutAndRecordingVerifyCallbacks
1090#endif
1091
henrikaf2f91fa2017-03-17 04:26:22 -07001092// Start recording and verify that the native audio layer starts providing real
1093// audio samples using the RecordedDataIsAvailable() callback.
Yves Gereyff060ee2019-09-11 15:53:01 +02001094TEST_P(MAYBE_AudioDeviceTest, MAYBE_StartRecordingVerifyCallbacks) {
henrikaf2f91fa2017-03-17 04:26:22 -07001095 SKIP_TEST_IF_NOT(requirements_satisfied());
1096 MockAudioTransport mock(TransportType::kRecord);
henrikae24991d2017-04-06 01:14:23 -07001097 mock.HandleCallbacks(event(), nullptr, kNumCallbacks);
henrikaf2f91fa2017-03-17 04:26:22 -07001098 EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(), _, _, _, _, Ge(0u), 0, _,
1099 false, _))
1100 .Times(AtLeast(kNumCallbacks));
1101 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
1102 StartRecording();
1103 event()->Wait(kTestTimeOutInMilliseconds);
1104 StopRecording();
Yves Gereyb93a2452019-07-19 22:46:13 +02001105 PreTearDown();
henrikaf2f91fa2017-03-17 04:26:22 -07001106}
1107
1108// Start playout and recording (full-duplex audio) and verify that audio is
1109// active in both directions.
Yves Gereyff060ee2019-09-11 15:53:01 +02001110TEST_P(MAYBE_AudioDeviceTest, MAYBE_StartPlayoutAndRecordingVerifyCallbacks) {
henrikaf2f91fa2017-03-17 04:26:22 -07001111 SKIP_TEST_IF_NOT(requirements_satisfied());
1112 MockAudioTransport mock(TransportType::kPlayAndRecord);
henrikae24991d2017-04-06 01:14:23 -07001113 mock.HandleCallbacks(event(), nullptr, kNumCallbacks);
henrikaf2f91fa2017-03-17 04:26:22 -07001114 EXPECT_CALL(mock, NeedMorePlayData(_, _, _, _, NotNull(), _, _, _))
1115 .Times(AtLeast(kNumCallbacks));
1116 EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(), _, _, _, _, Ge(0u), 0, _,
1117 false, _))
1118 .Times(AtLeast(kNumCallbacks));
1119 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
1120 StartPlayout();
1121 StartRecording();
1122 event()->Wait(kTestTimeOutInMilliseconds);
1123 StopRecording();
1124 StopPlayout();
Yves Gereyb93a2452019-07-19 22:46:13 +02001125 PreTearDown();
henrikaf2f91fa2017-03-17 04:26:22 -07001126}
1127
henrikae24991d2017-04-06 01:14:23 -07001128// Start playout and recording and store recorded data in an intermediate FIFO
1129// buffer from which the playout side then reads its samples in the same order
1130// as they were stored. Under ideal circumstances, a callback sequence would
1131// look like: ...+-+-+-+-+-+-+-..., where '+' means 'packet recorded' and '-'
1132// means 'packet played'. Under such conditions, the FIFO would contain max 1,
1133// with an average somewhere in (0,1) depending on how long the packets are
1134// buffered. However, under more realistic conditions, the size
1135// of the FIFO will vary more due to an unbalance between the two sides.
1136// This test tries to verify that the device maintains a balanced callback-
1137// sequence by running in loopback for a few seconds while measuring the size
1138// (max and average) of the FIFO. The size of the FIFO is increased by the
1139// recording side and decreased by the playout side.
Yves Gereyff060ee2019-09-11 15:53:01 +02001140TEST_P(MAYBE_AudioDeviceTest, RunPlayoutAndRecordingInFullDuplex) {
henrikae24991d2017-04-06 01:14:23 -07001141 SKIP_TEST_IF_NOT(requirements_satisfied());
1142 NiceMock<MockAudioTransport> mock(TransportType::kPlayAndRecord);
1143 FifoAudioStream audio_stream;
1144 mock.HandleCallbacks(event(), &audio_stream,
1145 kFullDuplexTimeInSec * kNumCallbacksPerSecond);
1146 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
henrikaeb98c722018-03-20 12:54:07 +01001147 // Run both sides using the same channel configuration to avoid conversions
1148 // between mono/stereo while running in full duplex mode. Also, some devices
1149 // (mainly on Windows) do not support mono.
1150 EXPECT_EQ(0, audio_device()->SetStereoPlayout(true));
1151 EXPECT_EQ(0, audio_device()->SetStereoRecording(true));
Gustaf Ullberg102b7282019-06-03 15:03:02 +02001152 // Mute speakers to prevent howling.
1153 EXPECT_EQ(0, audio_device()->SetSpeakerVolume(0));
henrikae24991d2017-04-06 01:14:23 -07001154 StartPlayout();
1155 StartRecording();
henrika714e5cd2017-04-20 08:03:11 -07001156 event()->Wait(static_cast<int>(
1157 std::max(kTestTimeOutInMilliseconds, 1000 * kFullDuplexTimeInSec)));
henrikae24991d2017-04-06 01:14:23 -07001158 StopRecording();
1159 StopPlayout();
Yves Gerey412282a2019-07-22 21:15:22 +02001160 PreTearDown();
henrikae24991d2017-04-06 01:14:23 -07001161}
1162
henrika5b6afc02018-09-05 14:34:40 +02001163// Runs audio in full duplex until user hits Enter. Intended as a manual test
1164// to ensure that the audio quality is good and that real device switches works
1165// as intended.
Yves Gereyff060ee2019-09-11 15:53:01 +02001166TEST_P(MAYBE_AudioDeviceTest,
henrika5b6afc02018-09-05 14:34:40 +02001167 DISABLED_RunPlayoutAndRecordingInFullDuplexAndWaitForEnterKey) {
1168 SKIP_TEST_IF_NOT(requirements_satisfied());
1169 if (audio_layer() != AudioDeviceModule::kWindowsCoreAudio2) {
1170 return;
1171 }
1172 NiceMock<MockAudioTransport> mock(TransportType::kPlayAndRecord);
1173 FifoAudioStream audio_stream;
1174 mock.HandleCallbacks(&audio_stream);
1175 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
1176 EXPECT_EQ(0, audio_device()->SetStereoPlayout(true));
1177 EXPECT_EQ(0, audio_device()->SetStereoRecording(true));
1178 // Ensure that the sample rate for both directions are identical so that we
1179 // always can listen to our own voice. Will lead to rate conversion (and
1180 // higher latency) if the native sample rate is not 48kHz.
1181 EXPECT_EQ(0, audio_device()->SetPlayoutSampleRate(48000));
1182 EXPECT_EQ(0, audio_device()->SetRecordingSampleRate(48000));
1183 StartPlayout();
1184 StartRecording();
1185 do {
1186 PRINT("Loopback audio is active at 48kHz. Press Enter to stop.\n");
1187 } while (getchar() != '\n');
1188 StopRecording();
1189 StopPlayout();
Yves Gereyb93a2452019-07-19 22:46:13 +02001190 PreTearDown();
henrika5b6afc02018-09-05 14:34:40 +02001191}
1192
henrika714e5cd2017-04-20 08:03:11 -07001193// Measures loopback latency and reports the min, max and average values for
1194// a full duplex audio session.
1195// The latency is measured like so:
1196// - Insert impulses periodically on the output side.
1197// - Detect the impulses on the input side.
1198// - Measure the time difference between the transmit time and receive time.
1199// - Store time differences in a vector and calculate min, max and average.
1200// This test needs the '--gtest_also_run_disabled_tests' flag to run and also
1201// some sort of audio feedback loop. E.g. a headset where the mic is placed
1202// close to the speaker to ensure highest possible echo. It is also recommended
1203// to run the test at highest possible output volume.
Yves Gereyff060ee2019-09-11 15:53:01 +02001204TEST_P(MAYBE_AudioDeviceTest, DISABLED_MeasureLoopbackLatency) {
henrika714e5cd2017-04-20 08:03:11 -07001205 SKIP_TEST_IF_NOT(requirements_satisfied());
1206 NiceMock<MockAudioTransport> mock(TransportType::kPlayAndRecord);
1207 LatencyAudioStream audio_stream;
1208 mock.HandleCallbacks(event(), &audio_stream,
1209 kMeasureLatencyTimeInSec * kNumCallbacksPerSecond);
1210 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
henrikaeb98c722018-03-20 12:54:07 +01001211 EXPECT_EQ(0, audio_device()->SetStereoPlayout(true));
1212 EXPECT_EQ(0, audio_device()->SetStereoRecording(true));
henrika714e5cd2017-04-20 08:03:11 -07001213 StartPlayout();
1214 StartRecording();
1215 event()->Wait(static_cast<int>(
1216 std::max(kTestTimeOutInMilliseconds, 1000 * kMeasureLatencyTimeInSec)));
1217 StopRecording();
1218 StopPlayout();
Yves Gerey412282a2019-07-22 21:15:22 +02001219 // Avoid concurrent access to audio_stream.
1220 PreTearDown();
henrikac7d93582018-09-14 15:37:34 +02001221 // Verify that a sufficient number of transmitted impulses are detected.
1222 EXPECT_GE(audio_stream.num_latency_values(),
henrika714e5cd2017-04-20 08:03:11 -07001223 static_cast<size_t>(
henrikac7d93582018-09-14 15:37:34 +02001224 kImpulseFrequencyInHz * kMeasureLatencyTimeInSec - 2));
henrika714e5cd2017-04-20 08:03:11 -07001225 // Print out min, max and average delay values for debugging purposes.
1226 audio_stream.PrintResults();
1227}
1228
henrikaec9c7452018-06-08 16:10:03 +02001229#ifdef WEBRTC_WIN
1230// Test two different audio layers (or rather two different Core Audio
1231// implementations) for Windows.
Mirko Bonadeic84f6612019-01-31 12:20:57 +01001232INSTANTIATE_TEST_SUITE_P(
henrikaec9c7452018-06-08 16:10:03 +02001233 AudioLayerWin,
Yves Gereyff060ee2019-09-11 15:53:01 +02001234 MAYBE_AudioDeviceTest,
henrikaec9c7452018-06-08 16:10:03 +02001235 ::testing::Values(AudioDeviceModule::kPlatformDefaultAudio,
1236 AudioDeviceModule::kWindowsCoreAudio2));
1237#else
1238// For all platforms but Windows, only test the default audio layer.
Mirko Bonadeic84f6612019-01-31 12:20:57 +01001239INSTANTIATE_TEST_SUITE_P(
henrikaec9c7452018-06-08 16:10:03 +02001240 AudioLayer,
Yves Gereyff060ee2019-09-11 15:53:01 +02001241 MAYBE_AudioDeviceTest,
henrikaec9c7452018-06-08 16:10:03 +02001242 ::testing::Values(AudioDeviceModule::kPlatformDefaultAudio));
1243#endif
1244
henrikaf2f91fa2017-03-17 04:26:22 -07001245} // namespace webrtc