1 /*
2 * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "sdk/android/src/jni/audio_device/audio_device_module.h"
12
13 #include <memory>
14 #include <utility>
15
16 #include "api/task_queue/default_task_queue_factory.h"
17 #include "api/task_queue/task_queue_factory.h"
18 #include "modules/audio_device/audio_device_buffer.h"
19 #include "rtc_base/checks.h"
20 #include "rtc_base/logging.h"
21 #include "rtc_base/ref_counted_object.h"
22 #include "rtc_base/thread_checker.h"
23 #include "sdk/android/generated_audio_device_module_base_jni/WebRtcAudioManager_jni.h"
24 #include "system_wrappers/include/metrics.h"
25
26 namespace webrtc {
27 namespace jni {
28
29 namespace {
30
31 // This class combines a generic instance of an AudioInput and a generic
32 // instance of an AudioOutput to create an AudioDeviceModule. This is mostly
33 // done by delegating to the audio input/output with some glue code. This class
34 // also directly implements some of the AudioDeviceModule methods with dummy
35 // implementations.
36 //
37 // An instance can be created on any thread, but must then be used on one and
38 // the same thread. All public methods must also be called on the same thread.
39 // A thread checker will RTC_DCHECK if any method is called on an invalid
40 // thread.
41 // TODO(henrika): it might be useful to also support a scenario where the ADM
42 // is constructed on thread T1, used on thread T2 and destructed on T2 or T3.
43 // If so, care must be taken to ensure that only T2 is a COM thread.
44 class AndroidAudioDeviceModule : public AudioDeviceModule {
45 public:
46 // For use with UMA logging. Must be kept in sync with histograms.xml in
47 // Chrome, located at
48 // https://cs.chromium.org/chromium/src/tools/metrics/histograms/histograms.xml
49 enum class InitStatus {
50 OK = 0,
51 PLAYOUT_ERROR = 1,
52 RECORDING_ERROR = 2,
53 OTHER_ERROR = 3,
54 NUM_STATUSES = 4
55 };
56
AndroidAudioDeviceModule(AudioDeviceModule::AudioLayer audio_layer,bool is_stereo_playout_supported,bool is_stereo_record_supported,uint16_t playout_delay_ms,std::unique_ptr<AudioInput> audio_input,std::unique_ptr<AudioOutput> audio_output)57 AndroidAudioDeviceModule(AudioDeviceModule::AudioLayer audio_layer,
58 bool is_stereo_playout_supported,
59 bool is_stereo_record_supported,
60 uint16_t playout_delay_ms,
61 std::unique_ptr<AudioInput> audio_input,
62 std::unique_ptr<AudioOutput> audio_output)
63 : audio_layer_(audio_layer),
64 is_stereo_playout_supported_(is_stereo_playout_supported),
65 is_stereo_record_supported_(is_stereo_record_supported),
66 playout_delay_ms_(playout_delay_ms),
67 task_queue_factory_(CreateDefaultTaskQueueFactory()),
68 input_(std::move(audio_input)),
69 output_(std::move(audio_output)),
70 initialized_(false) {
71 RTC_CHECK(input_);
72 RTC_CHECK(output_);
73 RTC_LOG(INFO) << __FUNCTION__;
74 thread_checker_.Detach();
75 }
76
~AndroidAudioDeviceModule()77 ~AndroidAudioDeviceModule() override { RTC_LOG(INFO) << __FUNCTION__; }
78
ActiveAudioLayer(AudioDeviceModule::AudioLayer * audioLayer) const79 int32_t ActiveAudioLayer(
80 AudioDeviceModule::AudioLayer* audioLayer) const override {
81 RTC_LOG(INFO) << __FUNCTION__;
82 *audioLayer = audio_layer_;
83 return 0;
84 }
85
RegisterAudioCallback(AudioTransport * audioCallback)86 int32_t RegisterAudioCallback(AudioTransport* audioCallback) override {
87 RTC_LOG(INFO) << __FUNCTION__;
88 return audio_device_buffer_->RegisterAudioCallback(audioCallback);
89 }
90
Init()91 int32_t Init() override {
92 RTC_LOG(INFO) << __FUNCTION__;
93 RTC_DCHECK(thread_checker_.IsCurrent());
94 audio_device_buffer_ =
95 std::make_unique<AudioDeviceBuffer>(task_queue_factory_.get());
96 AttachAudioBuffer();
97 if (initialized_) {
98 return 0;
99 }
100 InitStatus status;
101 if (output_->Init() != 0) {
102 status = InitStatus::PLAYOUT_ERROR;
103 } else if (input_->Init() != 0) {
104 output_->Terminate();
105 status = InitStatus::RECORDING_ERROR;
106 } else {
107 initialized_ = true;
108 status = InitStatus::OK;
109 }
110 RTC_HISTOGRAM_ENUMERATION("WebRTC.Audio.InitializationResult",
111 static_cast<int>(status),
112 static_cast<int>(InitStatus::NUM_STATUSES));
113 if (status != InitStatus::OK) {
114 RTC_LOG(LS_ERROR) << "Audio device initialization failed.";
115 return -1;
116 }
117 return 0;
118 }
119
Terminate()120 int32_t Terminate() override {
121 RTC_LOG(INFO) << __FUNCTION__;
122 if (!initialized_)
123 return 0;
124 RTC_DCHECK(thread_checker_.IsCurrent());
125 int32_t err = input_->Terminate();
126 err |= output_->Terminate();
127 initialized_ = false;
128 thread_checker_.Detach();
129 audio_device_buffer_.reset(nullptr);
130 RTC_DCHECK_EQ(err, 0);
131 return err;
132 }
133
Initialized() const134 bool Initialized() const override {
135 RTC_LOG(INFO) << __FUNCTION__ << ":" << initialized_;
136 return initialized_;
137 }
138
PlayoutDevices()139 int16_t PlayoutDevices() override {
140 RTC_LOG(INFO) << __FUNCTION__;
141 RTC_LOG(INFO) << "output: " << 1;
142 return 1;
143 }
144
RecordingDevices()145 int16_t RecordingDevices() override {
146 RTC_LOG(INFO) << __FUNCTION__;
147 RTC_LOG(INFO) << "output: " << 1;
148 return 1;
149 }
150
PlayoutDeviceName(uint16_t index,char name[kAdmMaxDeviceNameSize],char guid[kAdmMaxGuidSize])151 int32_t PlayoutDeviceName(uint16_t index,
152 char name[kAdmMaxDeviceNameSize],
153 char guid[kAdmMaxGuidSize]) override {
154 FATAL() << "Should never be called";
155 return -1;
156 }
157
RecordingDeviceName(uint16_t index,char name[kAdmMaxDeviceNameSize],char guid[kAdmMaxGuidSize])158 int32_t RecordingDeviceName(uint16_t index,
159 char name[kAdmMaxDeviceNameSize],
160 char guid[kAdmMaxGuidSize]) override {
161 FATAL() << "Should never be called";
162 return -1;
163 }
164
SetPlayoutDevice(uint16_t index)165 int32_t SetPlayoutDevice(uint16_t index) override {
166 // OK to use but it has no effect currently since device selection is
167 // done using Andoid APIs instead.
168 RTC_LOG(INFO) << __FUNCTION__ << "(" << index << ")";
169 return 0;
170 }
171
SetPlayoutDevice(AudioDeviceModule::WindowsDeviceType device)172 int32_t SetPlayoutDevice(
173 AudioDeviceModule::WindowsDeviceType device) override {
174 FATAL() << "Should never be called";
175 return -1;
176 }
177
SetRecordingDevice(uint16_t index)178 int32_t SetRecordingDevice(uint16_t index) override {
179 // OK to use but it has no effect currently since device selection is
180 // done using Andoid APIs instead.
181 RTC_LOG(INFO) << __FUNCTION__ << "(" << index << ")";
182 return 0;
183 }
184
SetRecordingDevice(AudioDeviceModule::WindowsDeviceType device)185 int32_t SetRecordingDevice(
186 AudioDeviceModule::WindowsDeviceType device) override {
187 FATAL() << "Should never be called";
188 return -1;
189 }
190
PlayoutIsAvailable(bool * available)191 int32_t PlayoutIsAvailable(bool* available) override {
192 RTC_LOG(INFO) << __FUNCTION__;
193 *available = true;
194 RTC_LOG(INFO) << "output: " << *available;
195 return 0;
196 }
197
InitPlayout()198 int32_t InitPlayout() override {
199 RTC_LOG(INFO) << __FUNCTION__;
200 if (!initialized_)
201 return -1;
202 if (PlayoutIsInitialized()) {
203 return 0;
204 }
205 int32_t result = output_->InitPlayout();
206 RTC_LOG(INFO) << "output: " << result;
207 RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.InitPlayoutSuccess",
208 static_cast<int>(result == 0));
209 return result;
210 }
211
PlayoutIsInitialized() const212 bool PlayoutIsInitialized() const override {
213 RTC_LOG(INFO) << __FUNCTION__;
214 return output_->PlayoutIsInitialized();
215 }
216
RecordingIsAvailable(bool * available)217 int32_t RecordingIsAvailable(bool* available) override {
218 RTC_LOG(INFO) << __FUNCTION__;
219 *available = true;
220 RTC_LOG(INFO) << "output: " << *available;
221 return 0;
222 }
223
InitRecording()224 int32_t InitRecording() override {
225 RTC_LOG(INFO) << __FUNCTION__;
226 if (!initialized_)
227 return -1;
228 if (RecordingIsInitialized()) {
229 return 0;
230 }
231 int32_t result = input_->InitRecording();
232 RTC_LOG(INFO) << "output: " << result;
233 RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.InitRecordingSuccess",
234 static_cast<int>(result == 0));
235 return result;
236 }
237
RecordingIsInitialized() const238 bool RecordingIsInitialized() const override {
239 RTC_LOG(INFO) << __FUNCTION__;
240 return input_->RecordingIsInitialized();
241 }
242
StartPlayout()243 int32_t StartPlayout() override {
244 RTC_LOG(INFO) << __FUNCTION__;
245 if (!initialized_)
246 return -1;
247 if (Playing()) {
248 return 0;
249 }
250 int32_t result = output_->StartPlayout();
251 RTC_LOG(INFO) << "output: " << result;
252 RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.StartPlayoutSuccess",
253 static_cast<int>(result == 0));
254 if (result == 0) {
255 // Only start playing the audio device buffer if starting the audio
256 // output succeeded.
257 audio_device_buffer_->StartPlayout();
258 }
259 return result;
260 }
261
StopPlayout()262 int32_t StopPlayout() override {
263 RTC_LOG(INFO) << __FUNCTION__;
264 if (!initialized_)
265 return -1;
266 if (!Playing())
267 return 0;
268 RTC_LOG(INFO) << __FUNCTION__;
269 audio_device_buffer_->StopPlayout();
270 int32_t result = output_->StopPlayout();
271 RTC_LOG(INFO) << "output: " << result;
272 RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.StopPlayoutSuccess",
273 static_cast<int>(result == 0));
274 return result;
275 }
276
Playing() const277 bool Playing() const override {
278 RTC_LOG(INFO) << __FUNCTION__;
279 return output_->Playing();
280 }
281
StartRecording()282 int32_t StartRecording() override {
283 RTC_LOG(INFO) << __FUNCTION__;
284 if (!initialized_)
285 return -1;
286 if (Recording()) {
287 return 0;
288 }
289 int32_t result = input_->StartRecording();
290 RTC_LOG(INFO) << "output: " << result;
291 RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.StartRecordingSuccess",
292 static_cast<int>(result == 0));
293 if (result == 0) {
294 // Only start recording the audio device buffer if starting the audio
295 // input succeeded.
296 audio_device_buffer_->StartRecording();
297 }
298 return result;
299 }
300
StopRecording()301 int32_t StopRecording() override {
302 RTC_LOG(INFO) << __FUNCTION__;
303 if (!initialized_)
304 return -1;
305 if (!Recording())
306 return 0;
307 audio_device_buffer_->StopRecording();
308 int32_t result = input_->StopRecording();
309 RTC_LOG(INFO) << "output: " << result;
310 RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.StopRecordingSuccess",
311 static_cast<int>(result == 0));
312 return result;
313 }
314
Recording() const315 bool Recording() const override {
316 RTC_LOG(INFO) << __FUNCTION__;
317 return input_->Recording();
318 }
319
InitSpeaker()320 int32_t InitSpeaker() override {
321 RTC_LOG(INFO) << __FUNCTION__;
322 return initialized_ ? 0 : -1;
323 }
324
SpeakerIsInitialized() const325 bool SpeakerIsInitialized() const override {
326 RTC_LOG(INFO) << __FUNCTION__;
327 return initialized_;
328 }
329
InitMicrophone()330 int32_t InitMicrophone() override {
331 RTC_LOG(INFO) << __FUNCTION__;
332 return initialized_ ? 0 : -1;
333 }
334
MicrophoneIsInitialized() const335 bool MicrophoneIsInitialized() const override {
336 RTC_LOG(INFO) << __FUNCTION__;
337 return initialized_;
338 }
339
SpeakerVolumeIsAvailable(bool * available)340 int32_t SpeakerVolumeIsAvailable(bool* available) override {
341 RTC_LOG(INFO) << __FUNCTION__;
342 if (!initialized_)
343 return -1;
344 *available = output_->SpeakerVolumeIsAvailable();
345 RTC_LOG(INFO) << "output: " << *available;
346 return 0;
347 }
348
SetSpeakerVolume(uint32_t volume)349 int32_t SetSpeakerVolume(uint32_t volume) override {
350 RTC_LOG(INFO) << __FUNCTION__;
351 if (!initialized_)
352 return -1;
353 return output_->SetSpeakerVolume(volume);
354 }
355
SpeakerVolume(uint32_t * output_volume) const356 int32_t SpeakerVolume(uint32_t* output_volume) const override {
357 RTC_LOG(INFO) << __FUNCTION__;
358 if (!initialized_)
359 return -1;
360 absl::optional<uint32_t> volume = output_->SpeakerVolume();
361 if (!volume)
362 return -1;
363 *output_volume = *volume;
364 RTC_LOG(INFO) << "output: " << *volume;
365 return 0;
366 }
367
MaxSpeakerVolume(uint32_t * output_max_volume) const368 int32_t MaxSpeakerVolume(uint32_t* output_max_volume) const override {
369 RTC_LOG(INFO) << __FUNCTION__;
370 if (!initialized_)
371 return -1;
372 absl::optional<uint32_t> max_volume = output_->MaxSpeakerVolume();
373 if (!max_volume)
374 return -1;
375 *output_max_volume = *max_volume;
376 return 0;
377 }
378
MinSpeakerVolume(uint32_t * output_min_volume) const379 int32_t MinSpeakerVolume(uint32_t* output_min_volume) const override {
380 RTC_LOG(INFO) << __FUNCTION__;
381 if (!initialized_)
382 return -1;
383 absl::optional<uint32_t> min_volume = output_->MinSpeakerVolume();
384 if (!min_volume)
385 return -1;
386 *output_min_volume = *min_volume;
387 return 0;
388 }
389
MicrophoneVolumeIsAvailable(bool * available)390 int32_t MicrophoneVolumeIsAvailable(bool* available) override {
391 RTC_LOG(INFO) << __FUNCTION__;
392 *available = false;
393 RTC_LOG(INFO) << "output: " << *available;
394 return -1;
395 }
396
SetMicrophoneVolume(uint32_t volume)397 int32_t SetMicrophoneVolume(uint32_t volume) override {
398 RTC_LOG(INFO) << __FUNCTION__ << "(" << volume << ")";
399 FATAL() << "Should never be called";
400 return -1;
401 }
402
MicrophoneVolume(uint32_t * volume) const403 int32_t MicrophoneVolume(uint32_t* volume) const override {
404 RTC_LOG(INFO) << __FUNCTION__;
405 FATAL() << "Should never be called";
406 return -1;
407 }
408
MaxMicrophoneVolume(uint32_t * maxVolume) const409 int32_t MaxMicrophoneVolume(uint32_t* maxVolume) const override {
410 RTC_LOG(INFO) << __FUNCTION__;
411 FATAL() << "Should never be called";
412 return -1;
413 }
414
MinMicrophoneVolume(uint32_t * minVolume) const415 int32_t MinMicrophoneVolume(uint32_t* minVolume) const override {
416 RTC_LOG(INFO) << __FUNCTION__;
417 FATAL() << "Should never be called";
418 return -1;
419 }
420
SpeakerMuteIsAvailable(bool * available)421 int32_t SpeakerMuteIsAvailable(bool* available) override {
422 RTC_LOG(INFO) << __FUNCTION__;
423 FATAL() << "Should never be called";
424 return -1;
425 }
426
SetSpeakerMute(bool enable)427 int32_t SetSpeakerMute(bool enable) override {
428 RTC_LOG(INFO) << __FUNCTION__ << "(" << enable << ")";
429 FATAL() << "Should never be called";
430 return -1;
431 }
432
SpeakerMute(bool * enabled) const433 int32_t SpeakerMute(bool* enabled) const override {
434 RTC_LOG(INFO) << __FUNCTION__;
435 FATAL() << "Should never be called";
436 return -1;
437 }
438
MicrophoneMuteIsAvailable(bool * available)439 int32_t MicrophoneMuteIsAvailable(bool* available) override {
440 RTC_LOG(INFO) << __FUNCTION__;
441 FATAL() << "Not implemented";
442 return -1;
443 }
444
SetMicrophoneMute(bool enable)445 int32_t SetMicrophoneMute(bool enable) override {
446 RTC_LOG(INFO) << __FUNCTION__ << "(" << enable << ")";
447 FATAL() << "Not implemented";
448 return -1;
449 }
450
MicrophoneMute(bool * enabled) const451 int32_t MicrophoneMute(bool* enabled) const override {
452 RTC_LOG(INFO) << __FUNCTION__;
453 FATAL() << "Not implemented";
454 return -1;
455 }
456
StereoPlayoutIsAvailable(bool * available) const457 int32_t StereoPlayoutIsAvailable(bool* available) const override {
458 RTC_LOG(INFO) << __FUNCTION__;
459 *available = is_stereo_playout_supported_;
460 RTC_LOG(INFO) << "output: " << *available;
461 return 0;
462 }
463
SetStereoPlayout(bool enable)464 int32_t SetStereoPlayout(bool enable) override {
465 RTC_LOG(INFO) << __FUNCTION__ << "(" << enable << ")";
466 // Android does not support changes between mono and stero on the fly. The
467 // use of stereo or mono is determined by the audio layer. It is allowed
468 // to call this method if that same state is not modified.
469 bool available = is_stereo_playout_supported_;
470 if (enable != available) {
471 RTC_LOG(WARNING) << "changing stereo playout not supported";
472 return -1;
473 }
474 return 0;
475 }
476
StereoPlayout(bool * enabled) const477 int32_t StereoPlayout(bool* enabled) const override {
478 RTC_LOG(INFO) << __FUNCTION__;
479 *enabled = is_stereo_playout_supported_;
480 RTC_LOG(INFO) << "output: " << *enabled;
481 return 0;
482 }
483
StereoRecordingIsAvailable(bool * available) const484 int32_t StereoRecordingIsAvailable(bool* available) const override {
485 RTC_LOG(INFO) << __FUNCTION__;
486 *available = is_stereo_record_supported_;
487 RTC_LOG(INFO) << "output: " << *available;
488 return 0;
489 }
490
SetStereoRecording(bool enable)491 int32_t SetStereoRecording(bool enable) override {
492 RTC_LOG(INFO) << __FUNCTION__ << "(" << enable << ")";
493 // Android does not support changes between mono and stero on the fly. The
494 // use of stereo or mono is determined by the audio layer. It is allowed
495 // to call this method if that same state is not modified.
496 bool available = is_stereo_record_supported_;
497 if (enable != available) {
498 RTC_LOG(WARNING) << "changing stereo recording not supported";
499 return -1;
500 }
501 return 0;
502 }
503
StereoRecording(bool * enabled) const504 int32_t StereoRecording(bool* enabled) const override {
505 RTC_LOG(INFO) << __FUNCTION__;
506 *enabled = is_stereo_record_supported_;
507 RTC_LOG(INFO) << "output: " << *enabled;
508 return 0;
509 }
510
PlayoutDelay(uint16_t * delay_ms) const511 int32_t PlayoutDelay(uint16_t* delay_ms) const override {
512 // Best guess we can do is to use half of the estimated total delay.
513 *delay_ms = playout_delay_ms_ / 2;
514 RTC_DCHECK_GT(*delay_ms, 0);
515 return 0;
516 }
517
518 // Returns true if the device both supports built in AEC and the device
519 // is not blocklisted.
520 // Currently, if OpenSL ES is used in both directions, this method will still
521 // report the correct value and it has the correct effect. As an example:
522 // a device supports built in AEC and this method returns true. Libjingle
523 // will then disable the WebRTC based AEC and that will work for all devices
524 // (mainly Nexus) even when OpenSL ES is used for input since our current
525 // implementation will enable built-in AEC by default also for OpenSL ES.
526 // The only "bad" thing that happens today is that when Libjingle calls
527 // OpenSLESRecorder::EnableBuiltInAEC() it will not have any real effect and
528 // a "Not Implemented" log will be filed. This non-perfect state will remain
529 // until I have added full support for audio effects based on OpenSL ES APIs.
BuiltInAECIsAvailable() const530 bool BuiltInAECIsAvailable() const override {
531 RTC_LOG(INFO) << __FUNCTION__;
532 if (!initialized_)
533 return false;
534 bool isAvailable = input_->IsAcousticEchoCancelerSupported();
535 RTC_LOG(INFO) << "output: " << isAvailable;
536 return isAvailable;
537 }
538
539 // Not implemented for any input device on Android.
BuiltInAGCIsAvailable() const540 bool BuiltInAGCIsAvailable() const override {
541 RTC_LOG(INFO) << __FUNCTION__;
542 RTC_LOG(INFO) << "output: " << false;
543 return false;
544 }
545
546 // Returns true if the device both supports built in NS and the device
547 // is not blocklisted.
548 // TODO(henrika): add implementation for OpenSL ES based audio as well.
549 // In addition, see comments for BuiltInAECIsAvailable().
BuiltInNSIsAvailable() const550 bool BuiltInNSIsAvailable() const override {
551 RTC_LOG(INFO) << __FUNCTION__;
552 if (!initialized_)
553 return false;
554 bool isAvailable = input_->IsNoiseSuppressorSupported();
555 RTC_LOG(INFO) << "output: " << isAvailable;
556 return isAvailable;
557 }
558
559 // TODO(henrika): add implementation for OpenSL ES based audio as well.
EnableBuiltInAEC(bool enable)560 int32_t EnableBuiltInAEC(bool enable) override {
561 RTC_LOG(INFO) << __FUNCTION__ << "(" << enable << ")";
562 if (!initialized_)
563 return -1;
564 RTC_CHECK(BuiltInAECIsAvailable()) << "HW AEC is not available";
565 int32_t result = input_->EnableBuiltInAEC(enable);
566 RTC_LOG(INFO) << "output: " << result;
567 return result;
568 }
569
EnableBuiltInAGC(bool enable)570 int32_t EnableBuiltInAGC(bool enable) override {
571 RTC_LOG(INFO) << __FUNCTION__ << "(" << enable << ")";
572 FATAL() << "HW AGC is not available";
573 return -1;
574 }
575
576 // TODO(henrika): add implementation for OpenSL ES based audio as well.
EnableBuiltInNS(bool enable)577 int32_t EnableBuiltInNS(bool enable) override {
578 RTC_LOG(INFO) << __FUNCTION__ << "(" << enable << ")";
579 if (!initialized_)
580 return -1;
581 RTC_CHECK(BuiltInNSIsAvailable()) << "HW NS is not available";
582 int32_t result = input_->EnableBuiltInNS(enable);
583 RTC_LOG(INFO) << "output: " << result;
584 return result;
585 }
586
GetPlayoutUnderrunCount() const587 int32_t GetPlayoutUnderrunCount() const override {
588 if (!initialized_)
589 return -1;
590 return output_->GetPlayoutUnderrunCount();
591 }
592
AttachAudioBuffer()593 int32_t AttachAudioBuffer() {
594 RTC_LOG(INFO) << __FUNCTION__;
595 output_->AttachAudioBuffer(audio_device_buffer_.get());
596 input_->AttachAudioBuffer(audio_device_buffer_.get());
597 return 0;
598 }
599
600 private:
601 rtc::ThreadChecker thread_checker_;
602
603 const AudioDeviceModule::AudioLayer audio_layer_;
604 const bool is_stereo_playout_supported_;
605 const bool is_stereo_record_supported_;
606 const uint16_t playout_delay_ms_;
607 const std::unique_ptr<TaskQueueFactory> task_queue_factory_;
608 const std::unique_ptr<AudioInput> input_;
609 const std::unique_ptr<AudioOutput> output_;
610 std::unique_ptr<AudioDeviceBuffer> audio_device_buffer_;
611
612 bool initialized_;
613 };
614
615 } // namespace
616
GetAudioManager(JNIEnv * env,const JavaRef<jobject> & j_context)617 ScopedJavaLocalRef<jobject> GetAudioManager(JNIEnv* env,
618 const JavaRef<jobject>& j_context) {
619 return Java_WebRtcAudioManager_getAudioManager(env, j_context);
620 }
621
GetDefaultSampleRate(JNIEnv * env,const JavaRef<jobject> & j_audio_manager)622 int GetDefaultSampleRate(JNIEnv* env, const JavaRef<jobject>& j_audio_manager) {
623 return Java_WebRtcAudioManager_getSampleRate(env, j_audio_manager);
624 }
625
GetAudioParameters(JNIEnv * env,const JavaRef<jobject> & j_context,const JavaRef<jobject> & j_audio_manager,int input_sample_rate,int output_sample_rate,bool use_stereo_input,bool use_stereo_output,AudioParameters * input_parameters,AudioParameters * output_parameters)626 void GetAudioParameters(JNIEnv* env,
627 const JavaRef<jobject>& j_context,
628 const JavaRef<jobject>& j_audio_manager,
629 int input_sample_rate,
630 int output_sample_rate,
631 bool use_stereo_input,
632 bool use_stereo_output,
633 AudioParameters* input_parameters,
634 AudioParameters* output_parameters) {
635 const int output_channels = use_stereo_output ? 2 : 1;
636 const int input_channels = use_stereo_input ? 2 : 1;
637 const size_t output_buffer_size = Java_WebRtcAudioManager_getOutputBufferSize(
638 env, j_context, j_audio_manager, output_sample_rate, output_channels);
639 const size_t input_buffer_size = Java_WebRtcAudioManager_getInputBufferSize(
640 env, j_context, j_audio_manager, input_sample_rate, input_channels);
641 output_parameters->reset(output_sample_rate,
642 static_cast<size_t>(output_channels),
643 static_cast<size_t>(output_buffer_size));
644 input_parameters->reset(input_sample_rate,
645 static_cast<size_t>(input_channels),
646 static_cast<size_t>(input_buffer_size));
647 RTC_CHECK(input_parameters->is_valid());
648 RTC_CHECK(output_parameters->is_valid());
649 }
650
CreateAudioDeviceModuleFromInputAndOutput(AudioDeviceModule::AudioLayer audio_layer,bool is_stereo_playout_supported,bool is_stereo_record_supported,uint16_t playout_delay_ms,std::unique_ptr<AudioInput> audio_input,std::unique_ptr<AudioOutput> audio_output)651 rtc::scoped_refptr<AudioDeviceModule> CreateAudioDeviceModuleFromInputAndOutput(
652 AudioDeviceModule::AudioLayer audio_layer,
653 bool is_stereo_playout_supported,
654 bool is_stereo_record_supported,
655 uint16_t playout_delay_ms,
656 std::unique_ptr<AudioInput> audio_input,
657 std::unique_ptr<AudioOutput> audio_output) {
658 RTC_LOG(INFO) << __FUNCTION__;
659 return new rtc::RefCountedObject<AndroidAudioDeviceModule>(
660 audio_layer, is_stereo_playout_supported, is_stereo_record_supported,
661 playout_delay_ms, std::move(audio_input), std::move(audio_output));
662 }
663
664 } // namespace jni
665 } // namespace webrtc
666