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 30 namespace webrtc { 31 32 // AudioManager::JavaAudioManager implementation 33 AudioManager::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 47 AudioManager::JavaAudioManager::~JavaAudioManager() { 48 ALOGD("JavaAudioManager::dtor%s", GetThreadInfo().c_str()); 49 } 50 51 bool AudioManager::JavaAudioManager::Init() { 52 return audio_manager_->CallBooleanMethod(init_); 53 } 54 55 void AudioManager::JavaAudioManager::Close() { 56 audio_manager_->CallVoidMethod(dispose_); 57 } 58 59 bool AudioManager::JavaAudioManager::IsCommunicationModeEnabled() { 60 return audio_manager_->CallBooleanMethod(is_communication_mode_enabled_); 61 } 62 63 bool AudioManager::JavaAudioManager::IsDeviceBlacklistedForOpenSLESUsage() { 64 return audio_manager_->CallBooleanMethod( 65 is_device_blacklisted_for_open_sles_usage_); 66 } 67 68 // AudioManager implementation 69 AudioManager::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 94 AudioManager::~AudioManager() { 95 ALOGD("~dtor%s", GetThreadInfo().c_str()); 96 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 97 Close(); 98 } 99 100 void 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 118 bool 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 131 bool 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 141 bool AudioManager::IsCommunicationModeEnabled() const { 142 ALOGD("IsCommunicationModeEnabled()"); 143 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 144 return j_audio_manager_->IsCommunicationModeEnabled(); 145 } 146 147 bool AudioManager::IsAcousticEchoCancelerSupported() const { 148 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 149 return hardware_aec_; 150 } 151 152 bool AudioManager::IsAutomaticGainControlSupported() const { 153 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 154 return hardware_agc_; 155 } 156 157 bool AudioManager::IsNoiseSuppressorSupported() const { 158 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 159 return hardware_ns_; 160 } 161 162 bool 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 171 int AudioManager::GetDelayEstimateInMilliseconds() const { 172 return delay_estimate_in_milliseconds_; 173 } 174 175 void 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 193 void 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 223 const AudioParameters& AudioManager::GetPlayoutAudioParameters() { 224 RTC_CHECK(playout_parameters_.is_valid()); 225 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 226 return playout_parameters_; 227 } 228 229 const 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