blob: 63020bb7ecc63a287d3def71c3e2305ce9b8e985 [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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "modules/audio_device/android/audio_common.h"
16#include "modules/utility/include/helpers_android.h"
17#include "rtc_base/arraysize.h"
18#include "rtc_base/checks.h"
henrika53e048d2018-01-12 14:35:07 +010019#include "rtc_base/logging.h"
Magnus Jedvert9185bde2017-12-28 14:12:05 +010020#include "rtc_base/platform_thread.h"
henrika8324b522015-03-27 10:56:23 +010021
henrika8324b522015-03-27 10:56:23 +010022namespace webrtc {
23
henrikab2619892015-05-18 16:49:16 +020024// AudioManager::JavaAudioManager implementation
25AudioManager::JavaAudioManager::JavaAudioManager(
kwiberg0eb15ed2015-12-17 03:04:15 -080026 NativeRegistration* native_reg,
kwibergf01633e2016-02-24 05:00:36 -080027 std::unique_ptr<GlobalRef> audio_manager)
kwiberg0eb15ed2015-12-17 03:04:15 -080028 : audio_manager_(std::move(audio_manager)),
henrikab2619892015-05-18 16:49:16 +020029 init_(native_reg->GetMethodId("init", "()Z")),
30 dispose_(native_reg->GetMethodId("dispose", "()V")),
henrikafe55c382015-06-05 11:45:56 +020031 is_communication_mode_enabled_(
henrika8a897182015-06-09 10:45:09 +020032 native_reg->GetMethodId("isCommunicationModeEnabled", "()Z")),
33 is_device_blacklisted_for_open_sles_usage_(
kwiberg0eb15ed2015-12-17 03:04:15 -080034 native_reg->GetMethodId("isDeviceBlacklistedForOpenSLESUsage",
35 "()Z")) {
henrika53e048d2018-01-12 14:35:07 +010036 RTC_LOG(INFO) << "JavaAudioManager::ctor";
henrika8324b522015-03-27 10:56:23 +010037}
38
henrikab2619892015-05-18 16:49:16 +020039AudioManager::JavaAudioManager::~JavaAudioManager() {
henrika53e048d2018-01-12 14:35:07 +010040 RTC_LOG(INFO) << "JavaAudioManager::~dtor";
henrika8324b522015-03-27 10:56:23 +010041}
42
henrikab2619892015-05-18 16:49:16 +020043bool AudioManager::JavaAudioManager::Init() {
44 return audio_manager_->CallBooleanMethod(init_);
45}
46
47void AudioManager::JavaAudioManager::Close() {
48 audio_manager_->CallVoidMethod(dispose_);
49}
50
henrikafe55c382015-06-05 11:45:56 +020051bool AudioManager::JavaAudioManager::IsCommunicationModeEnabled() {
52 return audio_manager_->CallBooleanMethod(is_communication_mode_enabled_);
henrikab2619892015-05-18 16:49:16 +020053}
54
henrika8a897182015-06-09 10:45:09 +020055bool AudioManager::JavaAudioManager::IsDeviceBlacklistedForOpenSLESUsage() {
56 return audio_manager_->CallBooleanMethod(
57 is_device_blacklisted_for_open_sles_usage_);
58}
59
henrikab2619892015-05-18 16:49:16 +020060// AudioManager implementation
henrika8324b522015-03-27 10:56:23 +010061AudioManager::AudioManager()
kwiberg1c7fdd82016-04-26 08:18:04 -070062 : j_environment_(JVM::GetInstance()->environment()),
henrikab2619892015-05-18 16:49:16 +020063 audio_layer_(AudioDeviceModule::kPlatformDefaultAudio),
64 initialized_(false),
65 hardware_aec_(false),
henrikac14f5ff2015-09-23 14:08:33 +020066 hardware_agc_(false),
67 hardware_ns_(false),
henrikab2619892015-05-18 16:49:16 +020068 low_latency_playout_(false),
henrika918b5542016-09-19 15:44:09 +020069 low_latency_record_(false),
henrika1ba936a2015-11-03 04:27:58 -080070 delay_estimate_in_milliseconds_(0) {
henrika53e048d2018-01-12 14:35:07 +010071 RTC_LOG(INFO) << "ctor";
henrikg91d6ede2015-09-17 00:24:34 -070072 RTC_CHECK(j_environment_);
henrikab2619892015-05-18 16:49:16 +020073 JNINativeMethod native_methods[] = {
henrika883d00f2018-03-16 10:09:49 +010074 {"nativeCacheAudioParameters", "(IIIZZZZZZZIIJ)V",
henrikab2619892015-05-18 16:49:16 +020075 reinterpret_cast<void*>(&webrtc::AudioManager::CacheAudioParameters)}};
kwiberg1c7fdd82016-04-26 08:18:04 -070076 j_native_registration_ = j_environment_->RegisterNatives(
77 "org/webrtc/voiceengine/WebRtcAudioManager", native_methods,
78 arraysize(native_methods));
sakald7fdb802017-05-26 01:51:53 -070079 j_audio_manager_.reset(
80 new JavaAudioManager(j_native_registration_.get(),
81 j_native_registration_->NewObject(
82 "<init>", "(J)V", PointerTojlong(this))));
henrika8324b522015-03-27 10:56:23 +010083}
84
85AudioManager::~AudioManager() {
henrika53e048d2018-01-12 14:35:07 +010086 RTC_LOG(INFO) << "dtor";
henrikg91d6ede2015-09-17 00:24:34 -070087 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrika8324b522015-03-27 10:56:23 +010088 Close();
henrikab2619892015-05-18 16:49:16 +020089}
90
91void AudioManager::SetActiveAudioLayer(
92 AudioDeviceModule::AudioLayer audio_layer) {
henrika53e048d2018-01-12 14:35:07 +010093 RTC_LOG(INFO) << "SetActiveAudioLayer: " << audio_layer;
henrikg91d6ede2015-09-17 00:24:34 -070094 RTC_DCHECK(thread_checker_.CalledOnValidThread());
95 RTC_DCHECK(!initialized_);
henrika521f7a82016-05-31 07:03:17 -070096 // Store the currently utilized audio layer.
henrikab2619892015-05-18 16:49:16 +020097 audio_layer_ = audio_layer;
98 // The delay estimate can take one of two fixed values depending on if the
99 // device supports low-latency output or not. However, it is also possible
100 // that the user explicitly selects the high-latency audio path, hence we use
101 // the selected |audio_layer| here to set the delay estimate.
102 delay_estimate_in_milliseconds_ =
Mirko Bonadei72c42502017-11-09 09:33:23 +0100103 (audio_layer == AudioDeviceModule::kAndroidJavaAudio)
104 ? kHighLatencyModeDelayEstimateInMilliseconds
105 : kLowLatencyModeDelayEstimateInMilliseconds;
henrika53e048d2018-01-12 14:35:07 +0100106 RTC_LOG(INFO) << "delay_estimate_in_milliseconds: "
107 << delay_estimate_in_milliseconds_;
henrika8324b522015-03-27 10:56:23 +0100108}
109
henrika521f7a82016-05-31 07:03:17 -0700110SLObjectItf AudioManager::GetOpenSLEngine() {
henrika53e048d2018-01-12 14:35:07 +0100111 RTC_LOG(INFO) << "GetOpenSLEngine";
henrika521f7a82016-05-31 07:03:17 -0700112 RTC_DCHECK(thread_checker_.CalledOnValidThread());
113 // Only allow usage of OpenSL ES if such an audio layer has been specified.
114 if (audio_layer_ != AudioDeviceModule::kAndroidOpenSLESAudio &&
115 audio_layer_ !=
116 AudioDeviceModule::kAndroidJavaInputAndOpenSLESOutputAudio) {
henrika53e048d2018-01-12 14:35:07 +0100117 RTC_LOG(INFO)
118 << "Unable to create OpenSL engine for the current audio layer: "
119 << audio_layer_;
henrika521f7a82016-05-31 07:03:17 -0700120 return nullptr;
121 }
122 // OpenSL ES for Android only supports a single engine per application.
123 // If one already has been created, return existing object instead of
124 // creating a new.
125 if (engine_object_.Get() != nullptr) {
henrika53e048d2018-01-12 14:35:07 +0100126 RTC_LOG(WARNING) << "The OpenSL ES engine object has already been created";
henrika521f7a82016-05-31 07:03:17 -0700127 return engine_object_.Get();
128 }
129 // Create the engine object in thread safe mode.
130 const SLEngineOption option[] = {
131 {SL_ENGINEOPTION_THREADSAFE, static_cast<SLuint32>(SL_BOOLEAN_TRUE)}};
132 SLresult result =
133 slCreateEngine(engine_object_.Receive(), 1, option, 0, NULL, NULL);
134 if (result != SL_RESULT_SUCCESS) {
henrika53e048d2018-01-12 14:35:07 +0100135 RTC_LOG(LS_ERROR) << "slCreateEngine() failed: "
136 << GetSLErrorString(result);
henrika521f7a82016-05-31 07:03:17 -0700137 engine_object_.Reset();
138 return nullptr;
139 }
140 // Realize the SL Engine in synchronous mode.
141 result = engine_object_->Realize(engine_object_.Get(), SL_BOOLEAN_FALSE);
142 if (result != SL_RESULT_SUCCESS) {
henrika53e048d2018-01-12 14:35:07 +0100143 RTC_LOG(LS_ERROR) << "Realize() failed: " << GetSLErrorString(result);
henrika521f7a82016-05-31 07:03:17 -0700144 engine_object_.Reset();
145 return nullptr;
146 }
147 // Finally return the SLObjectItf interface of the engine object.
148 return engine_object_.Get();
149}
150
henrika8324b522015-03-27 10:56:23 +0100151bool AudioManager::Init() {
henrika53e048d2018-01-12 14:35:07 +0100152 RTC_LOG(INFO) << "Init";
henrikg91d6ede2015-09-17 00:24:34 -0700153 RTC_DCHECK(thread_checker_.CalledOnValidThread());
154 RTC_DCHECK(!initialized_);
155 RTC_DCHECK_NE(audio_layer_, AudioDeviceModule::kPlatformDefaultAudio);
henrikab2619892015-05-18 16:49:16 +0200156 if (!j_audio_manager_->Init()) {
henrika53e048d2018-01-12 14:35:07 +0100157 RTC_LOG(LS_ERROR) << "Init() failed";
henrika8324b522015-03-27 10:56:23 +0100158 return false;
159 }
160 initialized_ = true;
161 return true;
162}
163
164bool AudioManager::Close() {
henrika53e048d2018-01-12 14:35:07 +0100165 RTC_LOG(INFO) << "Close";
henrikg91d6ede2015-09-17 00:24:34 -0700166 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrika8324b522015-03-27 10:56:23 +0100167 if (!initialized_)
168 return true;
henrikab2619892015-05-18 16:49:16 +0200169 j_audio_manager_->Close();
henrika8324b522015-03-27 10:56:23 +0100170 initialized_ = false;
171 return true;
172}
173
henrikafe55c382015-06-05 11:45:56 +0200174bool AudioManager::IsCommunicationModeEnabled() const {
henrikg91d6ede2015-09-17 00:24:34 -0700175 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrikafe55c382015-06-05 11:45:56 +0200176 return j_audio_manager_->IsCommunicationModeEnabled();
henrika09bf1a12015-04-10 11:46:55 +0200177}
178
henrikab2619892015-05-18 16:49:16 +0200179bool AudioManager::IsAcousticEchoCancelerSupported() const {
henrikg91d6ede2015-09-17 00:24:34 -0700180 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrikab2619892015-05-18 16:49:16 +0200181 return hardware_aec_;
182}
183
henrikac14f5ff2015-09-23 14:08:33 +0200184bool AudioManager::IsAutomaticGainControlSupported() const {
185 RTC_DCHECK(thread_checker_.CalledOnValidThread());
186 return hardware_agc_;
187}
188
189bool AudioManager::IsNoiseSuppressorSupported() const {
190 RTC_DCHECK(thread_checker_.CalledOnValidThread());
191 return hardware_ns_;
192}
193
henrikab2619892015-05-18 16:49:16 +0200194bool AudioManager::IsLowLatencyPlayoutSupported() const {
henrikg91d6ede2015-09-17 00:24:34 -0700195 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrika8a897182015-06-09 10:45:09 +0200196 // Some devices are blacklisted for usage of OpenSL ES even if they report
197 // that low-latency playout is supported. See b/21485703 for details.
Mirko Bonadei72c42502017-11-09 09:33:23 +0100198 return j_audio_manager_->IsDeviceBlacklistedForOpenSLESUsage()
199 ? false
200 : low_latency_playout_;
henrikab2619892015-05-18 16:49:16 +0200201}
202
henrika918b5542016-09-19 15:44:09 +0200203bool AudioManager::IsLowLatencyRecordSupported() const {
204 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrika918b5542016-09-19 15:44:09 +0200205 return low_latency_record_;
206}
207
henrika1f0ad102016-05-25 05:15:10 -0700208bool AudioManager::IsProAudioSupported() const {
209 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrika1f0ad102016-05-25 05:15:10 -0700210 // TODO(henrika): return the state independently of if OpenSL ES is
211 // blacklisted or not for now. We could use the same approach as in
212 // IsLowLatencyPlayoutSupported() but I can't see the need for it yet.
213 return pro_audio_;
214}
215
henrika883d00f2018-03-16 10:09:49 +0100216// TODO(henrika): improve comments...
217bool AudioManager::IsAAudioSupported() const {
218#if defined(AUDIO_DEVICE_INCLUDE_ANDROID_AAUDIO)
219 return a_audio_;
220#else
221 return false;
222#endif
223}
224
henrika76535de2017-09-11 01:25:55 -0700225bool AudioManager::IsStereoPlayoutSupported() const {
226 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrika76535de2017-09-11 01:25:55 -0700227 return (playout_parameters_.channels() == 2);
228}
229
230bool AudioManager::IsStereoRecordSupported() const {
231 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrika76535de2017-09-11 01:25:55 -0700232 return (record_parameters_.channels() == 2);
233}
234
henrikab2619892015-05-18 16:49:16 +0200235int AudioManager::GetDelayEstimateInMilliseconds() const {
236 return delay_estimate_in_milliseconds_;
237}
238
239void JNICALL AudioManager::CacheAudioParameters(JNIEnv* env,
240 jobject obj,
241 jint sample_rate,
henrika779017d2016-11-16 06:30:46 -0800242 jint output_channels,
243 jint input_channels,
henrikab2619892015-05-18 16:49:16 +0200244 jboolean hardware_aec,
henrikac14f5ff2015-09-23 14:08:33 +0200245 jboolean hardware_agc,
246 jboolean hardware_ns,
henrikab2619892015-05-18 16:49:16 +0200247 jboolean low_latency_output,
henrika918b5542016-09-19 15:44:09 +0200248 jboolean low_latency_input,
henrika1f0ad102016-05-25 05:15:10 -0700249 jboolean pro_audio,
henrika883d00f2018-03-16 10:09:49 +0100250 jboolean a_audio,
henrikab2619892015-05-18 16:49:16 +0200251 jint output_buffer_size,
252 jint input_buffer_size,
253 jlong native_audio_manager) {
henrika8324b522015-03-27 10:56:23 +0100254 webrtc::AudioManager* this_object =
henrikab2619892015-05-18 16:49:16 +0200255 reinterpret_cast<webrtc::AudioManager*>(native_audio_manager);
256 this_object->OnCacheAudioParameters(
henrika779017d2016-11-16 06:30:46 -0800257 env, sample_rate, output_channels, input_channels, hardware_aec,
258 hardware_agc, hardware_ns, low_latency_output, low_latency_input,
henrika883d00f2018-03-16 10:09:49 +0100259 pro_audio, a_audio, output_buffer_size, input_buffer_size);
henrika8324b522015-03-27 10:56:23 +0100260}
261
henrikab2619892015-05-18 16:49:16 +0200262void AudioManager::OnCacheAudioParameters(JNIEnv* env,
263 jint sample_rate,
henrika779017d2016-11-16 06:30:46 -0800264 jint output_channels,
265 jint input_channels,
henrikab2619892015-05-18 16:49:16 +0200266 jboolean hardware_aec,
henrikac14f5ff2015-09-23 14:08:33 +0200267 jboolean hardware_agc,
268 jboolean hardware_ns,
henrikab2619892015-05-18 16:49:16 +0200269 jboolean low_latency_output,
henrika918b5542016-09-19 15:44:09 +0200270 jboolean low_latency_input,
henrika1f0ad102016-05-25 05:15:10 -0700271 jboolean pro_audio,
henrika883d00f2018-03-16 10:09:49 +0100272 jboolean a_audio,
henrikab2619892015-05-18 16:49:16 +0200273 jint output_buffer_size,
henrika1ba936a2015-11-03 04:27:58 -0800274 jint input_buffer_size) {
henrika53e048d2018-01-12 14:35:07 +0100275 RTC_LOG(INFO)
276 << "OnCacheAudioParameters: "
277 << "hardware_aec: " << static_cast<bool>(hardware_aec)
278 << ", hardware_agc: " << static_cast<bool>(hardware_agc)
279 << ", hardware_ns: " << static_cast<bool>(hardware_ns)
280 << ", low_latency_output: " << static_cast<bool>(low_latency_output)
281 << ", low_latency_input: " << static_cast<bool>(low_latency_input)
282 << ", pro_audio: " << static_cast<bool>(pro_audio)
henrika883d00f2018-03-16 10:09:49 +0100283 << ", a_audio: " << static_cast<bool>(a_audio)
henrika53e048d2018-01-12 14:35:07 +0100284 << ", sample_rate: " << static_cast<int>(sample_rate)
285 << ", output_channels: " << static_cast<int>(output_channels)
286 << ", input_channels: " << static_cast<int>(input_channels)
287 << ", output_buffer_size: " << static_cast<int>(output_buffer_size)
288 << ", input_buffer_size: " << static_cast<int>(input_buffer_size);
henrikg91d6ede2015-09-17 00:24:34 -0700289 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrikab2619892015-05-18 16:49:16 +0200290 hardware_aec_ = hardware_aec;
henrikac14f5ff2015-09-23 14:08:33 +0200291 hardware_agc_ = hardware_agc;
292 hardware_ns_ = hardware_ns;
henrikab2619892015-05-18 16:49:16 +0200293 low_latency_playout_ = low_latency_output;
henrika918b5542016-09-19 15:44:09 +0200294 low_latency_record_ = low_latency_input;
henrika1f0ad102016-05-25 05:15:10 -0700295 pro_audio_ = pro_audio;
henrika883d00f2018-03-16 10:09:49 +0100296 a_audio_ = a_audio;
henrika779017d2016-11-16 06:30:46 -0800297 playout_parameters_.reset(sample_rate, static_cast<size_t>(output_channels),
Peter Kasting1380e262015-08-28 17:31:03 -0700298 static_cast<size_t>(output_buffer_size));
henrika779017d2016-11-16 06:30:46 -0800299 record_parameters_.reset(sample_rate, static_cast<size_t>(input_channels),
Peter Kasting1380e262015-08-28 17:31:03 -0700300 static_cast<size_t>(input_buffer_size));
henrika8324b522015-03-27 10:56:23 +0100301}
302
henrikab2619892015-05-18 16:49:16 +0200303const AudioParameters& AudioManager::GetPlayoutAudioParameters() {
henrikg91d6ede2015-09-17 00:24:34 -0700304 RTC_CHECK(playout_parameters_.is_valid());
305 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrika8324b522015-03-27 10:56:23 +0100306 return playout_parameters_;
307}
308
henrikab2619892015-05-18 16:49:16 +0200309const AudioParameters& AudioManager::GetRecordAudioParameters() {
henrikg91d6ede2015-09-17 00:24:34 -0700310 RTC_CHECK(record_parameters_.is_valid());
311 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrika8324b522015-03-27 10:56:23 +0100312 return record_parameters_;
313}
314
henrika8324b522015-03-27 10:56:23 +0100315} // namespace webrtc