diff options
| author | Eric Laurent <elaurent@google.com> | 2011-10-18 19:33:39 -0700 |
|---|---|---|
| committer | Android Git Automerger <android-git-automerger@android.com> | 2011-10-18 19:33:39 -0700 |
| commit | 0781f0851f9719be81fa40ad3e80e5f632ca5aa9 (patch) | |
| tree | c0a5808a44fb547dd0a41e7e829513efe930a87a | |
| parent | 63e6d195a46e41c671d63cff69da52114cf442d4 (diff) | |
| parent | e43c5c4ca4477a6b384711552c3e990609039d93 (diff) | |
| download | hardware_libhardware_legacy-0781f0851f9719be81fa40ad3e80e5f632ca5aa9.tar.gz hardware_libhardware_legacy-0781f0851f9719be81fa40ad3e80e5f632ca5aa9.tar.bz2 hardware_libhardware_legacy-0781f0851f9719be81fa40ad3e80e5f632ca5aa9.zip | |
am e43c5c4c: Fix issue 5440852: Youtube volume is too small ...
* commit 'e43c5c4ca4477a6b384711552c3e990609039d93':
Fix issue 5440852: Youtube volume is too small ...
| -rw-r--r-- | audio/AudioPolicyManagerBase.cpp | 137 | ||||
| -rw-r--r-- | include/hardware_legacy/AudioPolicyManagerBase.h | 27 |
2 files changed, 135 insertions, 29 deletions
diff --git a/audio/AudioPolicyManagerBase.cpp b/audio/AudioPolicyManagerBase.cpp index 35d72e2..191ba9d 100644 --- a/audio/AudioPolicyManagerBase.cpp +++ b/audio/AudioPolicyManagerBase.cpp @@ -1868,61 +1868,146 @@ audio_io_handle_t AudioPolicyManagerBase::getActiveInput() return 0; } + +AudioPolicyManagerBase::device_category AudioPolicyManagerBase::getDeviceCategory(uint32_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) { + // 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; + } + + LOGW_IF(AudioSystem::popCount(device) != 1, + "getDeviceCategory() invalid device combination: %08x", + device); + + switch(device) { + case AUDIO_DEVICE_OUT_EARPIECE: + return DEVICE_CATEGORY_EARPIECE; + case AUDIO_DEVICE_OUT_WIRED_HEADSET: + case AUDIO_DEVICE_OUT_WIRED_HEADPHONE: + case AUDIO_DEVICE_OUT_BLUETOOTH_SCO: + case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET: + case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP: + case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES: + return DEVICE_CATEGORY_HEADSET; + case AUDIO_DEVICE_OUT_SPEAKER: + case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT: + case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER: + default: + return DEVICE_CATEGORY_SPEAKER; + } +} + float AudioPolicyManagerBase::volIndexToAmpl(uint32_t device, const StreamDescriptor& streamDesc, - int indexInUi) { + int indexInUi) +{ + device_category deviceCategory = getDeviceCategory(device); + const VolumeCurvePoint *curve = streamDesc.mVolumeCurve[deviceCategory]; + // the volume index in the UI is relative to the min and max volume indices for this stream type - int nbSteps = 1 + streamDesc.mVolumeCurve[VOLMAX].mIndex - - streamDesc.mVolumeCurve[VOLMIN].mIndex; + int nbSteps = 1 + curve[VOLMAX].mIndex - + curve[VOLMIN].mIndex; int volIdx = (nbSteps * (indexInUi - streamDesc.mIndexMin)) / (streamDesc.mIndexMax - streamDesc.mIndexMin); // find what part of the curve this index volume belongs to, or if it's out of bounds int segment = 0; - if (volIdx < streamDesc.mVolumeCurve[VOLMIN].mIndex) { // out of bounds + if (volIdx < curve[VOLMIN].mIndex) { // out of bounds return 0.0f; - } else if (volIdx < streamDesc.mVolumeCurve[VOLKNEE1].mIndex) { + } else if (volIdx < curve[VOLKNEE1].mIndex) { segment = 0; - } else if (volIdx < streamDesc.mVolumeCurve[VOLKNEE2].mIndex) { + } else if (volIdx < curve[VOLKNEE2].mIndex) { segment = 1; - } else if (volIdx <= streamDesc.mVolumeCurve[VOLMAX].mIndex) { + } else if (volIdx <= curve[VOLMAX].mIndex) { segment = 2; } else { // out of bounds return 1.0f; } // linear interpolation in the attenuation table in dB - float decibels = streamDesc.mVolumeCurve[segment].mDBAttenuation + - ((float)(volIdx - streamDesc.mVolumeCurve[segment].mIndex)) * - ( (streamDesc.mVolumeCurve[segment+1].mDBAttenuation - - streamDesc.mVolumeCurve[segment].mDBAttenuation) / - ((float)(streamDesc.mVolumeCurve[segment+1].mIndex - - streamDesc.mVolumeCurve[segment].mIndex)) ); + float decibels = curve[segment].mDBAttenuation + + ((float)(volIdx - curve[segment].mIndex)) * + ( (curve[segment+1].mDBAttenuation - + curve[segment].mDBAttenuation) / + ((float)(curve[segment+1].mIndex - + curve[segment].mIndex)) ); float amplification = exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 ) LOGV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f", - streamDesc.mVolumeCurve[segment].mIndex, volIdx, - streamDesc.mVolumeCurve[segment+1].mIndex, - streamDesc.mVolumeCurve[segment].mDBAttenuation, + curve[segment].mIndex, volIdx, + curve[segment+1].mIndex, + curve[segment].mDBAttenuation, decibels, - streamDesc.mVolumeCurve[segment+1].mDBAttenuation, + curve[segment+1].mDBAttenuation, amplification); return amplification; } const AudioPolicyManagerBase::VolumeCurvePoint - AudioPolicyManagerBase::sVolumeProfiles[AudioPolicyManagerBase::NUM_STRATEGIES] - [AudioPolicyManagerBase::VOLCNT] = { - { {1, -58.0f}, {20, -40.0f}, {60, -17.0f}, {100, 0.0f}}, // STRATEGY_MEDIA - { {1, -49.5f}, {33, -33.5f}, {66, -17.0f}, {100, 0.0f}}, // STRATEGY_PHONE - { {1, -29.7f}, {33, -20.1f}, {66, -10.2f}, {100, 0.0f}}, // STRATEGY_SONIFICATION - { {1, -49.5f}, {33, -33.5f}, {66, -17.0f}, {100, 0.0f}} // STRATEGY_DTMF + AudioPolicyManagerBase::sDefaultVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { + {1, -49.5f}, {33, -33.5f}, {66, -17.0f}, {100, 0.0f} +}; + +const AudioPolicyManagerBase::VolumeCurvePoint + AudioPolicyManagerBase::sDefaultMediaVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { + {1, -58.0f}, {20, -40.0f}, {60, -17.0f}, {100, 0.0f} }; -void AudioPolicyManagerBase::initializeVolumeCurves() { - for (int i=0; i < AudioSystem::NUM_STREAM_TYPES; i++) { - for (int j=0; j < VOLCNT; j++) { +const AudioPolicyManagerBase::VolumeCurvePoint + AudioPolicyManagerBase::sSpeakerMediaVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { + {1, -56.0f}, {20, -34.0f}, {60, -11.0f}, {100, 0.0f} +}; + +const AudioPolicyManagerBase::VolumeCurvePoint + AudioPolicyManagerBase::sSpeakerSonificationVolumeCurve[AudioPolicyManagerBase::VOLCNT] = { + {1, -29.7f}, {33, -20.1f}, {66, -10.2f}, {100, 0.0f} +}; + + +const AudioPolicyManagerBase::VolumeCurvePoint + *AudioPolicyManagerBase::sVolumeProfiles[AudioPolicyManagerBase::NUM_STRATEGIES] + [AudioPolicyManagerBase::DEVICE_CATEGORY_CNT] = { + { // STRATEGY_MEDIA + sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET + sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER + sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EARPIECE + }, + { // STRATEGY_PHONE + sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET + sDefaultVolumeCurve, // DEVICE_CATEGORY_SPEAKER + sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE + }, + { // STRATEGY_SONIFICATION + sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET + sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER + sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE + }, + { // STRATEGY_DTMF + sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET + sDefaultVolumeCurve, // DEVICE_CATEGORY_SPEAKER + sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE + } +}; + +void AudioPolicyManagerBase::initializeVolumeCurves() +{ + for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { + for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) { mStreams[i].mVolumeCurve[j] = sVolumeProfiles[getStrategy((AudioSystem::stream_type)i)][j]; } diff --git a/include/hardware_legacy/AudioPolicyManagerBase.h b/include/hardware_legacy/AudioPolicyManagerBase.h index 2cc8d87..d864b0a 100644 --- a/include/hardware_legacy/AudioPolicyManagerBase.h +++ b/include/hardware_legacy/AudioPolicyManagerBase.h @@ -146,7 +146,24 @@ protected: float mDBAttenuation; }; - static const VolumeCurvePoint sVolumeProfiles[NUM_STRATEGIES][VOLCNT]; + // device categories used for volume curve management. + enum device_category { + DEVICE_CATEGORY_HEADSET, + DEVICE_CATEGORY_SPEAKER, + DEVICE_CATEGORY_EARPIECE, + DEVICE_CATEGORY_CNT + }; + + // default volume curve + static const VolumeCurvePoint sDefaultVolumeCurve[AudioPolicyManagerBase::VOLCNT]; + // default volume curve for media strategy + static const VolumeCurvePoint sDefaultMediaVolumeCurve[AudioPolicyManagerBase::VOLCNT]; + // volume curve for media strategy on speakers + static const VolumeCurvePoint sSpeakerMediaVolumeCurve[AudioPolicyManagerBase::VOLCNT]; + // volume curve for sonification strategy on speakers + static const VolumeCurvePoint sSpeakerSonificationVolumeCurve[AudioPolicyManagerBase::VOLCNT]; + // default volume curves per strategy and device category. See initializeVolumeCurves() + static const VolumeCurvePoint *sVolumeProfiles[NUM_STRATEGIES][DEVICE_CATEGORY_CNT]; // descriptor for audio outputs. Used to maintain current configuration of each opened audio output // and keep track of the usage of this output by each audio stream type. @@ -211,7 +228,7 @@ protected: int mIndexCur; // current volume index bool mCanBeMuted; // true is the stream can be muted - VolumeCurvePoint mVolumeCurve[VOLCNT]; + const VolumeCurvePoint *mVolumeCurve[DEVICE_CATEGORY_CNT]; }; // stream descriptor used for volume control @@ -249,7 +266,8 @@ protected: virtual uint32_t getDeviceForInputSource(int inputSource); // return io handle of active input or 0 if no input is active audio_io_handle_t getActiveInput(); - virtual void initializeVolumeCurves(); + // initialize volume curves for each strategy and device category + void initializeVolumeCurves(); // compute the actual volume for a given stream according to the requested index and a particular // device virtual float computeVolume(int stream, int index, audio_io_handle_t output, uint32_t device); @@ -319,6 +337,9 @@ protected: status_t setEffectEnabled(EffectDescriptor *pDesc, bool enabled); + // returns the category the device belongs to with regard to volume curve management + static device_category getDeviceCategory(uint32_t device); + AudioPolicyClientInterface *mpClientInterface; // audio policy client interface audio_io_handle_t mHardwareOutput; // hardware output handler audio_io_handle_t mA2dpOutput; // A2DP output handler |
