blob: 25735eb441b6931970e866025d90644398399d50 [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_(
37 native_reg->GetMethodId("isCommunicationModeEnabled", "()Z")) {
henrikab2619892015-05-18 16:49:16 +020038 ALOGD("JavaAudioManager::ctor%s", GetThreadInfo().c_str());
henrika8324b522015-03-27 10:56:23 +010039}
40
henrikab2619892015-05-18 16:49:16 +020041AudioManager::JavaAudioManager::~JavaAudioManager() {
42 ALOGD("JavaAudioManager::dtor%s", GetThreadInfo().c_str());
henrika8324b522015-03-27 10:56:23 +010043}
44
henrikab2619892015-05-18 16:49:16 +020045bool AudioManager::JavaAudioManager::Init() {
46 return audio_manager_->CallBooleanMethod(init_);
47}
48
49void AudioManager::JavaAudioManager::Close() {
50 audio_manager_->CallVoidMethod(dispose_);
51}
52
henrikafe55c382015-06-05 11:45:56 +020053bool AudioManager::JavaAudioManager::IsCommunicationModeEnabled() {
54 return audio_manager_->CallBooleanMethod(is_communication_mode_enabled_);
henrikab2619892015-05-18 16:49:16 +020055}
56
57// AudioManager implementation
henrika8324b522015-03-27 10:56:23 +010058AudioManager::AudioManager()
henrikab2619892015-05-18 16:49:16 +020059 : j_environment_(JVM::GetInstance()->environment()),
60 audio_layer_(AudioDeviceModule::kPlatformDefaultAudio),
61 initialized_(false),
62 hardware_aec_(false),
63 low_latency_playout_(false),
64 delay_estimate_in_milliseconds_(0) {
henrika8324b522015-03-27 10:56:23 +010065 ALOGD("ctor%s", GetThreadInfo().c_str());
henrikab2619892015-05-18 16:49:16 +020066 CHECK(j_environment_);
67 JNINativeMethod native_methods[] = {
68 {"nativeCacheAudioParameters",
69 "(IIZZIIJ)V",
70 reinterpret_cast<void*>(&webrtc::AudioManager::CacheAudioParameters)}};
71 j_native_registration_ = j_environment_->RegisterNatives(
72 "org/webrtc/voiceengine/WebRtcAudioManager",
73 native_methods, arraysize(native_methods));
74 j_audio_manager_.reset(new JavaAudioManager(
75 j_native_registration_.get(),
76 j_native_registration_->NewObject(
77 "<init>", "(Landroid/content/Context;J)V",
78 JVM::GetInstance()->context(), PointerTojlong(this))));
henrika8324b522015-03-27 10:56:23 +010079}
80
81AudioManager::~AudioManager() {
82 ALOGD("~dtor%s", GetThreadInfo().c_str());
83 DCHECK(thread_checker_.CalledOnValidThread());
84 Close();
henrikab2619892015-05-18 16:49:16 +020085}
86
87void AudioManager::SetActiveAudioLayer(
88 AudioDeviceModule::AudioLayer audio_layer) {
89 ALOGD("SetActiveAudioLayer(%d)%s", audio_layer, GetThreadInfo().c_str());
90 DCHECK(thread_checker_.CalledOnValidThread());
henrika8324b522015-03-27 10:56:23 +010091 DCHECK(!initialized_);
henrikab2619892015-05-18 16:49:16 +020092 // Store the currenttly utilized audio layer.
93 audio_layer_ = audio_layer;
94 // The delay estimate can take one of two fixed values depending on if the
95 // device supports low-latency output or not. However, it is also possible
96 // that the user explicitly selects the high-latency audio path, hence we use
97 // the selected |audio_layer| here to set the delay estimate.
98 delay_estimate_in_milliseconds_ =
99 (audio_layer == AudioDeviceModule::kAndroidJavaAudio) ?
100 kHighLatencyModeDelayEstimateInMilliseconds :
101 kLowLatencyModeDelayEstimateInMilliseconds;
102 ALOGD("delay_estimate_in_milliseconds: %d", delay_estimate_in_milliseconds_);
henrika8324b522015-03-27 10:56:23 +0100103}
104
105bool AudioManager::Init() {
106 ALOGD("Init%s", GetThreadInfo().c_str());
107 DCHECK(thread_checker_.CalledOnValidThread());
108 DCHECK(!initialized_);
henrikab2619892015-05-18 16:49:16 +0200109 DCHECK_NE(audio_layer_, AudioDeviceModule::kPlatformDefaultAudio);
110 if (!j_audio_manager_->Init()) {
henrika8324b522015-03-27 10:56:23 +0100111 ALOGE("init failed!");
112 return false;
113 }
114 initialized_ = true;
115 return true;
116}
117
118bool AudioManager::Close() {
119 ALOGD("Close%s", GetThreadInfo().c_str());
120 DCHECK(thread_checker_.CalledOnValidThread());
121 if (!initialized_)
122 return true;
henrikab2619892015-05-18 16:49:16 +0200123 j_audio_manager_->Close();
henrika8324b522015-03-27 10:56:23 +0100124 initialized_ = false;
125 return true;
126}
127
henrikafe55c382015-06-05 11:45:56 +0200128bool AudioManager::IsCommunicationModeEnabled() const {
129 ALOGD("IsCommunicationModeEnabled()");
henrika09bf1a12015-04-10 11:46:55 +0200130 DCHECK(thread_checker_.CalledOnValidThread());
henrikafe55c382015-06-05 11:45:56 +0200131 return j_audio_manager_->IsCommunicationModeEnabled();
henrika09bf1a12015-04-10 11:46:55 +0200132}
133
henrikab2619892015-05-18 16:49:16 +0200134bool AudioManager::IsAcousticEchoCancelerSupported() const {
135 DCHECK(thread_checker_.CalledOnValidThread());
136 return hardware_aec_;
137}
138
139bool AudioManager::IsLowLatencyPlayoutSupported() const {
140 DCHECK(thread_checker_.CalledOnValidThread());
141 ALOGD("IsLowLatencyPlayoutSupported()");
henrikabf738d72015-05-29 11:42:43 +0200142 // TODO(henrika): enable again once issue in b/21485703 has been sorted out.
143 // This is just a temporary fix.
144 ALOGW("NOTE: OpenSL ES output is currently disabled!");
145 return false;
henrikab2619892015-05-18 16:49:16 +0200146}
147
148int AudioManager::GetDelayEstimateInMilliseconds() const {
149 return delay_estimate_in_milliseconds_;
150}
151
152void JNICALL AudioManager::CacheAudioParameters(JNIEnv* env,
153 jobject obj,
154 jint sample_rate,
155 jint channels,
156 jboolean hardware_aec,
157 jboolean low_latency_output,
158 jint output_buffer_size,
159 jint input_buffer_size,
160 jlong native_audio_manager) {
henrika8324b522015-03-27 10:56:23 +0100161 webrtc::AudioManager* this_object =
henrikab2619892015-05-18 16:49:16 +0200162 reinterpret_cast<webrtc::AudioManager*>(native_audio_manager);
163 this_object->OnCacheAudioParameters(
164 env, sample_rate, channels, hardware_aec, low_latency_output,
165 output_buffer_size, input_buffer_size);
henrika8324b522015-03-27 10:56:23 +0100166}
167
henrikab2619892015-05-18 16:49:16 +0200168void AudioManager::OnCacheAudioParameters(JNIEnv* env,
169 jint sample_rate,
170 jint channels,
171 jboolean hardware_aec,
172 jboolean low_latency_output,
173 jint output_buffer_size,
174 jint input_buffer_size) {
henrika8324b522015-03-27 10:56:23 +0100175 ALOGD("OnCacheAudioParameters%s", GetThreadInfo().c_str());
henrikab2619892015-05-18 16:49:16 +0200176 ALOGD("hardware_aec: %d", hardware_aec);
177 ALOGD("low_latency_output: %d", low_latency_output);
henrika8324b522015-03-27 10:56:23 +0100178 ALOGD("sample_rate: %d", sample_rate);
179 ALOGD("channels: %d", channels);
henrikab2619892015-05-18 16:49:16 +0200180 ALOGD("output_buffer_size: %d", output_buffer_size);
181 ALOGD("input_buffer_size: %d", input_buffer_size);
henrika8324b522015-03-27 10:56:23 +0100182 DCHECK(thread_checker_.CalledOnValidThread());
henrikab2619892015-05-18 16:49:16 +0200183 hardware_aec_ = hardware_aec;
184 low_latency_playout_ = low_latency_output;
185 // TODO(henrika): add support for stereo output.
186 playout_parameters_.reset(sample_rate, channels, output_buffer_size);
187 record_parameters_.reset(sample_rate, channels, input_buffer_size);
henrika8324b522015-03-27 10:56:23 +0100188}
189
henrikab2619892015-05-18 16:49:16 +0200190const AudioParameters& AudioManager::GetPlayoutAudioParameters() {
henrika8324b522015-03-27 10:56:23 +0100191 CHECK(playout_parameters_.is_valid());
henrikab2619892015-05-18 16:49:16 +0200192 DCHECK(thread_checker_.CalledOnValidThread());
henrika8324b522015-03-27 10:56:23 +0100193 return playout_parameters_;
194}
195
henrikab2619892015-05-18 16:49:16 +0200196const AudioParameters& AudioManager::GetRecordAudioParameters() {
henrika8324b522015-03-27 10:56:23 +0100197 CHECK(record_parameters_.is_valid());
henrikab2619892015-05-18 16:49:16 +0200198 DCHECK(thread_checker_.CalledOnValidThread());
henrika8324b522015-03-27 10:56:23 +0100199 return record_parameters_;
200}
201
henrika8324b522015-03-27 10:56:23 +0100202} // namespace webrtc