Skip to content

Commit e42bf81

Browse files
Artem TitovWebRTC LUCI CQ
authored andcommitted
Migrate TestAudioDeviceModule on AudioDeviceModuleImpl
Bug: b/272350185 Change-Id: Ia3d85d6fa3b0d4809e987a39d60d3eb022687132 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/300363 Commit-Queue: Artem Titov <titovartem@webrtc.org> Reviewed-by: Henrik Andreassson <henrika@webrtc.org> Cr-Commit-Position: refs/heads/main@{#39877}
1 parent 59d09ae commit e42bf81

11 files changed

+970
-183
lines changed

modules/audio_device/BUILD.gn

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ rtc_library("audio_device_impl") {
192192
"../../api:scoped_refptr",
193193
"../../api:sequence_checker",
194194
"../../api/task_queue",
195+
"../../api/units:time_delta",
195196
"../../common_audio",
196197
"../../common_audio:common_audio_c",
197198
"../../rtc_base:buffer",
@@ -217,6 +218,7 @@ rtc_library("audio_device_impl") {
217218
absl_deps = [
218219
"//third_party/abseil-cpp/absl/base:core_headers",
219220
"//third_party/abseil-cpp/absl/strings:strings",
221+
"//third_party/abseil-cpp/absl/types:optional",
220222
]
221223
if (rtc_include_internal_audio_device && is_ios) {
222224
deps += [ "../../sdk:audio_device" ]
@@ -228,8 +230,6 @@ rtc_library("audio_device_impl") {
228230
"dummy/file_audio_device.cc",
229231
"dummy/file_audio_device.h",
230232
"include/fake_audio_device.h",
231-
"include/test_audio_device.cc",
232-
"include/test_audio_device.h",
233233
]
234234

235235
if (build_with_mozilla) {
@@ -253,6 +253,10 @@ rtc_library("audio_device_impl") {
253253
"audio_device_impl.cc",
254254
"audio_device_impl.h",
255255
"include/audio_device_data_observer.h",
256+
"include/test_audio_device.cc",
257+
"include/test_audio_device.h",
258+
"test_audio_device_impl.cc",
259+
"test_audio_device_impl.h",
256260
]
257261
if (is_android) {
258262
sources += [
@@ -414,17 +418,21 @@ if (rtc_include_tests && !build_with_chromium) {
414418
sources = [
415419
"fine_audio_buffer_unittest.cc",
416420
"include/test_audio_device_unittest.cc",
421+
"test_audio_device_impl_test.cc",
417422
]
418423
deps = [
419424
":audio_device",
420425
":audio_device_buffer",
426+
":audio_device_generic",
421427
":audio_device_impl",
422428
":mock_audio_device",
423429
"../../api:array_view",
424430
"../../api:scoped_refptr",
425431
"../../api:sequence_checker",
426432
"../../api/task_queue",
427433
"../../api/task_queue:default_task_queue_factory",
434+
"../../api/units:time_delta",
435+
"../../api/units:timestamp",
428436
"../../common_audio",
429437
"../../rtc_base:buffer",
430438
"../../rtc_base:checks",
@@ -439,6 +447,7 @@ if (rtc_include_tests && !build_with_chromium) {
439447
"../../system_wrappers",
440448
"../../test:fileutils",
441449
"../../test:test_support",
450+
"../../test/time_controller",
442451
]
443452
absl_deps = [
444453
"//third_party/abseil-cpp/absl/strings",

modules/audio_device/audio_device_buffer.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ static const size_t kMinValidCallTimeTimeInMilliseconds =
4141
static const double k2Pi = 6.28318530717959;
4242
#endif
4343

44-
AudioDeviceBuffer::AudioDeviceBuffer(TaskQueueFactory* task_queue_factory)
44+
AudioDeviceBuffer::AudioDeviceBuffer(TaskQueueFactory* task_queue_factory,
45+
bool create_detached)
4546
: task_queue_(task_queue_factory->CreateTaskQueue(
4647
kTimerQueueName,
4748
TaskQueueFactory::Priority::NORMAL)),
@@ -67,6 +68,9 @@ AudioDeviceBuffer::AudioDeviceBuffer(TaskQueueFactory* task_queue_factory)
6768
phase_ = 0.0;
6869
RTC_LOG(LS_WARNING) << "AUDIO_DEVICE_PLAYS_SINUS_TONE is defined!";
6970
#endif
71+
if (create_detached) {
72+
main_thread_checker_.Detach();
73+
}
7074
}
7175

7276
AudioDeviceBuffer::~AudioDeviceBuffer() {

modules/audio_device/audio_device_buffer.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,11 @@ class AudioDeviceBuffer {
7878
int16_t max_play_level = 0;
7979
};
8080

81-
explicit AudioDeviceBuffer(TaskQueueFactory* task_queue_factory);
81+
// If `create_detached` is true, created buffer can be used on another
82+
// thread compared to the one on which it was created. It's useful for
83+
// testing.
84+
explicit AudioDeviceBuffer(TaskQueueFactory* task_queue_factory,
85+
bool create_detached = false);
8286
virtual ~AudioDeviceBuffer();
8387

8488
int32_t RegisterAudioCallback(AudioTransport* audio_callback);

modules/audio_device/audio_device_impl.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,17 @@ AudioDeviceModuleImpl::AudioDeviceModuleImpl(
121121
RTC_DLOG(LS_INFO) << __FUNCTION__;
122122
}
123123

124+
AudioDeviceModuleImpl::AudioDeviceModuleImpl(
125+
AudioLayer audio_layer,
126+
std::unique_ptr<AudioDeviceGeneric> audio_device,
127+
TaskQueueFactory* task_queue_factory,
128+
bool create_detached)
129+
: audio_layer_(audio_layer),
130+
audio_device_buffer_(task_queue_factory, create_detached),
131+
audio_device_(std::move(audio_device)) {
132+
RTC_DLOG(LS_INFO) << __FUNCTION__;
133+
}
134+
124135
int32_t AudioDeviceModuleImpl::CheckPlatform() {
125136
RTC_DLOG(LS_INFO) << __FUNCTION__;
126137
// Ensure that the current platform is supported
@@ -140,6 +151,9 @@ int32_t AudioDeviceModuleImpl::CheckPlatform() {
140151
#elif defined(WEBRTC_MAC)
141152
platform = kPlatformMac;
142153
RTC_LOG(LS_INFO) << "current platform is Mac";
154+
#elif defined(WEBRTC_FUCHSIA)
155+
platform = kPlatformFuchsia;
156+
RTC_LOG(LS_INFO) << "current platform is Fuchsia";
143157
#endif
144158
if (platform == kPlatformNotSupported) {
145159
RTC_LOG(LS_ERROR)
@@ -153,6 +167,10 @@ int32_t AudioDeviceModuleImpl::CheckPlatform() {
153167

154168
int32_t AudioDeviceModuleImpl::CreatePlatformSpecificObjects() {
155169
RTC_LOG(LS_INFO) << __FUNCTION__;
170+
if (audio_device_ != nullptr) {
171+
RTC_LOG(LS_INFO) << "Reusing provided audio device";
172+
return 0;
173+
}
156174
// Dummy ADM implementations if build flags are set.
157175
#if defined(WEBRTC_DUMMY_AUDIO_BUILD)
158176
audio_device_.reset(new AudioDeviceDummy());

modules/audio_device/audio_device_impl.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,12 @@ class AudioDeviceModuleImpl : public AudioDeviceModuleForTest {
3535
kPlatformLinux = 3,
3636
kPlatformMac = 4,
3737
kPlatformAndroid = 5,
38-
kPlatformIOS = 6
38+
kPlatformIOS = 6,
39+
// Fuchsia isn't fully supported, as there is no implementation for
40+
// AudioDeviceGeneric which will be created for Fuchsia, so
41+
// `CreatePlatformSpecificObjects()` call will fail unless usable
42+
// implementation will be provided by the user.
43+
kPlatformFuchsia = 7,
3944
};
4045

4146
int32_t CheckPlatform();
@@ -44,6 +49,12 @@ class AudioDeviceModuleImpl : public AudioDeviceModuleForTest {
4449

4550
AudioDeviceModuleImpl(AudioLayer audio_layer,
4651
TaskQueueFactory* task_queue_factory);
52+
// If `create_detached` is true, created ADM can be used on another thread
53+
// compared to the one on which it was created. It's useful for testing.
54+
AudioDeviceModuleImpl(AudioLayer audio_layer,
55+
std::unique_ptr<AudioDeviceGeneric> audio_device,
56+
TaskQueueFactory* task_queue_factory,
57+
bool create_detached);
4758
~AudioDeviceModuleImpl() override;
4859

4960
// Retrieve the currently utilized audio layer

modules/audio_device/include/test_audio_device.cc

Lines changed: 37 additions & 158 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222
#include "api/array_view.h"
2323
#include "api/make_ref_counted.h"
2424
#include "common_audio/wav_file.h"
25+
#include "modules/audio_device/audio_device_impl.h"
2526
#include "modules/audio_device/include/audio_device_default.h"
27+
#include "modules/audio_device/test_audio_device_impl.h"
2628
#include "rtc_base/buffer.h"
2729
#include "rtc_base/checks.h"
2830
#include "rtc_base/event.h"
@@ -43,164 +45,23 @@ namespace {
4345
constexpr int kFrameLengthUs = 10000;
4446
constexpr int kFramesPerSecond = rtc::kNumMicrosecsPerSec / kFrameLengthUs;
4547

46-
// TestAudioDeviceModule implements an AudioDevice module that can act both as a
47-
// capturer and a renderer. It will use 10ms audio frames.
48-
class TestAudioDeviceModuleImpl
49-
: public webrtc_impl::AudioDeviceModuleDefault<TestAudioDeviceModule> {
48+
class TestAudioDeviceModuleImpl : public AudioDeviceModuleImpl {
5049
public:
51-
// Creates a new TestAudioDeviceModule. When capturing or playing, 10 ms audio
52-
// frames will be processed every 10ms / `speed`.
53-
// `capturer` is an object that produces audio data. Can be nullptr if this
54-
// device is never used for recording.
55-
// `renderer` is an object that receives audio data that would have been
56-
// played out. Can be nullptr if this device is never used for playing.
57-
// Use one of the Create... functions to get these instances.
58-
TestAudioDeviceModuleImpl(TaskQueueFactory* task_queue_factory,
59-
std::unique_ptr<Capturer> capturer,
60-
std::unique_ptr<Renderer> renderer,
61-
float speed = 1)
62-
: task_queue_factory_(task_queue_factory),
63-
capturer_(std::move(capturer)),
64-
renderer_(std::move(renderer)),
65-
process_interval_us_(kFrameLengthUs / speed),
66-
audio_callback_(nullptr),
67-
rendering_(false),
68-
capturing_(false) {
69-
auto good_sample_rate = [](int sr) {
70-
return sr == 8000 || sr == 16000 || sr == 32000 || sr == 44100 ||
71-
sr == 48000;
72-
};
73-
74-
if (renderer_) {
75-
const int sample_rate = renderer_->SamplingFrequency();
76-
playout_buffer_.resize(
77-
SamplesPerFrame(sample_rate) * renderer_->NumChannels(), 0);
78-
RTC_CHECK(good_sample_rate(sample_rate));
79-
}
80-
if (capturer_) {
81-
RTC_CHECK(good_sample_rate(capturer_->SamplingFrequency()));
82-
}
83-
}
84-
85-
~TestAudioDeviceModuleImpl() override {
86-
StopPlayout();
87-
StopRecording();
88-
}
89-
90-
int32_t Init() override {
91-
task_queue_ =
92-
std::make_unique<rtc::TaskQueue>(task_queue_factory_->CreateTaskQueue(
93-
"TestAudioDeviceModuleImpl", TaskQueueFactory::Priority::NORMAL));
94-
95-
RepeatingTaskHandle::Start(task_queue_->Get(), [this]() {
96-
ProcessAudio();
97-
return TimeDelta::Micros(process_interval_us_);
98-
});
99-
return 0;
100-
}
101-
102-
int32_t RegisterAudioCallback(AudioTransport* callback) override {
103-
MutexLock lock(&lock_);
104-
RTC_DCHECK(callback || audio_callback_);
105-
audio_callback_ = callback;
106-
return 0;
107-
}
108-
109-
int32_t StartPlayout() override {
110-
MutexLock lock(&lock_);
111-
RTC_CHECK(renderer_);
112-
rendering_ = true;
113-
return 0;
114-
}
115-
116-
int32_t StopPlayout() override {
117-
MutexLock lock(&lock_);
118-
rendering_ = false;
119-
return 0;
120-
}
121-
122-
int32_t StartRecording() override {
123-
MutexLock lock(&lock_);
124-
RTC_CHECK(capturer_);
125-
capturing_ = true;
126-
return 0;
127-
}
128-
129-
int32_t StopRecording() override {
130-
MutexLock lock(&lock_);
131-
capturing_ = false;
132-
return 0;
133-
}
134-
135-
bool Playing() const override {
136-
MutexLock lock(&lock_);
137-
return rendering_;
138-
}
139-
140-
bool Recording() const override {
141-
MutexLock lock(&lock_);
142-
return capturing_;
143-
}
144-
145-
// Blocks forever until the Recorder stops producing data.
146-
void WaitForRecordingEnd() override {
147-
done_capturing_.Wait(rtc::Event::kForever);
148-
}
149-
150-
private:
151-
void ProcessAudio() {
152-
MutexLock lock(&lock_);
153-
if (capturing_) {
154-
// Capture 10ms of audio. 2 bytes per sample.
155-
const bool keep_capturing = capturer_->Capture(&recording_buffer_);
156-
uint32_t new_mic_level = 0;
157-
if (recording_buffer_.size() > 0) {
158-
audio_callback_->RecordedDataIsAvailable(
159-
recording_buffer_.data(),
160-
recording_buffer_.size() / capturer_->NumChannels(),
161-
2 * capturer_->NumChannels(), capturer_->NumChannels(),
162-
capturer_->SamplingFrequency(), /*totalDelayMS=*/0,
163-
/*clockDrift=*/0,
164-
/*currentMicLevel=*/0, /*keyPressed=*/false, new_mic_level,
165-
absl::make_optional(rtc::TimeNanos()));
166-
}
167-
if (!keep_capturing) {
168-
capturing_ = false;
169-
done_capturing_.Set();
170-
}
171-
}
172-
if (rendering_) {
173-
size_t samples_out = 0;
174-
int64_t elapsed_time_ms = -1;
175-
int64_t ntp_time_ms = -1;
176-
const int sampling_frequency = renderer_->SamplingFrequency();
177-
audio_callback_->NeedMorePlayData(
178-
SamplesPerFrame(sampling_frequency), 2 * renderer_->NumChannels(),
179-
renderer_->NumChannels(), sampling_frequency, playout_buffer_.data(),
180-
samples_out, &elapsed_time_ms, &ntp_time_ms);
181-
const bool keep_rendering = renderer_->Render(
182-
rtc::ArrayView<const int16_t>(playout_buffer_.data(), samples_out));
183-
if (!keep_rendering) {
184-
rendering_ = false;
185-
done_rendering_.Set();
186-
}
187-
}
188-
}
189-
TaskQueueFactory* const task_queue_factory_;
190-
const std::unique_ptr<Capturer> capturer_ RTC_GUARDED_BY(lock_);
191-
const std::unique_ptr<Renderer> renderer_ RTC_GUARDED_BY(lock_);
192-
const int64_t process_interval_us_;
193-
194-
mutable Mutex lock_;
195-
AudioTransport* audio_callback_ RTC_GUARDED_BY(lock_);
196-
bool rendering_ RTC_GUARDED_BY(lock_);
197-
bool capturing_ RTC_GUARDED_BY(lock_);
198-
rtc::Event done_rendering_;
199-
rtc::Event done_capturing_;
200-
201-
std::vector<int16_t> playout_buffer_ RTC_GUARDED_BY(lock_);
202-
rtc::BufferT<int16_t> recording_buffer_ RTC_GUARDED_BY(lock_);
203-
std::unique_ptr<rtc::TaskQueue> task_queue_;
50+
TestAudioDeviceModuleImpl(
51+
TaskQueueFactory* task_queue_factory,
52+
std::unique_ptr<TestAudioDeviceModule::Capturer> capturer,
53+
std::unique_ptr<TestAudioDeviceModule::Renderer> renderer,
54+
float speed = 1)
55+
: AudioDeviceModuleImpl(
56+
AudioLayer::kDummyAudio,
57+
std::make_unique<TestAudioDevice>(task_queue_factory,
58+
std::move(capturer),
59+
std::move(renderer),
60+
speed),
61+
task_queue_factory,
62+
/*create_detached=*/true) {}
63+
64+
~TestAudioDeviceModuleImpl() override = default;
20465
};
20566

20667
// A fake capturer that generates pulses with random samples between
@@ -444,8 +305,26 @@ rtc::scoped_refptr<AudioDeviceModule> TestAudioDeviceModule::Create(
444305
std::unique_ptr<TestAudioDeviceModule::Capturer> capturer,
445306
std::unique_ptr<TestAudioDeviceModule::Renderer> renderer,
446307
float speed) {
447-
return rtc::make_ref_counted<TestAudioDeviceModuleImpl>(
308+
auto audio_device = rtc::make_ref_counted<TestAudioDeviceModuleImpl>(
448309
task_queue_factory, std::move(capturer), std::move(renderer), speed);
310+
311+
// Ensure that the current platform is supported.
312+
if (audio_device->CheckPlatform() == -1) {
313+
return nullptr;
314+
}
315+
316+
// Create the platform-dependent implementation.
317+
if (audio_device->CreatePlatformSpecificObjects() == -1) {
318+
return nullptr;
319+
}
320+
321+
// Ensure that the generic audio buffer can communicate with the platform
322+
// specific parts.
323+
if (audio_device->AttachAudioBuffer() == -1) {
324+
return nullptr;
325+
}
326+
327+
return audio_device;
449328
}
450329

451330
std::unique_ptr<TestAudioDeviceModule::PulsedNoiseCapturer>

0 commit comments

Comments
 (0)