blob: 260e793d600e645d9c18d66e03d3439e3e15a311 [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
11#include "webrtc/modules/audio_device/android/audio_manager.h"
12
13#include <android/log.h>
14
15#include "webrtc/base/arraysize.h"
16#include "webrtc/base/checks.h"
henrikab2619892015-05-18 16:49:16 +020017#include "webrtc/base/scoped_ptr.h"
henrika8324b522015-03-27 10:56:23 +010018#include "webrtc/modules/audio_device/android/audio_common.h"
19#include "webrtc/modules/utility/interface/helpers_android.h"
20
21#define TAG "AudioManager"
22#define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)
23#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
24#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
25#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, TAG, __VA_ARGS__)
26#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
27
28namespace webrtc {
29
henrikab2619892015-05-18 16:49:16 +020030// AudioManager::JavaAudioManager implementation
31AudioManager::JavaAudioManager::JavaAudioManager(
32 NativeRegistration* native_reg, rtc::scoped_ptr<GlobalRef> audio_manager)
33 : audio_manager_(audio_manager.Pass()),
34 init_(native_reg->GetMethodId("init", "()Z")),
35 dispose_(native_reg->GetMethodId("dispose", "()V")),
henrikafe55c382015-06-05 11:45:56 +020036 is_communication_mode_enabled_(
henrika8a897182015-06-09 10:45:09 +020037 native_reg->GetMethodId("isCommunicationModeEnabled", "()Z")),
38 is_device_blacklisted_for_open_sles_usage_(
39 native_reg->GetMethodId(
40 "isDeviceBlacklistedForOpenSLESUsage", "()Z")) {
henrikab2619892015-05-18 16:49:16 +020041 ALOGD("JavaAudioManager::ctor%s", GetThreadInfo().c_str());
henrika8324b522015-03-27 10:56:23 +010042}
43
henrikab2619892015-05-18 16:49:16 +020044AudioManager::JavaAudioManager::~JavaAudioManager() {
45 ALOGD("JavaAudioManager::dtor%s", GetThreadInfo().c_str());
henrika8324b522015-03-27 10:56:23 +010046}
47
henrikab2619892015-05-18 16:49:16 +020048bool AudioManager::JavaAudioManager::Init() {
49 return audio_manager_->CallBooleanMethod(init_);
50}
51
52void AudioManager::JavaAudioManager::Close() {
53 audio_manager_->CallVoidMethod(dispose_);
54}
55
henrikafe55c382015-06-05 11:45:56 +020056bool AudioManager::JavaAudioManager::IsCommunicationModeEnabled() {
57 return audio_manager_->CallBooleanMethod(is_communication_mode_enabled_);
henrikab2619892015-05-18 16:49:16 +020058}
59
henrika8a897182015-06-09 10:45:09 +020060bool AudioManager::JavaAudioManager::IsDeviceBlacklistedForOpenSLESUsage() {
61 return audio_manager_->CallBooleanMethod(
62 is_device_blacklisted_for_open_sles_usage_);
63}
64
henrikab2619892015-05-18 16:49:16 +020065// AudioManager implementation
henrika8324b522015-03-27 10:56:23 +010066AudioManager::AudioManager()
henrikab2619892015-05-18 16:49:16 +020067 : j_environment_(JVM::GetInstance()->environment()),
68 audio_layer_(AudioDeviceModule::kPlatformDefaultAudio),
69 initialized_(false),
70 hardware_aec_(false),
henrikac14f5ff2015-09-23 14:08:33 +020071 hardware_agc_(false),
72 hardware_ns_(false),
henrikab2619892015-05-18 16:49:16 +020073 low_latency_playout_(false),
74 delay_estimate_in_milliseconds_(0) {
henrika8324b522015-03-27 10:56:23 +010075 ALOGD("ctor%s", GetThreadInfo().c_str());
henrikg91d6ede2015-09-17 00:24:34 -070076 RTC_CHECK(j_environment_);
henrikab2619892015-05-18 16:49:16 +020077 JNINativeMethod native_methods[] = {
78 {"nativeCacheAudioParameters",
henrikac14f5ff2015-09-23 14:08:33 +020079 "(IIZZZZIIJ)V",
henrikab2619892015-05-18 16:49:16 +020080 reinterpret_cast<void*>(&webrtc::AudioManager::CacheAudioParameters)}};
81 j_native_registration_ = j_environment_->RegisterNatives(
82 "org/webrtc/voiceengine/WebRtcAudioManager",
83 native_methods, arraysize(native_methods));
84 j_audio_manager_.reset(new JavaAudioManager(
85 j_native_registration_.get(),
86 j_native_registration_->NewObject(
87 "<init>", "(Landroid/content/Context;J)V",
88 JVM::GetInstance()->context(), PointerTojlong(this))));
henrika8324b522015-03-27 10:56:23 +010089}
90
91AudioManager::~AudioManager() {
92 ALOGD("~dtor%s", GetThreadInfo().c_str());
henrikg91d6ede2015-09-17 00:24:34 -070093 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrika8324b522015-03-27 10:56:23 +010094 Close();
henrikab2619892015-05-18 16:49:16 +020095}
96
97void AudioManager::SetActiveAudioLayer(
98 AudioDeviceModule::AudioLayer audio_layer) {
99 ALOGD("SetActiveAudioLayer(%d)%s", audio_layer, GetThreadInfo().c_str());
henrikg91d6ede2015-09-17 00:24:34 -0700100 RTC_DCHECK(thread_checker_.CalledOnValidThread());
101 RTC_DCHECK(!initialized_);
henrikab2619892015-05-18 16:49:16 +0200102 // Store the currenttly utilized audio layer.
103 audio_layer_ = audio_layer;
104 // The delay estimate can take one of two fixed values depending on if the
105 // device supports low-latency output or not. However, it is also possible
106 // that the user explicitly selects the high-latency audio path, hence we use
107 // the selected |audio_layer| here to set the delay estimate.
108 delay_estimate_in_milliseconds_ =
109 (audio_layer == AudioDeviceModule::kAndroidJavaAudio) ?
110 kHighLatencyModeDelayEstimateInMilliseconds :
111 kLowLatencyModeDelayEstimateInMilliseconds;
112 ALOGD("delay_estimate_in_milliseconds: %d", delay_estimate_in_milliseconds_);
henrika8324b522015-03-27 10:56:23 +0100113}
114
115bool AudioManager::Init() {
116 ALOGD("Init%s", GetThreadInfo().c_str());
henrikg91d6ede2015-09-17 00:24:34 -0700117 RTC_DCHECK(thread_checker_.CalledOnValidThread());
118 RTC_DCHECK(!initialized_);
119 RTC_DCHECK_NE(audio_layer_, AudioDeviceModule::kPlatformDefaultAudio);
henrikab2619892015-05-18 16:49:16 +0200120 if (!j_audio_manager_->Init()) {
henrika8324b522015-03-27 10:56:23 +0100121 ALOGE("init failed!");
122 return false;
123 }
124 initialized_ = true;
125 return true;
126}
127
128bool AudioManager::Close() {
129 ALOGD("Close%s", GetThreadInfo().c_str());
henrikg91d6ede2015-09-17 00:24:34 -0700130 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrika8324b522015-03-27 10:56:23 +0100131 if (!initialized_)
132 return true;
henrikab2619892015-05-18 16:49:16 +0200133 j_audio_manager_->Close();
henrika8324b522015-03-27 10:56:23 +0100134 initialized_ = false;
135 return true;
136}
137
henrikafe55c382015-06-05 11:45:56 +0200138bool AudioManager::IsCommunicationModeEnabled() const {
139 ALOGD("IsCommunicationModeEnabled()");
henrikg91d6ede2015-09-17 00:24:34 -0700140 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrikafe55c382015-06-05 11:45:56 +0200141 return j_audio_manager_->IsCommunicationModeEnabled();
henrika09bf1a12015-04-10 11:46:55 +0200142}
143
henrikab2619892015-05-18 16:49:16 +0200144bool AudioManager::IsAcousticEchoCancelerSupported() const {
henrikg91d6ede2015-09-17 00:24:34 -0700145 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrikab2619892015-05-18 16:49:16 +0200146 return hardware_aec_;
147}
148
henrikac14f5ff2015-09-23 14:08:33 +0200149bool AudioManager::IsAutomaticGainControlSupported() const {
150 RTC_DCHECK(thread_checker_.CalledOnValidThread());
151 return hardware_agc_;
152}
153
154bool AudioManager::IsNoiseSuppressorSupported() const {
155 RTC_DCHECK(thread_checker_.CalledOnValidThread());
156 return hardware_ns_;
157}
158
henrikab2619892015-05-18 16:49:16 +0200159bool AudioManager::IsLowLatencyPlayoutSupported() const {
henrikg91d6ede2015-09-17 00:24:34 -0700160 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrikab2619892015-05-18 16:49:16 +0200161 ALOGD("IsLowLatencyPlayoutSupported()");
henrika8a897182015-06-09 10:45:09 +0200162 // Some devices are blacklisted for usage of OpenSL ES even if they report
163 // that low-latency playout is supported. See b/21485703 for details.
164 return j_audio_manager_->IsDeviceBlacklistedForOpenSLESUsage() ?
165 false : low_latency_playout_;
henrikab2619892015-05-18 16:49:16 +0200166}
167
168int AudioManager::GetDelayEstimateInMilliseconds() const {
169 return delay_estimate_in_milliseconds_;
170}
171
172void JNICALL AudioManager::CacheAudioParameters(JNIEnv* env,
173 jobject obj,
174 jint sample_rate,
175 jint channels,
176 jboolean hardware_aec,
henrikac14f5ff2015-09-23 14:08:33 +0200177 jboolean hardware_agc,
178 jboolean hardware_ns,
henrikab2619892015-05-18 16:49:16 +0200179 jboolean low_latency_output,
180 jint output_buffer_size,
181 jint input_buffer_size,
182 jlong native_audio_manager) {
henrika8324b522015-03-27 10:56:23 +0100183 webrtc::AudioManager* this_object =
henrikab2619892015-05-18 16:49:16 +0200184 reinterpret_cast<webrtc::AudioManager*>(native_audio_manager);
185 this_object->OnCacheAudioParameters(
henrikac14f5ff2015-09-23 14:08:33 +0200186 env, sample_rate, channels, hardware_aec, hardware_agc, hardware_ns,
187 low_latency_output, output_buffer_size, input_buffer_size);
henrika8324b522015-03-27 10:56:23 +0100188}
189
henrikab2619892015-05-18 16:49:16 +0200190void AudioManager::OnCacheAudioParameters(JNIEnv* env,
191 jint sample_rate,
192 jint channels,
193 jboolean hardware_aec,
henrikac14f5ff2015-09-23 14:08:33 +0200194 jboolean hardware_agc,
195 jboolean hardware_ns,
henrikab2619892015-05-18 16:49:16 +0200196 jboolean low_latency_output,
197 jint output_buffer_size,
198 jint input_buffer_size) {
henrika8324b522015-03-27 10:56:23 +0100199 ALOGD("OnCacheAudioParameters%s", GetThreadInfo().c_str());
henrikab2619892015-05-18 16:49:16 +0200200 ALOGD("hardware_aec: %d", hardware_aec);
henrikac14f5ff2015-09-23 14:08:33 +0200201 ALOGD("hardware_agc: %d", hardware_agc);
202 ALOGD("hardware_ns: %d", hardware_ns);
henrikab2619892015-05-18 16:49:16 +0200203 ALOGD("low_latency_output: %d", low_latency_output);
henrika8324b522015-03-27 10:56:23 +0100204 ALOGD("sample_rate: %d", sample_rate);
205 ALOGD("channels: %d", channels);
henrikab2619892015-05-18 16:49:16 +0200206 ALOGD("output_buffer_size: %d", output_buffer_size);
207 ALOGD("input_buffer_size: %d", input_buffer_size);
henrikg91d6ede2015-09-17 00:24:34 -0700208 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrikab2619892015-05-18 16:49:16 +0200209 hardware_aec_ = hardware_aec;
henrikac14f5ff2015-09-23 14:08:33 +0200210 hardware_agc_ = hardware_agc;
211 hardware_ns_ = hardware_ns;
henrikab2619892015-05-18 16:49:16 +0200212 low_latency_playout_ = low_latency_output;
213 // TODO(henrika): add support for stereo output.
Peter Kasting1380e262015-08-28 17:31:03 -0700214 playout_parameters_.reset(sample_rate, channels,
215 static_cast<size_t>(output_buffer_size));
216 record_parameters_.reset(sample_rate, channels,
217 static_cast<size_t>(input_buffer_size));
henrika8324b522015-03-27 10:56:23 +0100218}
219
henrikab2619892015-05-18 16:49:16 +0200220const AudioParameters& AudioManager::GetPlayoutAudioParameters() {
henrikg91d6ede2015-09-17 00:24:34 -0700221 RTC_CHECK(playout_parameters_.is_valid());
222 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrika8324b522015-03-27 10:56:23 +0100223 return playout_parameters_;
224}
225
henrikab2619892015-05-18 16:49:16 +0200226const AudioParameters& AudioManager::GetRecordAudioParameters() {
henrikg91d6ede2015-09-17 00:24:34 -0700227 RTC_CHECK(record_parameters_.is_valid());
228 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrika8324b522015-03-27 10:56:23 +0100229 return record_parameters_;
230}
231
henrika8324b522015-03-27 10:56:23 +0100232} // namespace webrtc