blob: b0af9521c6d4684b7c7492579fc068e4addacfe9 [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"
Artem Titovd15a5752021-02-10 14:31:24 +010022#include "api/sequence_checker.h"
Danil Chapovalov1c41be62019-04-01 09:16:12 +020023#include "api/task_queue/default_task_queue_factory.h"
24#include "api/task_queue/task_queue_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "modules/audio_device/audio_device_impl.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020026#include "modules/audio_device/include/mock_audio_transport.h"
henrika351173c2019-11-18 17:36:08 +010027#include "rtc_base/arraysize.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020028#include "rtc_base/buffer.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"
Markus Handell5f612822020-07-08 10:13:20 +020033#include "rtc_base/synchronization/mutex.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020034#include "rtc_base/thread_annotations.h"
Steve Anton10542f22019-01-11 09:11:00 -080035#include "rtc_base/time_utils.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020036#include "test/gmock.h"
37#include "test/gtest.h"
henrikaec9c7452018-06-08 16:10:03 +020038#ifdef WEBRTC_WIN
39#include "modules/audio_device/include/audio_device_factory.h"
40#include "modules/audio_device/win/core_audio_utility_win.h"
Austin Orion0bb354c2020-10-29 11:30:10 -070041#include "rtc_base/win/scoped_com_initializer.h"
42#endif // WEBRTC_WIN
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 = [&] {
Markus Handell5f612822020-07-08 10:13:20 +0200140 MutexLock lock(&lock_);
henrikae24991d2017-04-06 01:14:23 -0700141 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 {
Markus Handell5f612822020-07-08 10:13:20 +0200155 MutexLock lock(&lock_);
henrikae24991d2017-04-06 01:14:23 -0700156 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 {
Markus Handell5f612822020-07-08 10:13:20 +0200186 MutexLock lock(&lock_);
henrikae24991d2017-04-06 01:14:23 -0700187 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
Markus Handell5f612822020-07-08 10:13:20 +0200202 mutable Mutex lock_;
henrikae24991d2017-04-06 01:14:23 -0700203 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 {
Markus Handell5f612822020-07-08 10:13:20 +0200233 MutexLock lock(&lock_);
henrika714e5cd2017-04-20 08:03:11 -0700234 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_);
Markus Handell5f612822020-07-08 10:13:20 +0200248 MutexLock lock(&lock_);
henrika714e5cd2017-04-20 08:03:11 -0700249 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
Markus Handell5f612822020-07-08 10:13:20 +0200318 Mutex lock_;
henrika714e5cd2017-04-20 08:03:11 -0700319 rtc::RaceChecker race_checker_;
Artem Titovc8421c42021-02-02 10:57:19 +0100320 SequenceChecker read_thread_checker_;
321 SequenceChecker write_thread_checker_;
henrika714e5cd2017-04-20 08:03:11 -0700322
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 {
Markus Handell5f612822020-07-08 10:13:20 +0200393 MutexLock lock(&lock_);
henrika78e0ac12018-09-27 16:23:21 +0200394 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 {
Markus Handell5f612822020-07-08 10:13:20 +0200433 MutexLock lock(&lock_);
henrika78e0ac12018-09-27 16:23:21 +0200434 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()) {
Markus Handell5f612822020-07-08 10:13:20 +0200456 MutexLock 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()) {
Markus Handell5f612822020-07-08 10:13:20 +0200463 MutexLock 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() {
Markus Handell5f612822020-07-08 10:13:20 +0200482 MutexLock 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:
Markus Handell5f612822020-07-08 10:13:20 +0200492 Mutex 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.
Austin Orion0bb354c2020-10-29 11:30:10 -0700599 com_initializer_ =
600 std::make_unique<ScopedCOMInitializer>(ScopedCOMInitializer::kMTA);
henrikaec9c7452018-06-08 16:10:03 +0200601 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.
Austin Orion0bb354c2020-10-29 11:30:10 -0700659 std::unique_ptr<ScopedCOMInitializer> com_initializer_;
henrikaec9c7452018-06-08 16:10:03 +0200660#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.
Austin Orion0bb354c2020-10-29 11:30:10 -0700694 ScopedCOMInitializer com_initializer(ScopedCOMInitializer::kMTA);
henrikaec9c7452018-06-08 16:10:03 +0200695 EXPECT_TRUE(com_initializer.Succeeded());
Danil Chapovalov1c41be62019-04-01 09:16:12 +0200696 audio_device =
697 CreateWindowsCoreAudioAudioDeviceModule(task_queue_factory.get());
henrikaec9c7452018-06-08 16:10:03 +0200698 EXPECT_TRUE(audio_device);
699 AudioDeviceModule::AudioLayer audio_layer;
700 EXPECT_EQ(0, audio_device->ActiveAudioLayer(&audio_layer));
701 EXPECT_EQ(audio_layer, AudioDeviceModule::kWindowsCoreAudio2);
702#endif
703}
henrikaf2f91fa2017-03-17 04:26:22 -0700704
henrikaec9c7452018-06-08 16:10:03 +0200705// Uses the test fixture to create, initialize and destruct the ADM.
Yves Gereyff060ee2019-09-11 15:53:01 +0200706TEST_P(MAYBE_AudioDeviceTest, ConstructDestructDefault) {}
henrikaec9c7452018-06-08 16:10:03 +0200707
Yves Gereyff060ee2019-09-11 15:53:01 +0200708TEST_P(MAYBE_AudioDeviceTest, InitTerminate) {
henrikaf2f91fa2017-03-17 04:26:22 -0700709 SKIP_TEST_IF_NOT(requirements_satisfied());
710 // Initialization is part of the test fixture.
711 EXPECT_TRUE(audio_device()->Initialized());
712 EXPECT_EQ(0, audio_device()->Terminate());
713 EXPECT_FALSE(audio_device()->Initialized());
714}
715
henrikaec9c7452018-06-08 16:10:03 +0200716// Enumerate all available and active output devices.
Yves Gereyff060ee2019-09-11 15:53:01 +0200717TEST_P(MAYBE_AudioDeviceTest, PlayoutDeviceNames) {
henrikaf2f91fa2017-03-17 04:26:22 -0700718 SKIP_TEST_IF_NOT(requirements_satisfied());
henrikaec9c7452018-06-08 16:10:03 +0200719 char device_name[kAdmMaxDeviceNameSize];
720 char unique_id[kAdmMaxGuidSize];
721 int num_devices = audio_device()->PlayoutDevices();
722 if (NewWindowsAudioDeviceModuleIsUsed()) {
723 num_devices += 2;
724 }
725 EXPECT_GT(num_devices, 0);
726 for (int i = 0; i < num_devices; ++i) {
727 EXPECT_EQ(0, audio_device()->PlayoutDeviceName(i, device_name, unique_id));
728 }
729 EXPECT_EQ(-1, audio_device()->PlayoutDeviceName(num_devices, device_name,
730 unique_id));
731}
732
733// Enumerate all available and active input devices.
Yves Gereyff060ee2019-09-11 15:53:01 +0200734TEST_P(MAYBE_AudioDeviceTest, RecordingDeviceNames) {
henrikaec9c7452018-06-08 16:10:03 +0200735 SKIP_TEST_IF_NOT(requirements_satisfied());
736 char device_name[kAdmMaxDeviceNameSize];
737 char unique_id[kAdmMaxGuidSize];
738 int num_devices = audio_device()->RecordingDevices();
739 if (NewWindowsAudioDeviceModuleIsUsed()) {
740 num_devices += 2;
741 }
742 EXPECT_GT(num_devices, 0);
743 for (int i = 0; i < num_devices; ++i) {
744 EXPECT_EQ(0,
745 audio_device()->RecordingDeviceName(i, device_name, unique_id));
746 }
747 EXPECT_EQ(-1, audio_device()->RecordingDeviceName(num_devices, device_name,
748 unique_id));
749}
750
751// Counts number of active output devices and ensure that all can be selected.
Yves Gereyff060ee2019-09-11 15:53:01 +0200752TEST_P(MAYBE_AudioDeviceTest, SetPlayoutDevice) {
henrikaec9c7452018-06-08 16:10:03 +0200753 SKIP_TEST_IF_NOT(requirements_satisfied());
754 int num_devices = audio_device()->PlayoutDevices();
755 if (NewWindowsAudioDeviceModuleIsUsed()) {
756 num_devices += 2;
757 }
758 EXPECT_GT(num_devices, 0);
759 // Verify that all available playout devices can be set (not enabled yet).
760 for (int i = 0; i < num_devices; ++i) {
761 EXPECT_EQ(0, audio_device()->SetPlayoutDevice(i));
762 }
763 EXPECT_EQ(-1, audio_device()->SetPlayoutDevice(num_devices));
764#ifdef WEBRTC_WIN
765 // On Windows, verify the alternative method where the user can select device
766 // by role.
767 EXPECT_EQ(
768 0, audio_device()->SetPlayoutDevice(AudioDeviceModule::kDefaultDevice));
769 EXPECT_EQ(0, audio_device()->SetPlayoutDevice(
770 AudioDeviceModule::kDefaultCommunicationDevice));
771#endif
772}
773
774// Counts number of active input devices and ensure that all can be selected.
Yves Gereyff060ee2019-09-11 15:53:01 +0200775TEST_P(MAYBE_AudioDeviceTest, SetRecordingDevice) {
henrikaec9c7452018-06-08 16:10:03 +0200776 SKIP_TEST_IF_NOT(requirements_satisfied());
777 int num_devices = audio_device()->RecordingDevices();
778 if (NewWindowsAudioDeviceModuleIsUsed()) {
779 num_devices += 2;
780 }
781 EXPECT_GT(num_devices, 0);
782 // Verify that all available recording devices can be set (not enabled yet).
783 for (int i = 0; i < num_devices; ++i) {
784 EXPECT_EQ(0, audio_device()->SetRecordingDevice(i));
785 }
786 EXPECT_EQ(-1, audio_device()->SetRecordingDevice(num_devices));
787#ifdef WEBRTC_WIN
788 // On Windows, verify the alternative method where the user can select device
789 // by role.
790 EXPECT_EQ(
791 0, audio_device()->SetRecordingDevice(AudioDeviceModule::kDefaultDevice));
792 EXPECT_EQ(0, audio_device()->SetRecordingDevice(
793 AudioDeviceModule::kDefaultCommunicationDevice));
794#endif
795}
796
797// Tests Start/Stop playout without any registered audio callback.
Yves Gereyff060ee2019-09-11 15:53:01 +0200798TEST_P(MAYBE_AudioDeviceTest, StartStopPlayout) {
henrikaec9c7452018-06-08 16:10:03 +0200799 SKIP_TEST_IF_NOT(requirements_satisfied());
henrikaf2f91fa2017-03-17 04:26:22 -0700800 StartPlayout();
801 StopPlayout();
802}
803
804// Tests Start/Stop recording without any registered audio callback.
Yves Gereyff060ee2019-09-11 15:53:01 +0200805TEST_P(MAYBE_AudioDeviceTest, StartStopRecording) {
henrikaf2f91fa2017-03-17 04:26:22 -0700806 SKIP_TEST_IF_NOT(requirements_satisfied());
807 StartRecording();
808 StopRecording();
henrikaf2f91fa2017-03-17 04:26:22 -0700809}
810
henrika351173c2019-11-18 17:36:08 +0100811// Tests Start/Stop playout for all available input devices to ensure that
812// the selected device can be created and used as intended.
813TEST_P(MAYBE_AudioDeviceTest, StartStopPlayoutWithRealDevice) {
814 SKIP_TEST_IF_NOT(requirements_satisfied());
815 int num_devices = audio_device()->PlayoutDevices();
816 if (NewWindowsAudioDeviceModuleIsUsed()) {
817 num_devices += 2;
818 }
819 EXPECT_GT(num_devices, 0);
820 // Verify that all available playout devices can be set and used.
821 for (int i = 0; i < num_devices; ++i) {
822 EXPECT_EQ(0, audio_device()->SetPlayoutDevice(i));
823 StartPlayout();
824 StopPlayout();
825 }
826#ifdef WEBRTC_WIN
827 AudioDeviceModule::WindowsDeviceType device_role[] = {
828 AudioDeviceModule::kDefaultDevice,
829 AudioDeviceModule::kDefaultCommunicationDevice};
830 for (size_t i = 0; i < arraysize(device_role); ++i) {
831 EXPECT_EQ(0, audio_device()->SetPlayoutDevice(device_role[i]));
832 StartPlayout();
833 StopPlayout();
834 }
835#endif
836}
837
838// Tests Start/Stop recording for all available input devices to ensure that
839// the selected device can be created and used as intended.
840TEST_P(MAYBE_AudioDeviceTest, StartStopRecordingWithRealDevice) {
841 SKIP_TEST_IF_NOT(requirements_satisfied());
842 int num_devices = audio_device()->RecordingDevices();
843 if (NewWindowsAudioDeviceModuleIsUsed()) {
844 num_devices += 2;
845 }
846 EXPECT_GT(num_devices, 0);
847 // Verify that all available recording devices can be set and used.
848 for (int i = 0; i < num_devices; ++i) {
849 EXPECT_EQ(0, audio_device()->SetRecordingDevice(i));
850 StartRecording();
851 StopRecording();
852 }
853#ifdef WEBRTC_WIN
854 AudioDeviceModule::WindowsDeviceType device_role[] = {
855 AudioDeviceModule::kDefaultDevice,
856 AudioDeviceModule::kDefaultCommunicationDevice};
857 for (size_t i = 0; i < arraysize(device_role); ++i) {
858 EXPECT_EQ(0, audio_device()->SetRecordingDevice(device_role[i]));
859 StartRecording();
860 StopRecording();
861 }
862#endif
863}
864
henrika6b3e1a22017-09-25 16:34:30 +0200865// Tests Init/Stop/Init recording without any registered audio callback.
866// See https://bugs.chromium.org/p/webrtc/issues/detail?id=8041 for details
867// on why this test is useful.
Yves Gereyff060ee2019-09-11 15:53:01 +0200868TEST_P(MAYBE_AudioDeviceTest, InitStopInitRecording) {
henrika6b3e1a22017-09-25 16:34:30 +0200869 SKIP_TEST_IF_NOT(requirements_satisfied());
870 EXPECT_EQ(0, audio_device()->InitRecording());
871 EXPECT_TRUE(audio_device()->RecordingIsInitialized());
872 StopRecording();
873 EXPECT_EQ(0, audio_device()->InitRecording());
874 StopRecording();
875}
876
henrikad4049462019-07-12 13:37:11 +0200877// Verify that additional attempts to initialize or start recording while
878// already being active works. Additional calls should just be ignored.
Yves Gereyff060ee2019-09-11 15:53:01 +0200879TEST_P(MAYBE_AudioDeviceTest, StartInitRecording) {
henrikad4049462019-07-12 13:37:11 +0200880 SKIP_TEST_IF_NOT(requirements_satisfied());
881 StartRecording();
882 // An additional attempt to initialize at this stage should be ignored.
883 EXPECT_EQ(0, audio_device()->InitRecording());
884 // Same for additional request to start recording while already active.
885 EXPECT_EQ(0, audio_device()->StartRecording());
886 StopRecording();
887}
888
889// Verify that additional attempts to initialize or start playou while
890// already being active works. Additional calls should just be ignored.
Yves Gereyff060ee2019-09-11 15:53:01 +0200891TEST_P(MAYBE_AudioDeviceTest, StartInitPlayout) {
henrikad4049462019-07-12 13:37:11 +0200892 SKIP_TEST_IF_NOT(requirements_satisfied());
893 StartPlayout();
894 // An additional attempt to initialize at this stage should be ignored.
895 EXPECT_EQ(0, audio_device()->InitPlayout());
896 // Same for additional request to start playout while already active.
897 EXPECT_EQ(0, audio_device()->StartPlayout());
898 StopPlayout();
899}
900
henrika6b3e1a22017-09-25 16:34:30 +0200901// Tests Init/Stop/Init recording while playout is active.
Yves Gereyff060ee2019-09-11 15:53:01 +0200902TEST_P(MAYBE_AudioDeviceTest, InitStopInitRecordingWhilePlaying) {
henrika6b3e1a22017-09-25 16:34:30 +0200903 SKIP_TEST_IF_NOT(requirements_satisfied());
904 StartPlayout();
905 EXPECT_EQ(0, audio_device()->InitRecording());
906 EXPECT_TRUE(audio_device()->RecordingIsInitialized());
907 StopRecording();
908 EXPECT_EQ(0, audio_device()->InitRecording());
909 StopRecording();
910 StopPlayout();
911}
912
913// Tests Init/Stop/Init playout without any registered audio callback.
Yves Gereyff060ee2019-09-11 15:53:01 +0200914TEST_P(MAYBE_AudioDeviceTest, InitStopInitPlayout) {
henrika6b3e1a22017-09-25 16:34:30 +0200915 SKIP_TEST_IF_NOT(requirements_satisfied());
916 EXPECT_EQ(0, audio_device()->InitPlayout());
917 EXPECT_TRUE(audio_device()->PlayoutIsInitialized());
918 StopPlayout();
919 EXPECT_EQ(0, audio_device()->InitPlayout());
920 StopPlayout();
921}
922
923// Tests Init/Stop/Init playout while recording is active.
Yves Gereyff060ee2019-09-11 15:53:01 +0200924TEST_P(MAYBE_AudioDeviceTest, InitStopInitPlayoutWhileRecording) {
henrika6b3e1a22017-09-25 16:34:30 +0200925 SKIP_TEST_IF_NOT(requirements_satisfied());
926 StartRecording();
927 EXPECT_EQ(0, audio_device()->InitPlayout());
928 EXPECT_TRUE(audio_device()->PlayoutIsInitialized());
929 StopPlayout();
930 EXPECT_EQ(0, audio_device()->InitPlayout());
931 StopPlayout();
932 StopRecording();
933}
934
henrika5b6afc02018-09-05 14:34:40 +0200935// TODO(henrika): restart without intermediate destruction is currently only
936// supported on Windows.
937#ifdef WEBRTC_WIN
938// Tests Start/Stop playout followed by a second session (emulates a restart
939// triggered by a user using public APIs).
Yves Gereyff060ee2019-09-11 15:53:01 +0200940TEST_P(MAYBE_AudioDeviceTest, StartStopPlayoutWithExternalRestart) {
henrika5b6afc02018-09-05 14:34:40 +0200941 SKIP_TEST_IF_NOT(requirements_satisfied());
942 StartPlayout();
943 StopPlayout();
944 // Restart playout without destroying the ADM in between. Ensures that we
945 // support: Init(), Start(), Stop(), Init(), Start(), Stop().
946 StartPlayout();
947 StopPlayout();
948}
949
950// Tests Start/Stop recording followed by a second session (emulates a restart
951// triggered by a user using public APIs).
Yves Gereyff060ee2019-09-11 15:53:01 +0200952TEST_P(MAYBE_AudioDeviceTest, StartStopRecordingWithExternalRestart) {
henrika5b6afc02018-09-05 14:34:40 +0200953 SKIP_TEST_IF_NOT(requirements_satisfied());
954 StartRecording();
955 StopRecording();
956 // Restart recording without destroying the ADM in between. Ensures that we
957 // support: Init(), Start(), Stop(), Init(), Start(), Stop().
958 StartRecording();
959 StopRecording();
960}
961
962// Tests Start/Stop playout followed by a second session (emulates a restart
963// triggered by an internal callback e.g. corresponding to a device switch).
964// Note that, internal restart is only supported in combination with the latest
965// Windows ADM.
Yves Gereyff060ee2019-09-11 15:53:01 +0200966TEST_P(MAYBE_AudioDeviceTest, StartStopPlayoutWithInternalRestart) {
henrika5b6afc02018-09-05 14:34:40 +0200967 SKIP_TEST_IF_NOT(requirements_satisfied());
968 if (audio_layer() != AudioDeviceModule::kWindowsCoreAudio2) {
969 return;
970 }
971 MockAudioTransport mock(TransportType::kPlay);
972 mock.HandleCallbacks(event(), nullptr, kNumCallbacks);
973 EXPECT_CALL(mock, NeedMorePlayData(_, _, _, _, NotNull(), _, _, _))
974 .Times(AtLeast(kNumCallbacks));
975 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
976 StartPlayout();
977 event()->Wait(kTestTimeOutInMilliseconds);
978 EXPECT_TRUE(audio_device()->Playing());
979 // Restart playout but without stopping the internal audio thread.
980 // This procedure uses a non-public test API and it emulates what happens
981 // inside the ADM when e.g. a device is removed.
982 EXPECT_EQ(0, audio_device()->RestartPlayoutInternally());
983
984 // Run basic tests of public APIs while a restart attempt is active.
985 // These calls should now be very thin and not trigger any new actions.
986 EXPECT_EQ(-1, audio_device()->StopPlayout());
987 EXPECT_TRUE(audio_device()->Playing());
988 EXPECT_TRUE(audio_device()->PlayoutIsInitialized());
989 EXPECT_EQ(0, audio_device()->InitPlayout());
990 EXPECT_EQ(0, audio_device()->StartPlayout());
991
992 // Wait until audio has restarted and a new sequence of audio callbacks
993 // becomes active.
994 // TODO(henrika): is it possible to verify that the internal state transition
995 // is Stop->Init->Start?
996 ASSERT_TRUE(Mock::VerifyAndClearExpectations(&mock));
997 mock.ResetCallbackCounters();
998 EXPECT_CALL(mock, NeedMorePlayData(_, _, _, _, NotNull(), _, _, _))
999 .Times(AtLeast(kNumCallbacks));
1000 event()->Wait(kTestTimeOutInMilliseconds);
1001 EXPECT_TRUE(audio_device()->Playing());
1002 // Stop playout and the audio thread after successful internal restart.
1003 StopPlayout();
Yves Gereyb93a2452019-07-19 22:46:13 +02001004 PreTearDown();
henrika5b6afc02018-09-05 14:34:40 +02001005}
1006
1007// Tests Start/Stop recording followed by a second session (emulates a restart
1008// triggered by an internal callback e.g. corresponding to a device switch).
1009// Note that, internal restart is only supported in combination with the latest
1010// Windows ADM.
Yves Gereyff060ee2019-09-11 15:53:01 +02001011TEST_P(MAYBE_AudioDeviceTest, StartStopRecordingWithInternalRestart) {
henrika5b6afc02018-09-05 14:34:40 +02001012 SKIP_TEST_IF_NOT(requirements_satisfied());
1013 if (audio_layer() != AudioDeviceModule::kWindowsCoreAudio2) {
1014 return;
1015 }
1016 MockAudioTransport mock(TransportType::kRecord);
1017 mock.HandleCallbacks(event(), nullptr, kNumCallbacks);
1018 EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(), _, _, _, _, Ge(0u), 0, _,
1019 false, _))
1020 .Times(AtLeast(kNumCallbacks));
1021 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
1022 StartRecording();
1023 event()->Wait(kTestTimeOutInMilliseconds);
1024 EXPECT_TRUE(audio_device()->Recording());
1025 // Restart recording but without stopping the internal audio thread.
1026 // This procedure uses a non-public test API and it emulates what happens
1027 // inside the ADM when e.g. a device is removed.
1028 EXPECT_EQ(0, audio_device()->RestartRecordingInternally());
1029
1030 // Run basic tests of public APIs while a restart attempt is active.
1031 // These calls should now be very thin and not trigger any new actions.
1032 EXPECT_EQ(-1, audio_device()->StopRecording());
1033 EXPECT_TRUE(audio_device()->Recording());
1034 EXPECT_TRUE(audio_device()->RecordingIsInitialized());
1035 EXPECT_EQ(0, audio_device()->InitRecording());
1036 EXPECT_EQ(0, audio_device()->StartRecording());
1037
1038 // Wait until audio has restarted and a new sequence of audio callbacks
1039 // becomes active.
1040 // TODO(henrika): is it possible to verify that the internal state transition
1041 // is Stop->Init->Start?
1042 ASSERT_TRUE(Mock::VerifyAndClearExpectations(&mock));
1043 mock.ResetCallbackCounters();
1044 EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(), _, _, _, _, Ge(0u), 0, _,
1045 false, _))
1046 .Times(AtLeast(kNumCallbacks));
1047 event()->Wait(kTestTimeOutInMilliseconds);
1048 EXPECT_TRUE(audio_device()->Recording());
1049 // Stop recording and the audio thread after successful internal restart.
1050 StopRecording();
Yves Gereyb93a2452019-07-19 22:46:13 +02001051 PreTearDown();
henrika5b6afc02018-09-05 14:34:40 +02001052}
1053#endif // #ifdef WEBRTC_WIN
1054
henrikaf2f91fa2017-03-17 04:26:22 -07001055// Start playout and verify that the native audio layer starts asking for real
1056// audio samples to play out using the NeedMorePlayData() callback.
1057// Note that we can't add expectations on audio parameters in EXPECT_CALL
1058// since parameter are not provided in the each callback. We therefore test and
1059// verify the parameters in the fake audio transport implementation instead.
Yves Gereyff060ee2019-09-11 15:53:01 +02001060TEST_P(MAYBE_AudioDeviceTest, StartPlayoutVerifyCallbacks) {
henrikaf2f91fa2017-03-17 04:26:22 -07001061 SKIP_TEST_IF_NOT(requirements_satisfied());
1062 MockAudioTransport mock(TransportType::kPlay);
henrikae24991d2017-04-06 01:14:23 -07001063 mock.HandleCallbacks(event(), nullptr, kNumCallbacks);
henrikaf2f91fa2017-03-17 04:26:22 -07001064 EXPECT_CALL(mock, NeedMorePlayData(_, _, _, _, NotNull(), _, _, _))
1065 .Times(AtLeast(kNumCallbacks));
1066 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
1067 StartPlayout();
1068 event()->Wait(kTestTimeOutInMilliseconds);
1069 StopPlayout();
Yves Gerey412282a2019-07-22 21:15:22 +02001070 PreTearDown();
henrikaf2f91fa2017-03-17 04:26:22 -07001071}
1072
Yves Gerey704c8c42019-08-13 22:32:46 +02001073// Don't run these tests in combination with sanitizers.
1074// They are already flaky *without* sanitizers.
1075// Sanitizers seem to increase flakiness (which brings noise),
1076// without reporting anything.
1077// TODO(webrtc:10867): Re-enable when flakiness fixed.
1078#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
1079 defined(THREAD_SANITIZER)
1080#define MAYBE_StartRecordingVerifyCallbacks \
1081 DISABLED_StartRecordingVerifyCallbacks
1082#define MAYBE_StartPlayoutAndRecordingVerifyCallbacks \
1083 DISABLED_StartPlayoutAndRecordingVerifyCallbacks
1084#else
1085#define MAYBE_StartRecordingVerifyCallbacks StartRecordingVerifyCallbacks
1086#define MAYBE_StartPlayoutAndRecordingVerifyCallbacks \
1087 StartPlayoutAndRecordingVerifyCallbacks
1088#endif
1089
henrikaf2f91fa2017-03-17 04:26:22 -07001090// Start recording and verify that the native audio layer starts providing real
1091// audio samples using the RecordedDataIsAvailable() callback.
Yves Gereyff060ee2019-09-11 15:53:01 +02001092TEST_P(MAYBE_AudioDeviceTest, MAYBE_StartRecordingVerifyCallbacks) {
henrikaf2f91fa2017-03-17 04:26:22 -07001093 SKIP_TEST_IF_NOT(requirements_satisfied());
1094 MockAudioTransport mock(TransportType::kRecord);
henrikae24991d2017-04-06 01:14:23 -07001095 mock.HandleCallbacks(event(), nullptr, kNumCallbacks);
henrikaf2f91fa2017-03-17 04:26:22 -07001096 EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(), _, _, _, _, Ge(0u), 0, _,
1097 false, _))
1098 .Times(AtLeast(kNumCallbacks));
1099 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
1100 StartRecording();
1101 event()->Wait(kTestTimeOutInMilliseconds);
1102 StopRecording();
Yves Gereyb93a2452019-07-19 22:46:13 +02001103 PreTearDown();
henrikaf2f91fa2017-03-17 04:26:22 -07001104}
1105
1106// Start playout and recording (full-duplex audio) and verify that audio is
1107// active in both directions.
Yves Gereyff060ee2019-09-11 15:53:01 +02001108TEST_P(MAYBE_AudioDeviceTest, MAYBE_StartPlayoutAndRecordingVerifyCallbacks) {
henrikaf2f91fa2017-03-17 04:26:22 -07001109 SKIP_TEST_IF_NOT(requirements_satisfied());
1110 MockAudioTransport mock(TransportType::kPlayAndRecord);
henrikae24991d2017-04-06 01:14:23 -07001111 mock.HandleCallbacks(event(), nullptr, kNumCallbacks);
henrikaf2f91fa2017-03-17 04:26:22 -07001112 EXPECT_CALL(mock, NeedMorePlayData(_, _, _, _, NotNull(), _, _, _))
1113 .Times(AtLeast(kNumCallbacks));
1114 EXPECT_CALL(mock, RecordedDataIsAvailable(NotNull(), _, _, _, _, Ge(0u), 0, _,
1115 false, _))
1116 .Times(AtLeast(kNumCallbacks));
1117 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
1118 StartPlayout();
1119 StartRecording();
1120 event()->Wait(kTestTimeOutInMilliseconds);
1121 StopRecording();
1122 StopPlayout();
Yves Gereyb93a2452019-07-19 22:46:13 +02001123 PreTearDown();
henrikaf2f91fa2017-03-17 04:26:22 -07001124}
1125
henrikae24991d2017-04-06 01:14:23 -07001126// Start playout and recording and store recorded data in an intermediate FIFO
1127// buffer from which the playout side then reads its samples in the same order
1128// as they were stored. Under ideal circumstances, a callback sequence would
1129// look like: ...+-+-+-+-+-+-+-..., where '+' means 'packet recorded' and '-'
1130// means 'packet played'. Under such conditions, the FIFO would contain max 1,
1131// with an average somewhere in (0,1) depending on how long the packets are
1132// buffered. However, under more realistic conditions, the size
1133// of the FIFO will vary more due to an unbalance between the two sides.
1134// This test tries to verify that the device maintains a balanced callback-
1135// sequence by running in loopback for a few seconds while measuring the size
1136// (max and average) of the FIFO. The size of the FIFO is increased by the
1137// recording side and decreased by the playout side.
Yves Gereyff060ee2019-09-11 15:53:01 +02001138TEST_P(MAYBE_AudioDeviceTest, RunPlayoutAndRecordingInFullDuplex) {
henrikae24991d2017-04-06 01:14:23 -07001139 SKIP_TEST_IF_NOT(requirements_satisfied());
1140 NiceMock<MockAudioTransport> mock(TransportType::kPlayAndRecord);
1141 FifoAudioStream audio_stream;
1142 mock.HandleCallbacks(event(), &audio_stream,
1143 kFullDuplexTimeInSec * kNumCallbacksPerSecond);
1144 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
henrikaeb98c722018-03-20 12:54:07 +01001145 // Run both sides using the same channel configuration to avoid conversions
1146 // between mono/stereo while running in full duplex mode. Also, some devices
1147 // (mainly on Windows) do not support mono.
1148 EXPECT_EQ(0, audio_device()->SetStereoPlayout(true));
1149 EXPECT_EQ(0, audio_device()->SetStereoRecording(true));
Gustaf Ullberg102b7282019-06-03 15:03:02 +02001150 // Mute speakers to prevent howling.
1151 EXPECT_EQ(0, audio_device()->SetSpeakerVolume(0));
henrikae24991d2017-04-06 01:14:23 -07001152 StartPlayout();
1153 StartRecording();
henrika714e5cd2017-04-20 08:03:11 -07001154 event()->Wait(static_cast<int>(
1155 std::max(kTestTimeOutInMilliseconds, 1000 * kFullDuplexTimeInSec)));
henrikae24991d2017-04-06 01:14:23 -07001156 StopRecording();
1157 StopPlayout();
Yves Gerey412282a2019-07-22 21:15:22 +02001158 PreTearDown();
henrikae24991d2017-04-06 01:14:23 -07001159}
1160
henrika5b6afc02018-09-05 14:34:40 +02001161// Runs audio in full duplex until user hits Enter. Intended as a manual test
1162// to ensure that the audio quality is good and that real device switches works
1163// as intended.
Yves Gereyff060ee2019-09-11 15:53:01 +02001164TEST_P(MAYBE_AudioDeviceTest,
henrika5b6afc02018-09-05 14:34:40 +02001165 DISABLED_RunPlayoutAndRecordingInFullDuplexAndWaitForEnterKey) {
1166 SKIP_TEST_IF_NOT(requirements_satisfied());
1167 if (audio_layer() != AudioDeviceModule::kWindowsCoreAudio2) {
1168 return;
1169 }
1170 NiceMock<MockAudioTransport> mock(TransportType::kPlayAndRecord);
1171 FifoAudioStream audio_stream;
1172 mock.HandleCallbacks(&audio_stream);
1173 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
1174 EXPECT_EQ(0, audio_device()->SetStereoPlayout(true));
1175 EXPECT_EQ(0, audio_device()->SetStereoRecording(true));
1176 // Ensure that the sample rate for both directions are identical so that we
1177 // always can listen to our own voice. Will lead to rate conversion (and
1178 // higher latency) if the native sample rate is not 48kHz.
1179 EXPECT_EQ(0, audio_device()->SetPlayoutSampleRate(48000));
1180 EXPECT_EQ(0, audio_device()->SetRecordingSampleRate(48000));
1181 StartPlayout();
1182 StartRecording();
1183 do {
1184 PRINT("Loopback audio is active at 48kHz. Press Enter to stop.\n");
1185 } while (getchar() != '\n');
1186 StopRecording();
1187 StopPlayout();
Yves Gereyb93a2452019-07-19 22:46:13 +02001188 PreTearDown();
henrika5b6afc02018-09-05 14:34:40 +02001189}
1190
henrika714e5cd2017-04-20 08:03:11 -07001191// Measures loopback latency and reports the min, max and average values for
1192// a full duplex audio session.
1193// The latency is measured like so:
1194// - Insert impulses periodically on the output side.
1195// - Detect the impulses on the input side.
1196// - Measure the time difference between the transmit time and receive time.
1197// - Store time differences in a vector and calculate min, max and average.
1198// This test needs the '--gtest_also_run_disabled_tests' flag to run and also
1199// some sort of audio feedback loop. E.g. a headset where the mic is placed
1200// close to the speaker to ensure highest possible echo. It is also recommended
1201// to run the test at highest possible output volume.
Yves Gereyff060ee2019-09-11 15:53:01 +02001202TEST_P(MAYBE_AudioDeviceTest, DISABLED_MeasureLoopbackLatency) {
henrika714e5cd2017-04-20 08:03:11 -07001203 SKIP_TEST_IF_NOT(requirements_satisfied());
1204 NiceMock<MockAudioTransport> mock(TransportType::kPlayAndRecord);
1205 LatencyAudioStream audio_stream;
1206 mock.HandleCallbacks(event(), &audio_stream,
1207 kMeasureLatencyTimeInSec * kNumCallbacksPerSecond);
1208 EXPECT_EQ(0, audio_device()->RegisterAudioCallback(&mock));
henrikaeb98c722018-03-20 12:54:07 +01001209 EXPECT_EQ(0, audio_device()->SetStereoPlayout(true));
1210 EXPECT_EQ(0, audio_device()->SetStereoRecording(true));
henrika714e5cd2017-04-20 08:03:11 -07001211 StartPlayout();
1212 StartRecording();
1213 event()->Wait(static_cast<int>(
1214 std::max(kTestTimeOutInMilliseconds, 1000 * kMeasureLatencyTimeInSec)));
1215 StopRecording();
1216 StopPlayout();
Yves Gerey412282a2019-07-22 21:15:22 +02001217 // Avoid concurrent access to audio_stream.
1218 PreTearDown();
henrikac7d93582018-09-14 15:37:34 +02001219 // Verify that a sufficient number of transmitted impulses are detected.
1220 EXPECT_GE(audio_stream.num_latency_values(),
henrika714e5cd2017-04-20 08:03:11 -07001221 static_cast<size_t>(
henrikac7d93582018-09-14 15:37:34 +02001222 kImpulseFrequencyInHz * kMeasureLatencyTimeInSec - 2));
henrika714e5cd2017-04-20 08:03:11 -07001223 // Print out min, max and average delay values for debugging purposes.
1224 audio_stream.PrintResults();
1225}
1226
henrikaec9c7452018-06-08 16:10:03 +02001227#ifdef WEBRTC_WIN
1228// Test two different audio layers (or rather two different Core Audio
1229// implementations) for Windows.
Mirko Bonadeic84f6612019-01-31 12:20:57 +01001230INSTANTIATE_TEST_SUITE_P(
henrikaec9c7452018-06-08 16:10:03 +02001231 AudioLayerWin,
Yves Gereyff060ee2019-09-11 15:53:01 +02001232 MAYBE_AudioDeviceTest,
henrikaec9c7452018-06-08 16:10:03 +02001233 ::testing::Values(AudioDeviceModule::kPlatformDefaultAudio,
1234 AudioDeviceModule::kWindowsCoreAudio2));
1235#else
1236// For all platforms but Windows, only test the default audio layer.
Mirko Bonadeic84f6612019-01-31 12:20:57 +01001237INSTANTIATE_TEST_SUITE_P(
henrikaec9c7452018-06-08 16:10:03 +02001238 AudioLayer,
Yves Gereyff060ee2019-09-11 15:53:01 +02001239 MAYBE_AudioDeviceTest,
henrikaec9c7452018-06-08 16:10:03 +02001240 ::testing::Values(AudioDeviceModule::kPlatformDefaultAudio));
1241#endif
1242
henrikaf2f91fa2017-03-17 04:26:22 -07001243} // namespace webrtc