AudioSystem.cpp revision 7562408b2261d38415453378b6188f74fda99d88
189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project/*
289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Copyright (C) 2006-2007 The Android Open Source Project
389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *
489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * you may not use this file except in compliance with the License.
689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * You may obtain a copy of the License at
789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *
889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *
1089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * See the License for the specific language governing permissions and
1489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * limitations under the License.
1589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project */
1689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
1789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#define LOG_TAG "AudioSystem"
1889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//#define LOG_NDEBUG 0
1989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <utils/Log.h>
217562408b2261d38415453378b6188f74fda99d88Mathias Agopian#include <binder/IServiceManager.h>
2289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <media/AudioSystem.h>
2389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <math.h>
2489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectnamespace android {
2689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// client singleton for AudioFlinger binder interface
2889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectMutex AudioSystem::gLock;
2989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectsp<IAudioFlinger> AudioSystem::gAudioFlinger;
3089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectsp<AudioSystem::AudioFlingerClient> AudioSystem::gAudioFlingerClient;
3189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectaudio_error_callback AudioSystem::gAudioErrorCallback = NULL;
3289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Cached values
3389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint AudioSystem::gOutSamplingRate[NUM_AUDIO_OUTPUT_TYPES];
3489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint AudioSystem::gOutFrameCount[NUM_AUDIO_OUTPUT_TYPES];
3589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectuint32_t AudioSystem::gOutLatency[NUM_AUDIO_OUTPUT_TYPES];
3689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool AudioSystem::gA2dpEnabled;
3789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Cached values for recording queries
3889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectuint32_t AudioSystem::gPrevInSamplingRate = 16000;
3989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint AudioSystem::gPrevInFormat = AudioSystem::PCM_16_BIT;
4089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint AudioSystem::gPrevInChannelCount = 1;
4189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectsize_t AudioSystem::gInBuffSize = 0;
4289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
4389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
4489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// establish binder interface to AudioFlinger service
4589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectconst sp<IAudioFlinger>& AudioSystem::get_audio_flinger()
4689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
4789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Mutex::Autolock _l(gLock);
4889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (gAudioFlinger.get() == 0) {
4989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        sp<IServiceManager> sm = defaultServiceManager();
5089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        sp<IBinder> binder;
5189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        do {
5289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            binder = sm->getService(String16("media.audio_flinger"));
5389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            if (binder != 0)
5489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                break;
5589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            LOGW("AudioFlinger not published, waiting...");
5689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            usleep(500000); // 0.5 s
5789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        } while(true);
5889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (gAudioFlingerClient == NULL) {
5989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            gAudioFlingerClient = new AudioFlingerClient();
6089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        } else {
6189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            if (gAudioErrorCallback) {
6289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                gAudioErrorCallback(NO_ERROR);
6389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            }
6489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project         }
6589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        binder->linkToDeath(gAudioFlingerClient);
6689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        gAudioFlinger = interface_cast<IAudioFlinger>(binder);
6789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        gAudioFlinger->registerClient(gAudioFlingerClient);
6889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // Cache frequently accessed parameters
6989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        for (int output = 0; output < NUM_AUDIO_OUTPUT_TYPES; output++) {
7089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            gOutFrameCount[output] = (int)gAudioFlinger->frameCount(output);
7189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            gOutSamplingRate[output] = (int)gAudioFlinger->sampleRate(output);
7289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            gOutLatency[output] = gAudioFlinger->latency(output);
7389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
7489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        gA2dpEnabled = gAudioFlinger->isA2dpEnabled();
7589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
7689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    LOGE_IF(gAudioFlinger==0, "no AudioFlinger!?");
7789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return gAudioFlinger;
7889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
7989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
8089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// routing helper functions
8189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioSystem::speakerphone(bool state) {
8289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t routes = state ? ROUTE_SPEAKER : ROUTE_EARPIECE;
8389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return setRouting(MODE_IN_CALL, routes, ROUTE_ALL);
8489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
8589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
8689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioSystem::isSpeakerphoneOn(bool* state) {
8789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t routes = 0;
8889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    status_t s = getRouting(MODE_IN_CALL, &routes);
8989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *state = !!(routes & ROUTE_SPEAKER);
9089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return s;
9189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
9289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
9389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioSystem::bluetoothSco(bool state) {
9489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t mask = ROUTE_BLUETOOTH_SCO;
9589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t routes = state ? mask : ROUTE_EARPIECE;
9689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return setRouting(MODE_IN_CALL, routes, ROUTE_ALL);
9789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
9889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
9989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioSystem::isBluetoothScoOn(bool* state) {
10089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t routes = 0;
10189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    status_t s = getRouting(MODE_IN_CALL, &routes);
10289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *state = !!(routes & ROUTE_BLUETOOTH_SCO);
10389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return s;
10489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
10589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
10689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioSystem::muteMicrophone(bool state) {
10789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
10889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (af == 0) return PERMISSION_DENIED;
10989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return af->setMicMute(state);
11089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
11189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
11289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioSystem::isMicrophoneMuted(bool* state) {
11389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
11489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (af == 0) return PERMISSION_DENIED;
11589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *state = af->getMicMute();
11689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
11789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
11889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
11989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioSystem::setMasterVolume(float value)
12089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
12189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
12289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (af == 0) return PERMISSION_DENIED;
12389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    af->setMasterVolume(value);
12489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
12589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
12689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
12789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioSystem::setMasterMute(bool mute)
12889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
12989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
13089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (af == 0) return PERMISSION_DENIED;
13189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    af->setMasterMute(mute);
13289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
13389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
13489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
13589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioSystem::getMasterVolume(float* volume)
13689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
13789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
13889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (af == 0) return PERMISSION_DENIED;
13989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *volume = af->masterVolume();
14089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
14189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
14289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
14389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioSystem::getMasterMute(bool* mute)
14489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
14589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
14689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (af == 0) return PERMISSION_DENIED;
14789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *mute = af->masterMute();
14889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
14989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
15089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
15189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioSystem::setStreamVolume(int stream, float value)
15289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
15389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (uint32_t(stream) >= NUM_STREAM_TYPES) return BAD_VALUE;
15489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
15589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (af == 0) return PERMISSION_DENIED;
15689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    af->setStreamVolume(stream, value);
15789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
15889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
15989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
16089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioSystem::setStreamMute(int stream, bool mute)
16189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
16289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (uint32_t(stream) >= NUM_STREAM_TYPES) return BAD_VALUE;
16389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
16489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (af == 0) return PERMISSION_DENIED;
16589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    af->setStreamMute(stream, mute);
16689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
16789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
16889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
16989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioSystem::getStreamVolume(int stream, float* volume)
17089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
17189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (uint32_t(stream) >= NUM_STREAM_TYPES) return BAD_VALUE;
17289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
17389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (af == 0) return PERMISSION_DENIED;
17489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *volume = af->streamVolume(stream);
17589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
17689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
17789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
17889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioSystem::getStreamMute(int stream, bool* mute)
17989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
18089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (uint32_t(stream) >= NUM_STREAM_TYPES) return BAD_VALUE;
18189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
18289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (af == 0) return PERMISSION_DENIED;
18389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *mute = af->streamMute(stream);
18489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
18589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
18689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
18789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioSystem::setMode(int mode)
18889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
18989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mode >= NUM_MODES) return BAD_VALUE;
19089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
19189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (af == 0) return PERMISSION_DENIED;
19289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return af->setMode(mode);
19389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
19489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
19589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioSystem::getMode(int* mode)
19689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
19789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
19889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (af == 0) return PERMISSION_DENIED;
19989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *mode = af->getMode();
20089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
20189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
20289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
20389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioSystem::setRouting(int mode, uint32_t routes, uint32_t mask)
20489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
20589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
20689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (af == 0) return PERMISSION_DENIED;
20789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return af->setRouting(mode, routes, mask);
20889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
20989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
21089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioSystem::getRouting(int mode, uint32_t* routes)
21189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
21289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
21389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (af == 0) return PERMISSION_DENIED;
21489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t r = af->getRouting(mode);
21589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *routes = r;
21689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
21789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
21889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
21989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioSystem::isMusicActive(bool* state) {
22089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
22189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (af == 0) return PERMISSION_DENIED;
22289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *state = af->isMusicActive();
22389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
22489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
22589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
22689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Temporary interface, do not use
22789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// TODO: Replace with a more generic key:value get/set mechanism
22889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioSystem::setParameter(const char* key, const char* value) {
22989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
23089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (af == 0) return PERMISSION_DENIED;
23189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return af->setParameter(key, value);
23289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
23389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
23489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// convert volume steps to natural log scale
23589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
23689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// change this value to change volume scaling
23789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic const float dBPerStep = 0.5f;
23889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// shouldn't need to touch these
23989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic const float dBConvert = -dBPerStep * 2.302585093f / 20.0f;
24089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic const float dBConvertInverse = 1.0f / dBConvert;
24189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
24289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectfloat AudioSystem::linearToLog(int volume)
24389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
24489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // float v = volume ? exp(float(100 - volume) * dBConvert) : 0;
24589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // LOGD("linearToLog(%d)=%f", volume, v);
24689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // return v;
24789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return volume ? exp(float(100 - volume) * dBConvert) : 0;
24889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
24989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
25089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint AudioSystem::logToLinear(float volume)
25189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
25289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // int v = volume ? 100 - int(dBConvertInverse * log(volume) + 0.5) : 0;
25389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // LOGD("logTolinear(%d)=%f", v, volume);
25489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // return v;
25589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return volume ? 100 - int(dBConvertInverse * log(volume) + 0.5) : 0;
25689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
25789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
25889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioSystem::getOutputSamplingRate(int* samplingRate, int streamType)
25989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
26089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    int output = getOutput(streamType);
26148f7f5e8359909ddfc6492a79a8b9c44759ca6c3Eric Laurent
26248f7f5e8359909ddfc6492a79a8b9c44759ca6c3Eric Laurent    if (output == NUM_AUDIO_OUTPUT_TYPES) return PERMISSION_DENIED;
26389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
26448f7f5e8359909ddfc6492a79a8b9c44759ca6c3Eric Laurent    // gOutSamplingRate[] is updated by getOutput() which calls get_audio_flinger()
26589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    LOGV("getOutputSamplingRate() streamType %d, output %d, sampling rate %d", streamType, output, gOutSamplingRate[output]);
26648f7f5e8359909ddfc6492a79a8b9c44759ca6c3Eric Laurent
26789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *samplingRate = gOutSamplingRate[output];
26889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
26989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
27089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
27189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
27289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioSystem::getOutputFrameCount(int* frameCount, int streamType)
27389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
27489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    int output = getOutput(streamType);
27589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
27648f7f5e8359909ddfc6492a79a8b9c44759ca6c3Eric Laurent    if (output == NUM_AUDIO_OUTPUT_TYPES) return PERMISSION_DENIED;
27748f7f5e8359909ddfc6492a79a8b9c44759ca6c3Eric Laurent
27848f7f5e8359909ddfc6492a79a8b9c44759ca6c3Eric Laurent    // gOutFrameCount[] is updated by getOutput() which calls get_audio_flinger()
27989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    LOGV("getOutputFrameCount() streamType %d, output %d, frame count %d", streamType, output, gOutFrameCount[output]);
28089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
28189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *frameCount = gOutFrameCount[output];
28248f7f5e8359909ddfc6492a79a8b9c44759ca6c3Eric Laurent
28389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
28489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
28589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
28689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioSystem::getOutputLatency(uint32_t* latency, int streamType)
28789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
28889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    int output = getOutput(streamType);
28989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
29048f7f5e8359909ddfc6492a79a8b9c44759ca6c3Eric Laurent    if (output == NUM_AUDIO_OUTPUT_TYPES) return PERMISSION_DENIED;
29148f7f5e8359909ddfc6492a79a8b9c44759ca6c3Eric Laurent
29248f7f5e8359909ddfc6492a79a8b9c44759ca6c3Eric Laurent    // gOutLatency[] is updated by getOutput() which calls get_audio_flinger()
29389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    LOGV("getOutputLatency() streamType %d, output %d, latency %d", streamType, output, gOutLatency[output]);
29489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
29589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *latency = gOutLatency[output];
29689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
29789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
29889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
29989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
30089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioSystem::getInputBufferSize(uint32_t sampleRate, int format, int channelCount,
30189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    size_t* buffSize)
30289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
30389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // Do we have a stale gInBufferSize or are we requesting the input buffer size for new values
30489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if ((gInBuffSize == 0) || (sampleRate != gPrevInSamplingRate) || (format != gPrevInFormat)
30589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        || (channelCount != gPrevInChannelCount)) {
30689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // save the request params
30789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        gPrevInSamplingRate = sampleRate;
30889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        gPrevInFormat = format;
30989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        gPrevInChannelCount = channelCount;
31089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
31189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        gInBuffSize = 0;
31289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
31389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (af == 0) {
31489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            return PERMISSION_DENIED;
31589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
31689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        gInBuffSize = af->getInputBufferSize(sampleRate, format, channelCount);
31789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
31889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *buffSize = gInBuffSize;
31989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
32089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
32189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
32289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
32389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ---------------------------------------------------------------------------
32489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
32589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who) {
32689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Mutex::Autolock _l(AudioSystem::gLock);
32789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    AudioSystem::gAudioFlinger.clear();
32889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
32989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    for (int output = 0; output < NUM_AUDIO_OUTPUT_TYPES; output++) {
33089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        gOutFrameCount[output] = 0;
33189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        gOutSamplingRate[output] = 0;
33289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        gOutLatency[output] = 0;
33389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
33489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    AudioSystem::gInBuffSize = 0;
33589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
33689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (gAudioErrorCallback) {
33789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        gAudioErrorCallback(DEAD_OBJECT);
33889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
33989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    LOGW("AudioFlinger server died!");
34089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
34189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
34289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid AudioSystem::AudioFlingerClient::a2dpEnabledChanged(bool enabled) {
34389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    gA2dpEnabled = enabled;
34489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    LOGV("AudioFlinger A2DP enabled status changed! %d", enabled);
34589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
34689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
34789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid AudioSystem::setErrorCallback(audio_error_callback cb) {
34889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Mutex::Autolock _l(AudioSystem::gLock);
34989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    gAudioErrorCallback = cb;
35089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
35189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
35289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint AudioSystem::getOutput(int streamType)
35348f7f5e8359909ddfc6492a79a8b9c44759ca6c3Eric Laurent{
35448f7f5e8359909ddfc6492a79a8b9c44759ca6c3Eric Laurent    // make sure that gA2dpEnabled is valid by calling get_audio_flinger() which in turn
35548f7f5e8359909ddfc6492a79a8b9c44759ca6c3Eric Laurent    // will call gAudioFlinger->isA2dpEnabled()
35648f7f5e8359909ddfc6492a79a8b9c44759ca6c3Eric Laurent    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
35748f7f5e8359909ddfc6492a79a8b9c44759ca6c3Eric Laurent    if (af == 0) return NUM_AUDIO_OUTPUT_TYPES;
35848f7f5e8359909ddfc6492a79a8b9c44759ca6c3Eric Laurent
35989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (streamType == DEFAULT) {
36089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        streamType = MUSIC;
36189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
36289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (gA2dpEnabled && routedToA2dpOutput(streamType)) {
36389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return AUDIO_OUTPUT_A2DP;
36489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else {
36589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return AUDIO_OUTPUT_HARDWARE;
36689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
36789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
36889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
36989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool AudioSystem::routedToA2dpOutput(int streamType) {
37089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    switch(streamType) {
37189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    case MUSIC:
37289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    case VOICE_CALL:
37389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    case BLUETOOTH_SCO:
37489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    case SYSTEM:
37589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return true;
37689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    default:
37789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return false;
37889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
37989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
38089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
38189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
38289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
38389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}; // namespace android
38489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
385