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