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