AudioSystem.cpp revision 5e07b5774c8b376776caa4f5b0a193767697e97e
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 <utils/IServiceManager.h> 22#include <media/AudioSystem.h> 23#include <media/AudioTrack.h> 24#include <math.h> 25 26namespace android { 27 28// client singleton for AudioFlinger binder interface 29Mutex AudioSystem::gLock; 30sp<IAudioFlinger> AudioSystem::gAudioFlinger; 31sp<AudioSystem::AudioFlingerClient> AudioSystem::gAudioFlingerClient; 32audio_error_callback AudioSystem::gAudioErrorCallback = NULL; 33// Cached values 34int AudioSystem::gOutSamplingRate = 0; 35int AudioSystem::gOutFrameCount = 0; 36uint32_t AudioSystem::gOutLatency = 0; 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 gOutFrameCount = (int)gAudioFlinger->frameCount(); 70 gOutSamplingRate = (int)gAudioFlinger->sampleRate(); 71 gOutLatency = gAudioFlinger->latency(); 72 } 73 LOGE_IF(gAudioFlinger==0, "no AudioFlinger!?"); 74 return gAudioFlinger; 75} 76 77// routing helper functions 78status_t AudioSystem::speakerphone(bool state) { 79 uint32_t routes = state ? ROUTE_SPEAKER : ROUTE_EARPIECE; 80 return setRouting(MODE_IN_CALL, routes, ROUTE_ALL); 81} 82 83status_t AudioSystem::isSpeakerphoneOn(bool* state) { 84 uint32_t routes = 0; 85 status_t s = getRouting(MODE_IN_CALL, &routes); 86 *state = !!(routes & ROUTE_SPEAKER); 87 return s; 88} 89 90status_t AudioSystem::bluetoothSco(bool state) { 91 uint32_t mask = ROUTE_BLUETOOTH_SCO; 92 uint32_t routes = state ? mask : ROUTE_EARPIECE; 93 return setRouting(MODE_IN_CALL, routes, ROUTE_ALL); 94} 95 96status_t AudioSystem::isBluetoothScoOn(bool* state) { 97 uint32_t routes = 0; 98 status_t s = getRouting(MODE_IN_CALL, &routes); 99 *state = !!(routes & ROUTE_BLUETOOTH_SCO); 100 return s; 101} 102 103status_t AudioSystem::muteMicrophone(bool state) { 104 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 105 if (af == 0) return PERMISSION_DENIED; 106 return af->setMicMute(state); 107} 108 109status_t AudioSystem::isMicrophoneMuted(bool* state) { 110 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 111 if (af == 0) return PERMISSION_DENIED; 112 *state = af->getMicMute(); 113 return NO_ERROR; 114} 115 116status_t AudioSystem::setMasterVolume(float value) 117{ 118 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 119 if (af == 0) return PERMISSION_DENIED; 120 af->setMasterVolume(value); 121 return NO_ERROR; 122} 123 124status_t AudioSystem::setMasterMute(bool mute) 125{ 126 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 127 if (af == 0) return PERMISSION_DENIED; 128 af->setMasterMute(mute); 129 return NO_ERROR; 130} 131 132status_t AudioSystem::getMasterVolume(float* volume) 133{ 134 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 135 if (af == 0) return PERMISSION_DENIED; 136 *volume = af->masterVolume(); 137 return NO_ERROR; 138} 139 140status_t AudioSystem::getMasterMute(bool* mute) 141{ 142 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 143 if (af == 0) return PERMISSION_DENIED; 144 *mute = af->masterMute(); 145 return NO_ERROR; 146} 147 148status_t AudioSystem::setStreamVolume(int stream, float value) 149{ 150 if (uint32_t(stream) >= AudioTrack::NUM_STREAM_TYPES) return BAD_VALUE; 151 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 152 if (af == 0) return PERMISSION_DENIED; 153 af->setStreamVolume(stream, value); 154 return NO_ERROR; 155} 156 157status_t AudioSystem::setStreamMute(int stream, bool mute) 158{ 159 if (uint32_t(stream) >= AudioTrack::NUM_STREAM_TYPES) return BAD_VALUE; 160 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 161 if (af == 0) return PERMISSION_DENIED; 162 af->setStreamMute(stream, mute); 163 return NO_ERROR; 164} 165 166status_t AudioSystem::getStreamVolume(int stream, float* volume) 167{ 168 if (uint32_t(stream) >= AudioTrack::NUM_STREAM_TYPES) return BAD_VALUE; 169 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 170 if (af == 0) return PERMISSION_DENIED; 171 *volume = af->streamVolume(stream); 172 return NO_ERROR; 173} 174 175status_t AudioSystem::getStreamMute(int stream, bool* mute) 176{ 177 if (uint32_t(stream) >= AudioTrack::NUM_STREAM_TYPES) return BAD_VALUE; 178 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 179 if (af == 0) return PERMISSION_DENIED; 180 *mute = af->streamMute(stream); 181 return NO_ERROR; 182} 183 184status_t AudioSystem::setMode(int mode) 185{ 186 if (mode >= NUM_MODES) return BAD_VALUE; 187 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 188 if (af == 0) return PERMISSION_DENIED; 189 return af->setMode(mode); 190} 191 192status_t AudioSystem::getMode(int* mode) 193{ 194 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 195 if (af == 0) return PERMISSION_DENIED; 196 *mode = af->getMode(); 197 return NO_ERROR; 198} 199 200status_t AudioSystem::setRouting(int mode, uint32_t routes, uint32_t mask) 201{ 202 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 203 if (af == 0) return PERMISSION_DENIED; 204 return af->setRouting(mode, routes, mask); 205} 206 207status_t AudioSystem::getRouting(int mode, uint32_t* routes) 208{ 209 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 210 if (af == 0) return PERMISSION_DENIED; 211 uint32_t r = af->getRouting(mode); 212 *routes = r; 213 return NO_ERROR; 214} 215 216status_t AudioSystem::isMusicActive(bool* state) { 217 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 218 if (af == 0) return PERMISSION_DENIED; 219 *state = af->isMusicActive(); 220 return NO_ERROR; 221} 222 223// Temporary interface, do not use 224// TODO: Replace with a more generic key:value get/set mechanism 225status_t AudioSystem::setParameter(const char* key, const char* value) { 226 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 227 if (af == 0) return PERMISSION_DENIED; 228 return af->setParameter(key, value); 229} 230 231// convert volume steps to natural log scale 232 233// change this value to change volume scaling 234static const float dBPerStep = 0.5f; 235// shouldn't need to touch these 236static const float dBConvert = -dBPerStep * 2.302585093f / 20.0f; 237static const float dBConvertInverse = 1.0f / dBConvert; 238 239float AudioSystem::linearToLog(int volume) 240{ 241 // float v = volume ? exp(float(100 - volume) * dBConvert) : 0; 242 // LOGD("linearToLog(%d)=%f", volume, v); 243 // return v; 244 return volume ? exp(float(100 - volume) * dBConvert) : 0; 245} 246 247int AudioSystem::logToLinear(float volume) 248{ 249 // int v = volume ? 100 - int(dBConvertInverse * log(volume) + 0.5) : 0; 250 // LOGD("logTolinear(%d)=%f", v, volume); 251 // return v; 252 return volume ? 100 - int(dBConvertInverse * log(volume) + 0.5) : 0; 253} 254 255status_t AudioSystem::getOutputSamplingRate(int* samplingRate) 256{ 257 if (gOutSamplingRate == 0) { 258 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 259 if (af == 0) return PERMISSION_DENIED; 260 // gOutSamplingRate is updated by get_audio_flinger() 261 } 262 *samplingRate = gOutSamplingRate; 263 264 return NO_ERROR; 265} 266 267status_t AudioSystem::getOutputFrameCount(int* frameCount) 268{ 269 if (gOutFrameCount == 0) { 270 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 271 if (af == 0) return PERMISSION_DENIED; 272 // gOutFrameCount is updated by get_audio_flinger() 273 } 274 *frameCount = gOutFrameCount; 275 return NO_ERROR; 276} 277 278status_t AudioSystem::getOutputLatency(uint32_t* latency) 279{ 280 if (gOutLatency == 0) { 281 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 282 if (af == 0) return PERMISSION_DENIED; 283 // gOutLatency is updated by get_audio_flinger() 284 } 285 *latency = gOutLatency; 286 287 return NO_ERROR; 288} 289 290status_t AudioSystem::getInputBufferSize(uint32_t sampleRate, int format, int channelCount, 291 size_t* buffSize) 292{ 293 // Do we have a stale gInBufferSize or are we requesting the input buffer size for new values 294 if ((gInBuffSize == 0) || (sampleRate != gPrevInSamplingRate) || (format != gPrevInFormat) 295 || (channelCount != gPrevInChannelCount)) { 296 // save the request params 297 gPrevInSamplingRate = sampleRate; 298 gPrevInFormat = format; 299 gPrevInChannelCount = channelCount; 300 301 gInBuffSize = 0; 302 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 303 if (af == 0) { 304 return PERMISSION_DENIED; 305 } 306 gInBuffSize = af->getInputBufferSize(sampleRate, format, channelCount); 307 } 308 *buffSize = gInBuffSize; 309 310 return NO_ERROR; 311} 312 313// --------------------------------------------------------------------------- 314 315void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who) { 316 Mutex::Autolock _l(AudioSystem::gLock); 317 AudioSystem::gAudioFlinger.clear(); 318 AudioSystem::gOutSamplingRate = 0; 319 AudioSystem::gOutFrameCount = 0; 320 AudioSystem::gOutLatency = 0; 321 AudioSystem::gInBuffSize = 0; 322 323 if (gAudioErrorCallback) { 324 gAudioErrorCallback(DEAD_OBJECT); 325 } 326 LOGW("AudioFlinger server died!"); 327} 328 329void AudioSystem::AudioFlingerClient::audioOutputChanged(uint32_t frameCount, uint32_t samplingRate, uint32_t latency) { 330 331 AudioSystem::gOutFrameCount = frameCount; 332 AudioSystem::gOutSamplingRate = samplingRate; 333 AudioSystem::gOutLatency = latency; 334 335 LOGV("AudioFlinger output changed!"); 336} 337 338void AudioSystem::setErrorCallback(audio_error_callback cb) { 339 Mutex::Autolock _l(AudioSystem::gLock); 340 gAudioErrorCallback = cb; 341} 342 343}; // namespace android 344 345