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