blob: ad15ad5ac519418a7846503d2e29cdeb671ff98a [file] [log] [blame]
Artem Titov2cf8eb92023-06-30 13:26:091/*
2 * Copyright (c) 2023 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#include "modules/audio_device/test_audio_device_impl.h"
11
12#include <memory>
13#include <utility>
14
15#include "absl/types/optional.h"
Florent Castellif4673f92024-04-19 19:46:0316#include "api/audio/audio_device.h"
17#include "api/audio/audio_device_defines.h"
Artem Titov2cf8eb92023-06-30 13:26:0918#include "api/task_queue/task_queue_factory.h"
19#include "api/units/time_delta.h"
20#include "api/units/timestamp.h"
21#include "modules/audio_device/audio_device_buffer.h"
22#include "modules/audio_device/audio_device_generic.h"
Artem Titov2cf8eb92023-06-30 13:26:0923#include "modules/audio_device/include/test_audio_device.h"
24#include "rtc_base/checks.h"
25#include "rtc_base/synchronization/mutex.h"
26#include "test/gmock.h"
27#include "test/gtest.h"
28#include "test/time_controller/simulated_time_controller.h"
29
30namespace webrtc {
31namespace {
32
33using ::testing::ElementsAre;
34
35constexpr Timestamp kStartTime = Timestamp::Millis(10000);
36
37class TestAudioTransport : public AudioTransport {
38 public:
39 enum class Mode { kPlaying, kRecording };
40
41 explicit TestAudioTransport(Mode mode) : mode_(mode) {}
42 ~TestAudioTransport() override = default;
43
44 int32_t RecordedDataIsAvailable(
45 const void* audioSamples,
46 size_t samples_per_channel,
47 size_t bytes_per_sample,
48 size_t number_of_channels,
49 uint32_t samples_per_second,
50 uint32_t total_delay_ms,
51 int32_t clock_drift,
52 uint32_t current_mic_level,
53 bool key_pressed,
54 uint32_t& new_mic_level,
55 absl::optional<int64_t> estimated_capture_time_ns) override {
56 new_mic_level = 1;
57
58 if (mode_ != Mode::kRecording) {
59 EXPECT_TRUE(false) << "RecordedDataIsAvailable mustn't be called when "
60 "mode isn't kRecording";
61 return -1;
62 }
63
64 MutexLock lock(&mutex_);
65 samples_per_channel_.push_back(samples_per_channel);
66 number_of_channels_.push_back(number_of_channels);
67 bytes_per_sample_.push_back(bytes_per_sample);
68 samples_per_second_.push_back(samples_per_second);
69 return 0;
70 }
71
72 int32_t NeedMorePlayData(size_t samples_per_channel,
73 size_t bytes_per_sample,
74 size_t number_of_channels,
75 uint32_t samples_per_second,
76 void* audio_samples,
77 size_t& samples_out,
78 int64_t* elapsed_time_ms,
79 int64_t* ntp_time_ms) override {
80 const size_t num_bytes = samples_per_channel * number_of_channels;
81 std::memset(audio_samples, 1, num_bytes);
82 samples_out = samples_per_channel * number_of_channels;
83 *elapsed_time_ms = 0;
84 *ntp_time_ms = 0;
85
86 if (mode_ != Mode::kPlaying) {
87 EXPECT_TRUE(false)
88 << "NeedMorePlayData mustn't be called when mode isn't kPlaying";
89 return -1;
90 }
91
92 MutexLock lock(&mutex_);
93 samples_per_channel_.push_back(samples_per_channel);
94 number_of_channels_.push_back(number_of_channels);
95 bytes_per_sample_.push_back(bytes_per_sample);
96 samples_per_second_.push_back(samples_per_second);
97 return 0;
98 }
99
100 int32_t RecordedDataIsAvailable(const void* audio_samples,
101 size_t samples_per_channel,
102 size_t bytes_per_sample,
103 size_t number_of_channels,
104 uint32_t samples_per_second,
105 uint32_t total_delay_ms,
106 int32_t clockDrift,
107 uint32_t current_mic_level,
108 bool key_pressed,
109 uint32_t& new_mic_level) override {
110 RTC_CHECK(false) << "This methods should be never executed";
111 }
112
113 void PullRenderData(int bits_per_sample,
114 int sample_rate,
115 size_t number_of_channels,
116 size_t number_of_frames,
117 void* audio_data,
118 int64_t* elapsed_time_ms,
119 int64_t* ntp_time_ms) override {
120 RTC_CHECK(false) << "This methods should be never executed";
121 }
122
123 std::vector<size_t> samples_per_channel() const {
124 MutexLock lock(&mutex_);
125 return samples_per_channel_;
126 }
127 std::vector<size_t> number_of_channels() const {
128 MutexLock lock(&mutex_);
129 return number_of_channels_;
130 }
131 std::vector<size_t> bytes_per_sample() const {
132 MutexLock lock(&mutex_);
133 return bytes_per_sample_;
134 }
135 std::vector<size_t> samples_per_second() const {
136 MutexLock lock(&mutex_);
137 return samples_per_second_;
138 }
139
140 private:
141 const Mode mode_;
142
143 mutable Mutex mutex_;
144 std::vector<size_t> samples_per_channel_ RTC_GUARDED_BY(mutex_);
145 std::vector<size_t> number_of_channels_ RTC_GUARDED_BY(mutex_);
146 std::vector<size_t> bytes_per_sample_ RTC_GUARDED_BY(mutex_);
147 std::vector<size_t> samples_per_second_ RTC_GUARDED_BY(mutex_);
148};
149
150TEST(TestAudioDeviceTest, EnablingRecordingProducesAudio) {
151 GlobalSimulatedTimeController time_controller(kStartTime);
152 TestAudioTransport audio_transport(TestAudioTransport::Mode::kRecording);
153 AudioDeviceBuffer audio_buffer(time_controller.GetTaskQueueFactory());
154 ASSERT_EQ(audio_buffer.RegisterAudioCallback(&audio_transport), 0);
155 std::unique_ptr<TestAudioDeviceModule::PulsedNoiseCapturer> capturer =
156 TestAudioDeviceModule::CreatePulsedNoiseCapturer(
157 /*max_amplitude=*/1000,
158 /*sampling_frequency_in_hz=*/48000, /*num_channels=*/2);
159
160 TestAudioDevice audio_device(time_controller.GetTaskQueueFactory(),
161 std::move(capturer),
162 /*renderer=*/nullptr);
163 ASSERT_EQ(audio_device.Init(), AudioDeviceGeneric::InitStatus::OK);
164 audio_device.AttachAudioBuffer(&audio_buffer);
165
166 EXPECT_FALSE(audio_device.RecordingIsInitialized());
167 ASSERT_EQ(audio_device.InitRecording(), 0);
168 EXPECT_TRUE(audio_device.RecordingIsInitialized());
169 audio_buffer.StartRecording();
170 ASSERT_EQ(audio_device.StartRecording(), 0);
171 time_controller.AdvanceTime(TimeDelta::Millis(10));
172 ASSERT_TRUE(audio_device.Recording());
173 time_controller.AdvanceTime(TimeDelta::Millis(10));
174 ASSERT_EQ(audio_device.StopRecording(), 0);
175 audio_buffer.StopRecording();
176
177 EXPECT_THAT(audio_transport.samples_per_channel(),
178 ElementsAre(480, 480, 480));
179 EXPECT_THAT(audio_transport.number_of_channels(), ElementsAre(2, 2, 2));
180 EXPECT_THAT(audio_transport.bytes_per_sample(), ElementsAre(4, 4, 4));
181 EXPECT_THAT(audio_transport.samples_per_second(),
182 ElementsAre(48000, 48000, 48000));
183}
184
185TEST(TestAudioDeviceTest, RecordingIsAvailableWhenCapturerIsSet) {
186 GlobalSimulatedTimeController time_controller(kStartTime);
187 std::unique_ptr<TestAudioDeviceModule::PulsedNoiseCapturer> capturer =
188 TestAudioDeviceModule::CreatePulsedNoiseCapturer(
189 /*max_amplitude=*/1000,
190 /*sampling_frequency_in_hz=*/48000, /*num_channels=*/2);
191
192 TestAudioDevice audio_device(time_controller.GetTaskQueueFactory(),
193 std::move(capturer),
194 /*renderer=*/nullptr);
195 ASSERT_EQ(audio_device.Init(), AudioDeviceGeneric::InitStatus::OK);
196
197 bool available;
198 EXPECT_EQ(audio_device.RecordingIsAvailable(available), 0);
199 EXPECT_TRUE(available);
200}
201
202TEST(TestAudioDeviceTest, RecordingIsNotAvailableWhenCapturerIsNotSet) {
203 GlobalSimulatedTimeController time_controller(kStartTime);
204 TestAudioDevice audio_device(time_controller.GetTaskQueueFactory(),
205 /*capturer=*/nullptr,
206 /*renderer=*/nullptr);
207 ASSERT_EQ(audio_device.Init(), AudioDeviceGeneric::InitStatus::OK);
208
209 bool available;
210 EXPECT_EQ(audio_device.RecordingIsAvailable(available), 0);
211 EXPECT_FALSE(available);
212}
213
214TEST(TestAudioDeviceTest, EnablingPlayoutProducesAudio) {
215 GlobalSimulatedTimeController time_controller(kStartTime);
216 TestAudioTransport audio_transport(TestAudioTransport::Mode::kPlaying);
217 AudioDeviceBuffer audio_buffer(time_controller.GetTaskQueueFactory());
218 ASSERT_EQ(audio_buffer.RegisterAudioCallback(&audio_transport), 0);
219 std::unique_ptr<TestAudioDeviceModule::Renderer> renderer =
220 TestAudioDeviceModule::CreateDiscardRenderer(
221 /*sampling_frequency_in_hz=*/48000, /*num_channels=*/2);
222
223 TestAudioDevice audio_device(time_controller.GetTaskQueueFactory(),
224 /*capturer=*/nullptr, std::move(renderer));
225 ASSERT_EQ(audio_device.Init(), AudioDeviceGeneric::InitStatus::OK);
226 audio_device.AttachAudioBuffer(&audio_buffer);
227
228 EXPECT_FALSE(audio_device.PlayoutIsInitialized());
229 ASSERT_EQ(audio_device.InitPlayout(), 0);
230 EXPECT_TRUE(audio_device.PlayoutIsInitialized());
231 audio_buffer.StartPlayout();
232 ASSERT_EQ(audio_device.StartPlayout(), 0);
233 time_controller.AdvanceTime(TimeDelta::Millis(10));
234 ASSERT_TRUE(audio_device.Playing());
235 time_controller.AdvanceTime(TimeDelta::Millis(10));
236 ASSERT_EQ(audio_device.StopPlayout(), 0);
237 audio_buffer.StopPlayout();
238
239 EXPECT_THAT(audio_transport.samples_per_channel(),
240 ElementsAre(480, 480, 480));
241 EXPECT_THAT(audio_transport.number_of_channels(), ElementsAre(2, 2, 2));
242 EXPECT_THAT(audio_transport.bytes_per_sample(), ElementsAre(4, 4, 4));
243 EXPECT_THAT(audio_transport.samples_per_second(),
244 ElementsAre(48000, 48000, 48000));
245}
246
247TEST(TestAudioDeviceTest, PlayoutIsAvailableWhenRendererIsSet) {
248 GlobalSimulatedTimeController time_controller(kStartTime);
249 std::unique_ptr<TestAudioDeviceModule::Renderer> renderer =
250 TestAudioDeviceModule::CreateDiscardRenderer(
251 /*sampling_frequency_in_hz=*/48000, /*num_channels=*/2);
252
253 TestAudioDevice audio_device(time_controller.GetTaskQueueFactory(),
254 /*capturer=*/nullptr, std::move(renderer));
255 ASSERT_EQ(audio_device.Init(), AudioDeviceGeneric::InitStatus::OK);
256
257 bool available;
258 EXPECT_EQ(audio_device.PlayoutIsAvailable(available), 0);
259 EXPECT_TRUE(available);
260}
261
262TEST(TestAudioDeviceTest, PlayoutIsNotAvailableWhenRendererIsNotSet) {
263 GlobalSimulatedTimeController time_controller(kStartTime);
264 TestAudioDevice audio_device(time_controller.GetTaskQueueFactory(),
265 /*capturer=*/nullptr,
266 /*renderer=*/nullptr);
267 ASSERT_EQ(audio_device.Init(), AudioDeviceGeneric::InitStatus::OK);
268
269 bool available;
270 EXPECT_EQ(audio_device.PlayoutIsAvailable(available), 0);
271 EXPECT_FALSE(available);
272}
273
274} // namespace
275} // namespace webrtc