AudioSystem.cpp revision 7b5eb023f8d87cca6d830ae6c11c6aadbe02aca8
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// Cached values 32int AudioSystem::gOutSamplingRate = 0; 33int AudioSystem::gOutFrameCount = 0; 34uint32_t AudioSystem::gOutLatency = 0; 35 36 37// establish binder interface to AudioFlinger service 38const sp<IAudioFlinger>& AudioSystem::get_audio_flinger() 39{ 40 Mutex::Autolock _l(gLock); 41 if (gAudioFlinger.get() == 0) { 42 sp<IServiceManager> sm = defaultServiceManager(); 43 sp<IBinder> binder; 44 do { 45 binder = sm->getService(String16("media.audio_flinger")); 46 if (binder != 0) 47 break; 48 LOGW("AudioFlinger not published, waiting..."); 49 usleep(500000); // 0.5 s 50 } while(true); 51 if (gDeathNotifier == NULL) { 52 gDeathNotifier = new DeathNotifier(); 53 } else { 54 if (gAudioErrorCallback) { 55 gAudioErrorCallback(NO_ERROR); 56 } 57 } 58 binder->linkToDeath(gDeathNotifier); 59 gAudioFlinger = interface_cast<IAudioFlinger>(binder); 60 // Cache frequently accessed parameters 61 gOutFrameCount = (int)gAudioFlinger->frameCount(); 62 gOutSamplingRate = (int)gAudioFlinger->sampleRate(); 63 gOutLatency = gAudioFlinger->latency(); 64 } 65 LOGE_IF(gAudioFlinger==0, "no AudioFlinger!?"); 66 return gAudioFlinger; 67} 68 69// routing helper functions 70status_t AudioSystem::speakerphone(bool state) { 71 uint32_t routes = state ? ROUTE_SPEAKER : ROUTE_EARPIECE; 72 return setRouting(MODE_IN_CALL, routes, ROUTE_ALL); 73} 74 75status_t AudioSystem::isSpeakerphoneOn(bool* state) { 76 uint32_t routes = 0; 77 status_t s = getRouting(MODE_IN_CALL, &routes); 78 *state = !!(routes & ROUTE_SPEAKER); 79 return s; 80} 81 82status_t AudioSystem::bluetoothSco(bool state) { 83 uint32_t mask = ROUTE_BLUETOOTH_SCO; 84 uint32_t routes = state ? mask : ROUTE_EARPIECE; 85 return setRouting(MODE_IN_CALL, routes, ROUTE_ALL); 86} 87 88status_t AudioSystem::isBluetoothScoOn(bool* state) { 89 uint32_t routes = 0; 90 status_t s = getRouting(MODE_IN_CALL, &routes); 91 *state = !!(routes & ROUTE_BLUETOOTH_SCO); 92 return s; 93} 94 95status_t AudioSystem::muteMicrophone(bool state) { 96 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 97 if (af == 0) return PERMISSION_DENIED; 98 return af->setMicMute(state); 99} 100 101status_t AudioSystem::isMicrophoneMuted(bool* state) { 102 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 103 if (af == 0) return PERMISSION_DENIED; 104 *state = af->getMicMute(); 105 return NO_ERROR; 106} 107 108status_t AudioSystem::setMasterVolume(float value) 109{ 110 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 111 if (af == 0) return PERMISSION_DENIED; 112 af->setMasterVolume(value); 113 return NO_ERROR; 114} 115 116status_t AudioSystem::setMasterMute(bool mute) 117{ 118 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 119 if (af == 0) return PERMISSION_DENIED; 120 af->setMasterMute(mute); 121 return NO_ERROR; 122} 123 124status_t AudioSystem::getMasterVolume(float* volume) 125{ 126 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 127 if (af == 0) return PERMISSION_DENIED; 128 *volume = af->masterVolume(); 129 return NO_ERROR; 130} 131 132status_t AudioSystem::getMasterMute(bool* mute) 133{ 134 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 135 if (af == 0) return PERMISSION_DENIED; 136 *mute = af->masterMute(); 137 return NO_ERROR; 138} 139 140status_t AudioSystem::setStreamVolume(int stream, float value) 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->setStreamVolume(stream, value); 146 return NO_ERROR; 147} 148 149status_t AudioSystem::setStreamMute(int stream, bool mute) 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 af->setStreamMute(stream, mute); 155 return NO_ERROR; 156} 157 158status_t AudioSystem::getStreamVolume(int stream, float* volume) 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 *volume = af->streamVolume(stream); 164 return NO_ERROR; 165} 166 167status_t AudioSystem::getStreamMute(int stream, bool* mute) 168{ 169 if (uint32_t(stream) >= AudioTrack::NUM_STREAM_TYPES) return BAD_VALUE; 170 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 171 if (af == 0) return PERMISSION_DENIED; 172 *mute = af->streamMute(stream); 173 return NO_ERROR; 174} 175 176status_t AudioSystem::setMode(int mode) 177{ 178 if (mode >= NUM_MODES) return BAD_VALUE; 179 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 180 if (af == 0) return PERMISSION_DENIED; 181 return af->setMode(mode); 182} 183 184status_t AudioSystem::getMode(int* mode) 185{ 186 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 187 if (af == 0) return PERMISSION_DENIED; 188 *mode = af->getMode(); 189 return NO_ERROR; 190} 191 192status_t AudioSystem::setRouting(int mode, uint32_t routes, uint32_t mask) 193{ 194 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 195 if (af == 0) return PERMISSION_DENIED; 196 return af->setRouting(mode, routes, mask); 197} 198 199status_t AudioSystem::getRouting(int mode, uint32_t* routes) 200{ 201 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 202 if (af == 0) return PERMISSION_DENIED; 203 uint32_t r = af->getRouting(mode); 204 *routes = r; 205 return NO_ERROR; 206} 207 208status_t AudioSystem::isMusicActive(bool* state) { 209 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 210 if (af == 0) return PERMISSION_DENIED; 211 *state = af->isMusicActive(); 212 return NO_ERROR; 213} 214 215// Temporary interface, do not use 216// TODO: Replace with a more generic key:value get/set mechanism 217status_t AudioSystem::setParameter(const char* key, const char* value) { 218 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 219 if (af == 0) return PERMISSION_DENIED; 220 return af->setParameter(key, value); 221} 222 223// convert volume steps to natural log scale 224 225// change this value to change volume scaling 226static const float dBPerStep = 0.5f; 227// shouldn't need to touch these 228static const float dBConvert = -dBPerStep * 2.302585093f / 20.0f; 229static const float dBConvertInverse = 1.0f / dBConvert; 230 231float AudioSystem::linearToLog(int volume) 232{ 233 // float v = volume ? exp(float(100 - volume) * dBConvert) : 0; 234 // LOGD("linearToLog(%d)=%f", volume, v); 235 // return v; 236 return volume ? exp(float(100 - volume) * dBConvert) : 0; 237} 238 239int AudioSystem::logToLinear(float volume) 240{ 241 // int v = volume ? 100 - int(dBConvertInverse * log(volume) + 0.5) : 0; 242 // LOGD("logTolinear(%d)=%f", v, volume); 243 // return v; 244 return volume ? 100 - int(dBConvertInverse * log(volume) + 0.5) : 0; 245} 246 247status_t AudioSystem::getOutputSamplingRate(int* samplingRate) 248{ 249 if (gOutSamplingRate == 0) { 250 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 251 if (af == 0) return PERMISSION_DENIED; 252 // gOutSamplingRate is updated by get_audio_flinger() 253 } 254 *samplingRate = gOutSamplingRate; 255 256 return NO_ERROR; 257} 258 259status_t AudioSystem::getOutputFrameCount(int* frameCount) 260{ 261 if (gOutFrameCount == 0) { 262 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 263 if (af == 0) return PERMISSION_DENIED; 264 // gOutSamplingRate is updated by get_audio_flinger() 265 } 266 *frameCount = gOutFrameCount; 267 return NO_ERROR; 268} 269 270status_t AudioSystem::getOutputLatency(uint32_t* latency) 271{ 272 if (gOutLatency == 0) { 273 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 274 if (af == 0) return PERMISSION_DENIED; 275 // gOutLatency is updated by get_audio_flinger() 276 } 277 *latency = gOutLatency; 278 279 return NO_ERROR; 280} 281 282// --------------------------------------------------------------------------- 283 284void AudioSystem::DeathNotifier::binderDied(const wp<IBinder>& who) { 285 Mutex::Autolock _l(AudioSystem::gLock); 286 AudioSystem::gAudioFlinger.clear(); 287 AudioSystem::gOutSamplingRate = 0; 288 AudioSystem::gOutFrameCount = 0; 289 AudioSystem::gOutLatency = 0; 290 291 if (gAudioErrorCallback) { 292 gAudioErrorCallback(DEAD_OBJECT); 293 } 294 LOGW("AudioFlinger server died!"); 295} 296 297void AudioSystem::setErrorCallback(audio_error_callback cb) { 298 Mutex::Autolock _l(AudioSystem::gLock); 299 gAudioErrorCallback = cb; 300} 301 302}; // namespace android 303 304