From a35c8f521c9cbb64f3d32df5ded7eab2db2727ee Mon Sep 17 00:00:00 2001 From: Mingming Yin Date: Thu, 27 Dec 2012 17:43:05 -0800 Subject: qcom-fm: audio: add support for FM feature Change-Id: Idd5c7a0364710d54809ef5d4c7b2404b22dc4cf6 Conflicts: include/media/IAudioFlinger.h media/libmediaplayerservice/StagefrightRecorder.cpp media/libstagefright/Android.mk --- services/audioflinger/AudioFlinger.cpp | 26 ++++++++++- services/audioflinger/AudioFlinger.h | 10 +++- services/audioflinger/AudioPolicyService.cpp | 69 ++++++++++++++++++++++++++++ services/audioflinger/AudioPolicyService.h | 22 ++++++++- 4 files changed, 123 insertions(+), 4 deletions(-) (limited to 'services') diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 5975b62..88da88c 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -1,9 +1,8 @@ /* ** ** Copyright 2007, The Android Open Source Project -** Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. +** Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. ** -** Copyright (c) 2012, The Linux Foundation. All rights reserved. ** Not a Contribution, Apache license notifications and license are retained ** for attribution purposes only. ** @@ -1377,6 +1376,29 @@ status_t AudioFlinger::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrame return BAD_VALUE; } +#ifdef QCOM_FM_ENABLED +status_t AudioFlinger::setFmVolume(float value) +{ + status_t ret = initCheck(); + if (ret != NO_ERROR) { + return ret; + } + + // check calling permissions + if (!settingsAllowed()) { + return PERMISSION_DENIED; + } + + AutoMutex lock(mHardwareLock); + audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice(); + mHardwareStatus = AUDIO_SET_FM_VOLUME; + ret = dev->set_fm_volume(dev, value); + mHardwareStatus = AUDIO_HW_IDLE; + + return ret; +} +#endif + void AudioFlinger::registerClient(const sp& client) { diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index cbda3fe..d6a3815 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -1,7 +1,8 @@ /* ** ** Copyright 2007, The Android Open Source Project -** Copyright (c) 2012, The Linux Foundation. All rights reserved. +** Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. +** ** Not a Contribution, Apache license notifications and license are retained ** for attribution purposes only. ** @@ -228,6 +229,10 @@ public: virtual status_t moveEffects(int sessionId, audio_io_handle_t srcOutput, audio_io_handle_t dstOutput); +#ifdef QCOM_FM_ENABLED + virtual status_t setFmVolume(float volume); +#endif + virtual audio_module_handle_t loadHwModule(const char *name); virtual int32_t getPrimaryOutputSamplingRate(); @@ -2209,6 +2214,9 @@ mutable Mutex mLock; // mutex for process, commands and handl AUDIO_HW_SET_MIC_MUTE, // set_mic_mute AUDIO_HW_SET_VOICE_VOLUME, // set_voice_volume AUDIO_HW_SET_PARAMETER, // set_parameters +#ifdef QCOM_FM_ENABLED + AUDIO_SET_FM_VOLUME, +#endif AUDIO_HW_GET_INPUT_BUFFER_SIZE, // get_input_buffer_size AUDIO_HW_GET_MASTER_VOLUME, // get_master_volume AUDIO_HW_GET_PARAMETER, // get_parameters diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp index 7dd46f2..388ad6c 100644 --- a/services/audioflinger/AudioPolicyService.cpp +++ b/services/audioflinger/AudioPolicyService.cpp @@ -1,5 +1,9 @@ /* * Copyright (C) 2009 The Android Open Source Project + * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. + * + * Not a Contribution, Apache license notifications and license are retained + * for attribution purposes only * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -730,6 +734,18 @@ bool AudioPolicyService::AudioCommandThread::threadLoop() } delete data; }break; +#ifdef QCOM_FM_ENABLED + case SET_FM_VOLUME: { + FmVolumeData *data = (FmVolumeData *)command->mParam; + ALOGV("AudioCommandThread() processing set fm volume volume %f", data->mVolume); + command->mStatus = AudioSystem::setFmVolume(data->mVolume); + if (command->mWaitStatus) { + command->mCond.signal(); + mWaitWorkCV.wait(mLock); + } + delete data; + }break; +#endif default: ALOGW("AudioCommandThread() unknown command %d", command->mCommand); } @@ -885,6 +901,34 @@ status_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume return status; } +#ifdef QCOM_FM_ENABLED +status_t AudioPolicyService::AudioCommandThread::fmVolumeCommand(float volume, int delayMs) +{ + status_t status = NO_ERROR; + + AudioCommand *command = new AudioCommand(); + command->mCommand = SET_FM_VOLUME; + FmVolumeData *data = new FmVolumeData(); + data->mVolume = volume; + command->mParam = data; + if (delayMs == 0) { + command->mWaitStatus = true; + } else { + command->mWaitStatus = false; + } + Mutex::Autolock _l(mLock); + insertCommand_l(command, delayMs); + ALOGV("AudioCommandThread() adding set fm volume volume %f", volume); + mWaitWorkCV.signal(); + if (command->mWaitStatus) { + command->mCond.wait(mLock); + status = command->mStatus; + mWaitWorkCV.signal(); + } + return status; +} +#endif + // insertCommand_l() must be called with mLock held void AudioPolicyService::AudioCommandThread::insertCommand_l(AudioCommand *command, int delayMs) { @@ -950,6 +994,12 @@ void AudioPolicyService::AudioCommandThread::insertCommand_l(AudioCommand *comma removedCommands.add(command2); time = command2->mTime; } break; +#ifdef QCOM_FM_ENABLED + case SET_FM_VOLUME: { + removedCommands.add(command2); + time = command2->mTime; + } break; +#endif case START_TONE: case STOP_TONE: default: @@ -1026,6 +1076,13 @@ int AudioPolicyService::setStreamVolume(audio_stream_type_t stream, output, delayMs); } +#ifdef QCOM_FM_ENABLED +status_t AudioPolicyService::setFmVolume(float volume, int delayMs) +{ + return mAudioCommandThread->fmVolumeCommand(volume, delayMs); +} +#endif + int AudioPolicyService::startTone(audio_policy_tone_t tone, audio_stream_type_t stream) { @@ -1546,6 +1603,15 @@ static int aps_set_voice_volume(void *service, float volume, int delay_ms) return audioPolicyService->setVoiceVolume(volume, delay_ms); } +#ifdef QCOM_FM_ENABLED +static int aps_set_fm_volume(void *service, float volume, int delay_ms) +{ + AudioPolicyService *audioPolicyService = (AudioPolicyService *)service; + + return audioPolicyService->setFmVolume(volume, delay_ms); +} +#endif + }; // extern "C" namespace { @@ -1565,6 +1631,9 @@ namespace { stop_tone : aps_stop_tone, set_voice_volume : aps_set_voice_volume, move_effects : aps_move_effects, +#ifdef QCOM_FM_ENABLED + set_fm_volume : aps_set_fm_volume, +#endif load_hw_module : aps_load_hw_module, open_output_on_module : aps_open_output_on_module, open_input_on_module : aps_open_input_on_module, diff --git a/services/audioflinger/AudioPolicyService.h b/services/audioflinger/AudioPolicyService.h index 63f9549..1176411 100644 --- a/services/audioflinger/AudioPolicyService.h +++ b/services/audioflinger/AudioPolicyService.h @@ -1,5 +1,9 @@ /* * Copyright (C) 2009 The Android Open Source Project + * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. + * + * Not a Contribution, Apache license notifications and license are retained + * for attribution purposes only * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -134,6 +138,9 @@ public: virtual status_t startTone(audio_policy_tone_t tone, audio_stream_type_t stream); virtual status_t stopTone(); virtual status_t setVoiceVolume(float volume, int delayMs = 0); +#ifdef QCOM_FM_ENABLED + virtual status_t setFmVolume(float volume, int delayMs = 0); +#endif private: AudioPolicyService(); @@ -157,7 +164,10 @@ private: STOP_TONE, SET_VOLUME, SET_PARAMETERS, - SET_VOICE_VOLUME + SET_VOICE_VOLUME, +#ifdef QCOM_FM_ENABLED + SET_FM_VOLUME +#endif }; AudioCommandThread (String8 name); @@ -178,6 +188,9 @@ private: status_t parametersCommand(audio_io_handle_t ioHandle, const char *keyValuePairs, int delayMs = 0); status_t voiceVolumeCommand(float volume, int delayMs = 0); +#ifdef QCOM_FM_ENABLED + status_t fmVolumeCommand(float volume, int delayMs = 0); +#endif void insertCommand_l(AudioCommand *command, int delayMs = 0); private: @@ -222,6 +235,13 @@ private: float mVolume; }; +#ifdef QCOM_FM_ENABLED + class FmVolumeData { + public: + float mVolume; + }; +#endif + Mutex mLock; Condition mWaitWorkCV; Vector mAudioCommands; // list of pending commands -- cgit v1.1