audiohal: Fix volume changes handling

Some legacy implementations of the effects HAL use the condition
of the reply buffer being NULL as an indication that they shouldn't
apply attenuation to the input audio data. Therefore, separate
methods are needed to distinguish the use cases of delegating the
volume control to the effect, and just informing the effect of the
volume changes.

A new method added to IEffect: volumeChangeNotification that implements
the second use case. The contract of setAndGetVolume method has been
updated to indicate that it is only called in the first use case.

Also updated the wrapper for a generic IEffect commands to pass NULL
pointers to the command and reply buffers in case when the size
of the input or output data is 0, to preserve compatibility with
direct calls from the framework.

Bug: 34368451
Test: volume control works when both Bass Boost and Equalizer are
      enabled in the NXP implementation of the effects

Change-Id: I3c9a5bbdff561802bc94080c51703385a8903282
This commit is contained in:
Mikhail Naganov
2017-01-19 12:38:39 -08:00
parent 6fdbe86350
commit f4f2ff3974
25 changed files with 100 additions and 12 deletions

View File

@@ -83,26 +83,36 @@ interface IEffect {
/*
* Set and get volume. Used by audio framework to delegate volume control to
* effect engine. The effect implementation must set EFFECT_FLAG_VOLUME_IND
* or EFFECT_FLAG_VOLUME_CTRL flag in its descriptor to receive this command
* before every call to 'process' function If EFFECT_FLAG_VOLUME_CTRL flag
* is set in the effect descriptor, the effect engine must return the volume
* that should be applied before the effect is processed. The overall volume
* (the volume actually applied by the effect engine multiplied by the
* returned value) should match the value indicated in the command.
* effect engine. The effect implementation must set EFFECT_FLAG_VOLUME_CTRL
* flag in its descriptor to receive this command. The effect engine must
* return the volume that should be applied before the effect is
* processed. The overall volume (the volume actually applied by the effect
* engine multiplied by the returned value) should match the value indicated
* in the command.
*
* @param volumes vector containing volume for each channel defined in
* EffectConfig for output buffer expressed in 8.24 fixed
* point format.
* @return result updated volume values. It is OK to receive an empty vector
* as a result in which case the effect framework has
* delegated volume control to another effect.
* @return result updated volume values.
* @return retval operation completion status.
*/
@callflow(next={"*"})
setAndGetVolume(vec<uint32_t> volumes)
generates (Result retval, vec<uint32_t> result);
/*
* Notify the effect of the volume change. The effect implementation must
* set EFFECT_FLAG_VOLUME_IND flag in its descriptor to receive this
* command.
*
* @param volumes vector containing volume for each channel defined in
* EffectConfig for output buffer expressed in 8.24 fixed
* point format.
* @return retval operation completion status.
*/
volumeChangeNotification(vec<uint32_t> volumes)
generates (Result retval);
/*
* Set the audio mode. The effect implementation must set
* EFFECT_FLAG_AUDIO_MODE_IND flag in its descriptor to receive this command

View File

@@ -66,6 +66,11 @@ Return<void> AcousticEchoCancelerEffect::setAndGetVolume(
return mEffect->setAndGetVolume(volumes, _hidl_cb);
}
Return<Result> AcousticEchoCancelerEffect::volumeChangeNotification(
const hidl_vec<uint32_t>& volumes) {
return mEffect->volumeChangeNotification(volumes);
}
Return<Result> AcousticEchoCancelerEffect::setAudioMode(AudioMode mode) {
return mEffect->setAudioMode(mode);
}

View File

@@ -54,6 +54,7 @@ struct AcousticEchoCancelerEffect : public IAcousticEchoCancelerEffect {
Return<Result> setDevice(AudioDevice device) override;
Return<void> setAndGetVolume(
const hidl_vec<uint32_t>& volumes, setAndGetVolume_cb _hidl_cb) override;
Return<Result> volumeChangeNotification(const hidl_vec<uint32_t>& volumes) override;
Return<Result> setAudioMode(AudioMode mode) override;
Return<Result> setConfigReverse(
const EffectConfig& config,

View File

@@ -81,6 +81,11 @@ Return<void> AutomaticGainControlEffect::setAndGetVolume(
return mEffect->setAndGetVolume(volumes, _hidl_cb);
}
Return<Result> AutomaticGainControlEffect::volumeChangeNotification(
const hidl_vec<uint32_t>& volumes) {
return mEffect->volumeChangeNotification(volumes);
}
Return<Result> AutomaticGainControlEffect::setAudioMode(AudioMode mode) {
return mEffect->setAudioMode(mode);
}

View File

@@ -56,6 +56,7 @@ struct AutomaticGainControlEffect : public IAutomaticGainControlEffect {
Return<Result> setDevice(AudioDevice device) override;
Return<void> setAndGetVolume(
const hidl_vec<uint32_t>& volumes, setAndGetVolume_cb _hidl_cb) override;
Return<Result> volumeChangeNotification(const hidl_vec<uint32_t>& volumes) override;
Return<Result> setAudioMode(AudioMode mode) override;
Return<Result> setConfigReverse(
const EffectConfig& config,

View File

@@ -66,6 +66,11 @@ Return<void> BassBoostEffect::setAndGetVolume(
return mEffect->setAndGetVolume(volumes, _hidl_cb);
}
Return<Result> BassBoostEffect::volumeChangeNotification(
const hidl_vec<uint32_t>& volumes) {
return mEffect->volumeChangeNotification(volumes);
}
Return<Result> BassBoostEffect::setAudioMode(AudioMode mode) {
return mEffect->setAudioMode(mode);
}

View File

@@ -54,6 +54,7 @@ struct BassBoostEffect : public IBassBoostEffect {
Return<Result> setDevice(AudioDevice device) override;
Return<void> setAndGetVolume(
const hidl_vec<uint32_t>& volumes, setAndGetVolume_cb _hidl_cb) override;
Return<Result> volumeChangeNotification(const hidl_vec<uint32_t>& volumes) override;
Return<Result> setAudioMode(AudioMode mode) override;
Return<Result> setConfigReverse(
const EffectConfig& config,

View File

@@ -66,6 +66,11 @@ Return<void> DownmixEffect::setAndGetVolume(
return mEffect->setAndGetVolume(volumes, _hidl_cb);
}
Return<Result> DownmixEffect::volumeChangeNotification(
const hidl_vec<uint32_t>& volumes) {
return mEffect->volumeChangeNotification(volumes);
}
Return<Result> DownmixEffect::setAudioMode(AudioMode mode) {
return mEffect->setAudioMode(mode);
}

View File

@@ -54,6 +54,7 @@ struct DownmixEffect : public IDownmixEffect {
Return<Result> setDevice(AudioDevice device) override;
Return<void> setAndGetVolume(
const hidl_vec<uint32_t>& volumes, setAndGetVolume_cb _hidl_cb) override;
Return<Result> volumeChangeNotification(const hidl_vec<uint32_t>& volumes) override;
Return<Result> setAudioMode(AudioMode mode) override;
Return<Result> setConfigReverse(
const EffectConfig& config,

View File

@@ -533,6 +533,14 @@ Return<void> Effect::setAndGetVolume(
return Void();
}
Return<Result> Effect::volumeChangeNotification(const hidl_vec<uint32_t>& volumes) {
uint32_t halDataSize;
std::unique_ptr<uint8_t[]> halData = hidlVecToHal(volumes, &halDataSize);
return sendCommand(
EFFECT_CMD_SET_VOLUME, "SET_VOLUME",
halDataSize, &halData[0]);
}
Return<Result> Effect::setAudioMode(AudioMode mode) {
uint32_t halMode = static_cast<uint32_t>(mode);
return sendCommand(
@@ -641,10 +649,13 @@ Return<void> Effect::command(
uint32_t halResultSize = resultMaxSize;
std::unique_ptr<uint8_t[]> halResult(new uint8_t[halResultSize]);
memset(&halResult[0], 0, halResultSize);
void* dataPtr = halDataSize > 0 ? &halData[0] : NULL;
void* resultPtr = halResultSize > 0 ? &halResult[0] : NULL;
status_t status = (*mHandle)->command(
mHandle, commandId, halDataSize, &halData[0], &halResultSize, &halResult[0]);
mHandle, commandId, halDataSize, dataPtr, &halResultSize, resultPtr);
hidl_vec<uint8_t> result;
if (status == OK) {
if (status == OK && resultPtr != NULL) {
result.setToExternal(&halResult[0], halResultSize);
}
_hidl_cb(status, result);

View File

@@ -75,6 +75,7 @@ struct Effect : public IEffect {
Return<Result> setDevice(AudioDevice device) override;
Return<void> setAndGetVolume(
const hidl_vec<uint32_t>& volumes, setAndGetVolume_cb _hidl_cb) override;
Return<Result> volumeChangeNotification(const hidl_vec<uint32_t>& volumes) override;
Return<Result> setAudioMode(AudioMode mode) override;
Return<Result> setConfigReverse(
const EffectConfig& config,

View File

@@ -95,6 +95,11 @@ Return<void> EnvironmentalReverbEffect::setAndGetVolume(
return mEffect->setAndGetVolume(volumes, _hidl_cb);
}
Return<Result> EnvironmentalReverbEffect::volumeChangeNotification(
const hidl_vec<uint32_t>& volumes) {
return mEffect->volumeChangeNotification(volumes);
}
Return<Result> EnvironmentalReverbEffect::setAudioMode(AudioMode mode) {
return mEffect->setAudioMode(mode);
}

View File

@@ -66,6 +66,7 @@ struct EnvironmentalReverbEffect : public IEnvironmentalReverbEffect {
Return<Result> setDevice(AudioDevice device) override;
Return<void> setAndGetVolume(
const hidl_vec<uint32_t>& volumes, setAndGetVolume_cb _hidl_cb) override;
Return<Result> volumeChangeNotification(const hidl_vec<uint32_t>& volumes) override;
Return<Result> setAudioMode(AudioMode mode) override;
Return<Result> setConfigReverse(
const EffectConfig& config,

View File

@@ -86,6 +86,11 @@ Return<void> EqualizerEffect::setAndGetVolume(
return mEffect->setAndGetVolume(volumes, _hidl_cb);
}
Return<Result> EqualizerEffect::volumeChangeNotification(
const hidl_vec<uint32_t>& volumes) {
return mEffect->volumeChangeNotification(volumes);
}
Return<Result> EqualizerEffect::setAudioMode(AudioMode mode) {
return mEffect->setAudioMode(mode);
}

View File

@@ -68,6 +68,7 @@ struct EqualizerEffect : public IEqualizerEffect {
Return<Result> setDevice(AudioDevice device) override;
Return<void> setAndGetVolume(
const hidl_vec<uint32_t>& volumes, setAndGetVolume_cb _hidl_cb) override;
Return<Result> volumeChangeNotification(const hidl_vec<uint32_t>& volumes) override;
Return<Result> setAudioMode(AudioMode mode) override;
Return<Result> setConfigReverse(
const EffectConfig& config,

View File

@@ -68,6 +68,11 @@ Return<void> LoudnessEnhancerEffect::setAndGetVolume(
return mEffect->setAndGetVolume(volumes, _hidl_cb);
}
Return<Result> LoudnessEnhancerEffect::volumeChangeNotification(
const hidl_vec<uint32_t>& volumes) {
return mEffect->volumeChangeNotification(volumes);
}
Return<Result> LoudnessEnhancerEffect::setAudioMode(AudioMode mode) {
return mEffect->setAudioMode(mode);
}

View File

@@ -64,6 +64,7 @@ struct LoudnessEnhancerEffect : public ILoudnessEnhancerEffect {
Return<Result> setDevice(AudioDevice device) override;
Return<void> setAndGetVolume(
const hidl_vec<uint32_t>& volumes, setAndGetVolume_cb _hidl_cb) override;
Return<Result> volumeChangeNotification(const hidl_vec<uint32_t>& volumes) override;
Return<Result> setAudioMode(AudioMode mode) override;
Return<Result> setConfigReverse(
const EffectConfig& config,

View File

@@ -79,6 +79,11 @@ Return<void> NoiseSuppressionEffect::setAndGetVolume(
return mEffect->setAndGetVolume(volumes, _hidl_cb);
}
Return<Result> NoiseSuppressionEffect::volumeChangeNotification(
const hidl_vec<uint32_t>& volumes) {
return mEffect->volumeChangeNotification(volumes);
}
Return<Result> NoiseSuppressionEffect::setAudioMode(AudioMode mode) {
return mEffect->setAudioMode(mode);
}

View File

@@ -66,6 +66,7 @@ struct NoiseSuppressionEffect : public INoiseSuppressionEffect {
Return<Result> setDevice(AudioDevice device) override;
Return<void> setAndGetVolume(
const hidl_vec<uint32_t>& volumes, setAndGetVolume_cb _hidl_cb) override;
Return<Result> volumeChangeNotification(const hidl_vec<uint32_t>& volumes) override;
Return<Result> setAudioMode(AudioMode mode) override;
Return<Result> setConfigReverse(
const EffectConfig& config,

View File

@@ -66,6 +66,11 @@ Return<void> PresetReverbEffect::setAndGetVolume(
return mEffect->setAndGetVolume(volumes, _hidl_cb);
}
Return<Result> PresetReverbEffect::volumeChangeNotification(
const hidl_vec<uint32_t>& volumes) {
return mEffect->volumeChangeNotification(volumes);
}
Return<Result> PresetReverbEffect::setAudioMode(AudioMode mode) {
return mEffect->setAudioMode(mode);
}

View File

@@ -64,6 +64,7 @@ struct PresetReverbEffect : public IPresetReverbEffect {
Return<Result> setDevice(AudioDevice device) override;
Return<void> setAndGetVolume(
const hidl_vec<uint32_t>& volumes, setAndGetVolume_cb _hidl_cb) override;
Return<Result> volumeChangeNotification(const hidl_vec<uint32_t>& volumes) override;
Return<Result> setAudioMode(AudioMode mode) override;
Return<Result> setConfigReverse(
const EffectConfig& config,

View File

@@ -78,6 +78,11 @@ Return<void> VirtualizerEffect::setAndGetVolume(
return mEffect->setAndGetVolume(volumes, _hidl_cb);
}
Return<Result> VirtualizerEffect::volumeChangeNotification(
const hidl_vec<uint32_t>& volumes) {
return mEffect->volumeChangeNotification(volumes);
}
Return<Result> VirtualizerEffect::setAudioMode(AudioMode mode) {
return mEffect->setAudioMode(mode);
}

View File

@@ -65,6 +65,7 @@ struct VirtualizerEffect : public IVirtualizerEffect {
Return<Result> setDevice(AudioDevice device) override;
Return<void> setAndGetVolume(
const hidl_vec<uint32_t>& volumes, setAndGetVolume_cb _hidl_cb) override;
Return<Result> volumeChangeNotification(const hidl_vec<uint32_t>& volumes) override;
Return<Result> setAudioMode(AudioMode mode) override;
Return<Result> setConfigReverse(
const EffectConfig& config,

View File

@@ -66,6 +66,11 @@ Return<void> VisualizerEffect::setAndGetVolume(
return mEffect->setAndGetVolume(volumes, _hidl_cb);
}
Return<Result> VisualizerEffect::volumeChangeNotification(
const hidl_vec<uint32_t>& volumes) {
return mEffect->volumeChangeNotification(volumes);
}
Return<Result> VisualizerEffect::setAudioMode(AudioMode mode) {
return mEffect->setAudioMode(mode);
}

View File

@@ -64,6 +64,7 @@ struct VisualizerEffect : public IVisualizerEffect {
Return<Result> setDevice(AudioDevice device) override;
Return<void> setAndGetVolume(
const hidl_vec<uint32_t>& volumes, setAndGetVolume_cb _hidl_cb) override;
Return<Result> volumeChangeNotification(const hidl_vec<uint32_t>& volumes) override;
Return<Result> setAudioMode(AudioMode mode) override;
Return<Result> setConfigReverse(
const EffectConfig& config,