• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
JavaAudioManager(NativeRegistration * native_reg,rtc::scoped_ptr<GlobalRef> audio_manager)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 
~JavaAudioManager()47 AudioManager::JavaAudioManager::~JavaAudioManager() {
48   ALOGD("JavaAudioManager::dtor%s", GetThreadInfo().c_str());
49 }
50 
Init()51 bool AudioManager::JavaAudioManager::Init() {
52   return audio_manager_->CallBooleanMethod(init_);
53 }
54 
Close()55 void AudioManager::JavaAudioManager::Close() {
56   audio_manager_->CallVoidMethod(dispose_);
57 }
58 
IsCommunicationModeEnabled()59 bool AudioManager::JavaAudioManager::IsCommunicationModeEnabled() {
60   return audio_manager_->CallBooleanMethod(is_communication_mode_enabled_);
61 }
62 
IsDeviceBlacklistedForOpenSLESUsage()63 bool AudioManager::JavaAudioManager::IsDeviceBlacklistedForOpenSLESUsage() {
64   return audio_manager_->CallBooleanMethod(
65       is_device_blacklisted_for_open_sles_usage_);
66 }
67 
68 // AudioManager implementation
AudioManager()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 
~AudioManager()94 AudioManager::~AudioManager() {
95   ALOGD("~dtor%s", GetThreadInfo().c_str());
96   RTC_DCHECK(thread_checker_.CalledOnValidThread());
97   Close();
98 }
99 
SetActiveAudioLayer(AudioDeviceModule::AudioLayer audio_layer)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 
Init()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 
Close()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 
IsCommunicationModeEnabled() const141 bool AudioManager::IsCommunicationModeEnabled() const {
142   ALOGD("IsCommunicationModeEnabled()");
143   RTC_DCHECK(thread_checker_.CalledOnValidThread());
144   return j_audio_manager_->IsCommunicationModeEnabled();
145 }
146 
IsAcousticEchoCancelerSupported() const147 bool AudioManager::IsAcousticEchoCancelerSupported() const {
148   RTC_DCHECK(thread_checker_.CalledOnValidThread());
149   return hardware_aec_;
150 }
151 
IsAutomaticGainControlSupported() const152 bool AudioManager::IsAutomaticGainControlSupported() const {
153   RTC_DCHECK(thread_checker_.CalledOnValidThread());
154   return hardware_agc_;
155 }
156 
IsNoiseSuppressorSupported() const157 bool AudioManager::IsNoiseSuppressorSupported() const {
158   RTC_DCHECK(thread_checker_.CalledOnValidThread());
159   return hardware_ns_;
160 }
161 
IsLowLatencyPlayoutSupported() const162 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 
GetDelayEstimateInMilliseconds() const171 int AudioManager::GetDelayEstimateInMilliseconds() const {
172   return delay_estimate_in_milliseconds_;
173 }
174 
CacheAudioParameters(JNIEnv * env,jobject obj,jint sample_rate,jint channels,jboolean hardware_aec,jboolean hardware_agc,jboolean hardware_ns,jboolean low_latency_output,jint output_buffer_size,jint input_buffer_size,jlong native_audio_manager)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 
OnCacheAudioParameters(JNIEnv * env,jint sample_rate,jint channels,jboolean hardware_aec,jboolean hardware_agc,jboolean hardware_ns,jboolean low_latency_output,jint output_buffer_size,jint input_buffer_size)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 
GetPlayoutAudioParameters()223 const AudioParameters& AudioManager::GetPlayoutAudioParameters() {
224   RTC_CHECK(playout_parameters_.is_valid());
225   RTC_DCHECK(thread_checker_.CalledOnValidThread());
226   return playout_parameters_;
227 }
228 
GetRecordAudioParameters()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