1/* 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 <utility> 14 15#include <android/log.h> 16 17#include "webrtc/base/arraysize.h" 18#include "webrtc/base/checks.h" 19#include "webrtc/base/scoped_ptr.h" 20#include "webrtc/modules/audio_device/android/audio_common.h" 21#include "webrtc/modules/utility/include/helpers_android.h" 22 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 32// AudioManager::JavaAudioManager implementation 33AudioManager::JavaAudioManager::JavaAudioManager( 34 NativeRegistration* native_reg, 35 rtc::scoped_ptr<GlobalRef> audio_manager) 36 : audio_manager_(std::move(audio_manager)), 37 init_(native_reg->GetMethodId("init", "()Z")), 38 dispose_(native_reg->GetMethodId("dispose", "()V")), 39 is_communication_mode_enabled_( 40 native_reg->GetMethodId("isCommunicationModeEnabled", "()Z")), 41 is_device_blacklisted_for_open_sles_usage_( 42 native_reg->GetMethodId("isDeviceBlacklistedForOpenSLESUsage", 43 "()Z")) { 44 ALOGD("JavaAudioManager::ctor%s", GetThreadInfo().c_str()); 45} 46 47AudioManager::JavaAudioManager::~JavaAudioManager() { 48 ALOGD("JavaAudioManager::dtor%s", GetThreadInfo().c_str()); 49} 50 51bool AudioManager::JavaAudioManager::Init() { 52 return audio_manager_->CallBooleanMethod(init_); 53} 54 55void AudioManager::JavaAudioManager::Close() { 56 audio_manager_->CallVoidMethod(dispose_); 57} 58 59bool AudioManager::JavaAudioManager::IsCommunicationModeEnabled() { 60 return audio_manager_->CallBooleanMethod(is_communication_mode_enabled_); 61} 62 63bool AudioManager::JavaAudioManager::IsDeviceBlacklistedForOpenSLESUsage() { 64 return audio_manager_->CallBooleanMethod( 65 is_device_blacklisted_for_open_sles_usage_); 66} 67 68// AudioManager implementation 69AudioManager::AudioManager() 70 : j_environment_(JVM::GetInstance()->environment()), 71 audio_layer_(AudioDeviceModule::kPlatformDefaultAudio), 72 initialized_(false), 73 hardware_aec_(false), 74 hardware_agc_(false), 75 hardware_ns_(false), 76 low_latency_playout_(false), 77 delay_estimate_in_milliseconds_(0) { 78 ALOGD("ctor%s", GetThreadInfo().c_str()); 79 RTC_CHECK(j_environment_); 80 JNINativeMethod native_methods[] = { 81 {"nativeCacheAudioParameters", 82 "(IIZZZZIIJ)V", 83 reinterpret_cast<void*>(&webrtc::AudioManager::CacheAudioParameters)}}; 84 j_native_registration_ = j_environment_->RegisterNatives( 85 "org/webrtc/voiceengine/WebRtcAudioManager", 86 native_methods, arraysize(native_methods)); 87 j_audio_manager_.reset(new JavaAudioManager( 88 j_native_registration_.get(), 89 j_native_registration_->NewObject( 90 "<init>", "(Landroid/content/Context;J)V", 91 JVM::GetInstance()->context(), PointerTojlong(this)))); 92} 93 94AudioManager::~AudioManager() { 95 ALOGD("~dtor%s", GetThreadInfo().c_str()); 96 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 97 Close(); 98} 99 100void AudioManager::SetActiveAudioLayer( 101 AudioDeviceModule::AudioLayer audio_layer) { 102 ALOGD("SetActiveAudioLayer(%d)%s", audio_layer, GetThreadInfo().c_str()); 103 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 104 RTC_DCHECK(!initialized_); 105 // Store the currenttly utilized audio layer. 106 audio_layer_ = audio_layer; 107 // The delay estimate can take one of two fixed values depending on if the 108 // device supports low-latency output or not. However, it is also possible 109 // that the user explicitly selects the high-latency audio path, hence we use 110 // the selected |audio_layer| here to set the delay estimate. 111 delay_estimate_in_milliseconds_ = 112 (audio_layer == AudioDeviceModule::kAndroidJavaAudio) ? 113 kHighLatencyModeDelayEstimateInMilliseconds : 114 kLowLatencyModeDelayEstimateInMilliseconds; 115 ALOGD("delay_estimate_in_milliseconds: %d", delay_estimate_in_milliseconds_); 116} 117 118bool AudioManager::Init() { 119 ALOGD("Init%s", GetThreadInfo().c_str()); 120 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 121 RTC_DCHECK(!initialized_); 122 RTC_DCHECK_NE(audio_layer_, AudioDeviceModule::kPlatformDefaultAudio); 123 if (!j_audio_manager_->Init()) { 124 ALOGE("init failed!"); 125 return false; 126 } 127 initialized_ = true; 128 return true; 129} 130 131bool AudioManager::Close() { 132 ALOGD("Close%s", GetThreadInfo().c_str()); 133 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 134 if (!initialized_) 135 return true; 136 j_audio_manager_->Close(); 137 initialized_ = false; 138 return true; 139} 140 141bool AudioManager::IsCommunicationModeEnabled() const { 142 ALOGD("IsCommunicationModeEnabled()"); 143 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 144 return j_audio_manager_->IsCommunicationModeEnabled(); 145} 146 147bool AudioManager::IsAcousticEchoCancelerSupported() const { 148 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 149 return hardware_aec_; 150} 151 152bool AudioManager::IsAutomaticGainControlSupported() const { 153 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 154 return hardware_agc_; 155} 156 157bool AudioManager::IsNoiseSuppressorSupported() const { 158 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 159 return hardware_ns_; 160} 161 162bool AudioManager::IsLowLatencyPlayoutSupported() const { 163 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 164 ALOGD("IsLowLatencyPlayoutSupported()"); 165 // Some devices are blacklisted for usage of OpenSL ES even if they report 166 // that low-latency playout is supported. See b/21485703 for details. 167 return j_audio_manager_->IsDeviceBlacklistedForOpenSLESUsage() ? 168 false : low_latency_playout_; 169} 170 171int AudioManager::GetDelayEstimateInMilliseconds() const { 172 return delay_estimate_in_milliseconds_; 173} 174 175void JNICALL AudioManager::CacheAudioParameters(JNIEnv* env, 176 jobject obj, 177 jint sample_rate, 178 jint channels, 179 jboolean hardware_aec, 180 jboolean hardware_agc, 181 jboolean hardware_ns, 182 jboolean low_latency_output, 183 jint output_buffer_size, 184 jint input_buffer_size, 185 jlong native_audio_manager) { 186 webrtc::AudioManager* this_object = 187 reinterpret_cast<webrtc::AudioManager*>(native_audio_manager); 188 this_object->OnCacheAudioParameters( 189 env, sample_rate, channels, hardware_aec, hardware_agc, hardware_ns, 190 low_latency_output, output_buffer_size, input_buffer_size); 191} 192 193void AudioManager::OnCacheAudioParameters(JNIEnv* env, 194 jint sample_rate, 195 jint channels, 196 jboolean hardware_aec, 197 jboolean hardware_agc, 198 jboolean hardware_ns, 199 jboolean low_latency_output, 200 jint output_buffer_size, 201 jint input_buffer_size) { 202 ALOGD("OnCacheAudioParameters%s", GetThreadInfo().c_str()); 203 ALOGD("hardware_aec: %d", hardware_aec); 204 ALOGD("hardware_agc: %d", hardware_agc); 205 ALOGD("hardware_ns: %d", hardware_ns); 206 ALOGD("low_latency_output: %d", low_latency_output); 207 ALOGD("sample_rate: %d", sample_rate); 208 ALOGD("channels: %d", channels); 209 ALOGD("output_buffer_size: %d", output_buffer_size); 210 ALOGD("input_buffer_size: %d", input_buffer_size); 211 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 212 hardware_aec_ = hardware_aec; 213 hardware_agc_ = hardware_agc; 214 hardware_ns_ = hardware_ns; 215 low_latency_playout_ = low_latency_output; 216 // TODO(henrika): add support for stereo output. 217 playout_parameters_.reset(sample_rate, static_cast<size_t>(channels), 218 static_cast<size_t>(output_buffer_size)); 219 record_parameters_.reset(sample_rate, static_cast<size_t>(channels), 220 static_cast<size_t>(input_buffer_size)); 221} 222 223const AudioParameters& AudioManager::GetPlayoutAudioParameters() { 224 RTC_CHECK(playout_parameters_.is_valid()); 225 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 226 return playout_parameters_; 227} 228 229const AudioParameters& AudioManager::GetRecordAudioParameters() { 230 RTC_CHECK(record_parameters_.is_valid()); 231 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 232 return record_parameters_; 233} 234 235} // namespace webrtc 236