AudioSystem.cpp revision 0795272aa226f4e965968a03daddc53ce30b7cda
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//#define LOG_NDEBUG 0 19 20#include <utils/Log.h> 21#include <binder/IServiceManager.h> 22#include <media/AudioSystem.h> 23#include <math.h> 24 25namespace android { 26 27// client singleton for AudioFlinger binder interface 28Mutex AudioSystem::gLock; 29sp<IAudioFlinger> AudioSystem::gAudioFlinger; 30sp<AudioSystem::AudioFlingerClient> AudioSystem::gAudioFlingerClient; 31audio_error_callback AudioSystem::gAudioErrorCallback = NULL; 32// Cached values 33int AudioSystem::gOutSamplingRate[NUM_AUDIO_OUTPUT_TYPES]; 34int AudioSystem::gOutFrameCount[NUM_AUDIO_OUTPUT_TYPES]; 35uint32_t AudioSystem::gOutLatency[NUM_AUDIO_OUTPUT_TYPES]; 36bool AudioSystem::gA2dpEnabled; 37// Cached values for recording queries 38uint32_t AudioSystem::gPrevInSamplingRate = 16000; 39int AudioSystem::gPrevInFormat = AudioSystem::PCM_16_BIT; 40int AudioSystem::gPrevInChannelCount = 1; 41size_t AudioSystem::gInBuffSize = 0; 42 43 44// establish binder interface to AudioFlinger service 45const sp<IAudioFlinger>& AudioSystem::get_audio_flinger() 46{ 47 Mutex::Autolock _l(gLock); 48 if (gAudioFlinger.get() == 0) { 49 sp<IServiceManager> sm = defaultServiceManager(); 50 sp<IBinder> binder; 51 do { 52 binder = sm->getService(String16("media.audio_flinger")); 53 if (binder != 0) 54 break; 55 LOGW("AudioFlinger not published, waiting..."); 56 usleep(500000); // 0.5 s 57 } while(true); 58 if (gAudioFlingerClient == NULL) { 59 gAudioFlingerClient = new AudioFlingerClient(); 60 } else { 61 if (gAudioErrorCallback) { 62 gAudioErrorCallback(NO_ERROR); 63 } 64 } 65 binder->linkToDeath(gAudioFlingerClient); 66 gAudioFlinger = interface_cast<IAudioFlinger>(binder); 67 gAudioFlinger->registerClient(gAudioFlingerClient); 68 // Cache frequently accessed parameters 69 for (int output = 0; output < NUM_AUDIO_OUTPUT_TYPES; output++) { 70 gOutFrameCount[output] = (int)gAudioFlinger->frameCount(output); 71 gOutSamplingRate[output] = (int)gAudioFlinger->sampleRate(output); 72 gOutLatency[output] = gAudioFlinger->latency(output); 73 } 74 gA2dpEnabled = gAudioFlinger->isA2dpEnabled(); 75 } 76 LOGE_IF(gAudioFlinger==0, "no AudioFlinger!?"); 77 return gAudioFlinger; 78} 79 80// routing helper functions 81status_t AudioSystem::speakerphone(bool state) { 82 uint32_t routes = state ? ROUTE_SPEAKER : ROUTE_EARPIECE; 83 return setRouting(MODE_IN_CALL, routes, ROUTE_ALL); 84} 85 86status_t AudioSystem::isSpeakerphoneOn(bool* state) { 87 uint32_t routes = 0; 88 status_t s = getRouting(MODE_IN_CALL, &routes); 89 *state = !!(routes & ROUTE_SPEAKER); 90 return s; 91} 92 93status_t AudioSystem::bluetoothSco(bool state) { 94 uint32_t mask = ROUTE_BLUETOOTH_SCO; 95 uint32_t routes = state ? mask : ROUTE_EARPIECE; 96 return setRouting(MODE_IN_CALL, routes, ROUTE_ALL); 97} 98 99status_t AudioSystem::isBluetoothScoOn(bool* state) { 100 uint32_t routes = 0; 101 status_t s = getRouting(MODE_IN_CALL, &routes); 102 *state = !!(routes & ROUTE_BLUETOOTH_SCO); 103 return s; 104} 105 106status_t AudioSystem::muteMicrophone(bool state) { 107 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 108 if (af == 0) return PERMISSION_DENIED; 109 return af->setMicMute(state); 110} 111 112status_t AudioSystem::isMicrophoneMuted(bool* state) { 113 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 114 if (af == 0) return PERMISSION_DENIED; 115 *state = af->getMicMute(); 116 return NO_ERROR; 117} 118 119status_t AudioSystem::setMasterVolume(float value) 120{ 121 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 122 if (af == 0) return PERMISSION_DENIED; 123 af->setMasterVolume(value); 124 return NO_ERROR; 125} 126 127status_t AudioSystem::setMasterMute(bool mute) 128{ 129 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 130 if (af == 0) return PERMISSION_DENIED; 131 af->setMasterMute(mute); 132 return NO_ERROR; 133} 134 135status_t AudioSystem::getMasterVolume(float* volume) 136{ 137 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 138 if (af == 0) return PERMISSION_DENIED; 139 *volume = af->masterVolume(); 140 return NO_ERROR; 141} 142 143status_t AudioSystem::getMasterMute(bool* mute) 144{ 145 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 146 if (af == 0) return PERMISSION_DENIED; 147 *mute = af->masterMute(); 148 return NO_ERROR; 149} 150 151status_t AudioSystem::setStreamVolume(int stream, float value) 152{ 153 if (uint32_t(stream) >= NUM_STREAM_TYPES) return BAD_VALUE; 154 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 155 if (af == 0) return PERMISSION_DENIED; 156 af->setStreamVolume(stream, value); 157 return NO_ERROR; 158} 159 160status_t AudioSystem::setStreamMute(int stream, bool mute) 161{ 162 if (uint32_t(stream) >= NUM_STREAM_TYPES) return BAD_VALUE; 163 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 164 if (af == 0) return PERMISSION_DENIED; 165 af->setStreamMute(stream, mute); 166 return NO_ERROR; 167} 168 169status_t AudioSystem::getStreamVolume(int stream, float* volume) 170{ 171 if (uint32_t(stream) >= NUM_STREAM_TYPES) return BAD_VALUE; 172 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 173 if (af == 0) return PERMISSION_DENIED; 174 *volume = af->streamVolume(stream); 175 return NO_ERROR; 176} 177 178status_t AudioSystem::getStreamMute(int stream, bool* mute) 179{ 180 if (uint32_t(stream) >= NUM_STREAM_TYPES) return BAD_VALUE; 181 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 182 if (af == 0) return PERMISSION_DENIED; 183 *mute = af->streamMute(stream); 184 return NO_ERROR; 185} 186 187status_t AudioSystem::setMode(int mode) 188{ 189 if (mode >= NUM_MODES) return BAD_VALUE; 190 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 191 if (af == 0) return PERMISSION_DENIED; 192 return af->setMode(mode); 193} 194 195status_t AudioSystem::getMode(int* mode) 196{ 197 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 198 if (af == 0) return PERMISSION_DENIED; 199 *mode = af->getMode(); 200 return NO_ERROR; 201} 202 203status_t AudioSystem::setRouting(int mode, uint32_t routes, uint32_t mask) 204{ 205 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 206 if (af == 0) return PERMISSION_DENIED; 207 return af->setRouting(mode, routes, mask); 208} 209 210status_t AudioSystem::getRouting(int mode, uint32_t* routes) 211{ 212 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 213 if (af == 0) return PERMISSION_DENIED; 214 uint32_t r = af->getRouting(mode); 215 *routes = r; 216 return NO_ERROR; 217} 218 219status_t AudioSystem::isMusicActive(bool* state) { 220 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 221 if (af == 0) return PERMISSION_DENIED; 222 *state = af->isMusicActive(); 223 return NO_ERROR; 224} 225 226// Temporary interface, do not use 227// TODO: Replace with a more generic key:value get/set mechanism 228status_t AudioSystem::setParameter(const char* key, const char* value) { 229 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 230 if (af == 0) return PERMISSION_DENIED; 231 return af->setParameter(key, value); 232} 233 234// convert volume steps to natural log scale 235 236// change this value to change volume scaling 237static const float dBPerStep = 0.5f; 238// shouldn't need to touch these 239static const float dBConvert = -dBPerStep * 2.302585093f / 20.0f; 240static const float dBConvertInverse = 1.0f / dBConvert; 241 242float AudioSystem::linearToLog(int volume) 243{ 244 // float v = volume ? exp(float(100 - volume) * dBConvert) : 0; 245 // LOGD("linearToLog(%d)=%f", volume, v); 246 // return v; 247 return volume ? exp(float(100 - volume) * dBConvert) : 0; 248} 249 250int AudioSystem::logToLinear(float volume) 251{ 252 // int v = volume ? 100 - int(dBConvertInverse * log(volume) + 0.5) : 0; 253 // LOGD("logTolinear(%d)=%f", v, volume); 254 // return v; 255 return volume ? 100 - int(dBConvertInverse * log(volume) + 0.5) : 0; 256} 257 258status_t AudioSystem::getOutputSamplingRate(int* samplingRate, int streamType) 259{ 260 int output = getOutput(streamType); 261 262 if (output == NUM_AUDIO_OUTPUT_TYPES) return PERMISSION_DENIED; 263 264 // gOutSamplingRate[] is updated by getOutput() which calls get_audio_flinger() 265 LOGV("getOutputSamplingRate() streamType %d, output %d, sampling rate %d", streamType, output, gOutSamplingRate[output]); 266 267 *samplingRate = gOutSamplingRate[output]; 268 269 return NO_ERROR; 270} 271 272status_t AudioSystem::getOutputFrameCount(int* frameCount, int streamType) 273{ 274 int output = getOutput(streamType); 275 276 if (output == NUM_AUDIO_OUTPUT_TYPES) return PERMISSION_DENIED; 277 278 // gOutFrameCount[] is updated by getOutput() which calls get_audio_flinger() 279 LOGV("getOutputFrameCount() streamType %d, output %d, frame count %d", streamType, output, gOutFrameCount[output]); 280 281 *frameCount = gOutFrameCount[output]; 282 283 return NO_ERROR; 284} 285 286status_t AudioSystem::getOutputLatency(uint32_t* latency, int streamType) 287{ 288 int output = getOutput(streamType); 289 290 if (output == NUM_AUDIO_OUTPUT_TYPES) return PERMISSION_DENIED; 291 292 // gOutLatency[] is updated by getOutput() which calls get_audio_flinger() 293 LOGV("getOutputLatency() streamType %d, output %d, latency %d", streamType, output, gOutLatency[output]); 294 295 *latency = gOutLatency[output]; 296 297 return NO_ERROR; 298} 299 300status_t AudioSystem::getInputBufferSize(uint32_t sampleRate, int format, int channelCount, 301 size_t* buffSize) 302{ 303 // Do we have a stale gInBufferSize or are we requesting the input buffer size for new values 304 if ((gInBuffSize == 0) || (sampleRate != gPrevInSamplingRate) || (format != gPrevInFormat) 305 || (channelCount != gPrevInChannelCount)) { 306 // save the request params 307 gPrevInSamplingRate = sampleRate; 308 gPrevInFormat = format; 309 gPrevInChannelCount = channelCount; 310 311 gInBuffSize = 0; 312 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 313 if (af == 0) { 314 return PERMISSION_DENIED; 315 } 316 gInBuffSize = af->getInputBufferSize(sampleRate, format, channelCount); 317 } 318 *buffSize = gInBuffSize; 319 320 return NO_ERROR; 321} 322 323// --------------------------------------------------------------------------- 324 325void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who) { 326 Mutex::Autolock _l(AudioSystem::gLock); 327 AudioSystem::gAudioFlinger.clear(); 328 329 for (int output = 0; output < NUM_AUDIO_OUTPUT_TYPES; output++) { 330 gOutFrameCount[output] = 0; 331 gOutSamplingRate[output] = 0; 332 gOutLatency[output] = 0; 333 } 334 AudioSystem::gInBuffSize = 0; 335 336 if (gAudioErrorCallback) { 337 gAudioErrorCallback(DEAD_OBJECT); 338 } 339 LOGW("AudioFlinger server died!"); 340} 341 342void AudioSystem::AudioFlingerClient::a2dpEnabledChanged(bool enabled) { 343 gA2dpEnabled = enabled; 344 LOGV("AudioFlinger A2DP enabled status changed! %d", enabled); 345} 346 347void AudioSystem::setErrorCallback(audio_error_callback cb) { 348 Mutex::Autolock _l(AudioSystem::gLock); 349 gAudioErrorCallback = cb; 350} 351 352int AudioSystem::getOutput(int streamType) 353{ 354 // make sure that gA2dpEnabled is valid by calling get_audio_flinger() which in turn 355 // will call gAudioFlinger->isA2dpEnabled() 356 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 357 if (af == 0) return NUM_AUDIO_OUTPUT_TYPES; 358 359 if (streamType == DEFAULT) { 360 streamType = MUSIC; 361 } 362 if (gA2dpEnabled && routedToA2dpOutput(streamType)) { 363 return AUDIO_OUTPUT_A2DP; 364 } else { 365 return AUDIO_OUTPUT_HARDWARE; 366 } 367} 368 369bool AudioSystem::routedToA2dpOutput(int streamType) { 370 switch(streamType) { 371 case MUSIC: 372 case VOICE_CALL: 373 case BLUETOOTH_SCO: 374 case SYSTEM: 375 return true; 376 default: 377 return false; 378 } 379} 380 381 382 383}; // namespace android 384 385