blob: 1420e5ea8a575e2dd4219b682b6dc32bf9ba4289 [file] [log] [blame]
Avi Drissmand6cdf9b2022-09-15 19:52:531// Copyright 2016 The Chromium Authors
sergeyu2c5c0c202016-10-05 22:51:142// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "remoting/protocol/webrtc_audio_module.h"
6
Jinho Bang138fde32018-01-18 23:13:427#include <memory>
8
sergeyu2c5c0c202016-10-05 22:51:149#include "base/bind.h"
Patrick Monette643cdf62021-10-15 19:13:4210#include "base/task/single_thread_task_runner.h"
sergeyu53c571c2017-01-24 07:11:0111#include "base/timer/timer.h"
sergeyu2c5c0c202016-10-05 22:51:1412
Joe Downing39d710e2022-08-25 20:11:4513namespace remoting::protocol {
sergeyu2c5c0c202016-10-05 22:51:1414
15namespace {
16
17const int kSamplingRate = 48000;
18
19// Webrtc uses 10ms frames.
20const int kFrameLengthMs = 10;
21const int kSamplesPerFrame = kSamplingRate * kFrameLengthMs / 1000;
22
23constexpr base::TimeDelta kPollInterval =
Peter Kastinge5a38ed2021-10-02 03:06:3524 base::Milliseconds(5 * kFrameLengthMs);
sergeyu2c5c0c202016-10-05 22:51:1425const int kChannels = 2;
26const int kBytesPerSample = 2;
27
28} // namespace
29
30// webrtc::AudioDeviceModule is a generic interface that aims to provide all
31// functionality normally supported audio input/output devices, but most of
32// the functions are never called in Webrtc. This class implements only
33// functions that are actually used. All unused functions are marked as
34// NOTREACHED().
35
Chris Watkins6fe52aa2017-11-28 03:24:0536WebrtcAudioModule::WebrtcAudioModule() = default;
37WebrtcAudioModule::~WebrtcAudioModule() = default;
sergeyu2c5c0c202016-10-05 22:51:1438
39void WebrtcAudioModule::SetAudioTaskRunner(
40 scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner) {
41 DCHECK(!audio_task_runner_);
42 DCHECK(audio_task_runner);
43 audio_task_runner_ = audio_task_runner;
44}
45
sergeyu2c5c0c202016-10-05 22:51:1446int32_t WebrtcAudioModule::ActiveAudioLayer(AudioLayer* audio_layer) const {
47 NOTREACHED();
48 return -1;
49}
50
sergeyu2c5c0c202016-10-05 22:51:1451int32_t WebrtcAudioModule::RegisterAudioCallback(
52 webrtc::AudioTransport* audio_transport) {
53 base::AutoLock lock(lock_);
54 audio_transport_ = audio_transport;
55 return 0;
56}
57
58int32_t WebrtcAudioModule::Init() {
59 base::AutoLock auto_lock(lock_);
60 initialized_ = true;
61 return 0;
62}
63
64int32_t WebrtcAudioModule::Terminate() {
65 base::AutoLock auto_lock(lock_);
66 initialized_ = false;
67 return 0;
68}
69
70bool WebrtcAudioModule::Initialized() const {
71 base::AutoLock auto_lock(lock_);
72 return initialized_;
73}
74
75int16_t WebrtcAudioModule::PlayoutDevices() {
76 return 0;
77}
78
79int16_t WebrtcAudioModule::RecordingDevices() {
80 return 0;
81}
82
83int32_t WebrtcAudioModule::PlayoutDeviceName(
84 uint16_t index,
85 char name[webrtc::kAdmMaxDeviceNameSize],
86 char guid[webrtc::kAdmMaxGuidSize]) {
87 return 0;
88}
89
90int32_t WebrtcAudioModule::RecordingDeviceName(
91 uint16_t index,
92 char name[webrtc::kAdmMaxDeviceNameSize],
93 char guid[webrtc::kAdmMaxGuidSize]) {
94 return 0;
95}
96
97int32_t WebrtcAudioModule::SetPlayoutDevice(uint16_t index) {
98 return 0;
99}
100
101int32_t WebrtcAudioModule::SetPlayoutDevice(WindowsDeviceType device) {
102 return 0;
103}
104
105int32_t WebrtcAudioModule::SetRecordingDevice(uint16_t index) {
106 return 0;
107}
108
109int32_t WebrtcAudioModule::SetRecordingDevice(WindowsDeviceType device) {
110 return 0;
111}
112
113int32_t WebrtcAudioModule::PlayoutIsAvailable(bool* available) {
114 NOTREACHED();
115 return -1;
116}
117
118int32_t WebrtcAudioModule::InitPlayout() {
119 return 0;
120}
121
122bool WebrtcAudioModule::PlayoutIsInitialized() const {
123 base::AutoLock auto_lock(lock_);
124 return initialized_;
125}
126
127int32_t WebrtcAudioModule::RecordingIsAvailable(bool* available) {
128 NOTREACHED();
129 return -1;
130}
131
132int32_t WebrtcAudioModule::InitRecording() {
133 return 0;
134}
135
136bool WebrtcAudioModule::RecordingIsInitialized() const {
137 return false;
138}
139
140int32_t WebrtcAudioModule::StartPlayout() {
141 base::AutoLock auto_lock(lock_);
142 if (!playing_ && audio_task_runner_) {
143 audio_task_runner_->PostTask(
tzikecb28472018-07-27 00:59:12144 FROM_HERE, base::BindOnce(&WebrtcAudioModule::StartPlayoutOnAudioThread,
145 rtc::scoped_refptr<WebrtcAudioModule>(this)));
sergeyu2c5c0c202016-10-05 22:51:14146 playing_ = true;
147 }
148 return 0;
149}
150
151int32_t WebrtcAudioModule::StopPlayout() {
152 base::AutoLock auto_lock(lock_);
153 if (playing_) {
154 audio_task_runner_->PostTask(
tzikecb28472018-07-27 00:59:12155 FROM_HERE, base::BindOnce(&WebrtcAudioModule::StopPlayoutOnAudioThread,
156 rtc::scoped_refptr<WebrtcAudioModule>(this)));
sergeyu2c5c0c202016-10-05 22:51:14157 playing_ = false;
158 }
159 return 0;
160}
161
162bool WebrtcAudioModule::Playing() const {
163 base::AutoLock auto_lock(lock_);
164 return playing_;
165}
166
167int32_t WebrtcAudioModule::StartRecording() {
168 return 0;
169}
170
171int32_t WebrtcAudioModule::StopRecording() {
172 return 0;
173}
174
175bool WebrtcAudioModule::Recording() const {
176 return false;
177}
178
sergeyu2c5c0c202016-10-05 22:51:14179int32_t WebrtcAudioModule::InitSpeaker() {
180 return 0;
181}
182
183bool WebrtcAudioModule::SpeakerIsInitialized() const {
184 return false;
185}
186
187int32_t WebrtcAudioModule::InitMicrophone() {
188 return 0;
189}
190
191bool WebrtcAudioModule::MicrophoneIsInitialized() const {
192 return false;
193}
194
195int32_t WebrtcAudioModule::SpeakerVolumeIsAvailable(bool* available) {
196 NOTREACHED();
197 return -1;
198}
199
200int32_t WebrtcAudioModule::SetSpeakerVolume(uint32_t volume) {
201 NOTREACHED();
202 return -1;
203}
204
205int32_t WebrtcAudioModule::SpeakerVolume(uint32_t* volume) const {
206 NOTREACHED();
207 return -1;
208}
209
210int32_t WebrtcAudioModule::MaxSpeakerVolume(uint32_t* max_volume) const {
211 NOTREACHED();
212 return -1;
213}
214
215int32_t WebrtcAudioModule::MinSpeakerVolume(uint32_t* min_volume) const {
216 NOTREACHED();
217 return -1;
218}
219
sergeyu2c5c0c202016-10-05 22:51:14220int32_t WebrtcAudioModule::MicrophoneVolumeIsAvailable(bool* available) {
221 NOTREACHED();
222 return -1;
223}
224
225int32_t WebrtcAudioModule::SetMicrophoneVolume(uint32_t volume) {
226 NOTREACHED();
227 return -1;
228}
229
230int32_t WebrtcAudioModule::MicrophoneVolume(uint32_t* volume) const {
231 NOTREACHED();
232 return -1;
233}
234
235int32_t WebrtcAudioModule::MaxMicrophoneVolume(uint32_t* max_volume) const {
236 NOTREACHED();
237 return -1;
238}
239
240int32_t WebrtcAudioModule::MinMicrophoneVolume(uint32_t* min_volume) const {
241 NOTREACHED();
242 return -1;
243}
244
sergeyu2c5c0c202016-10-05 22:51:14245int32_t WebrtcAudioModule::SpeakerMuteIsAvailable(bool* available) {
246 NOTREACHED();
247 return -1;
248}
249
250int32_t WebrtcAudioModule::SetSpeakerMute(bool enable) {
251 NOTREACHED();
252 return -1;
253}
254
255int32_t WebrtcAudioModule::SpeakerMute(bool* enabled) const {
256 NOTREACHED();
257 return -1;
258}
259
260int32_t WebrtcAudioModule::MicrophoneMuteIsAvailable(bool* available) {
261 NOTREACHED();
262 return -1;
263}
264
265int32_t WebrtcAudioModule::SetMicrophoneMute(bool enable) {
266 NOTREACHED();
267 return -1;
268}
269
270int32_t WebrtcAudioModule::MicrophoneMute(bool* enabled) const {
271 NOTREACHED();
272 return -1;
273}
274
sergeyu2c5c0c202016-10-05 22:51:14275int32_t WebrtcAudioModule::StereoPlayoutIsAvailable(bool* available) const {
276 *available = true;
277 return 0;
278}
279
280int32_t WebrtcAudioModule::SetStereoPlayout(bool enable) {
281 DCHECK(enable);
282 return 0;
283}
284
285int32_t WebrtcAudioModule::StereoPlayout(bool* enabled) const {
286 NOTREACHED();
287 return -1;
288}
289
290int32_t WebrtcAudioModule::StereoRecordingIsAvailable(bool* available) const {
291 *available = false;
292 return 0;
293}
294
295int32_t WebrtcAudioModule::SetStereoRecording(bool enable) {
296 return 0;
297}
298
299int32_t WebrtcAudioModule::StereoRecording(bool* enabled) const {
300 NOTREACHED();
301 return -1;
302}
303
sergeyu2c5c0c202016-10-05 22:51:14304int32_t WebrtcAudioModule::PlayoutDelay(uint16_t* delay_ms) const {
305 *delay_ms = 0;
306 return 0;
307}
308
sergeyu2c5c0c202016-10-05 22:51:14309bool WebrtcAudioModule::BuiltInAECIsAvailable() const {
310 return false;
311}
312
313bool WebrtcAudioModule::BuiltInAGCIsAvailable() const {
314 return false;
315}
316
317bool WebrtcAudioModule::BuiltInNSIsAvailable() const {
318 return false;
319}
320
321int32_t WebrtcAudioModule::EnableBuiltInAEC(bool enable) {
322 NOTREACHED();
323 return -1;
324}
325
326int32_t WebrtcAudioModule::EnableBuiltInAGC(bool enable) {
327 NOTREACHED();
328 return -1;
329}
330
331int32_t WebrtcAudioModule::EnableBuiltInNS(bool enable) {
332 NOTREACHED();
333 return -1;
334}
335
336#if defined(WEBRTC_IOS)
337int WebrtcAudioModule::GetPlayoutAudioParameters(
nicholss1b5df0c2016-10-25 16:04:49338 webrtc::AudioParameters* params) const {
sergeyu2c5c0c202016-10-05 22:51:14339 NOTREACHED();
340 return -1;
341}
342
nicholss1b5df0c2016-10-25 16:04:49343int WebrtcAudioModule::GetRecordAudioParameters(
344 webrtc::AudioParameters* params) const {
sergeyu2c5c0c202016-10-05 22:51:14345 NOTREACHED();
346 return -1;
347}
348#endif // WEBRTC_IOS
349
350void WebrtcAudioModule::StartPlayoutOnAudioThread() {
351 DCHECK(audio_task_runner_->BelongsToCurrentThread());
Jinho Bang138fde32018-01-18 23:13:42352 poll_timer_ = std::make_unique<base::RepeatingTimer>();
tzikecb28472018-07-27 00:59:12353 poll_timer_->Start(FROM_HERE, kPollInterval,
354 base::BindRepeating(&WebrtcAudioModule::PollFromSource,
355 base::Unretained(this)));
sergeyu2c5c0c202016-10-05 22:51:14356}
357
358void WebrtcAudioModule::StopPlayoutOnAudioThread() {
359 DCHECK(audio_task_runner_->BelongsToCurrentThread());
sergeyu53c571c2017-01-24 07:11:01360 poll_timer_.reset();
sergeyu2c5c0c202016-10-05 22:51:14361}
362
363void WebrtcAudioModule::PollFromSource() {
364 DCHECK(audio_task_runner_->BelongsToCurrentThread());
365
366 base::AutoLock lock(lock_);
Joe Downing353ba2c72023-01-11 22:37:34367 if (!audio_transport_) {
sergeyu2c5c0c202016-10-05 22:51:14368 return;
Joe Downing353ba2c72023-01-11 22:37:34369 }
sergeyu2c5c0c202016-10-05 22:51:14370
371 for (int i = 0; i < kPollInterval.InMilliseconds() / kFrameLengthMs; i++) {
372 int64_t elapsed_time_ms = -1;
373 int64_t ntp_time_ms = -1;
374 char data[kBytesPerSample * kChannels * kSamplesPerFrame];
375 audio_transport_->PullRenderData(kBytesPerSample * 8, kSamplingRate,
376 kChannels, kSamplesPerFrame, data,
377 &elapsed_time_ms, &ntp_time_ms);
378 }
379}
380
Joe Downing39d710e2022-08-25 20:11:45381} // namespace remoting::protocol