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"
2625#include " modules/audio_device/include/audio_device_default.h"
27- #include " modules/audio_device/test_audio_device_impl.h"
2826#include " rtc_base/buffer.h"
2927#include " rtc_base/checks.h"
3028#include " rtc_base/event.h"
@@ -45,23 +43,164 @@ namespace {
4543constexpr int kFrameLengthUs = 10000 ;
4644constexpr int kFramesPerSecond = rtc::kNumMicrosecsPerSec / kFrameLengthUs ;
4745
48- class TestAudioDeviceModuleImpl : public AudioDeviceModuleImpl {
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> {
4950 public:
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 ;
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_;
65204};
66205
67206// A fake capturer that generates pulses with random samples between
@@ -305,26 +444,8 @@ rtc::scoped_refptr<AudioDeviceModule> TestAudioDeviceModule::Create(
305444 std::unique_ptr<TestAudioDeviceModule::Capturer> capturer,
306445 std::unique_ptr<TestAudioDeviceModule::Renderer> renderer,
307446 float speed) {
308- auto audio_device = rtc::make_ref_counted<TestAudioDeviceModuleImpl>(
447+ return rtc::make_ref_counted<TestAudioDeviceModuleImpl>(
309448 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;
328449}
329450
330451std::unique_ptr<TestAudioDeviceModule::PulsedNoiseCapturer>
0 commit comments