blob: 279b302b1386f1b96948df0e696d3d9cfe922685 [file] [log] [blame]
sergeyu2c5c0c202016-10-05 22:51:141// Copyright 2016 The Chromium Authors. All rights reserved.
2// 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"
Gabriel Charette5ff87ce2017-05-16 18:03:4510#include "base/single_thread_task_runner.h"
sergeyu2c5c0c202016-10-05 22:51:1411#include "base/stl_util.h"
12#include "base/threading/thread_task_runner_handle.h"
sergeyu53c571c2017-01-24 07:11:0113#include "base/timer/timer.h"
sergeyu2c5c0c202016-10-05 22:51:1414
15namespace remoting {
16namespace protocol {
17
18namespace {
19
20const int kSamplingRate = 48000;
21
22// Webrtc uses 10ms frames.
23const int kFrameLengthMs = 10;
24const int kSamplesPerFrame = kSamplingRate * kFrameLengthMs / 1000;
25
26constexpr base::TimeDelta kPollInterval =
27 base::TimeDelta::FromMilliseconds(5 * kFrameLengthMs);
28const int kChannels = 2;
29const int kBytesPerSample = 2;
30
31} // namespace
32
33// webrtc::AudioDeviceModule is a generic interface that aims to provide all
34// functionality normally supported audio input/output devices, but most of
35// the functions are never called in Webrtc. This class implements only
36// functions that are actually used. All unused functions are marked as
37// NOTREACHED().
38
Chris Watkins6fe52aa2017-11-28 03:24:0539WebrtcAudioModule::WebrtcAudioModule() = default;
40WebrtcAudioModule::~WebrtcAudioModule() = default;
sergeyu2c5c0c202016-10-05 22:51:1441
42void WebrtcAudioModule::SetAudioTaskRunner(
43 scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner) {
44 DCHECK(!audio_task_runner_);
45 DCHECK(audio_task_runner);
46 audio_task_runner_ = audio_task_runner;
47}
48
sergeyu2c5c0c202016-10-05 22:51:1449int32_t WebrtcAudioModule::ActiveAudioLayer(AudioLayer* audio_layer) const {
50 NOTREACHED();
51 return -1;
52}
53
sergeyu2c5c0c202016-10-05 22:51:1454int32_t WebrtcAudioModule::RegisterAudioCallback(
55 webrtc::AudioTransport* audio_transport) {
56 base::AutoLock lock(lock_);
57 audio_transport_ = audio_transport;
58 return 0;
59}
60
61int32_t WebrtcAudioModule::Init() {
62 base::AutoLock auto_lock(lock_);
63 initialized_ = true;
64 return 0;
65}
66
67int32_t WebrtcAudioModule::Terminate() {
68 base::AutoLock auto_lock(lock_);
69 initialized_ = false;
70 return 0;
71}
72
73bool WebrtcAudioModule::Initialized() const {
74 base::AutoLock auto_lock(lock_);
75 return initialized_;
76}
77
78int16_t WebrtcAudioModule::PlayoutDevices() {
79 return 0;
80}
81
82int16_t WebrtcAudioModule::RecordingDevices() {
83 return 0;
84}
85
86int32_t WebrtcAudioModule::PlayoutDeviceName(
87 uint16_t index,
88 char name[webrtc::kAdmMaxDeviceNameSize],
89 char guid[webrtc::kAdmMaxGuidSize]) {
90 return 0;
91}
92
93int32_t WebrtcAudioModule::RecordingDeviceName(
94 uint16_t index,
95 char name[webrtc::kAdmMaxDeviceNameSize],
96 char guid[webrtc::kAdmMaxGuidSize]) {
97 return 0;
98}
99
100int32_t WebrtcAudioModule::SetPlayoutDevice(uint16_t index) {
101 return 0;
102}
103
104int32_t WebrtcAudioModule::SetPlayoutDevice(WindowsDeviceType device) {
105 return 0;
106}
107
108int32_t WebrtcAudioModule::SetRecordingDevice(uint16_t index) {
109 return 0;
110}
111
112int32_t WebrtcAudioModule::SetRecordingDevice(WindowsDeviceType device) {
113 return 0;
114}
115
116int32_t WebrtcAudioModule::PlayoutIsAvailable(bool* available) {
117 NOTREACHED();
118 return -1;
119}
120
121int32_t WebrtcAudioModule::InitPlayout() {
122 return 0;
123}
124
125bool WebrtcAudioModule::PlayoutIsInitialized() const {
126 base::AutoLock auto_lock(lock_);
127 return initialized_;
128}
129
130int32_t WebrtcAudioModule::RecordingIsAvailable(bool* available) {
131 NOTREACHED();
132 return -1;
133}
134
135int32_t WebrtcAudioModule::InitRecording() {
136 return 0;
137}
138
139bool WebrtcAudioModule::RecordingIsInitialized() const {
140 return false;
141}
142
143int32_t WebrtcAudioModule::StartPlayout() {
144 base::AutoLock auto_lock(lock_);
145 if (!playing_ && audio_task_runner_) {
146 audio_task_runner_->PostTask(
147 FROM_HERE,
148 base::Bind(&WebrtcAudioModule::StartPlayoutOnAudioThread, this));
149 playing_ = true;
150 }
151 return 0;
152}
153
154int32_t WebrtcAudioModule::StopPlayout() {
155 base::AutoLock auto_lock(lock_);
156 if (playing_) {
157 audio_task_runner_->PostTask(
158 FROM_HERE,
159 base::Bind(&WebrtcAudioModule::StopPlayoutOnAudioThread, this));
160 playing_ = false;
161 }
162 return 0;
163}
164
165bool WebrtcAudioModule::Playing() const {
166 base::AutoLock auto_lock(lock_);
167 return playing_;
168}
169
170int32_t WebrtcAudioModule::StartRecording() {
171 return 0;
172}
173
174int32_t WebrtcAudioModule::StopRecording() {
175 return 0;
176}
177
178bool WebrtcAudioModule::Recording() const {
179 return false;
180}
181
sergeyu2c5c0c202016-10-05 22:51:14182int32_t WebrtcAudioModule::InitSpeaker() {
183 return 0;
184}
185
186bool WebrtcAudioModule::SpeakerIsInitialized() const {
187 return false;
188}
189
190int32_t WebrtcAudioModule::InitMicrophone() {
191 return 0;
192}
193
194bool WebrtcAudioModule::MicrophoneIsInitialized() const {
195 return false;
196}
197
198int32_t WebrtcAudioModule::SpeakerVolumeIsAvailable(bool* available) {
199 NOTREACHED();
200 return -1;
201}
202
203int32_t WebrtcAudioModule::SetSpeakerVolume(uint32_t volume) {
204 NOTREACHED();
205 return -1;
206}
207
208int32_t WebrtcAudioModule::SpeakerVolume(uint32_t* volume) const {
209 NOTREACHED();
210 return -1;
211}
212
213int32_t WebrtcAudioModule::MaxSpeakerVolume(uint32_t* max_volume) const {
214 NOTREACHED();
215 return -1;
216}
217
218int32_t WebrtcAudioModule::MinSpeakerVolume(uint32_t* min_volume) const {
219 NOTREACHED();
220 return -1;
221}
222
sergeyu2c5c0c202016-10-05 22:51:14223int32_t WebrtcAudioModule::MicrophoneVolumeIsAvailable(bool* available) {
224 NOTREACHED();
225 return -1;
226}
227
228int32_t WebrtcAudioModule::SetMicrophoneVolume(uint32_t volume) {
229 NOTREACHED();
230 return -1;
231}
232
233int32_t WebrtcAudioModule::MicrophoneVolume(uint32_t* volume) const {
234 NOTREACHED();
235 return -1;
236}
237
238int32_t WebrtcAudioModule::MaxMicrophoneVolume(uint32_t* max_volume) const {
239 NOTREACHED();
240 return -1;
241}
242
243int32_t WebrtcAudioModule::MinMicrophoneVolume(uint32_t* min_volume) const {
244 NOTREACHED();
245 return -1;
246}
247
sergeyu2c5c0c202016-10-05 22:51:14248int32_t WebrtcAudioModule::SpeakerMuteIsAvailable(bool* available) {
249 NOTREACHED();
250 return -1;
251}
252
253int32_t WebrtcAudioModule::SetSpeakerMute(bool enable) {
254 NOTREACHED();
255 return -1;
256}
257
258int32_t WebrtcAudioModule::SpeakerMute(bool* enabled) const {
259 NOTREACHED();
260 return -1;
261}
262
263int32_t WebrtcAudioModule::MicrophoneMuteIsAvailable(bool* available) {
264 NOTREACHED();
265 return -1;
266}
267
268int32_t WebrtcAudioModule::SetMicrophoneMute(bool enable) {
269 NOTREACHED();
270 return -1;
271}
272
273int32_t WebrtcAudioModule::MicrophoneMute(bool* enabled) const {
274 NOTREACHED();
275 return -1;
276}
277
sergeyu2c5c0c202016-10-05 22:51:14278int32_t WebrtcAudioModule::StereoPlayoutIsAvailable(bool* available) const {
279 *available = true;
280 return 0;
281}
282
283int32_t WebrtcAudioModule::SetStereoPlayout(bool enable) {
284 DCHECK(enable);
285 return 0;
286}
287
288int32_t WebrtcAudioModule::StereoPlayout(bool* enabled) const {
289 NOTREACHED();
290 return -1;
291}
292
293int32_t WebrtcAudioModule::StereoRecordingIsAvailable(bool* available) const {
294 *available = false;
295 return 0;
296}
297
298int32_t WebrtcAudioModule::SetStereoRecording(bool enable) {
299 return 0;
300}
301
302int32_t WebrtcAudioModule::StereoRecording(bool* enabled) const {
303 NOTREACHED();
304 return -1;
305}
306
sergeyu2c5c0c202016-10-05 22:51:14307int32_t WebrtcAudioModule::PlayoutDelay(uint16_t* delay_ms) const {
308 *delay_ms = 0;
309 return 0;
310}
311
sergeyu2c5c0c202016-10-05 22:51:14312bool WebrtcAudioModule::BuiltInAECIsAvailable() const {
313 return false;
314}
315
316bool WebrtcAudioModule::BuiltInAGCIsAvailable() const {
317 return false;
318}
319
320bool WebrtcAudioModule::BuiltInNSIsAvailable() const {
321 return false;
322}
323
324int32_t WebrtcAudioModule::EnableBuiltInAEC(bool enable) {
325 NOTREACHED();
326 return -1;
327}
328
329int32_t WebrtcAudioModule::EnableBuiltInAGC(bool enable) {
330 NOTREACHED();
331 return -1;
332}
333
334int32_t WebrtcAudioModule::EnableBuiltInNS(bool enable) {
335 NOTREACHED();
336 return -1;
337}
338
339#if defined(WEBRTC_IOS)
340int WebrtcAudioModule::GetPlayoutAudioParameters(
nicholss1b5df0c2016-10-25 16:04:49341 webrtc::AudioParameters* params) const {
sergeyu2c5c0c202016-10-05 22:51:14342 NOTREACHED();
343 return -1;
344}
345
nicholss1b5df0c2016-10-25 16:04:49346int WebrtcAudioModule::GetRecordAudioParameters(
347 webrtc::AudioParameters* params) const {
sergeyu2c5c0c202016-10-05 22:51:14348 NOTREACHED();
349 return -1;
350}
351#endif // WEBRTC_IOS
352
353void WebrtcAudioModule::StartPlayoutOnAudioThread() {
354 DCHECK(audio_task_runner_->BelongsToCurrentThread());
Jinho Bang138fde32018-01-18 23:13:42355 poll_timer_ = std::make_unique<base::RepeatingTimer>();
sergeyu53c571c2017-01-24 07:11:01356 poll_timer_->Start(
sergeyu2c5c0c202016-10-05 22:51:14357 FROM_HERE, kPollInterval,
358 base::Bind(&WebrtcAudioModule::PollFromSource, base::Unretained(this)));
359}
360
361void WebrtcAudioModule::StopPlayoutOnAudioThread() {
362 DCHECK(audio_task_runner_->BelongsToCurrentThread());
sergeyu53c571c2017-01-24 07:11:01363 poll_timer_.reset();
sergeyu2c5c0c202016-10-05 22:51:14364}
365
366void WebrtcAudioModule::PollFromSource() {
367 DCHECK(audio_task_runner_->BelongsToCurrentThread());
368
369 base::AutoLock lock(lock_);
370 if (!audio_transport_)
371 return;
372
373 for (int i = 0; i < kPollInterval.InMilliseconds() / kFrameLengthMs; i++) {
374 int64_t elapsed_time_ms = -1;
375 int64_t ntp_time_ms = -1;
376 char data[kBytesPerSample * kChannels * kSamplesPerFrame];
377 audio_transport_->PullRenderData(kBytesPerSample * 8, kSamplingRate,
378 kChannels, kSamplesPerFrame, data,
379 &elapsed_time_ms, &ntp_time_ms);
380 }
381}
382
383} // namespace protocol
384} // namespace remoting