blob: fae4ecce0cd3870acbd46cda011e09444a7a5fde [file] [log] [blame]
henrika8324b522015-03-27 10:56:23 +01001/*
2 * Copyright (c) 2015 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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/audio_device/android/audio_manager.h"
henrika8324b522015-03-27 10:56:23 +010012
kwiberg0eb15ed2015-12-17 03:04:15 -080013#include <utility>
14
henrika8324b522015-03-27 10:56:23 +010015#include <android/log.h>
16
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "modules/audio_device/android/audio_common.h"
18#include "modules/utility/include/helpers_android.h"
19#include "rtc_base/arraysize.h"
20#include "rtc_base/checks.h"
Magnus Jedvert9185bde2017-12-28 14:12:05 +010021#include "rtc_base/platform_thread.h"
henrika8324b522015-03-27 10:56:23 +010022
23#define TAG "AudioManager"
24#define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)
25#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
26#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
27#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, TAG, __VA_ARGS__)
28#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
29
30namespace webrtc {
31
henrikab2619892015-05-18 16:49:16 +020032// AudioManager::JavaAudioManager implementation
33AudioManager::JavaAudioManager::JavaAudioManager(
kwiberg0eb15ed2015-12-17 03:04:15 -080034 NativeRegistration* native_reg,
kwibergf01633e2016-02-24 05:00:36 -080035 std::unique_ptr<GlobalRef> audio_manager)
kwiberg0eb15ed2015-12-17 03:04:15 -080036 : audio_manager_(std::move(audio_manager)),
henrikab2619892015-05-18 16:49:16 +020037 init_(native_reg->GetMethodId("init", "()Z")),
38 dispose_(native_reg->GetMethodId("dispose", "()V")),
henrikafe55c382015-06-05 11:45:56 +020039 is_communication_mode_enabled_(
henrika8a897182015-06-09 10:45:09 +020040 native_reg->GetMethodId("isCommunicationModeEnabled", "()Z")),
41 is_device_blacklisted_for_open_sles_usage_(
kwiberg0eb15ed2015-12-17 03:04:15 -080042 native_reg->GetMethodId("isDeviceBlacklistedForOpenSLESUsage",
43 "()Z")) {
Magnus Jedvert9185bde2017-12-28 14:12:05 +010044 ALOGD("JavaAudioManager::ctor @[tid=%d]", rtc::CurrentThreadId());
henrika8324b522015-03-27 10:56:23 +010045}
46
henrikab2619892015-05-18 16:49:16 +020047AudioManager::JavaAudioManager::~JavaAudioManager() {
Magnus Jedvert9185bde2017-12-28 14:12:05 +010048 ALOGD("JavaAudioManager::dtor[tid=%d]", rtc::CurrentThreadId());
henrika8324b522015-03-27 10:56:23 +010049}
50
henrikab2619892015-05-18 16:49:16 +020051bool AudioManager::JavaAudioManager::Init() {
52 return audio_manager_->CallBooleanMethod(init_);
53}
54
55void AudioManager::JavaAudioManager::Close() {
56 audio_manager_->CallVoidMethod(dispose_);
57}
58
henrikafe55c382015-06-05 11:45:56 +020059bool AudioManager::JavaAudioManager::IsCommunicationModeEnabled() {
60 return audio_manager_->CallBooleanMethod(is_communication_mode_enabled_);
henrikab2619892015-05-18 16:49:16 +020061}
62
henrika8a897182015-06-09 10:45:09 +020063bool AudioManager::JavaAudioManager::IsDeviceBlacklistedForOpenSLESUsage() {
64 return audio_manager_->CallBooleanMethod(
65 is_device_blacklisted_for_open_sles_usage_);
66}
67
henrikab2619892015-05-18 16:49:16 +020068// AudioManager implementation
henrika8324b522015-03-27 10:56:23 +010069AudioManager::AudioManager()
kwiberg1c7fdd82016-04-26 08:18:04 -070070 : j_environment_(JVM::GetInstance()->environment()),
henrikab2619892015-05-18 16:49:16 +020071 audio_layer_(AudioDeviceModule::kPlatformDefaultAudio),
72 initialized_(false),
73 hardware_aec_(false),
henrikac14f5ff2015-09-23 14:08:33 +020074 hardware_agc_(false),
75 hardware_ns_(false),
henrikab2619892015-05-18 16:49:16 +020076 low_latency_playout_(false),
henrika918b5542016-09-19 15:44:09 +020077 low_latency_record_(false),
henrika1ba936a2015-11-03 04:27:58 -080078 delay_estimate_in_milliseconds_(0) {
Magnus Jedvert9185bde2017-12-28 14:12:05 +010079 ALOGD("ctor[tid=%d]", rtc::CurrentThreadId());
henrikg91d6ede2015-09-17 00:24:34 -070080 RTC_CHECK(j_environment_);
henrikab2619892015-05-18 16:49:16 +020081 JNINativeMethod native_methods[] = {
henrika779017d2016-11-16 06:30:46 -080082 {"nativeCacheAudioParameters", "(IIIZZZZZZIIJ)V",
henrikab2619892015-05-18 16:49:16 +020083 reinterpret_cast<void*>(&webrtc::AudioManager::CacheAudioParameters)}};
kwiberg1c7fdd82016-04-26 08:18:04 -070084 j_native_registration_ = j_environment_->RegisterNatives(
85 "org/webrtc/voiceengine/WebRtcAudioManager", native_methods,
86 arraysize(native_methods));
sakald7fdb802017-05-26 01:51:53 -070087 j_audio_manager_.reset(
88 new JavaAudioManager(j_native_registration_.get(),
89 j_native_registration_->NewObject(
90 "<init>", "(J)V", PointerTojlong(this))));
henrika8324b522015-03-27 10:56:23 +010091}
92
93AudioManager::~AudioManager() {
Magnus Jedvert9185bde2017-12-28 14:12:05 +010094 ALOGD("~dtor[tid=%d]", rtc::CurrentThreadId());
henrikg91d6ede2015-09-17 00:24:34 -070095 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrika8324b522015-03-27 10:56:23 +010096 Close();
henrikab2619892015-05-18 16:49:16 +020097}
98
99void AudioManager::SetActiveAudioLayer(
100 AudioDeviceModule::AudioLayer audio_layer) {
Magnus Jedvert9185bde2017-12-28 14:12:05 +0100101 ALOGD("SetActiveAudioLayer(%d)[tid=%d]", audio_layer, rtc::CurrentThreadId());
henrikg91d6ede2015-09-17 00:24:34 -0700102 RTC_DCHECK(thread_checker_.CalledOnValidThread());
103 RTC_DCHECK(!initialized_);
henrika521f7a82016-05-31 07:03:17 -0700104 // Store the currently utilized audio layer.
henrikab2619892015-05-18 16:49:16 +0200105 audio_layer_ = audio_layer;
106 // The delay estimate can take one of two fixed values depending on if the
107 // device supports low-latency output or not. However, it is also possible
108 // that the user explicitly selects the high-latency audio path, hence we use
109 // the selected |audio_layer| here to set the delay estimate.
110 delay_estimate_in_milliseconds_ =
Mirko Bonadei72c42502017-11-09 09:33:23 +0100111 (audio_layer == AudioDeviceModule::kAndroidJavaAudio)
112 ? kHighLatencyModeDelayEstimateInMilliseconds
113 : kLowLatencyModeDelayEstimateInMilliseconds;
henrikab2619892015-05-18 16:49:16 +0200114 ALOGD("delay_estimate_in_milliseconds: %d", delay_estimate_in_milliseconds_);
henrika8324b522015-03-27 10:56:23 +0100115}
116
henrika521f7a82016-05-31 07:03:17 -0700117SLObjectItf AudioManager::GetOpenSLEngine() {
Magnus Jedvert9185bde2017-12-28 14:12:05 +0100118 ALOGD("GetOpenSLEngine[tid=%d]", rtc::CurrentThreadId());
henrika521f7a82016-05-31 07:03:17 -0700119 RTC_DCHECK(thread_checker_.CalledOnValidThread());
120 // Only allow usage of OpenSL ES if such an audio layer has been specified.
121 if (audio_layer_ != AudioDeviceModule::kAndroidOpenSLESAudio &&
122 audio_layer_ !=
123 AudioDeviceModule::kAndroidJavaInputAndOpenSLESOutputAudio) {
124 ALOGI("Unable to create OpenSL engine for the current audio layer: %d",
125 audio_layer_);
126 return nullptr;
127 }
128 // OpenSL ES for Android only supports a single engine per application.
129 // If one already has been created, return existing object instead of
130 // creating a new.
131 if (engine_object_.Get() != nullptr) {
132 ALOGI("The OpenSL ES engine object has already been created");
133 return engine_object_.Get();
134 }
135 // Create the engine object in thread safe mode.
136 const SLEngineOption option[] = {
137 {SL_ENGINEOPTION_THREADSAFE, static_cast<SLuint32>(SL_BOOLEAN_TRUE)}};
138 SLresult result =
139 slCreateEngine(engine_object_.Receive(), 1, option, 0, NULL, NULL);
140 if (result != SL_RESULT_SUCCESS) {
141 ALOGE("slCreateEngine() failed: %s", GetSLErrorString(result));
142 engine_object_.Reset();
143 return nullptr;
144 }
145 // Realize the SL Engine in synchronous mode.
146 result = engine_object_->Realize(engine_object_.Get(), SL_BOOLEAN_FALSE);
147 if (result != SL_RESULT_SUCCESS) {
148 ALOGE("Realize() failed: %s", GetSLErrorString(result));
149 engine_object_.Reset();
150 return nullptr;
151 }
152 // Finally return the SLObjectItf interface of the engine object.
153 return engine_object_.Get();
154}
155
henrika8324b522015-03-27 10:56:23 +0100156bool AudioManager::Init() {
Magnus Jedvert9185bde2017-12-28 14:12:05 +0100157 ALOGD("Init[tid=%d]", rtc::CurrentThreadId());
henrikg91d6ede2015-09-17 00:24:34 -0700158 RTC_DCHECK(thread_checker_.CalledOnValidThread());
159 RTC_DCHECK(!initialized_);
160 RTC_DCHECK_NE(audio_layer_, AudioDeviceModule::kPlatformDefaultAudio);
henrikab2619892015-05-18 16:49:16 +0200161 if (!j_audio_manager_->Init()) {
henrika8324b522015-03-27 10:56:23 +0100162 ALOGE("init failed!");
163 return false;
164 }
165 initialized_ = true;
166 return true;
167}
168
169bool AudioManager::Close() {
Magnus Jedvert9185bde2017-12-28 14:12:05 +0100170 ALOGD("Close[tid=%d]", rtc::CurrentThreadId());
henrikg91d6ede2015-09-17 00:24:34 -0700171 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrika8324b522015-03-27 10:56:23 +0100172 if (!initialized_)
173 return true;
henrikab2619892015-05-18 16:49:16 +0200174 j_audio_manager_->Close();
henrika8324b522015-03-27 10:56:23 +0100175 initialized_ = false;
176 return true;
177}
178
henrikafe55c382015-06-05 11:45:56 +0200179bool AudioManager::IsCommunicationModeEnabled() const {
180 ALOGD("IsCommunicationModeEnabled()");
henrikg91d6ede2015-09-17 00:24:34 -0700181 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrikafe55c382015-06-05 11:45:56 +0200182 return j_audio_manager_->IsCommunicationModeEnabled();
henrika09bf1a12015-04-10 11:46:55 +0200183}
184
henrikab2619892015-05-18 16:49:16 +0200185bool AudioManager::IsAcousticEchoCancelerSupported() const {
henrikg91d6ede2015-09-17 00:24:34 -0700186 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrikab2619892015-05-18 16:49:16 +0200187 return hardware_aec_;
188}
189
henrikac14f5ff2015-09-23 14:08:33 +0200190bool AudioManager::IsAutomaticGainControlSupported() const {
191 RTC_DCHECK(thread_checker_.CalledOnValidThread());
192 return hardware_agc_;
193}
194
195bool AudioManager::IsNoiseSuppressorSupported() const {
196 RTC_DCHECK(thread_checker_.CalledOnValidThread());
197 return hardware_ns_;
198}
199
henrikab2619892015-05-18 16:49:16 +0200200bool AudioManager::IsLowLatencyPlayoutSupported() const {
henrikg91d6ede2015-09-17 00:24:34 -0700201 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrikab2619892015-05-18 16:49:16 +0200202 ALOGD("IsLowLatencyPlayoutSupported()");
henrika8a897182015-06-09 10:45:09 +0200203 // Some devices are blacklisted for usage of OpenSL ES even if they report
204 // that low-latency playout is supported. See b/21485703 for details.
Mirko Bonadei72c42502017-11-09 09:33:23 +0100205 return j_audio_manager_->IsDeviceBlacklistedForOpenSLESUsage()
206 ? false
207 : low_latency_playout_;
henrikab2619892015-05-18 16:49:16 +0200208}
209
henrika918b5542016-09-19 15:44:09 +0200210bool AudioManager::IsLowLatencyRecordSupported() const {
211 RTC_DCHECK(thread_checker_.CalledOnValidThread());
212 ALOGD("IsLowLatencyRecordSupported()");
213 return low_latency_record_;
214}
215
henrika1f0ad102016-05-25 05:15:10 -0700216bool AudioManager::IsProAudioSupported() const {
217 RTC_DCHECK(thread_checker_.CalledOnValidThread());
218 ALOGD("IsProAudioSupported()");
219 // TODO(henrika): return the state independently of if OpenSL ES is
220 // blacklisted or not for now. We could use the same approach as in
221 // IsLowLatencyPlayoutSupported() but I can't see the need for it yet.
222 return pro_audio_;
223}
224
henrika76535de2017-09-11 01:25:55 -0700225bool AudioManager::IsStereoPlayoutSupported() const {
226 RTC_DCHECK(thread_checker_.CalledOnValidThread());
227 ALOGD("IsStereoPlayoutSupported()");
228 return (playout_parameters_.channels() == 2);
229}
230
231bool AudioManager::IsStereoRecordSupported() const {
232 RTC_DCHECK(thread_checker_.CalledOnValidThread());
233 ALOGD("IsStereoRecordSupported()");
234 return (record_parameters_.channels() == 2);
235}
236
henrikab2619892015-05-18 16:49:16 +0200237int AudioManager::GetDelayEstimateInMilliseconds() const {
238 return delay_estimate_in_milliseconds_;
239}
240
241void JNICALL AudioManager::CacheAudioParameters(JNIEnv* env,
242 jobject obj,
243 jint sample_rate,
henrika779017d2016-11-16 06:30:46 -0800244 jint output_channels,
245 jint input_channels,
henrikab2619892015-05-18 16:49:16 +0200246 jboolean hardware_aec,
henrikac14f5ff2015-09-23 14:08:33 +0200247 jboolean hardware_agc,
248 jboolean hardware_ns,
henrikab2619892015-05-18 16:49:16 +0200249 jboolean low_latency_output,
henrika918b5542016-09-19 15:44:09 +0200250 jboolean low_latency_input,
henrika1f0ad102016-05-25 05:15:10 -0700251 jboolean pro_audio,
henrikab2619892015-05-18 16:49:16 +0200252 jint output_buffer_size,
253 jint input_buffer_size,
254 jlong native_audio_manager) {
henrika8324b522015-03-27 10:56:23 +0100255 webrtc::AudioManager* this_object =
henrikab2619892015-05-18 16:49:16 +0200256 reinterpret_cast<webrtc::AudioManager*>(native_audio_manager);
257 this_object->OnCacheAudioParameters(
henrika779017d2016-11-16 06:30:46 -0800258 env, sample_rate, output_channels, input_channels, hardware_aec,
259 hardware_agc, hardware_ns, low_latency_output, low_latency_input,
260 pro_audio, output_buffer_size, input_buffer_size);
henrika8324b522015-03-27 10:56:23 +0100261}
262
henrikab2619892015-05-18 16:49:16 +0200263void AudioManager::OnCacheAudioParameters(JNIEnv* env,
264 jint sample_rate,
henrika779017d2016-11-16 06:30:46 -0800265 jint output_channels,
266 jint input_channels,
henrikab2619892015-05-18 16:49:16 +0200267 jboolean hardware_aec,
henrikac14f5ff2015-09-23 14:08:33 +0200268 jboolean hardware_agc,
269 jboolean hardware_ns,
henrikab2619892015-05-18 16:49:16 +0200270 jboolean low_latency_output,
henrika918b5542016-09-19 15:44:09 +0200271 jboolean low_latency_input,
henrika1f0ad102016-05-25 05:15:10 -0700272 jboolean pro_audio,
henrikab2619892015-05-18 16:49:16 +0200273 jint output_buffer_size,
henrika1ba936a2015-11-03 04:27:58 -0800274 jint input_buffer_size) {
Magnus Jedvert9185bde2017-12-28 14:12:05 +0100275 ALOGD("OnCacheAudioParameters[tid=%d]", rtc::CurrentThreadId());
henrikab2619892015-05-18 16:49:16 +0200276 ALOGD("hardware_aec: %d", hardware_aec);
henrikac14f5ff2015-09-23 14:08:33 +0200277 ALOGD("hardware_agc: %d", hardware_agc);
278 ALOGD("hardware_ns: %d", hardware_ns);
henrikab2619892015-05-18 16:49:16 +0200279 ALOGD("low_latency_output: %d", low_latency_output);
henrika918b5542016-09-19 15:44:09 +0200280 ALOGD("low_latency_input: %d", low_latency_input);
henrika1f0ad102016-05-25 05:15:10 -0700281 ALOGD("pro_audio: %d", pro_audio);
henrika8324b522015-03-27 10:56:23 +0100282 ALOGD("sample_rate: %d", sample_rate);
henrika779017d2016-11-16 06:30:46 -0800283 ALOGD("output_channels: %d", output_channels);
284 ALOGD("input_channels: %d", input_channels);
henrikab2619892015-05-18 16:49:16 +0200285 ALOGD("output_buffer_size: %d", output_buffer_size);
286 ALOGD("input_buffer_size: %d", input_buffer_size);
henrikg91d6ede2015-09-17 00:24:34 -0700287 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrikab2619892015-05-18 16:49:16 +0200288 hardware_aec_ = hardware_aec;
henrikac14f5ff2015-09-23 14:08:33 +0200289 hardware_agc_ = hardware_agc;
290 hardware_ns_ = hardware_ns;
henrikab2619892015-05-18 16:49:16 +0200291 low_latency_playout_ = low_latency_output;
henrika918b5542016-09-19 15:44:09 +0200292 low_latency_record_ = low_latency_input;
henrika1f0ad102016-05-25 05:15:10 -0700293 pro_audio_ = pro_audio;
henrika779017d2016-11-16 06:30:46 -0800294 playout_parameters_.reset(sample_rate, static_cast<size_t>(output_channels),
Peter Kasting1380e262015-08-28 17:31:03 -0700295 static_cast<size_t>(output_buffer_size));
henrika779017d2016-11-16 06:30:46 -0800296 record_parameters_.reset(sample_rate, static_cast<size_t>(input_channels),
Peter Kasting1380e262015-08-28 17:31:03 -0700297 static_cast<size_t>(input_buffer_size));
henrika8324b522015-03-27 10:56:23 +0100298}
299
henrikab2619892015-05-18 16:49:16 +0200300const AudioParameters& AudioManager::GetPlayoutAudioParameters() {
henrikg91d6ede2015-09-17 00:24:34 -0700301 RTC_CHECK(playout_parameters_.is_valid());
302 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrika8324b522015-03-27 10:56:23 +0100303 return playout_parameters_;
304}
305
henrikab2619892015-05-18 16:49:16 +0200306const AudioParameters& AudioManager::GetRecordAudioParameters() {
henrikg91d6ede2015-09-17 00:24:34 -0700307 RTC_CHECK(record_parameters_.is_valid());
308 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrika8324b522015-03-27 10:56:23 +0100309 return record_parameters_;
310}
311
henrika8324b522015-03-27 10:56:23 +0100312} // namespace webrtc