android_media_AudioSystem.cpp revision d24b8183b93e781080b2c16c487e60d51c12da31
1/* //device/libs/android_runtime/android_media_AudioSystem.cpp 2** 3** Copyright 2006, The Android Open Source Project 4** 5** Licensed under the Apache License, Version 2.0 (the "License"); 6** you may not use this file except in compliance with the License. 7** You may obtain a copy of the License at 8** 9** http://www.apache.org/licenses/LICENSE-2.0 10** 11** Unless required by applicable law or agreed to in writing, software 12** distributed under the License is distributed on an "AS IS" BASIS, 13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14** See the License for the specific language governing permissions and 15** limitations under the License. 16*/ 17 18#define LOG_TAG "AudioSystem" 19#include "utils/Log.h" 20 21#include <stdio.h> 22#include <unistd.h> 23#include <fcntl.h> 24#include <math.h> 25 26#include "jni.h" 27#include "JNIHelp.h" 28#include "android_runtime/AndroidRuntime.h" 29 30#include <media/AudioSystem.h> 31#include <media/AudioTrack.h> 32 33// ---------------------------------------------------------------------------- 34 35using namespace android; 36 37enum AudioError { 38 kAudioStatusOk = 0, 39 kAudioStatusError = 1, 40 kAudioStatusMediaServerDied = 100 41}; 42 43static int check_AudioSystem_Command(status_t status) 44{ 45 if (status == NO_ERROR) { 46 return kAudioStatusOk; 47 } else { 48 return kAudioStatusError; 49 } 50} 51 52static int 53android_media_AudioSystem_setVolume(JNIEnv *env, jobject clazz, jint type, jint volume) 54{ 55 LOGV("setVolume(%d)", int(volume)); 56 if (int(type) == AudioTrack::VOICE_CALL) { 57 return check_AudioSystem_Command(AudioSystem::setStreamVolume(type, float(volume) / 100.0)); 58 } else if (int(type) == AudioTrack::BLUETOOTH_SCO) { 59 return check_AudioSystem_Command(AudioSystem::setStreamVolume(type, float(1.0))); 60 } else { 61 return check_AudioSystem_Command(AudioSystem::setStreamVolume(type, AudioSystem::linearToLog(volume))); 62 } 63} 64 65static int 66android_media_AudioSystem_getVolume(JNIEnv *env, jobject clazz, jint type) 67{ 68 float v; 69 int v_int = -1; 70 if (AudioSystem::getStreamVolume(int(type), &v) == NO_ERROR) { 71 // voice call volume is converted to log scale in the hardware 72 if (int(type) == AudioTrack::VOICE_CALL) { 73 v_int = lrint(v * 100.0); 74 } else { 75 v_int = AudioSystem::logToLinear(v); 76 } 77 } 78 return v_int; 79} 80 81static int 82android_media_AudioSystem_muteMicrophone(JNIEnv *env, jobject thiz, jboolean on) 83{ 84 return check_AudioSystem_Command(AudioSystem::muteMicrophone(on)); 85} 86 87static jboolean 88android_media_AudioSystem_isMicrophoneMuted(JNIEnv *env, jobject thiz) 89{ 90 bool state = false; 91 AudioSystem::isMicrophoneMuted(&state); 92 return state; 93} 94 95static int 96android_media_AudioSystem_setRouting(JNIEnv *env, jobject clazz, jint mode, jint routes, jint mask) 97{ 98 return check_AudioSystem_Command(AudioSystem::setRouting(mode, uint32_t(routes), uint32_t(mask))); 99} 100 101static jint 102android_media_AudioSystem_getRouting(JNIEnv *env, jobject clazz, jint mode) 103{ 104 uint32_t routes = -1; 105 AudioSystem::getRouting(mode, &routes); 106 return jint(routes); 107} 108 109static int 110android_media_AudioSystem_setMode(JNIEnv *env, jobject clazz, jint mode) 111{ 112 return check_AudioSystem_Command(AudioSystem::setMode(mode)); 113} 114 115static jint 116android_media_AudioSystem_getMode(JNIEnv *env, jobject clazz) 117{ 118 int mode = AudioSystem::MODE_INVALID; 119 AudioSystem::getMode(&mode); 120 return jint(mode); 121} 122 123static jboolean 124android_media_AudioSystem_isMusicActive(JNIEnv *env, jobject thiz) 125{ 126 bool state = false; 127 AudioSystem::isMusicActive(&state); 128 return state; 129} 130 131// Temporary interface, do not use 132// TODO: Replace with a more generic key:value get/set mechanism 133static void 134android_media_AudioSystem_setParameter(JNIEnv *env, jobject thiz, jstring key, jstring value) 135{ 136 const char *c_key = env->GetStringUTFChars(key, NULL); 137 const char *c_value = env->GetStringUTFChars(value, NULL); 138 AudioSystem::setParameter(c_key, c_value); 139 env->ReleaseStringUTFChars(key, c_key); 140 env->ReleaseStringUTFChars(value, c_value); 141} 142 143void android_media_AudioSystem_error_callback(status_t err) 144{ 145 JNIEnv *env = AndroidRuntime::getJNIEnv(); 146 jclass clazz = env->FindClass("android/media/AudioSystem"); 147 148 int error; 149 150 switch (err) { 151 case DEAD_OBJECT: 152 error = kAudioStatusMediaServerDied; 153 break; 154 case NO_ERROR: 155 error = kAudioStatusOk; 156 break; 157 default: 158 error = kAudioStatusError; 159 break; 160 } 161 162 env->CallStaticVoidMethod(clazz, env->GetStaticMethodID(clazz, "errorCallbackFromNative","(I)V"), error); 163} 164 165// ---------------------------------------------------------------------------- 166 167static JNINativeMethod gMethods[] = { 168 {"setVolume", "(II)I", (void *)android_media_AudioSystem_setVolume}, 169 {"getVolume", "(I)I", (void *)android_media_AudioSystem_getVolume}, 170 {"setParameter", "(Ljava/lang/String;Ljava/lang/String;)V", (void *)android_media_AudioSystem_setParameter}, 171 {"muteMicrophone", "(Z)I", (void *)android_media_AudioSystem_muteMicrophone}, 172 {"isMicrophoneMuted", "()Z", (void *)android_media_AudioSystem_isMicrophoneMuted}, 173 {"setRouting", "(III)I", (void *)android_media_AudioSystem_setRouting}, 174 {"getRouting", "(I)I", (void *)android_media_AudioSystem_getRouting}, 175 {"setMode", "(I)I", (void *)android_media_AudioSystem_setMode}, 176 {"getMode", "()I", (void *)android_media_AudioSystem_getMode}, 177 {"isMusicActive", "()Z", (void *)android_media_AudioSystem_isMusicActive}, 178}; 179 180const char* const kClassPathName = "android/media/AudioSystem"; 181 182int register_android_media_AudioSystem(JNIEnv *env) 183{ 184 AudioSystem::setErrorCallback(android_media_AudioSystem_error_callback); 185 186 return AndroidRuntime::registerNativeMethods(env, 187 "android/media/AudioSystem", gMethods, NELEM(gMethods)); 188} 189