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 {
4345constexpr int kFrameLengthUs = 10000 ;
4446constexpr 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
451330std::unique_ptr<TestAudioDeviceModule::PulsedNoiseCapturer>
0 commit comments