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/native_api/audio_device_module/audio_device_android.h"
12 
13 #include <stdlib.h>
14 
15 #include <memory>
16 #include <utility>
17 
18 #include "api/scoped_refptr.h"
19 #include "rtc_base/logging.h"
20 #include "rtc_base/ref_count.h"
21 #include "rtc_base/ref_counted_object.h"
22 
23 #if defined(WEBRTC_AUDIO_DEVICE_INCLUDE_ANDROID_AAUDIO)
24 #include "sdk/android/src/jni/audio_device/aaudio_player.h"
25 #include "sdk/android/src/jni/audio_device/aaudio_recorder.h"
26 #endif
27 
28 #include "sdk/android/src/jni/audio_device/audio_record_jni.h"
29 #include "sdk/android/src/jni/audio_device/audio_track_jni.h"
30 #include "sdk/android/src/jni/audio_device/opensles_player.h"
31 #include "sdk/android/src/jni/audio_device/opensles_recorder.h"
32 #include "system_wrappers/include/metrics.h"
33 
34 namespace webrtc {
35 
36 namespace {
37 
GetDefaultAudioParameters(JNIEnv * env,jobject application_context,AudioParameters * input_parameters,AudioParameters * output_parameters)38 void GetDefaultAudioParameters(JNIEnv* env,
39                                jobject application_context,
40                                AudioParameters* input_parameters,
41                                AudioParameters* output_parameters) {
42   const JavaParamRef<jobject> j_context(application_context);
43   const ScopedJavaLocalRef<jobject> j_audio_manager =
44       jni::GetAudioManager(env, j_context);
45   const int input_sample_rate = jni::GetDefaultSampleRate(env, j_audio_manager);
46   const int output_sample_rate =
47       jni::GetDefaultSampleRate(env, j_audio_manager);
48   jni::GetAudioParameters(env, j_context, j_audio_manager, input_sample_rate,
49                           output_sample_rate, false /* use_stereo_input */,
50                           false /* use_stereo_output */, input_parameters,
51                           output_parameters);
52 }
53 
54 }  // namespace
55 
56 #if defined(WEBRTC_AUDIO_DEVICE_INCLUDE_ANDROID_AAUDIO)
CreateAAudioAudioDeviceModule(JNIEnv * env,jobject application_context)57 rtc::scoped_refptr<AudioDeviceModule> CreateAAudioAudioDeviceModule(
58     JNIEnv* env,
59     jobject application_context) {
60   RTC_LOG(INFO) << __FUNCTION__;
61   // Get default audio input/output parameters.
62   AudioParameters input_parameters;
63   AudioParameters output_parameters;
64   GetDefaultAudioParameters(env, application_context, &input_parameters,
65                             &output_parameters);
66   // Create ADM from AAudioRecorder and AAudioPlayer.
67   return CreateAudioDeviceModuleFromInputAndOutput(
68       AudioDeviceModule::kAndroidAAudioAudio, false /* use_stereo_input */,
69       false /* use_stereo_output */,
70       jni::kLowLatencyModeDelayEstimateInMilliseconds,
71       std::make_unique<jni::AAudioRecorder>(input_parameters),
72       std::make_unique<jni::AAudioPlayer>(output_parameters));
73 }
74 #endif
75 
CreateJavaAudioDeviceModule(JNIEnv * env,jobject application_context)76 rtc::scoped_refptr<AudioDeviceModule> CreateJavaAudioDeviceModule(
77     JNIEnv* env,
78     jobject application_context) {
79   RTC_LOG(INFO) << __FUNCTION__;
80   // Get default audio input/output parameters.
81   const JavaParamRef<jobject> j_context(application_context);
82   const ScopedJavaLocalRef<jobject> j_audio_manager =
83       jni::GetAudioManager(env, j_context);
84   AudioParameters input_parameters;
85   AudioParameters output_parameters;
86   GetDefaultAudioParameters(env, application_context, &input_parameters,
87                             &output_parameters);
88   // Create ADM from AudioRecord and AudioTrack.
89   auto audio_input = std::make_unique<jni::AudioRecordJni>(
90       env, input_parameters, jni::kHighLatencyModeDelayEstimateInMilliseconds,
91       jni::AudioRecordJni::CreateJavaWebRtcAudioRecord(env, j_context,
92                                                        j_audio_manager));
93   auto audio_output = std::make_unique<jni::AudioTrackJni>(
94       env, output_parameters,
95       jni::AudioTrackJni::CreateJavaWebRtcAudioTrack(env, j_context,
96                                                      j_audio_manager));
97   return CreateAudioDeviceModuleFromInputAndOutput(
98       AudioDeviceModule::kAndroidJavaAudio, false /* use_stereo_input */,
99       false /* use_stereo_output */,
100       jni::kHighLatencyModeDelayEstimateInMilliseconds, std::move(audio_input),
101       std::move(audio_output));
102 }
103 
CreateOpenSLESAudioDeviceModule(JNIEnv * env,jobject application_context)104 rtc::scoped_refptr<AudioDeviceModule> CreateOpenSLESAudioDeviceModule(
105     JNIEnv* env,
106     jobject application_context) {
107   RTC_LOG(INFO) << __FUNCTION__;
108   // Get default audio input/output parameters.
109   AudioParameters input_parameters;
110   AudioParameters output_parameters;
111   GetDefaultAudioParameters(env, application_context, &input_parameters,
112                             &output_parameters);
113   // Create ADM from OpenSLESRecorder and OpenSLESPlayer.
114   rtc::scoped_refptr<jni::OpenSLEngineManager> engine_manager(
115       new jni::OpenSLEngineManager());
116   auto audio_input =
117       std::make_unique<jni::OpenSLESRecorder>(input_parameters, engine_manager);
118   auto audio_output = std::make_unique<jni::OpenSLESPlayer>(
119       output_parameters, std::move(engine_manager));
120   return CreateAudioDeviceModuleFromInputAndOutput(
121       AudioDeviceModule::kAndroidOpenSLESAudio, false /* use_stereo_input */,
122       false /* use_stereo_output */,
123       jni::kLowLatencyModeDelayEstimateInMilliseconds, std::move(audio_input),
124       std::move(audio_output));
125 }
126 
127 rtc::scoped_refptr<AudioDeviceModule>
CreateJavaInputAndOpenSLESOutputAudioDeviceModule(JNIEnv * env,jobject application_context)128 CreateJavaInputAndOpenSLESOutputAudioDeviceModule(JNIEnv* env,
129                                                   jobject application_context) {
130   RTC_LOG(INFO) << __FUNCTION__;
131   // Get default audio input/output parameters.
132   const JavaParamRef<jobject> j_context(application_context);
133   const ScopedJavaLocalRef<jobject> j_audio_manager =
134       jni::GetAudioManager(env, j_context);
135   AudioParameters input_parameters;
136   AudioParameters output_parameters;
137   GetDefaultAudioParameters(env, application_context, &input_parameters,
138                             &output_parameters);
139   // Create ADM from AudioRecord and OpenSLESPlayer.
140   auto audio_input = std::make_unique<jni::AudioRecordJni>(
141       env, input_parameters, jni::kLowLatencyModeDelayEstimateInMilliseconds,
142       jni::AudioRecordJni::CreateJavaWebRtcAudioRecord(env, j_context,
143                                                        j_audio_manager));
144 
145   rtc::scoped_refptr<jni::OpenSLEngineManager> engine_manager(
146       new jni::OpenSLEngineManager());
147   auto audio_output = std::make_unique<jni::OpenSLESPlayer>(
148       output_parameters, std::move(engine_manager));
149   return CreateAudioDeviceModuleFromInputAndOutput(
150       AudioDeviceModule::kAndroidJavaInputAndOpenSLESOutputAudio,
151       false /* use_stereo_input */, false /* use_stereo_output */,
152       jni::kLowLatencyModeDelayEstimateInMilliseconds, std::move(audio_input),
153       std::move(audio_output));
154 }
155 
156 }  // namespace webrtc
157