blob: fa2d15ec482c5b9f77e2fbf293a23096c50ac092 [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
7#include "base/bind.h"
8#include "base/stl_util.h"
9#include "base/threading/thread_task_runner_handle.h"
10
11namespace remoting {
12namespace protocol {
13
14namespace {
15
16const int kSamplingRate = 48000;
17
18// Webrtc uses 10ms frames.
19const int kFrameLengthMs = 10;
20const int kSamplesPerFrame = kSamplingRate * kFrameLengthMs / 1000;
21
22constexpr base::TimeDelta kPollInterval =
23 base::TimeDelta::FromMilliseconds(5 * kFrameLengthMs);
24const int kChannels = 2;
25const int kBytesPerSample = 2;
26
27} // namespace
28
29// webrtc::AudioDeviceModule is a generic interface that aims to provide all
30// functionality normally supported audio input/output devices, but most of
31// the functions are never called in Webrtc. This class implements only
32// functions that are actually used. All unused functions are marked as
33// NOTREACHED().
34
35WebrtcAudioModule::WebrtcAudioModule() {}
36WebrtcAudioModule::~WebrtcAudioModule() {}
37
38void WebrtcAudioModule::SetAudioTaskRunner(
39 scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner) {
40 DCHECK(!audio_task_runner_);
41 DCHECK(audio_task_runner);
42 audio_task_runner_ = audio_task_runner;
43}
44
45int64_t WebrtcAudioModule::TimeUntilNextProcess() {
46 // We don't need to do anything in Process(), so return an arbitrary value
47 // that's not too low, so that Process() doesn't get called too frequently.
48 return 1000000;
49}
50
51void WebrtcAudioModule::Process() {}
52
53int32_t WebrtcAudioModule::ActiveAudioLayer(AudioLayer* audio_layer) const {
54 NOTREACHED();
55 return -1;
56}
57
58WebrtcAudioModule::ErrorCode WebrtcAudioModule::LastError() const {
59 return kAdmErrNone;
60}
61
62int32_t WebrtcAudioModule::RegisterEventObserver(
63 webrtc::AudioDeviceObserver* event_callback) {
64 return 0;
65}
66
67int32_t WebrtcAudioModule::RegisterAudioCallback(
68 webrtc::AudioTransport* audio_transport) {
69 base::AutoLock lock(lock_);
70 audio_transport_ = audio_transport;
71 return 0;
72}
73
74int32_t WebrtcAudioModule::Init() {
75 base::AutoLock auto_lock(lock_);
76 initialized_ = true;
77 return 0;
78}
79
80int32_t WebrtcAudioModule::Terminate() {
81 base::AutoLock auto_lock(lock_);
82 initialized_ = false;
83 return 0;
84}
85
86bool WebrtcAudioModule::Initialized() const {
87 base::AutoLock auto_lock(lock_);
88 return initialized_;
89}
90
91int16_t WebrtcAudioModule::PlayoutDevices() {
92 return 0;
93}
94
95int16_t WebrtcAudioModule::RecordingDevices() {
96 return 0;
97}
98
99int32_t WebrtcAudioModule::PlayoutDeviceName(
100 uint16_t index,
101 char name[webrtc::kAdmMaxDeviceNameSize],
102 char guid[webrtc::kAdmMaxGuidSize]) {
103 return 0;
104}
105
106int32_t WebrtcAudioModule::RecordingDeviceName(
107 uint16_t index,
108 char name[webrtc::kAdmMaxDeviceNameSize],
109 char guid[webrtc::kAdmMaxGuidSize]) {
110 return 0;
111}
112
113int32_t WebrtcAudioModule::SetPlayoutDevice(uint16_t index) {
114 return 0;
115}
116
117int32_t WebrtcAudioModule::SetPlayoutDevice(WindowsDeviceType device) {
118 return 0;
119}
120
121int32_t WebrtcAudioModule::SetRecordingDevice(uint16_t index) {
122 return 0;
123}
124
125int32_t WebrtcAudioModule::SetRecordingDevice(WindowsDeviceType device) {
126 return 0;
127}
128
129int32_t WebrtcAudioModule::PlayoutIsAvailable(bool* available) {
130 NOTREACHED();
131 return -1;
132}
133
134int32_t WebrtcAudioModule::InitPlayout() {
135 return 0;
136}
137
138bool WebrtcAudioModule::PlayoutIsInitialized() const {
139 base::AutoLock auto_lock(lock_);
140 return initialized_;
141}
142
143int32_t WebrtcAudioModule::RecordingIsAvailable(bool* available) {
144 NOTREACHED();
145 return -1;
146}
147
148int32_t WebrtcAudioModule::InitRecording() {
149 return 0;
150}
151
152bool WebrtcAudioModule::RecordingIsInitialized() const {
153 return false;
154}
155
156int32_t WebrtcAudioModule::StartPlayout() {
157 base::AutoLock auto_lock(lock_);
158 if (!playing_ && audio_task_runner_) {
159 audio_task_runner_->PostTask(
160 FROM_HERE,
161 base::Bind(&WebrtcAudioModule::StartPlayoutOnAudioThread, this));
162 playing_ = true;
163 }
164 return 0;
165}
166
167int32_t WebrtcAudioModule::StopPlayout() {
168 base::AutoLock auto_lock(lock_);
169 if (playing_) {
170 audio_task_runner_->PostTask(
171 FROM_HERE,
172 base::Bind(&WebrtcAudioModule::StopPlayoutOnAudioThread, this));
173 playing_ = false;
174 }
175 return 0;
176}
177
178bool WebrtcAudioModule::Playing() const {
179 base::AutoLock auto_lock(lock_);
180 return playing_;
181}
182
183int32_t WebrtcAudioModule::StartRecording() {
184 return 0;
185}
186
187int32_t WebrtcAudioModule::StopRecording() {
188 return 0;
189}
190
191bool WebrtcAudioModule::Recording() const {
192 return false;
193}
194
195int32_t WebrtcAudioModule::SetAGC(bool enable) {
196 return 0;
197}
198
199bool WebrtcAudioModule::AGC() const {
200 NOTREACHED();
201 return false;
202}
203
204int32_t WebrtcAudioModule::SetWaveOutVolume(uint16_t volume_left,
205 uint16_t volume_right) {
206 NOTREACHED();
207 return -1;
208}
209
210int32_t WebrtcAudioModule::WaveOutVolume(uint16_t* volume_left,
211 uint16_t* volume_right) const {
212 NOTREACHED();
213 return -1;
214}
215
216int32_t WebrtcAudioModule::InitSpeaker() {
217 return 0;
218}
219
220bool WebrtcAudioModule::SpeakerIsInitialized() const {
221 return false;
222}
223
224int32_t WebrtcAudioModule::InitMicrophone() {
225 return 0;
226}
227
228bool WebrtcAudioModule::MicrophoneIsInitialized() const {
229 return false;
230}
231
232int32_t WebrtcAudioModule::SpeakerVolumeIsAvailable(bool* available) {
233 NOTREACHED();
234 return -1;
235}
236
237int32_t WebrtcAudioModule::SetSpeakerVolume(uint32_t volume) {
238 NOTREACHED();
239 return -1;
240}
241
242int32_t WebrtcAudioModule::SpeakerVolume(uint32_t* volume) const {
243 NOTREACHED();
244 return -1;
245}
246
247int32_t WebrtcAudioModule::MaxSpeakerVolume(uint32_t* max_volume) const {
248 NOTREACHED();
249 return -1;
250}
251
252int32_t WebrtcAudioModule::MinSpeakerVolume(uint32_t* min_volume) const {
253 NOTREACHED();
254 return -1;
255}
256
257int32_t WebrtcAudioModule::SpeakerVolumeStepSize(uint16_t* step_size) const {
258 NOTREACHED();
259 return -1;
260}
261
262int32_t WebrtcAudioModule::MicrophoneVolumeIsAvailable(bool* available) {
263 NOTREACHED();
264 return -1;
265}
266
267int32_t WebrtcAudioModule::SetMicrophoneVolume(uint32_t volume) {
268 NOTREACHED();
269 return -1;
270}
271
272int32_t WebrtcAudioModule::MicrophoneVolume(uint32_t* volume) const {
273 NOTREACHED();
274 return -1;
275}
276
277int32_t WebrtcAudioModule::MaxMicrophoneVolume(uint32_t* max_volume) const {
278 NOTREACHED();
279 return -1;
280}
281
282int32_t WebrtcAudioModule::MinMicrophoneVolume(uint32_t* min_volume) const {
283 NOTREACHED();
284 return -1;
285}
286
287int32_t WebrtcAudioModule::MicrophoneVolumeStepSize(uint16_t* step_size) const {
288 NOTREACHED();
289 return -1;
290}
291
292int32_t WebrtcAudioModule::SpeakerMuteIsAvailable(bool* available) {
293 NOTREACHED();
294 return -1;
295}
296
297int32_t WebrtcAudioModule::SetSpeakerMute(bool enable) {
298 NOTREACHED();
299 return -1;
300}
301
302int32_t WebrtcAudioModule::SpeakerMute(bool* enabled) const {
303 NOTREACHED();
304 return -1;
305}
306
307int32_t WebrtcAudioModule::MicrophoneMuteIsAvailable(bool* available) {
308 NOTREACHED();
309 return -1;
310}
311
312int32_t WebrtcAudioModule::SetMicrophoneMute(bool enable) {
313 NOTREACHED();
314 return -1;
315}
316
317int32_t WebrtcAudioModule::MicrophoneMute(bool* enabled) const {
318 NOTREACHED();
319 return -1;
320}
321
322int32_t WebrtcAudioModule::MicrophoneBoostIsAvailable(bool* available) {
323 NOTREACHED();
324 return -1;
325}
326
327int32_t WebrtcAudioModule::SetMicrophoneBoost(bool enable) {
328 NOTREACHED();
329 return -1;
330}
331
332int32_t WebrtcAudioModule::MicrophoneBoost(bool* enabled) const {
333 NOTREACHED();
334 return -1;
335}
336
337int32_t WebrtcAudioModule::StereoPlayoutIsAvailable(bool* available) const {
338 *available = true;
339 return 0;
340}
341
342int32_t WebrtcAudioModule::SetStereoPlayout(bool enable) {
343 DCHECK(enable);
344 return 0;
345}
346
347int32_t WebrtcAudioModule::StereoPlayout(bool* enabled) const {
348 NOTREACHED();
349 return -1;
350}
351
352int32_t WebrtcAudioModule::StereoRecordingIsAvailable(bool* available) const {
353 *available = false;
354 return 0;
355}
356
357int32_t WebrtcAudioModule::SetStereoRecording(bool enable) {
358 return 0;
359}
360
361int32_t WebrtcAudioModule::StereoRecording(bool* enabled) const {
362 NOTREACHED();
363 return -1;
364}
365
366int32_t WebrtcAudioModule::SetRecordingChannel(const ChannelType channel) {
367 return 0;
368}
369
370int32_t WebrtcAudioModule::RecordingChannel(ChannelType* channel) const {
371 NOTREACHED();
372 return -1;
373}
374
375int32_t WebrtcAudioModule::SetPlayoutBuffer(const BufferType type,
376 uint16_t size_ms) {
377 NOTREACHED();
378 return -1;
379}
380
381int32_t WebrtcAudioModule::PlayoutBuffer(BufferType* type,
382 uint16_t* size_ms) const {
383 NOTREACHED();
384 return -1;
385}
386
387int32_t WebrtcAudioModule::PlayoutDelay(uint16_t* delay_ms) const {
388 *delay_ms = 0;
389 return 0;
390}
391
392int32_t WebrtcAudioModule::RecordingDelay(uint16_t* delay_ms) const {
393 NOTREACHED();
394 return -1;
395}
396
397int32_t WebrtcAudioModule::CPULoad(uint16_t* load) const {
398 NOTREACHED();
399 return -1;
400}
401
402int32_t WebrtcAudioModule::StartRawOutputFileRecording(
403 const char pcm_file_name_utf8[webrtc::kAdmMaxFileNameSize]) {
404 NOTREACHED();
405 return -1;
406}
407
408int32_t WebrtcAudioModule::StopRawOutputFileRecording() {
409 NOTREACHED();
410 return -1;
411}
412
413int32_t WebrtcAudioModule::StartRawInputFileRecording(
414 const char pcm_file_name_utf8[webrtc::kAdmMaxFileNameSize]) {
415 NOTREACHED();
416 return -1;
417}
418
419int32_t WebrtcAudioModule::StopRawInputFileRecording() {
420 NOTREACHED();
421 return -1;
422}
423
424int32_t WebrtcAudioModule::SetRecordingSampleRate(
425 const uint32_t samples_per_sec) {
426 NOTREACHED();
427 return -1;
428}
429
430int32_t WebrtcAudioModule::RecordingSampleRate(
431 uint32_t* samples_per_sec) const {
432 NOTREACHED();
433 return -1;
434}
435
436int32_t WebrtcAudioModule::SetPlayoutSampleRate(
437 const uint32_t samples_per_sec) {
438 NOTREACHED();
439 return -1;
440}
441
442int32_t WebrtcAudioModule::PlayoutSampleRate(uint32_t* samples_per_sec) const {
443 NOTREACHED();
444 return -1;
445}
446
447int32_t WebrtcAudioModule::ResetAudioDevice() {
448 NOTREACHED();
449 return -1;
450}
451
452int32_t WebrtcAudioModule::SetLoudspeakerStatus(bool enable) {
453 NOTREACHED();
454 return -1;
455}
456
457int32_t WebrtcAudioModule::GetLoudspeakerStatus(bool* enabled) const {
458 NOTREACHED();
459 return -1;
460}
461
462bool WebrtcAudioModule::BuiltInAECIsAvailable() const {
463 return false;
464}
465
466bool WebrtcAudioModule::BuiltInAGCIsAvailable() const {
467 return false;
468}
469
470bool WebrtcAudioModule::BuiltInNSIsAvailable() const {
471 return false;
472}
473
474int32_t WebrtcAudioModule::EnableBuiltInAEC(bool enable) {
475 NOTREACHED();
476 return -1;
477}
478
479int32_t WebrtcAudioModule::EnableBuiltInAGC(bool enable) {
480 NOTREACHED();
481 return -1;
482}
483
484int32_t WebrtcAudioModule::EnableBuiltInNS(bool enable) {
485 NOTREACHED();
486 return -1;
487}
488
489#if defined(WEBRTC_IOS)
490int WebrtcAudioModule::GetPlayoutAudioParameters(
nicholss1b5df0c2016-10-25 16:04:49491 webrtc::AudioParameters* params) const {
sergeyu2c5c0c202016-10-05 22:51:14492 NOTREACHED();
493 return -1;
494}
495
nicholss1b5df0c2016-10-25 16:04:49496int WebrtcAudioModule::GetRecordAudioParameters(
497 webrtc::AudioParameters* params) const {
sergeyu2c5c0c202016-10-05 22:51:14498 NOTREACHED();
499 return -1;
500}
501#endif // WEBRTC_IOS
502
503void WebrtcAudioModule::StartPlayoutOnAudioThread() {
504 DCHECK(audio_task_runner_->BelongsToCurrentThread());
505 poll_timer_.Start(
506 FROM_HERE, kPollInterval,
507 base::Bind(&WebrtcAudioModule::PollFromSource, base::Unretained(this)));
508}
509
510void WebrtcAudioModule::StopPlayoutOnAudioThread() {
511 DCHECK(audio_task_runner_->BelongsToCurrentThread());
512 poll_timer_.Stop();
513}
514
515void WebrtcAudioModule::PollFromSource() {
516 DCHECK(audio_task_runner_->BelongsToCurrentThread());
517
518 base::AutoLock lock(lock_);
519 if (!audio_transport_)
520 return;
521
522 for (int i = 0; i < kPollInterval.InMilliseconds() / kFrameLengthMs; i++) {
523 int64_t elapsed_time_ms = -1;
524 int64_t ntp_time_ms = -1;
525 char data[kBytesPerSample * kChannels * kSamplesPerFrame];
526 audio_transport_->PullRenderData(kBytesPerSample * 8, kSamplingRate,
527 kChannels, kSamplesPerFrame, data,
528 &elapsed_time_ms, &ntp_time_ms);
529 }
530}
531
532} // namespace protocol
533} // namespace remoting