diff options
author | Eric Laurent <elaurent@google.com> | 2015-04-09 01:12:06 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-04-09 01:12:06 +0000 |
commit | 17769490d499bc665ddfef83143ac1ed647fa0d4 (patch) | |
tree | b2d5bc5fe875be119ffd3ce3352a9444caf2d1e2 /services | |
parent | 9c7f67264d3b3ace9703b3a96bd7bc4922111b4f (diff) | |
parent | ffbc80f5908eaf67a033c6e93a343c39dd6894eb (diff) | |
download | frameworks_av-17769490d499bc665ddfef83143ac1ed647fa0d4.zip frameworks_av-17769490d499bc665ddfef83143ac1ed647fa0d4.tar.gz frameworks_av-17769490d499bc665ddfef83143ac1ed647fa0d4.tar.bz2 |
Merge "audio policy: volume in dBs"
Diffstat (limited to 'services')
10 files changed, 77 insertions, 40 deletions
diff --git a/services/audiopolicy/common/include/Volume.h b/services/audiopolicy/common/include/Volume.h index a4cc759..4205589 100755 --- a/services/audiopolicy/common/include/Volume.h +++ b/services/audiopolicy/common/include/Volume.h @@ -18,6 +18,10 @@ #include <system/audio.h> #include <utils/Log.h> +#include <math.h> + +// Absolute min volume in dB (can be represented in single precision normal float value) +#define VOLUME_MIN_DB (-758) class VolumeCurvePoint { @@ -32,7 +36,7 @@ public: /** * 4 points to define the volume attenuation curve, each characterized by the volume * index (from 0 to 100) at which they apply, and the attenuation in dB at that index. - * we use 100 steps to avoid rounding errors when computing the volume in volIndexToAmpl() + * we use 100 steps to avoid rounding errors when computing the volume in volIndexToDb() * * @todo shall become configurable */ @@ -134,4 +138,20 @@ public: } } + static inline float DbToAmpl(float decibels) + { + if (decibels <= VOLUME_MIN_DB) { + return 0.0f; + } + return exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 ) + } + + static inline float AmplToDb(float amplification) + { + if (amplification == 0) { + return VOLUME_MIN_DB; + } + return 20 * log10(amplification); + } + }; diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h index c6bb975..f1aee46 100644 --- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h +++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h @@ -74,7 +74,7 @@ public: audio_patch_handle_t mPatchHandle; uint32_t mRefCount[AUDIO_STREAM_CNT]; // number of streams of each type using this output nsecs_t mStopTime[AUDIO_STREAM_CNT]; - float mCurVolume[AUDIO_STREAM_CNT]; // current stream volume + float mCurVolume[AUDIO_STREAM_CNT]; // current stream volume in dB int mMuteCount[AUDIO_STREAM_CNT]; // mute request counter bool mStrategyMutedByDevice[NUM_STRATEGIES]; // strategies muted because of incompatible // device selection. See checkDeviceMuteStrategies() diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp index 0837a54..596aa1d 100644 --- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp @@ -21,6 +21,7 @@ #include "AudioOutputDescriptor.h" #include "IOProfile.h" #include "AudioGain.h" +#include "Volume.h" #include "HwModule.h" #include <media/AudioPolicy.h> @@ -354,11 +355,12 @@ bool SwAudioOutputDescriptor::setVolume(float volume, if (changed) { // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is // enabled + float volume = Volume::DbToAmpl(mCurVolume[stream]); if (stream == AUDIO_STREAM_BLUETOOTH_SCO) { mClientInterface->setStreamVolume( - AUDIO_STREAM_VOICE_CALL, mCurVolume[stream], mIoHandle, delayMs); + AUDIO_STREAM_VOICE_CALL, volume, mIoHandle, delayMs); } - mClientInterface->setStreamVolume(stream, mCurVolume[stream], mIoHandle, delayMs); + mClientInterface->setStreamVolume(stream, volume, mIoHandle, delayMs); } return changed; } diff --git a/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h b/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h index eadaa77..db0573f 100755 --- a/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h +++ b/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h @@ -134,16 +134,16 @@ public: audio_policy_dev_state_t state) = 0; /** - * Translate a volume index given by the UI to an amplification value for a stream type + * Translate a volume index given by the UI to an amplification value in dB for a stream type * and a device category. * * @param[in] deviceCategory for which the conversion is requested. * @param[in] stream type for which the conversion is requested. * @param[in] indexInUi index received from the UI to be translated. * - * @return amplification value matching the UI index for this given device and stream. + * @return amplification value in dB matching the UI index for this given device and stream. */ - virtual float volIndexToAmpl(Volume::device_category deviceCategory, audio_stream_type_t stream, + virtual float volIndexToDb(Volume::device_category deviceCategory, audio_stream_type_t stream, int indexInUi) = 0; /** diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp index 26a0d09..50f1609 100755 --- a/services/audiopolicy/enginedefault/src/Engine.cpp +++ b/services/audiopolicy/enginedefault/src/Engine.cpp @@ -63,13 +63,14 @@ status_t Engine::initCheck() return (mApmObserver != NULL) ? NO_ERROR : NO_INIT; } -float Engine::volIndexToAmpl(Volume::device_category category, audio_stream_type_t streamType, +float Engine::volIndexToDb(Volume::device_category category, audio_stream_type_t streamType, int indexInUi) { const StreamDescriptor &streamDesc = mApmObserver->getStreamDescriptors().valueAt(streamType); - return Gains::volIndexToAmpl(category, streamDesc, indexInUi); + return Gains::volIndexToDb(category, streamDesc, indexInUi); } + status_t Engine::initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax) { ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax); diff --git a/services/audiopolicy/enginedefault/src/Engine.h b/services/audiopolicy/enginedefault/src/Engine.h index f44556c..56a4748 100755 --- a/services/audiopolicy/enginedefault/src/Engine.h +++ b/services/audiopolicy/enginedefault/src/Engine.h @@ -101,10 +101,10 @@ private: { return mPolicyEngine->initializeVolumeCurves(isSpeakerDrcEnabled); } - virtual float volIndexToAmpl(Volume::device_category deviceCategory, + virtual float volIndexToDb(Volume::device_category deviceCategory, audio_stream_type_t stream,int indexInUi) { - return mPolicyEngine->volIndexToAmpl(deviceCategory, stream, indexInUi); + return mPolicyEngine->volIndexToDb(deviceCategory, stream, indexInUi); } private: Engine *mPolicyEngine; @@ -141,7 +141,7 @@ private: audio_devices_t getDeviceForStrategy(routing_strategy strategy) const; audio_devices_t getDeviceForInputSource(audio_source_t inputSource) const; - float volIndexToAmpl(Volume::device_category category, + float volIndexToDb(Volume::device_category category, audio_stream_type_t stream, int indexInUi); status_t initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax); void initializeVolumeCurves(bool isSpeakerDrcEnabled); diff --git a/services/audiopolicy/enginedefault/src/Gains.cpp b/services/audiopolicy/enginedefault/src/Gains.cpp index a684fdd..78f2909 100644 --- a/services/audiopolicy/enginedefault/src/Gains.cpp +++ b/services/audiopolicy/enginedefault/src/Gains.cpp @@ -197,10 +197,10 @@ const VolumeCurvePoint *Gains::sVolumeProfiles[AUDIO_STREAM_CNT] }; //static -float Gains::volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc, - int indexInUi) +float Gains::volIndexToDb(Volume::device_category deviceCategory, + const StreamDescriptor& streamDesc, + int indexInUi) { - Volume::device_category deviceCategory = Volume::getDeviceCategory(device); const VolumeCurvePoint *curve = streamDesc.getVolumeCurvePoint(deviceCategory); // the volume index in the UI is relative to the min and max volume indices for this stream type @@ -212,7 +212,7 @@ float Gains::volIndexToAmpl(audio_devices_t device, const StreamDescriptor& stre // find what part of the curve this index volume belongs to, or if it's out of bounds int segment = 0; if (volIdx < curve[Volume::VOLMIN].mIndex) { // out of bounds - return 0.0f; + return VOLUME_MIN_DB; } else if (volIdx < curve[Volume::VOLKNEE1].mIndex) { segment = 0; } else if (volIdx < curve[Volume::VOLKNEE2].mIndex) { @@ -220,7 +220,7 @@ float Gains::volIndexToAmpl(audio_devices_t device, const StreamDescriptor& stre } else if (volIdx <= curve[Volume::VOLMAX].mIndex) { segment = 2; } else { // out of bounds - return 1.0f; + return 0.0f; } // linear interpolation in the attenuation table in dB @@ -231,17 +231,25 @@ float Gains::volIndexToAmpl(audio_devices_t device, const StreamDescriptor& stre ((float)(curve[segment+1].mIndex - curve[segment].mIndex)) ); - float amplification = exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 ) - - ALOGVV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f", + ALOGVV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f]", curve[segment].mIndex, volIdx, curve[segment+1].mIndex, curve[segment].mDBAttenuation, decibels, - curve[segment+1].mDBAttenuation, - amplification); + curve[segment+1].mDBAttenuation); + + return decibels; +} - return amplification; + +//static +float Gains::volIndexToAmpl(Volume::device_category deviceCategory, + const StreamDescriptor& streamDesc, + int indexInUi) +{ + return Volume::DbToAmpl(volIndexToDb(deviceCategory, streamDesc, indexInUi)); } + + }; // namespace android diff --git a/services/audiopolicy/enginedefault/src/Gains.h b/services/audiopolicy/enginedefault/src/Gains.h index b5601ca..7620b7d 100644 --- a/services/audiopolicy/enginedefault/src/Gains.h +++ b/services/audiopolicy/enginedefault/src/Gains.h @@ -29,8 +29,13 @@ class StreamDescriptor; class Gains { public : - static float volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc, - int indexInUi); + static float volIndexToAmpl(Volume::device_category deviceCategory, + const StreamDescriptor& streamDesc, + int indexInUi); + + static float volIndexToDb(Volume::device_category deviceCategory, + const StreamDescriptor& streamDesc, + int indexInUi); // default volume curve static const VolumeCurvePoint sDefaultVolumeCurve[Volume::VOLCNT]; diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp index b5ff9a9..686a0e1 100644 --- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp +++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp @@ -4251,9 +4251,7 @@ float AudioPolicyManager::computeVolume(audio_stream_type_t stream, int index, audio_devices_t device) { - float volume = 1.0; - - volume = mEngine->volIndexToAmpl(Volume::getDeviceCategory(device), stream, index); + float volumeDb = mEngine->volIndexToDb(Volume::getDeviceCategory(device), stream, index); // if a headset is connected, apply the following rules to ring tones and notifications // to avoid sound level bursts in user's ears: @@ -4271,26 +4269,26 @@ float AudioPolicyManager::computeVolume(audio_stream_type_t stream, || ((stream_strategy == STRATEGY_ENFORCED_AUDIBLE) && (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_NONE))) && mStreams.canBeMuted(stream)) { - volume *= SONIFICATION_HEADSET_VOLUME_FACTOR; + volumeDb += SONIFICATION_HEADSET_VOLUME_FACTOR_DB; // when the phone is ringing we must consider that music could have been paused just before // by the music application and behave as if music was active if the last music track was // just stopped if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) || mLimitRingtoneVolume) { audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/); - float musicVol = computeVolume(AUDIO_STREAM_MUSIC, - mStreams.valueFor(AUDIO_STREAM_MUSIC).getVolumeIndex(musicDevice), + float musicVolDB = computeVolume(AUDIO_STREAM_MUSIC, + mStreams.valueFor(AUDIO_STREAM_MUSIC).getVolumeIndex(musicDevice), musicDevice); - 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); + float minVolDB = (musicVolDB > SONIFICATION_HEADSET_VOLUME_MIN_DB) ? + musicVolDB : SONIFICATION_HEADSET_VOLUME_MIN_DB; + if (volumeDb > minVolDB) { + volumeDb = minVolDB; + ALOGV("computeVolume limiting volume to %f musicVol %f", minVolDB, musicVolDB); } } } - return volume; + return volumeDb; } status_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream, @@ -4320,12 +4318,12 @@ status_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream, device = outputDesc->device(); } - float volume = computeVolume(stream, index, device); + float volumeDb = computeVolume(stream, index, device); if (outputDesc->isFixedVolume(device)) { - volume = 1.0f; + volumeDb = 0.0f; } - outputDesc->setVolume(volume, stream, device, delayMs, force); + outputDesc->setVolume(volumeDb, stream, device, delayMs, force); if (stream == AUDIO_STREAM_VOICE_CALL || stream == AUDIO_STREAM_BLUETOOTH_SCO) { diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h index 9baeeb6..11fd5ff 100644 --- a/services/audiopolicy/managerdefault/AudioPolicyManager.h +++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h @@ -49,8 +49,11 @@ namespace android { // Attenuation applied to STRATEGY_SONIFICATION streams when a headset is connected: 6dB #define SONIFICATION_HEADSET_VOLUME_FACTOR 0.5 +#define SONIFICATION_HEADSET_VOLUME_FACTOR_DB (-6) // Min volume for STRATEGY_SONIFICATION streams when limited by music volume: -36dB #define SONIFICATION_HEADSET_VOLUME_MIN 0.016 +#define SONIFICATION_HEADSET_VOLUME_MIN_DB (-36) + // Time in milliseconds during which we consider that music is still active after a music // track was stopped - see computeVolume() #define SONIFICATION_HEADSET_MUSIC_DELAY 5000 |