diff options
author | Eric Laurent <elaurent@google.com> | 2014-05-31 01:55:53 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-05-31 01:55:53 +0000 |
commit | 481c8837c7f67852e06137d636915ea6e96247e3 (patch) | |
tree | 04503e831053d7a8df184ab5592ec4c7521d9671 /services/audiopolicy | |
parent | 68f5fb51f6ef2f54a0955bac98c16c2aa811f809 (diff) | |
parent | e1715a465a29db625da9d0ea365edf371e39e201 (diff) | |
download | frameworks_av-481c8837c7f67852e06137d636915ea6e96247e3.zip frameworks_av-481c8837c7f67852e06137d636915ea6e96247e3.tar.gz frameworks_av-481c8837c7f67852e06137d636915ea6e96247e3.tar.bz2 |
am e1715a46: audio policy: add audio port gain control
* commit 'e1715a465a29db625da9d0ea365edf371e39e201':
audio policy: add audio port gain control
Diffstat (limited to 'services/audiopolicy')
-rw-r--r-- | services/audiopolicy/AudioPolicyClientImpl.cpp | 7 | ||||
-rw-r--r-- | services/audiopolicy/AudioPolicyInterface.h | 3 | ||||
-rw-r--r-- | services/audiopolicy/AudioPolicyManager.cpp | 97 | ||||
-rw-r--r-- | services/audiopolicy/AudioPolicyService.cpp | 29 | ||||
-rw-r--r-- | services/audiopolicy/AudioPolicyService.h | 17 |
5 files changed, 148 insertions, 5 deletions
diff --git a/services/audiopolicy/AudioPolicyClientImpl.cpp b/services/audiopolicy/AudioPolicyClientImpl.cpp index cbab841..c322d92 100644 --- a/services/audiopolicy/AudioPolicyClientImpl.cpp +++ b/services/audiopolicy/AudioPolicyClientImpl.cpp @@ -195,6 +195,13 @@ status_t AudioPolicyService::AudioPolicyClient::releaseAudioPatch(audio_patch_ha return mAudioPolicyService->clientReleaseAudioPatch(handle, delayMs); } +status_t AudioPolicyService::AudioPolicyClient::setAudioPortConfig( + const struct audio_port_config *config, + int delayMs) +{ + return mAudioPolicyService->clientSetAudioPortConfig(config, delayMs); +} + void AudioPolicyService::AudioPolicyClient::onAudioPortListUpdate() { mAudioPolicyService->onAudioPortListUpdate(); diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h index e0c7f61..c025a45 100644 --- a/services/audiopolicy/AudioPolicyInterface.h +++ b/services/audiopolicy/AudioPolicyInterface.h @@ -273,6 +273,9 @@ public: virtual status_t releaseAudioPatch(audio_patch_handle_t handle, int delayMs) = 0; + /* Set audio port configuration */ + virtual status_t setAudioPortConfig(const struct audio_port_config *config, int delayMs) = 0; + virtual void onAudioPortListUpdate() = 0; virtual void onAudioPatchListUpdate() = 0; diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp index 1c6759f..bf5b9a8 100644 --- a/services/audiopolicy/AudioPolicyManager.cpp +++ b/services/audiopolicy/AudioPolicyManager.cpp @@ -2019,9 +2019,93 @@ status_t AudioPolicyManager::listAudioPatches(unsigned int *num_patches, return NO_ERROR; } -status_t AudioPolicyManager::setAudioPortConfig(const struct audio_port_config *config __unused) +status_t AudioPolicyManager::setAudioPortConfig(const struct audio_port_config *config) { - return NO_ERROR; + ALOGV("setAudioPortConfig()"); + + if (config == NULL) { + return BAD_VALUE; + } + ALOGV("setAudioPortConfig() on port handle %d", config->id); + // Only support gain configuration for now + if (config->config_mask != AUDIO_PORT_CONFIG_GAIN || config->gain.index < 0) { + return BAD_VALUE; + } + + sp<AudioPort> portDesc; + struct audio_port_config portConfig; + if (config->type == AUDIO_PORT_TYPE_MIX) { + if (config->role == AUDIO_PORT_ROLE_SOURCE) { + AudioOutputDescriptor *outputDesc = getOutputFromId(config->id); + if (outputDesc == NULL) { + return BAD_VALUE; + } + portDesc = outputDesc->mProfile; + outputDesc->toAudioPortConfig(&portConfig); + } else if (config->role == AUDIO_PORT_ROLE_SINK) { + AudioInputDescriptor *inputDesc = getInputFromId(config->id); + if (inputDesc == NULL) { + return BAD_VALUE; + } + portDesc = inputDesc->mProfile; + inputDesc->toAudioPortConfig(&portConfig); + } else { + return BAD_VALUE; + } + } else if (config->type == AUDIO_PORT_TYPE_DEVICE) { + sp<DeviceDescriptor> deviceDesc; + if (config->role == AUDIO_PORT_ROLE_SOURCE) { + deviceDesc = mAvailableInputDevices.getDeviceFromId(config->id); + } else if (config->role == AUDIO_PORT_ROLE_SINK) { + deviceDesc = mAvailableOutputDevices.getDeviceFromId(config->id); + } else { + return BAD_VALUE; + } + if (deviceDesc == NULL) { + return BAD_VALUE; + } + portDesc = deviceDesc; + deviceDesc->toAudioPortConfig(&portConfig); + } else { + return BAD_VALUE; + } + + if ((size_t)config->gain.index >= portDesc->mGains.size()) { + return INVALID_OPERATION; + } + const struct audio_gain *gain = &portDesc->mGains[config->gain.index]->mGain; + if ((config->gain.mode & ~gain->mode) != 0) { + return BAD_VALUE; + } + if ((config->gain.mode & AUDIO_GAIN_MODE_JOINT) == AUDIO_GAIN_MODE_JOINT) { + if ((config->gain.values[0] < gain->min_value) || + (config->gain.values[0] > gain->max_value)) { + return BAD_VALUE; + } + } else { + if ((config->gain.channel_mask & ~gain->channel_mask) != 0) { + return BAD_VALUE; + } + size_t numValues = popcount(config->gain.channel_mask); + for (size_t i = 0; i < numValues; i++) { + if ((config->gain.values[i] < gain->min_value) || + (config->gain.values[i] > gain->max_value)) { + return BAD_VALUE; + } + } + } + if ((config->gain.mode & AUDIO_GAIN_MODE_RAMP) == AUDIO_GAIN_MODE_RAMP) { + if ((config->gain.ramp_duration_ms < gain->min_ramp_ms) || + (config->gain.ramp_duration_ms > gain->max_ramp_ms)) { + return BAD_VALUE; + } + } + + portConfig.gain = config->gain; + + status_t status = mpClientInterface->setAudioPortConfig(&portConfig, 0); + + return status; } void AudioPolicyManager::clearAudioPatches(uid_t uid) @@ -4860,7 +4944,13 @@ void AudioPolicyManager::AudioPort::toAudioPort(struct audio_port *port) const port->formats[i] = mFormats[i]; } port->num_formats = i; - port->num_gains = 0; + + ALOGV("AudioPort::toAudioPort() num gains %d", mGains.size()); + + for (i = 0; i < mGains.size() && i < AUDIO_PORT_MAX_GAINS; i++) { + port->gains[i] = mGains[i]->mGain; + } + port->num_gains = i; } @@ -5416,6 +5506,7 @@ void AudioPolicyManager::DeviceDescriptor::toAudioPortConfig( void AudioPolicyManager::DeviceDescriptor::toAudioPort(struct audio_port *port) const { + ALOGV("DeviceVector::toAudioPort() handle %d type %x", mId, mDeviceType); AudioPort::toAudioPort(port); port->id = mId; toAudioPortConfig(&port->active_config); diff --git a/services/audiopolicy/AudioPolicyService.cpp b/services/audiopolicy/AudioPolicyService.cpp index f3d92ed..a2a0461 100644 --- a/services/audiopolicy/AudioPolicyService.cpp +++ b/services/audiopolicy/AudioPolicyService.cpp @@ -226,6 +226,12 @@ void AudioPolicyService::doOnAudioPatchListUpdate() } } +status_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_config *config, + int delayMs) +{ + return mAudioCommandThread->setAudioPortConfigCommand(config, delayMs); +} + AudioPolicyService::NotificationClient::NotificationClient(const sp<AudioPolicyService>& service, const sp<IAudioPolicyServiceClient>& client, uid_t uid) @@ -506,6 +512,16 @@ bool AudioPolicyService::AudioCommandThread::threadLoop() svc->doOnAudioPatchListUpdate(); mLock.lock(); }break; + case SET_AUDIOPORT_CONFIG: { + SetAudioPortConfigData *data = (SetAudioPortConfigData *)command->mParam.get(); + ALOGV("AudioCommandThread() processing set port config"); + sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); + if (af == 0) { + command->mStatus = PERMISSION_DENIED; + } else { + command->mStatus = af->setAudioPortConfig(&data->mConfig); + } + } break; default: ALOGW("AudioCommandThread() unknown command %d", command->mCommand); } @@ -716,6 +732,19 @@ void AudioPolicyService::AudioCommandThread::updateAudioPatchListCommand() sendCommand(command); } +status_t AudioPolicyService::AudioCommandThread::setAudioPortConfigCommand( + const struct audio_port_config *config, int delayMs) +{ + sp<AudioCommand> command = new AudioCommand(); + command->mCommand = SET_AUDIOPORT_CONFIG; + SetAudioPortConfigData *data = new SetAudioPortConfigData(); + data->mConfig = *config; + command->mParam = data; + command->mWaitStatus = true; + ALOGV("AudioCommandThread() adding set port config delay %d", delayMs); + return sendCommand(command, delayMs); +} + status_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs) { { diff --git a/services/audiopolicy/AudioPolicyService.h b/services/audiopolicy/AudioPolicyService.h index a579d1d..40f589b 100644 --- a/services/audiopolicy/AudioPolicyService.h +++ b/services/audiopolicy/AudioPolicyService.h @@ -166,6 +166,9 @@ public: int delayMs); status_t clientReleaseAudioPatch(audio_patch_handle_t handle, int delayMs); + virtual status_t clientSetAudioPortConfig(const struct audio_port_config *config, + int delayMs); + void removeNotificationClient(uid_t uid); void onAudioPortListUpdate(); void doOnAudioPortListUpdate(); @@ -200,7 +203,8 @@ private: CREATE_AUDIO_PATCH, RELEASE_AUDIO_PATCH, UPDATE_AUDIOPORT_LIST, - UPDATE_AUDIOPATCH_LIST + UPDATE_AUDIOPATCH_LIST, + SET_AUDIOPORT_CONFIG, }; AudioCommandThread (String8 name, const wp<AudioPolicyService>& service); @@ -234,7 +238,8 @@ private: int delayMs); void updateAudioPortListCommand(); void updateAudioPatchListCommand(); - + status_t setAudioPortConfigCommand(const struct audio_port_config *config, + int delayMs); void insertCommand_l(AudioCommand *command, int delayMs = 0); private: @@ -312,6 +317,11 @@ private: audio_patch_handle_t mHandle; }; + class SetAudioPortConfigData : public AudioCommandData { + public: + struct audio_port_config mConfig; + }; + Mutex mLock; Condition mWaitWorkCV; Vector < sp<AudioCommand> > mAudioCommands; // list of pending commands @@ -465,6 +475,9 @@ private: virtual status_t releaseAudioPatch(audio_patch_handle_t handle, int delayMs); + /* Set audio port configuration */ + virtual status_t setAudioPortConfig(const struct audio_port_config *config, int delayMs); + virtual void onAudioPortListUpdate(); virtual void onAudioPatchListUpdate(); |