AudioSystem.cpp revision 2729ea9262ca60d93047e984739887cfc89e82eb
1/* 2 * Copyright (C) 2006-2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "AudioSystem" 18#include <utils/Log.h> 19#include <utils/IServiceManager.h> 20#include <media/AudioSystem.h> 21#include <media/AudioTrack.h> 22#include <math.h> 23 24namespace android { 25 26// client singleton for AudioFlinger binder interface 27Mutex AudioSystem::gLock; 28sp<IAudioFlinger> AudioSystem::gAudioFlinger; 29sp<AudioSystem::DeathNotifier> AudioSystem::gDeathNotifier; 30audio_error_callback AudioSystem::gAudioErrorCallback = NULL; 31 32// establish binder interface to AudioFlinger service 33const sp<IAudioFlinger>& AudioSystem::get_audio_flinger() 34{ 35 Mutex::Autolock _l(gLock); 36 if (gAudioFlinger.get() == 0) { 37 sp<IServiceManager> sm = defaultServiceManager(); 38 sp<IBinder> binder; 39 do { 40 binder = sm->getService(String16("media.audio_flinger")); 41 if (binder != 0) 42 break; 43 LOGW("AudioFlinger not published, waiting..."); 44 usleep(500000); // 0.5 s 45 } while(true); 46 if (gDeathNotifier == NULL) { 47 gDeathNotifier = new DeathNotifier(); 48 } else { 49 if (gAudioErrorCallback) { 50 gAudioErrorCallback(NO_ERROR); 51 } 52 } 53 binder->linkToDeath(gDeathNotifier); 54 gAudioFlinger = interface_cast<IAudioFlinger>(binder); 55 } 56 LOGE_IF(gAudioFlinger==0, "no AudioFlinger!?"); 57 return gAudioFlinger; 58} 59 60// routing helper functions 61status_t AudioSystem::speakerphone(bool state) { 62 uint32_t routes = state ? ROUTE_SPEAKER : ROUTE_EARPIECE; 63 return setRouting(MODE_IN_CALL, routes, ROUTE_ALL); 64} 65 66status_t AudioSystem::isSpeakerphoneOn(bool* state) { 67 uint32_t routes = 0; 68 status_t s = getRouting(MODE_IN_CALL, &routes); 69 *state = !!(routes & ROUTE_SPEAKER); 70 return s; 71} 72 73status_t AudioSystem::bluetoothSco(bool state) { 74 uint32_t mask = ROUTE_BLUETOOTH; 75 uint32_t routes = state ? mask : ROUTE_EARPIECE; 76 return setRouting(MODE_IN_CALL, routes, ROUTE_ALL); 77} 78 79status_t AudioSystem::isBluetoothScoOn(bool* state) { 80 uint32_t routes = 0; 81 status_t s = getRouting(MODE_IN_CALL, &routes); 82 *state = !!(routes & ROUTE_BLUETOOTH); 83 return s; 84} 85 86status_t AudioSystem::muteMicrophone(bool state) { 87 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 88 if (af == 0) return PERMISSION_DENIED; 89 return af->setMicMute(state); 90} 91 92status_t AudioSystem::isMicrophoneMuted(bool* state) { 93 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 94 if (af == 0) return PERMISSION_DENIED; 95 *state = af->getMicMute(); 96 return NO_ERROR; 97} 98 99status_t AudioSystem::setMasterVolume(float value) 100{ 101 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 102 if (af == 0) return PERMISSION_DENIED; 103 af->setMasterVolume(value); 104 return NO_ERROR; 105} 106 107status_t AudioSystem::setMasterMute(bool mute) 108{ 109 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 110 if (af == 0) return PERMISSION_DENIED; 111 af->setMasterMute(mute); 112 return NO_ERROR; 113} 114 115status_t AudioSystem::getMasterVolume(float* volume) 116{ 117 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 118 if (af == 0) return PERMISSION_DENIED; 119 *volume = af->masterVolume(); 120 return NO_ERROR; 121} 122 123status_t AudioSystem::getMasterMute(bool* mute) 124{ 125 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 126 if (af == 0) return PERMISSION_DENIED; 127 *mute = af->masterMute(); 128 return NO_ERROR; 129} 130 131status_t AudioSystem::setStreamVolume(int stream, float value) 132{ 133 if (uint32_t(stream) >= AudioTrack::NUM_STREAM_TYPES) return BAD_VALUE; 134 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 135 if (af == 0) return PERMISSION_DENIED; 136 af->setStreamVolume(stream, value); 137 return NO_ERROR; 138} 139 140status_t AudioSystem::setStreamMute(int stream, bool mute) 141{ 142 if (uint32_t(stream) >= AudioTrack::NUM_STREAM_TYPES) return BAD_VALUE; 143 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 144 if (af == 0) return PERMISSION_DENIED; 145 af->setStreamMute(stream, mute); 146 return NO_ERROR; 147} 148 149status_t AudioSystem::getStreamVolume(int stream, float* volume) 150{ 151 if (uint32_t(stream) >= AudioTrack::NUM_STREAM_TYPES) return BAD_VALUE; 152 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 153 if (af == 0) return PERMISSION_DENIED; 154 *volume = af->streamVolume(stream); 155 return NO_ERROR; 156} 157 158status_t AudioSystem::getStreamMute(int stream, bool* mute) 159{ 160 if (uint32_t(stream) >= AudioTrack::NUM_STREAM_TYPES) return BAD_VALUE; 161 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 162 if (af == 0) return PERMISSION_DENIED; 163 *mute = af->streamMute(stream); 164 return NO_ERROR; 165} 166 167status_t AudioSystem::setMode(int mode) 168{ 169 if (mode >= NUM_MODES) return BAD_VALUE; 170 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 171 if (af == 0) return PERMISSION_DENIED; 172 return af->setMode(mode); 173} 174 175status_t AudioSystem::getMode(int* mode) 176{ 177 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 178 if (af == 0) return PERMISSION_DENIED; 179 *mode = af->getMode(); 180 return NO_ERROR; 181} 182 183status_t AudioSystem::setRouting(int mode, uint32_t routes, uint32_t mask) 184{ 185 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 186 if (af == 0) return PERMISSION_DENIED; 187 return af->setRouting(mode, routes, mask); 188} 189 190status_t AudioSystem::getRouting(int mode, uint32_t* routes) 191{ 192 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 193 if (af == 0) return PERMISSION_DENIED; 194 uint32_t r = af->getRouting(mode); 195 *routes = r; 196 return NO_ERROR; 197} 198 199status_t AudioSystem::isMusicActive(bool* state) { 200 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 201 if (af == 0) return PERMISSION_DENIED; 202 *state = af->isMusicActive(); 203 return NO_ERROR; 204} 205 206// Temporary interface, do not use 207// TODO: Replace with a more generic key:value get/set mechanism 208status_t AudioSystem::setParameter(const char* key, const char* value) { 209 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 210 if (af == 0) return PERMISSION_DENIED; 211 return af->setParameter(key, value); 212} 213 214// convert volume steps to natural log scale 215 216// change this value to change volume scaling 217static const float dBPerStep = 0.5f; 218// shouldn't need to touch these 219static const float dBConvert = -dBPerStep * 2.302585093f / 20.0f; 220static const float dBConvertInverse = 1.0f / dBConvert; 221 222float AudioSystem::linearToLog(int volume) 223{ 224 // float v = volume ? exp(float(100 - volume) * dBConvert) : 0; 225 // LOGD("linearToLog(%d)=%f", volume, v); 226 // return v; 227 return volume ? exp(float(100 - volume) * dBConvert) : 0; 228} 229 230int AudioSystem::logToLinear(float volume) 231{ 232 // int v = volume ? 100 - int(dBConvertInverse * log(volume) + 0.5) : 0; 233 // LOGD("logTolinear(%d)=%f", v, volume); 234 // return v; 235 return volume ? 100 - int(dBConvertInverse * log(volume) + 0.5) : 0; 236} 237 238// --------------------------------------------------------------------------- 239 240void AudioSystem::DeathNotifier::binderDied(const wp<IBinder>& who) { 241 Mutex::Autolock _l(AudioSystem::gLock); 242 AudioSystem::gAudioFlinger.clear(); 243 if (gAudioErrorCallback) { 244 gAudioErrorCallback(DEAD_OBJECT); 245 } 246 LOGW("AudioFlinger server died!"); 247} 248 249void AudioSystem::setErrorCallback(audio_error_callback cb) { 250 Mutex::Autolock _l(AudioSystem::gLock); 251 gAudioErrorCallback = cb; 252} 253 254}; // namespace android 255 256