diff options
author | Eric Laurent <elaurent@google.com> | 2012-01-17 17:34:58 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-01-17 17:34:58 -0800 |
commit | f6fc420a79f98d93d953a60b1fc0a5b5f71a3fe2 (patch) | |
tree | 0afc84b502a6687ef52343489bf9308deaa27675 /audio | |
parent | 9038c346d76d6f9e33be34b7760f39804553d993 (diff) | |
parent | c6f331b3f48455c9a9cdf00fc82894badd0a7da6 (diff) | |
download | hardware_libhardware_legacy-f6fc420a79f98d93d953a60b1fc0a5b5f71a3fe2.zip hardware_libhardware_legacy-f6fc420a79f98d93d953a60b1fc0a5b5f71a3fe2.tar.gz hardware_libhardware_legacy-f6fc420a79f98d93d953a60b1fc0a5b5f71a3fe2.tar.bz2 |
Merge "audio policy manager: stream volume per device"
Diffstat (limited to 'audio')
-rw-r--r-- | audio/AudioPolicyManagerBase.cpp | 162 | ||||
-rw-r--r-- | audio/audio_policy_hal.cpp | 30 |
2 files changed, 152 insertions, 40 deletions
diff --git a/audio/AudioPolicyManagerBase.cpp b/audio/AudioPolicyManagerBase.cpp index 45df7fe..12df7bd 100644 --- a/audio/AudioPolicyManagerBase.cpp +++ b/audio/AudioPolicyManagerBase.cpp @@ -573,8 +573,9 @@ status_t AudioPolicyManagerBase::startOutput(audio_io_handle_t output, // necassary for a correct control of hardware output routing by startOutput() and stopOutput() outputDesc->changeRefCount(stream, 1); - uint32_t prevDevice = outputDesc->mDevice; + uint32_t prevDevice = outputDesc->device(); setOutputDevice(output, getNewDevice(output)); + uint32_t newDevice = outputDesc->device(); // handle special case for sonification while in call if (isInCall()) { @@ -582,12 +583,15 @@ status_t AudioPolicyManagerBase::startOutput(audio_io_handle_t output, } // apply volume rules for current stream and device if necessary - checkAndSetVolume(stream, mStreams[stream].mIndexCur, output, outputDesc->device()); + checkAndSetVolume(stream, + mStreams[stream].getVolumeIndex((audio_devices_t)newDevice), + output, + newDevice); // FIXME: need a delay to make sure that audio path switches to speaker before sound // starts. Should be platform specific? if (stream == AudioSystem::ENFORCED_AUDIBLE && - prevDevice != outputDesc->mDevice) { + prevDevice != newDevice) { usleep(outputDesc->mLatency*4*1000); } @@ -814,18 +818,30 @@ void AudioPolicyManagerBase::initStreamVolume(AudioSystem::stream_type stream, mStreams[stream].mIndexMax = indexMax; } -status_t AudioPolicyManagerBase::setStreamVolumeIndex(AudioSystem::stream_type stream, int index) +status_t AudioPolicyManagerBase::setStreamVolumeIndex(AudioSystem::stream_type stream, + int index, + audio_devices_t device) { if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) { return BAD_VALUE; } + if (!audio_is_output_device(device)) { + return BAD_VALUE; + } // Force max volume if stream cannot be muted if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax; - ALOGV("setStreamVolumeIndex() stream %d, index %d", stream, index); - mStreams[stream].mIndexCur = index; + ALOGV("setStreamVolumeIndex() stream %d, device %08x, index %d", + stream, device, index); + + // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and + // clear all device specific values + if (device == AUDIO_DEVICE_OUT_DEFAULT) { + mStreams[stream].mIndexCur.clear(); + } + mStreams[stream].mIndexCur.add(device, index); // compute and apply stream volume on all outputs according to connected device status_t status = NO_ERROR; @@ -838,13 +854,25 @@ status_t AudioPolicyManagerBase::setStreamVolumeIndex(AudioSystem::stream_type s return status; } -status_t AudioPolicyManagerBase::getStreamVolumeIndex(AudioSystem::stream_type stream, int *index) +status_t AudioPolicyManagerBase::getStreamVolumeIndex(AudioSystem::stream_type stream, + int *index, + audio_devices_t device) { - if (index == 0) { + if (index == NULL) { return BAD_VALUE; } - ALOGV("getStreamVolumeIndex() stream %d", stream); - *index = mStreams[stream].mIndexCur; + if (!audio_is_output_device(device)) { + return BAD_VALUE; + } + // if device is AUDIO_DEVICE_OUT_DEFAULT, return volume for device corresponding to + // the strategy the stream belongs to. + if (device == AUDIO_DEVICE_OUT_DEFAULT) { + device = (audio_devices_t)getDeviceForStrategy(getStrategy(stream), true); + } + device = getDeviceForVolume(device); + + *index = mStreams[stream].getVolumeIndex(device); + ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index); return NO_ERROR; } @@ -1029,12 +1057,13 @@ status_t AudioPolicyManagerBase::dump(int fd) snprintf(buffer, SIZE, "\nStreams dump:\n"); write(fd, buffer, strlen(buffer)); - snprintf(buffer, SIZE, " Stream Index Min Index Max Index Cur Can be muted\n"); + snprintf(buffer, SIZE, + " Stream Can be muted Index Min Index Max Index Cur [device : index]...\n"); write(fd, buffer, strlen(buffer)); for (size_t i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { - snprintf(buffer, SIZE, " %02d", i); - mStreams[i].dump(buffer + 3, SIZE); + snprintf(buffer, SIZE, " %02d ", i); write(fd, buffer, strlen(buffer)); + mStreams[i].dump(fd); } snprintf(buffer, SIZE, "\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB\n", @@ -1896,31 +1925,35 @@ audio_io_handle_t AudioPolicyManagerBase::getActiveInput() } -AudioPolicyManagerBase::device_category AudioPolicyManagerBase::getDeviceCategory(uint32_t device) +audio_devices_t AudioPolicyManagerBase::getDeviceForVolume(audio_devices_t device) { if (device == 0) { // this happens when forcing a route update and no track is active on an output. // In this case the returned category is not important. - return DEVICE_CATEGORY_SPEAKER; - } - - if (AudioSystem::popCount(device) > 1) { + device = AUDIO_DEVICE_OUT_SPEAKER; + } else if (AudioSystem::popCount(device) > 1) { // Multiple device selection is either: // - speaker + one other device: give priority to speaker in this case. // - one A2DP device + another device: happens with duplicated output. In this case // retain the device on the A2DP output as the other must not correspond to an active // selection if not the speaker. - if (device & AUDIO_DEVICE_OUT_SPEAKER) - return DEVICE_CATEGORY_SPEAKER; - - device &= AUDIO_DEVICE_OUT_ALL_A2DP; + if (device & AUDIO_DEVICE_OUT_SPEAKER) { + device = AUDIO_DEVICE_OUT_SPEAKER; + } else { + device = (audio_devices_t)(device & AUDIO_DEVICE_OUT_ALL_A2DP); + } } ALOGW_IF(AudioSystem::popCount(device) != 1, - "getDeviceCategory() invalid device combination: %08x", + "getDeviceForVolume() invalid device combination: %08x", device); - switch(device) { + return device; +} + +AudioPolicyManagerBase::device_category AudioPolicyManagerBase::getDeviceCategory(uint32_t device) +{ + switch(getDeviceForVolume((audio_devices_t)device)) { case AUDIO_DEVICE_OUT_EARPIECE: return DEVICE_CATEGORY_EARPIECE; case AUDIO_DEVICE_OUT_WIRED_HEADSET: @@ -1933,6 +1966,7 @@ AudioPolicyManagerBase::device_category AudioPolicyManagerBase::getDeviceCategor case AUDIO_DEVICE_OUT_SPEAKER: case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT: case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER: + case AUDIO_DEVICE_OUT_AUX_DIGITAL: default: return DEVICE_CATEGORY_SPEAKER; } @@ -2046,7 +2080,10 @@ void AudioPolicyManagerBase::initializeVolumeCurves() } } -float AudioPolicyManagerBase::computeVolume(int stream, int index, audio_io_handle_t output, uint32_t device) +float AudioPolicyManagerBase::computeVolume(int stream, + int index, + audio_io_handle_t output, + uint32_t device) { float volume = 1.0; AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); @@ -2084,8 +2121,12 @@ float AudioPolicyManagerBase::computeVolume(int stream, int index, audio_io_hand // by the music application and behave as if music was active if the last music track was // just stopped if (outputDesc->mRefCount[AudioSystem::MUSIC] || mLimitRingtoneVolume) { - float musicVol = computeVolume(AudioSystem::MUSIC, mStreams[AudioSystem::MUSIC].mIndexCur, output, device); - float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ? musicVol : SONIFICATION_HEADSET_VOLUME_MIN; + float musicVol = computeVolume(AudioSystem::MUSIC, + mStreams[AudioSystem::MUSIC].getVolumeIndex((audio_devices_t)device), + output, + (uint32_t)device); + float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ? + musicVol : SONIFICATION_HEADSET_VOLUME_MIN; if (volume > minVol) { volume = minVol; ALOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol); @@ -2096,7 +2137,12 @@ float AudioPolicyManagerBase::computeVolume(int stream, int index, audio_io_hand return volume; } -status_t AudioPolicyManagerBase::checkAndSetVolume(int stream, int index, audio_io_handle_t output, uint32_t device, int delayMs, bool force) +status_t AudioPolicyManagerBase::checkAndSetVolume(int stream, + int index, + audio_io_handle_t output, + uint32_t device, + int delayMs, + bool force) { // do not change actual stream volume if the stream is muted @@ -2156,12 +2202,20 @@ status_t AudioPolicyManagerBase::checkAndSetVolume(int stream, int index, audio_ return NO_ERROR; } -void AudioPolicyManagerBase::applyStreamVolumes(audio_io_handle_t output, uint32_t device, int delayMs, bool force) +void AudioPolicyManagerBase::applyStreamVolumes(audio_io_handle_t output, + uint32_t device, + int delayMs, + bool force) { ALOGV("applyStreamVolumes() for output %d and device %x", output, device); for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { - checkAndSetVolume(stream, mStreams[stream].mIndexCur, output, device, delayMs, force); + checkAndSetVolume(stream, + mStreams[stream].getVolumeIndex((audio_devices_t)device), + output, + device, + delayMs, + force); } } @@ -2179,13 +2233,14 @@ void AudioPolicyManagerBase::setStreamMute(int stream, bool on, audio_io_handle_ { StreamDescriptor &streamDesc = mStreams[stream]; AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); + uint32_t device = outputDesc->device(); ALOGV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d", stream, on, output, outputDesc->mMuteCount[stream]); if (on) { if (outputDesc->mMuteCount[stream] == 0) { if (streamDesc.mCanBeMuted) { - checkAndSetVolume(stream, 0, output, outputDesc->device(), delayMs); + checkAndSetVolume(stream, 0, output, device, delayMs); } } // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored @@ -2196,7 +2251,11 @@ void AudioPolicyManagerBase::setStreamMute(int stream, bool on, audio_io_handle_ return; } if (--outputDesc->mMuteCount[stream] == 0) { - checkAndSetVolume(stream, streamDesc.mIndexCur, output, outputDesc->device(), delayMs); + checkAndSetVolume(stream, + streamDesc.getVolumeIndex((audio_devices_t)device), + output, + device, + delayMs); } } } @@ -2398,13 +2457,40 @@ status_t AudioPolicyManagerBase::AudioInputDescriptor::dump(int fd) // --- StreamDescriptor class implementation -void AudioPolicyManagerBase::StreamDescriptor::dump(char* buffer, size_t size) +AudioPolicyManagerBase::StreamDescriptor::StreamDescriptor() + : mIndexMin(0), mIndexMax(1), mCanBeMuted(true) +{ + mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT, 0); +} + +int AudioPolicyManagerBase::StreamDescriptor::getVolumeIndex(audio_devices_t device) +{ + device = AudioPolicyManagerBase::getDeviceForVolume(device); + // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT + if (mIndexCur.indexOfKey(device) < 0) { + device = AUDIO_DEVICE_OUT_DEFAULT; + } + return mIndexCur.valueFor(device); +} + +void AudioPolicyManagerBase::StreamDescriptor::dump(int fd) { - snprintf(buffer, size, " %02d %02d %02d %d\n", - mIndexMin, - mIndexMax, - mIndexCur, - mCanBeMuted); + const size_t SIZE = 256; + char buffer[SIZE]; + String8 result; + + snprintf(buffer, SIZE, "%s %02d %02d ", + mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax); + result.append(buffer); + for (size_t i = 0; i < mIndexCur.size(); i++) { + snprintf(buffer, SIZE, "%04x : %02d, ", + mIndexCur.keyAt(i), + mIndexCur.valueAt(i)); + result.append(buffer); + } + result.append("\n"); + + write(fd, result.string(), result.size()); } // --- EffectDescriptor class implementation diff --git a/audio/audio_policy_hal.cpp b/audio/audio_policy_hal.cpp index a0100a8..7d2e1e0 100644 --- a/audio/audio_policy_hal.cpp +++ b/audio/audio_policy_hal.cpp @@ -216,7 +216,8 @@ static int ap_set_stream_volume_index(struct audio_policy *pol, { struct legacy_audio_policy *lap = to_lap(pol); return lap->apm->setStreamVolumeIndex((AudioSystem::stream_type)stream, - index); + index, + AUDIO_DEVICE_OUT_DEFAULT); } static int ap_get_stream_volume_index(const struct audio_policy *pol, @@ -225,7 +226,30 @@ static int ap_get_stream_volume_index(const struct audio_policy *pol, { const struct legacy_audio_policy *lap = to_clap(pol); return lap->apm->getStreamVolumeIndex((AudioSystem::stream_type)stream, - index); + index, + AUDIO_DEVICE_OUT_DEFAULT); +} + +static int ap_set_stream_volume_index_for_device(struct audio_policy *pol, + audio_stream_type_t stream, + int index, + audio_devices_t device) +{ + struct legacy_audio_policy *lap = to_lap(pol); + return lap->apm->setStreamVolumeIndex((AudioSystem::stream_type)stream, + index, + device); +} + +static int ap_get_stream_volume_index_for_device(const struct audio_policy *pol, + audio_stream_type_t stream, + int *index, + audio_devices_t device) +{ + const struct legacy_audio_policy *lap = to_clap(pol); + return lap->apm->getStreamVolumeIndex((AudioSystem::stream_type)stream, + index, + device); } static uint32_t ap_get_strategy_for_stream(const struct audio_policy *pol, @@ -320,6 +344,8 @@ static int create_legacy_ap(const struct audio_policy_device *device, lap->policy.init_stream_volume = ap_init_stream_volume; lap->policy.set_stream_volume_index = ap_set_stream_volume_index; lap->policy.get_stream_volume_index = ap_get_stream_volume_index; + lap->policy.set_stream_volume_index_for_device = ap_set_stream_volume_index_for_device; + lap->policy.get_stream_volume_index_for_device = ap_get_stream_volume_index_for_device; lap->policy.get_strategy_for_stream = ap_get_strategy_for_stream; lap->policy.get_devices_for_stream = ap_get_devices_for_stream; lap->policy.get_output_for_effect = ap_get_output_for_effect; |