AudioHal: adapt effect_param_t handling with AIDL
Bug: 258124419
Test: atest EffectParamWrapper_tests
Test: Enable AIDL and build, run cts
Test: atest EffectsFactoryHalInterfaceTest
Change-Id: I404122422d4be70f6f24a1b4e40548fed41110b9
diff --git a/media/audioaidlconversion/AidlConversionNdk.cpp b/media/audioaidlconversion/AidlConversionNdk.cpp
index 9981435..8fec660 100644
--- a/media/audioaidlconversion/AidlConversionNdk.cpp
+++ b/media/audioaidlconversion/AidlConversionNdk.cpp
@@ -30,7 +30,10 @@
namespace android {
using ::aidl::android::hardware::audio::effect::AcousticEchoCanceler;
+using ::aidl::android::hardware::audio::effect::AutomaticGainControl;
+using ::aidl::android::hardware::audio::effect::BassBoost;
using ::aidl::android::hardware::audio::effect::Descriptor;
+using ::aidl::android::hardware::audio::effect::Downmix;
using ::aidl::android::hardware::audio::effect::Flags;
using ::aidl::android::hardware::audio::effect::Parameter;
using ::aidl::android::media::audio::common::AudioDeviceDescription;
@@ -39,14 +42,6 @@
using ::android::base::unexpected;
////////////////////////////////////////////////////////////////////////////////////////////////////
-// Utils
-
-ConversionResult<AcousticEchoCanceler> getParameterSpecificAec(const Parameter& aidl) {
- const auto& specific = VALUE_OR_RETURN(UNION_GET(aidl, specific));
- return VALUE_OR_RETURN(UNION_GET(specific, acousticEchoCanceler));
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
// Converters
ConversionResult<uint32_t> aidl2legacy_Flags_Type_uint32(Flags::Type type) {
@@ -65,6 +60,22 @@
return unexpected(BAD_VALUE);
}
+ConversionResult<Flags::Type> legacy2aidl_uint32_Flags_Type(uint32_t legacy) {
+ switch (legacy & EFFECT_FLAG_TYPE_MASK) {
+ case EFFECT_FLAG_TYPE_INSERT:
+ return Flags::Type::INSERT;
+ case EFFECT_FLAG_TYPE_AUXILIARY:
+ return Flags::Type::AUXILIARY;
+ case EFFECT_FLAG_TYPE_REPLACE:
+ return Flags::Type::REPLACE;
+ case EFFECT_FLAG_TYPE_PRE_PROC:
+ return Flags::Type::PRE_PROC;
+ case EFFECT_FLAG_TYPE_POST_PROC:
+ return Flags::Type::POST_PROC;
+ }
+ return unexpected(BAD_VALUE);
+}
+
ConversionResult<uint32_t> aidl2legacy_Flags_Insert_uint32(Flags::Insert insert) {
switch (insert) {
case Flags::Insert::ANY:
@@ -79,6 +90,20 @@
return unexpected(BAD_VALUE);
}
+ConversionResult<Flags::Insert> legacy2aidl_uint32_Flags_Insert(uint32_t legacy) {
+ switch (legacy & EFFECT_FLAG_INSERT_MASK) {
+ case EFFECT_FLAG_INSERT_ANY:
+ return Flags::Insert::ANY;
+ case EFFECT_FLAG_INSERT_FIRST:
+ return Flags::Insert::FIRST;
+ case EFFECT_FLAG_INSERT_LAST:
+ return Flags::Insert::LAST;
+ case EFFECT_FLAG_INSERT_EXCLUSIVE:
+ return Flags::Insert::EXCLUSIVE;
+ }
+ return unexpected(BAD_VALUE);
+}
+
ConversionResult<uint32_t> aidl2legacy_Flags_Volume_uint32(Flags::Volume volume) {
switch (volume) {
case Flags::Volume::NONE:
@@ -92,15 +117,17 @@
}
return unexpected(BAD_VALUE);
}
-ConversionResult<uint32_t> aidl2legacy_Flags_HardwareAccelerator_uint32(
- Flags::HardwareAccelerator hwAcceleratorMode) {
- switch (hwAcceleratorMode) {
- case Flags::HardwareAccelerator::NONE:
- return 0;
- case Flags::HardwareAccelerator::SIMPLE:
- return EFFECT_FLAG_HW_ACC_SIMPLE;
- case Flags::HardwareAccelerator::TUNNEL:
- return EFFECT_FLAG_HW_ACC_TUNNEL;
+
+ConversionResult<Flags::Volume> legacy2aidl_uint32_Flags_Volume(uint32_t legacy) {
+ switch (legacy & EFFECT_FLAG_VOLUME_MASK) {
+ case EFFECT_FLAG_VOLUME_CTRL:
+ return Flags::Volume::CTRL;
+ case EFFECT_FLAG_VOLUME_IND:
+ return Flags::Volume::IND;
+ case EFFECT_FLAG_VOLUME_MONITOR:
+ return Flags::Volume::MONITOR;
+ case EFFECT_FLAG_VOLUME_NONE:
+ return Flags::Volume::NONE;
}
return unexpected(BAD_VALUE);
}
@@ -130,59 +157,6 @@
return legacy;
}
-ConversionResult<Flags::Type> legacy2aidl_uint32_Flags_Type(uint32_t legacy) {
- switch (legacy & EFFECT_FLAG_TYPE_MASK) {
- case EFFECT_FLAG_TYPE_INSERT:
- return Flags::Type::INSERT;
- case EFFECT_FLAG_TYPE_AUXILIARY:
- return Flags::Type::AUXILIARY;
- case EFFECT_FLAG_TYPE_REPLACE:
- return Flags::Type::REPLACE;
- case EFFECT_FLAG_TYPE_PRE_PROC:
- return Flags::Type::PRE_PROC;
- case EFFECT_FLAG_TYPE_POST_PROC:
- return Flags::Type::POST_PROC;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<Flags::Insert> legacy2aidl_uint32_Flags_Insert(uint32_t legacy) {
- switch (legacy & EFFECT_FLAG_INSERT_MASK) {
- case EFFECT_FLAG_INSERT_ANY:
- return Flags::Insert::ANY;
- case EFFECT_FLAG_INSERT_FIRST:
- return Flags::Insert::FIRST;
- case EFFECT_FLAG_INSERT_LAST:
- return Flags::Insert::LAST;
- case EFFECT_FLAG_INSERT_EXCLUSIVE:
- return Flags::Insert::EXCLUSIVE;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<Flags::Volume> legacy2aidl_uint32_Flags_Volume(uint32_t legacy) {
- switch (legacy & EFFECT_FLAG_VOLUME_MASK) {
- case EFFECT_FLAG_VOLUME_IND:
- return Flags::Volume::IND;
- case EFFECT_FLAG_VOLUME_MONITOR:
- return Flags::Volume::MONITOR;
- case EFFECT_FLAG_VOLUME_NONE:
- return Flags::Volume::NONE;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<Flags::HardwareAccelerator> legacy2aidl_uint32_Flags_HardwareAccelerator(
- uint32_t legacy) {
- switch (legacy & EFFECT_FLAG_HW_ACC_MASK) {
- case EFFECT_FLAG_HW_ACC_SIMPLE:
- return Flags::HardwareAccelerator::SIMPLE;
- case EFFECT_FLAG_HW_ACC_TUNNEL:
- return Flags::HardwareAccelerator::TUNNEL;
- }
- return unexpected(BAD_VALUE);
-}
-
ConversionResult<Flags> legacy2aidl_uint32_Flags(uint32_t legacy) {
Flags aidl;
@@ -198,6 +172,32 @@
return aidl;
}
+ConversionResult<uint32_t> aidl2legacy_Flags_HardwareAccelerator_uint32(
+ Flags::HardwareAccelerator hwAcceleratorMode) {
+ switch (hwAcceleratorMode) {
+ case Flags::HardwareAccelerator::NONE:
+ return 0;
+ case Flags::HardwareAccelerator::SIMPLE:
+ return EFFECT_FLAG_HW_ACC_SIMPLE;
+ case Flags::HardwareAccelerator::TUNNEL:
+ return EFFECT_FLAG_HW_ACC_TUNNEL;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<Flags::HardwareAccelerator> legacy2aidl_uint32_Flags_HardwareAccelerator(
+ uint32_t legacy) {
+ switch (legacy & EFFECT_FLAG_HW_ACC_MASK) {
+ case EFFECT_FLAG_HW_ACC_SIMPLE:
+ return Flags::HardwareAccelerator::SIMPLE;
+ case EFFECT_FLAG_HW_ACC_TUNNEL:
+ return Flags::HardwareAccelerator::TUNNEL;
+ case 0:
+ return Flags::HardwareAccelerator::NONE;
+ }
+ return unexpected(BAD_VALUE);
+}
+
ConversionResult<effect_descriptor_t>
aidl2legacy_Descriptor_effect_descriptor(const Descriptor& aidl) {
effect_descriptor_t legacy;
@@ -231,6 +231,7 @@
return aidl;
}
+// buffer_provider_t is not supported thus skipped
ConversionResult<buffer_config_t> aidl2legacy_AudioConfigBase_buffer_config_t(
const media::audio::common::AudioConfigBase& aidl, bool isInput) {
buffer_config_t legacy;
@@ -245,6 +246,7 @@
legacy.format = VALUE_OR_RETURN(aidl2legacy_AudioFormatDescription_audio_format_t(aidl.format));
legacy.mask |= EFFECT_CONFIG_FORMAT;
+ // TODO: add accessMode and mask
return legacy;
}
@@ -263,37 +265,100 @@
aidl.format = VALUE_OR_RETURN(legacy2aidl_audio_format_t_AudioFormatDescription(
static_cast<audio_format_t>(legacy.format)));
}
+
+ // TODO: add accessMode and mask
return aidl;
}
-ConversionResult<uint32_t> aidl2legacy_Parameter_uint32_echoDelay(const Parameter& aidl) {
- const auto& aec = VALUE_OR_RETURN(getParameterSpecificAec(aidl));
- const auto& echoDelay = VALUE_OR_RETURN(UNION_GET(aec, echoDelayUs));
- return VALUE_OR_RETURN(convertIntegral<uint32_t>(echoDelay));
+ConversionResult<uint32_t> aidl2legacy_Parameter_aec_uint32_echoDelay(const Parameter& aidl) {
+ int echoDelay = VALUE_OR_RETURN(GET_PARAMETER_SPECIFIC_FIELD(
+ aidl, AcousticEchoCanceler, acousticEchoCanceler, echoDelayUs, int));
+ return VALUE_OR_RETURN(convertReinterpret<uint32_t>(echoDelay));
}
-ConversionResult<Parameter> legacy2aidl_uint32_echoDelay_Parameter(const uint32_t& legacy) {
+ConversionResult<Parameter> legacy2aidl_uint32_echoDelay_Parameter_aec(uint32_t legacy) {
int delay = VALUE_OR_RETURN(convertReinterpret<int32_t>(legacy));
- AcousticEchoCanceler aec = AcousticEchoCanceler::make<AcousticEchoCanceler::echoDelayUs>(delay);
- Parameter::Specific specific =
- Parameter::Specific::make<Parameter::Specific::acousticEchoCanceler>(aec);
-
- return Parameter::make<Parameter::specific>(specific);
+ return MAKE_SPECIFIC_PARAMETER(AcousticEchoCanceler, acousticEchoCanceler, echoDelayUs, delay);
}
-ConversionResult<uint32_t> aidl2legacy_Parameter_uint32_mobileMode(const Parameter& aidl) {
- const auto& aec = VALUE_OR_RETURN(getParameterSpecificAec(aidl));
- const auto& mobileMode = VALUE_OR_RETURN(UNION_GET(aec, mobileMode));
+ConversionResult<uint32_t> aidl2legacy_Parameter_aec_uint32_mobileMode(const Parameter& aidl) {
+ bool mobileMode = VALUE_OR_RETURN(GET_PARAMETER_SPECIFIC_FIELD(
+ aidl, AcousticEchoCanceler, acousticEchoCanceler, mobileMode, bool));
return VALUE_OR_RETURN(convertIntegral<uint32_t>(mobileMode));
}
-ConversionResult<Parameter> legacy2aidl_uint32_mobileMode_Parameter(const uint32_t& legacy) {
+ConversionResult<Parameter> legacy2aidl_uint32_mobileMode_Parameter_aec(uint32_t legacy) {
bool mode = VALUE_OR_RETURN(convertIntegral<bool>(legacy));
- AcousticEchoCanceler aec = AcousticEchoCanceler::make<AcousticEchoCanceler::mobileMode>(mode);
- Parameter::Specific specific =
- Parameter::Specific::make<Parameter::Specific::acousticEchoCanceler>(aec);
+ return MAKE_SPECIFIC_PARAMETER(AcousticEchoCanceler, acousticEchoCanceler, mobileMode, mode);
+}
- return Parameter::make<Parameter::specific>(specific);
+ConversionResult<uint32_t> aidl2legacy_Parameter_agc_uint32_fixedDigitalGain(
+ const Parameter& aidl) {
+ int gain = VALUE_OR_RETURN(GET_PARAMETER_SPECIFIC_FIELD(
+ aidl, AutomaticGainControl, automaticGainControl, fixedDigitalGainMb, int));
+ return VALUE_OR_RETURN(convertReinterpret<uint32_t>(gain));
+}
+
+ConversionResult<Parameter> legacy2aidl_uint32_fixedDigitalGain_Parameter_agc(uint32_t legacy) {
+ int gain = VALUE_OR_RETURN(convertReinterpret<int>(legacy));
+ return MAKE_SPECIFIC_PARAMETER(AutomaticGainControl, automaticGainControl, fixedDigitalGainMb,
+ gain);
+}
+
+ConversionResult<uint32_t> aidl2legacy_Parameter_agc_uint32_levelEstimator(
+ const Parameter& aidl) {
+ const auto& le = VALUE_OR_RETURN(
+ GET_PARAMETER_SPECIFIC_FIELD(aidl, AutomaticGainControl, automaticGainControl,
+ levelEstimator, AutomaticGainControl::LevelEstimator));
+ return static_cast<uint32_t>(le);
+}
+
+ConversionResult<Parameter> legacy2aidl_uint32_levelEstimator_Parameter_agc(uint32_t legacy) {
+ if (legacy > (uint32_t) AutomaticGainControl::LevelEstimator::PEAK) {
+ return unexpected(BAD_VALUE);
+ }
+ AutomaticGainControl::LevelEstimator le =
+ static_cast<AutomaticGainControl::LevelEstimator>(legacy);
+ return MAKE_SPECIFIC_PARAMETER(AutomaticGainControl, automaticGainControl, levelEstimator, le);
+}
+
+ConversionResult<uint32_t> aidl2legacy_Parameter_agc_uint32_saturationMargin(
+ const Parameter& aidl) {
+ int saturationMargin = VALUE_OR_RETURN(GET_PARAMETER_SPECIFIC_FIELD(
+ aidl, AutomaticGainControl, automaticGainControl, saturationMarginMb, int));
+ return VALUE_OR_RETURN(convertIntegral<uint32_t>(saturationMargin));
+}
+
+ConversionResult<Parameter> legacy2aidl_uint32_saturationMargin_Parameter_agc(uint32_t legacy) {
+ int saturationMargin = VALUE_OR_RETURN(convertIntegral<int>(legacy));
+ return MAKE_SPECIFIC_PARAMETER(AutomaticGainControl, automaticGainControl, saturationMarginMb,
+ saturationMargin);
+}
+
+ConversionResult<uint16_t> aidl2legacy_Parameter_BassBoost_uint16_strengthPm(
+ const Parameter& aidl) {
+ int strength = VALUE_OR_RETURN(
+ GET_PARAMETER_SPECIFIC_FIELD(aidl, BassBoost, bassBoost, strengthPm, int));
+ return VALUE_OR_RETURN(convertIntegral<uint16_t>(strength));
+}
+
+ConversionResult<Parameter> legacy2aidl_uint16_strengthPm_Parameter_BassBoost(uint16_t legacy) {
+ int strength = VALUE_OR_RETURN(convertIntegral<int>(legacy));
+ return MAKE_SPECIFIC_PARAMETER(BassBoost, bassBoost, strengthPm, strength);
+}
+
+ConversionResult<int16_t> aidl2legacy_Parameter_Downmix_int16_type(const Parameter& aidl) {
+ Downmix::Type aidlType = VALUE_OR_RETURN(
+ GET_PARAMETER_SPECIFIC_FIELD(aidl, Downmix, downmix, type, Downmix::Type));
+ return VALUE_OR_RETURN(convertIntegral<int16_t>(static_cast<uint32_t>(aidlType)));
+}
+
+ConversionResult<Parameter> legacy2aidl_int16_type_Parameter_Downmix(int16_t legacy) {
+ if (legacy > (uint32_t) Downmix::Type::FOLD) {
+ return unexpected(BAD_VALUE);
+ }
+ Downmix::Type aidlType = static_cast<Downmix::Type>(legacy);
+ return MAKE_SPECIFIC_PARAMETER(Downmix, downmix, type, aidlType);
}
} // namespace android
diff --git a/media/audioaidlconversion/include/media/AidlConversionNdk.h b/media/audioaidlconversion/include/media/AidlConversionNdk.h
index a1c0da7..d094dff 100644
--- a/media/audioaidlconversion/include/media/AidlConversionNdk.h
+++ b/media/audioaidlconversion/include/media/AidlConversionNdk.h
@@ -32,8 +32,32 @@
namespace aidl {
namespace android {
-ConversionResult<::aidl::android::hardware::audio::effect::AcousticEchoCanceler>
-getParameterSpecificAec(const ::aidl::android::hardware::audio::effect::Parameter& aidl);
+template <typename P, typename T, typename P::Specific::Tag tag>
+ConversionResult<T> getParameterSpecific(const P& u) {
+ const auto& spec = VALUE_OR_RETURN(UNION_GET(u, specific));
+ return unionGetField<typename P::Specific, tag>(spec);
+}
+
+template <typename P, typename T, typename P::Specific::Tag tag, typename T::Tag field, typename F>
+ConversionResult<F> getParameterSpecificField(const P& u) {
+ const auto& spec =
+ VALUE_OR_RETURN((getParameterSpecific<std::decay_t<decltype(u)>, T, tag>(u)));
+ return VALUE_OR_RETURN((unionGetField<T, field>(spec)));
+}
+
+#define GET_PARAMETER_SPECIFIC_FIELD(u, specific, tag, field, fieldType) \
+ getParameterSpecificField<std::decay_t<decltype(u)>, specific, \
+ aidl::android::hardware::audio::effect::Parameter::Specific::tag, \
+ specific::field, fieldType>(u)
+
+#define MAKE_SPECIFIC_PARAMETER(spec, tag, field, value) \
+ UNION_MAKE(aidl::android::hardware::audio::effect::Parameter, specific, \
+ UNION_MAKE(aidl::android::hardware::audio::effect::Parameter::Specific, tag, \
+ UNION_MAKE(spec, field, value)))
+
+#define MAKE_SPECIFIC_PARAMETER_ID(spec, tag, field) \
+ UNION_MAKE(aidl::android::hardware::audio::effect::Parameter::Id, tag, \
+ UNION_MAKE(spec::Id, commonTag, spec::field))
ConversionResult<uint32_t> aidl2legacy_Flags_Type_uint32(
::aidl::android::hardware::audio::effect::Flags::Type type);
@@ -67,16 +91,40 @@
ConversionResult<media::audio::common::AudioConfigBase> legacy2aidl_buffer_config_t_AudioConfigBase(
const buffer_config_t& legacy, bool isInput);
-ConversionResult<uint32_t> aidl2legacy_Parameter_uint32_echoDelay(
+ConversionResult<uint32_t> aidl2legacy_Parameter_aec_uint32_echoDelay(
const ::aidl::android::hardware::audio::effect::Parameter& aidl);
ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
-legacy2aidl_uint32_echoDelay_Parameter(const uint32_t& legacy);
+legacy2aidl_uint32_echoDelay_Parameter_aec(uint32_t legacy);
-ConversionResult<uint32_t> aidl2legacy_Parameter_uint32_mobileMode(
+ConversionResult<uint32_t> aidl2legacy_Parameter_aec_uint32_mobileMode(
const ::aidl::android::hardware::audio::effect::Parameter& aidl);
ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
-legacy2aidl_uint32_mobileMode_Parameter(const uint32_t& legacy);
+legacy2aidl_uint32_mobileMode_Parameter_aec(uint32_t legacy);
+ConversionResult<uint32_t> aidl2legacy_Parameter_agc_uint32_fixedDigitalGain(
+ const ::aidl::android::hardware::audio::effect::Parameter& aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
+legacy2aidl_uint32_fixedDigitalGain_Parameter_agc(uint32_t legacy);
+
+ConversionResult<uint32_t> aidl2legacy_Parameter_agc_uint32_levelEstimator(
+ const ::aidl::android::hardware::audio::effect::Parameter& aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
+legacy2aidl_uint32_levelEstimator_Parameter_agc(uint32_t legacy);
+
+ConversionResult<uint32_t> aidl2legacy_Parameter_agc_uint32_saturationMargin(
+ const ::aidl::android::hardware::audio::effect::Parameter& aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
+legacy2aidl_uint32_saturationMargin_Parameter_agc(uint32_t legacy);
+
+ConversionResult<uint16_t> aidl2legacy_Parameter_BassBoost_uint16_strengthPm(
+ const ::aidl::android::hardware::audio::effect::Parameter& aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
+legacy2aidl_uint16_strengthPm_Parameter_BassBoost(uint16_t legacy);
+
+ConversionResult<int16_t> aidl2legacy_Parameter_Downmix_int16_type(
+ const ::aidl::android::hardware::audio::effect::Parameter& aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
+legacy2aidl_int16_type_Parameter_Downmix(int16_t legacy);
} // namespace android
} // namespace aidl
diff --git a/media/audioaidlconversion/include/media/AidlConversionUtil.h b/media/audioaidlconversion/include/media/AidlConversionUtil.h
index a0830fc..8b2e0de 100644
--- a/media/audioaidlconversion/include/media/AidlConversionUtil.h
+++ b/media/audioaidlconversion/include/media/AidlConversionUtil.h
@@ -278,6 +278,8 @@
#define UNION_SET(u, field, value) \
(u).set<std::decay_t<decltype(u)>::Tag::field>(value)
+#define UNION_MAKE(u, field, value) u::make<u::Tag::field>(value)
+
namespace aidl_utils {
/**
diff --git a/media/libaudiohal/impl/EffectConversionHelperAidl.cpp b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
index 493d1ee..ec8abd7 100644
--- a/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
+++ b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
@@ -16,12 +16,27 @@
#include <cstdint>
#include <cstring>
+#include <optional>
#define LOG_TAG "EffectConversionHelperAidl"
//#define LOG_NDEBUG 0
#include <error/expected_utils.h>
#include <media/audiohal/AudioEffectUuid.h>
-#include <system/audio_effects/audio_effects_utils.h>
+#include <system/audio_effects/effect_aec.h>
+#include <system/audio_effects/effect_agc2.h>
+#include <system/audio_effects/effect_bassboost.h>
+#include <system/audio_effects/effect_downmix.h>
+#include <system/audio_effects/effect_dynamicsprocessing.h>
+#include <system/audio_effects/effect_environmentalreverb.h>
+#include <system/audio_effects/effect_equalizer.h>
+#include <system/audio_effects/effect_hapticgenerator.h>
+#include <system/audio_effects/effect_loudnessenhancer.h>
+#include <system/audio_effects/effect_ns.h>
+#include <system/audio_effects/effect_presetreverb.h>
+#include <system/audio_effects/effect_spatializer.h>
+#include <system/audio_effects/effect_virtualizer.h>
+#include <system/audio_effects/effect_visualizer.h>
+
#include <utils/Log.h>
#include "EffectConversionHelperAidl.h"
@@ -31,10 +46,16 @@
using ::aidl::android::aidl_utils::statusTFromBinderStatus;
using ::aidl::android::hardware::audio::effect::AcousticEchoCanceler;
+using ::aidl::android::hardware::audio::effect::AutomaticGainControl;
+using ::aidl::android::hardware::audio::effect::BassBoost;
using ::aidl::android::hardware::audio::effect::CommandId;
+using ::aidl::android::hardware::audio::effect::Descriptor;
+using ::aidl::android::hardware::audio::effect::Downmix;
using ::aidl::android::hardware::audio::effect::Parameter;
using ::aidl::android::media::audio::common::AudioDeviceDescription;
using ::aidl::android::media::audio::common::AudioUuid;
+using android::effect::utils::EffectParamReader;
+using android::effect::utils::EffectParamWriter;
using ::android::status_t;
@@ -59,8 +80,26 @@
EffectConversionHelperAidl::mParameterHandlerMap = {
{kAcousticEchoCancelerTypeUUID,
{&EffectConversionHelperAidl::setAecParameter,
- &EffectConversionHelperAidl::getAecParameter}}};
+ &EffectConversionHelperAidl::getAecParameter}},
+ {kAutomaticGainControlTypeUUID,
+ {&EffectConversionHelperAidl::setAgcParameter,
+ &EffectConversionHelperAidl::getAgcParameter}},
+ {kBassBoostTypeUUID,
+ {&EffectConversionHelperAidl::setBassBoostParameter,
+ &EffectConversionHelperAidl::getBassBoostParameter}},
+ {kDownmixTypeUUID,
+ {&EffectConversionHelperAidl::setDownmixParameter,
+ &EffectConversionHelperAidl::getDownmixParameter}}};
+EffectConversionHelperAidl::EffectConversionHelperAidl(
+ std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> effect,
+ int32_t sessionId, int32_t ioId,
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc)
+ : mSessionId(sessionId), mIoId(ioId), mDesc(desc), mEffect(std::move(effect)) {
+ mCommon.session = sessionId;
+ mCommon.ioHandle = ioId;
+ mCommon.input = mCommon.output = kDefaultAudioConfig;
+}
status_t EffectConversionHelperAidl::handleCommand(uint32_t cmdCode, uint32_t cmdSize,
void* pCmdData, uint32_t* replySize,
@@ -80,84 +119,87 @@
return BAD_VALUE;
}
- return *(status_t*)pReplyData = OK;
+ return *(status_t*)pReplyData =
+ statusTFromBinderStatus(mEffect->open(mCommon, std::nullopt, &mOpenReturn));
}
status_t EffectConversionHelperAidl::handleSetParameter(uint32_t cmdSize, const void* pCmdData,
uint32_t* replySize, void* pReplyData) {
- if (cmdSize < kEffectParamSize || !pCmdData || !replySize || *replySize < sizeof(int) ||
- !pReplyData) {
+ if (cmdSize < sizeof(effect_param_t) || !pCmdData || !replySize ||
+ *replySize < sizeof(int) || !pReplyData) {
return BAD_VALUE;
}
- const effect_param_t* param = (effect_param_t*)pCmdData;
- if (!validateCommandSize(*param, cmdSize)) {
- ALOGE("%s illegal param %s size %u", __func__, utils::toString(*param).c_str(), cmdSize);
+ auto reader = EffectParamReader(*(effect_param_t*)pCmdData);
+ if (!reader.validateCmdSize(cmdSize)) {
+ ALOGE("%s illegal param %s size %u", __func__, reader.toString().c_str(), cmdSize);
return BAD_VALUE;
}
- const auto& handler = mParameterHandlerMap.find(mTypeUuid);
+ const auto& handler = mParameterHandlerMap.find(mDesc.common.id.type);
if (handler == mParameterHandlerMap.end() || !handler->second.first) {
- ALOGE("%s handler for uuid %s not found", __func__, mTypeUuid.toString().c_str());
+ ALOGE("%s handler for uuid %s not found", __func__,
+ mDesc.common.id.type.toString().c_str());
return BAD_VALUE;
}
const SetParameter& functor = handler->second.first;
- return *(status_t*)pReplyData = (this->*functor)(*(const effect_param_t*)param);
+ return *(status_t*)pReplyData = (this->*functor)(reader);
}
status_t EffectConversionHelperAidl::handleGetParameter(uint32_t cmdSize, const void* pCmdData,
uint32_t* replySize, void* pReplyData) {
- if (cmdSize < kEffectParamSize || !pCmdData || !replySize || !pReplyData) {
+ if (cmdSize < sizeof(effect_param_t) || !pCmdData || !replySize || !pReplyData) {
return BAD_VALUE;
}
- const effect_param_t* param = (effect_param_t*)pCmdData;
- if (!validateCommandSize(*param, *replySize)) {
- ALOGE("%s illegal param %s, replysize %u", __func__, utils::toString(*param).c_str(),
+ const auto reader = EffectParamReader(*(effect_param_t*)pCmdData);
+ if (!reader.validateCmdSize(cmdSize)) {
+ ALOGE("%s illegal param %s, replysize %u", __func__, reader.toString().c_str(),
*replySize);
return BAD_VALUE;
}
- const auto& handler = mParameterHandlerMap.find(mTypeUuid);
+ const auto& handler = mParameterHandlerMap.find(mDesc.common.id.type);
if (handler == mParameterHandlerMap.end() || !handler->second.second) {
- ALOGE("%s handler for uuid %s not found", __func__, mTypeUuid.toString().c_str());
+ ALOGE("%s handler for uuid %s not found", __func__,
+ mDesc.common.id.type.toString().c_str());
return BAD_VALUE;
}
const GetParameter& functor = handler->second.second;
- memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + param->psize);
- effect_param_t* reply = (effect_param_t *)pReplyData;
- (this->*functor)(*reply);
- *replySize = kEffectParamSize + padding(reply->psize) + reply->vsize;
- return reply->status;
+ memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + reader.getParameterSize());
+ auto writer = EffectParamWriter(*(effect_param_t *)pReplyData);
+ (this->*functor)(writer);
+ *replySize = writer.getTotalSize();
+ return writer.getStatus();
}
status_t EffectConversionHelperAidl::handleSetConfig(uint32_t cmdSize, const void* pCmdData,
uint32_t* replySize, void* pReplyData) {
- if (!replySize || *replySize != sizeof(int) || !pReplyData || cmdSize != kEffectConfigSize) {
+ if (!replySize || *replySize != sizeof(int) || !pReplyData ||
+ cmdSize != sizeof(effect_config_t)) {
return BAD_VALUE;
}
const auto& legacyConfig = static_cast<const effect_config_t*>(pCmdData);
// already open, apply latest settings
- Parameter::Common common;
- common.input.base =
+ mCommon.input.base =
VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_buffer_config_t_AudioConfigBase(
legacyConfig->inputCfg, true /* isInput */));
- common.output.base =
+ mCommon.output.base =
VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_buffer_config_t_AudioConfigBase(
legacyConfig->outputCfg, false /* isInput */));
- common.session = mSessionId;
- common.ioHandle = mIoId;
+ mCommon.session = mSessionId;
+ mCommon.ioHandle = mIoId;
// TODO: add access mode support
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
- mEffect->setParameter(Parameter::make<Parameter::common>(common))));
+ mEffect->setParameter(Parameter::make<Parameter::common>(mCommon))));
return *static_cast<int32_t*>(pReplyData) = OK;
}
status_t EffectConversionHelperAidl::handleGetConfig(uint32_t cmdSize __unused,
const void* pCmdData __unused,
uint32_t* replySize, void* pReplyData) {
- if (!replySize || *replySize != kEffectConfigSize || !pReplyData) {
+ if (!replySize || *replySize != sizeof(effect_config_t) || !pReplyData) {
ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
return BAD_VALUE;
}
@@ -179,43 +221,40 @@
status_t EffectConversionHelperAidl::handleReset(uint32_t cmdSize __unused,
const void* pCmdData __unused, uint32_t* replySize,
void* pReplyData) {
- if (!replySize || *replySize != kEffectConfigSize || !pReplyData) {
+ if (!replySize || *replySize != sizeof(effect_config_t) || !pReplyData) {
ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
return BAD_VALUE;
}
- RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->command(CommandId::RESET)));
- return OK;
+ return statusTFromBinderStatus(mEffect->command(CommandId::RESET));
}
status_t EffectConversionHelperAidl::handleEnable(uint32_t cmdSize __unused,
const void* pCmdData __unused, uint32_t* replySize,
void* pReplyData) {
- if (!replySize || *replySize != kEffectConfigSize || !pReplyData) {
+ if (!replySize || *replySize != sizeof(effect_config_t) || !pReplyData) {
ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
return BAD_VALUE;
}
- RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->command(CommandId::START)));
- return OK;
+ return statusTFromBinderStatus(mEffect->command(CommandId::START));
}
status_t EffectConversionHelperAidl::handleDisable(uint32_t cmdSize __unused,
const void* pCmdData __unused,
uint32_t* replySize, void* pReplyData) {
- if (!replySize || *replySize != kEffectConfigSize || !pReplyData) {
+ if (!replySize || *replySize != sizeof(effect_config_t) || !pReplyData) {
ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
return BAD_VALUE;
}
- RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->command(CommandId::STOP)));
- return OK;
+ return statusTFromBinderStatus(mEffect->command(CommandId::STOP));
}
status_t EffectConversionHelperAidl::handleSetDevice(uint32_t cmdSize, const void* pCmdData,
uint32_t* replySize, void* pReplyData) {
- if (cmdSize != sizeof(uint32_t) || !pCmdData || !replySize || *replySize != kEffectConfigSize ||
- !pReplyData) {
+ if (cmdSize != sizeof(uint32_t) || !pCmdData || !replySize ||
+ *replySize != sizeof(effect_config_t) || !pReplyData) {
ALOGE("%s parameter invalid %u %p %p %p", __func__, cmdSize, pCmdData, replySize,
pReplyData);
return BAD_VALUE;
@@ -231,7 +270,7 @@
status_t EffectConversionHelperAidl::handleSetVolume(uint32_t cmdSize, const void* pCmdData,
uint32_t* replySize, void* pReplyData) {
if (cmdSize != 2 * sizeof(uint32_t) || !pCmdData || !replySize ||
- *replySize != kEffectConfigSize || !pReplyData) {
+ *replySize != sizeof(effect_config_t) || !pReplyData) {
ALOGE("%s parameter invalid %u %p %p %p", __func__, cmdSize, pCmdData, replySize,
pReplyData);
return BAD_VALUE;
@@ -246,7 +285,7 @@
status_t EffectConversionHelperAidl::handleSetOffload(uint32_t cmdSize, const void* pCmdData,
uint32_t* replySize, void* pReplyData) {
if (cmdSize < sizeof(effect_offload_param_t) || !pCmdData || !replySize ||
- *replySize != kEffectConfigSize || !pReplyData) {
+ *replySize != sizeof(effect_config_t) || !pReplyData) {
ALOGE("%s parameter invalid %u %p %p %p", __func__, cmdSize, pCmdData, replySize,
pReplyData);
return BAD_VALUE;
@@ -258,87 +297,270 @@
status_t EffectConversionHelperAidl::handleFirstPriority(uint32_t cmdSize __unused,
const void* pCmdData __unused,
uint32_t* replySize, void* pReplyData) {
- if (!replySize || *replySize != kEffectConfigSize || !pReplyData) {
+ if (!replySize || *replySize != sizeof(effect_config_t) || !pReplyData) {
ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
return BAD_VALUE;
}
- // TODO
+ // TODO to be implemented
return OK;
}
-status_t EffectConversionHelperAidl::setAecParameter(const effect_param_t& param) {
- const auto psize = sizeof(uint32_t);
- const auto vsize = sizeof(uint32_t);
- if (!validatePVsize(param, psize, vsize)) {
+status_t EffectConversionHelperAidl::setAecParameter(EffectParamReader& param) {
+ uint32_t type, value = 0;
+ if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
+ OK != param.readFromParameter(&type) ||
+ OK != param.readFromValue(&value)) {
+ ALOGW("%s invalid param %s", __func__, param.toString().c_str());
return BAD_VALUE;
}
- const auto& type = *(uint32_t*)param.data;
- const auto& value = *(uint32_t*)(param.data + psize);
Parameter aidlParam;
switch (type) {
case AEC_PARAM_ECHO_DELAY:
FALLTHROUGH_INTENDED;
case AEC_PARAM_PROPERTIES: {
aidlParam = VALUE_OR_RETURN_STATUS(
- aidl::android::legacy2aidl_uint32_echoDelay_Parameter(value));
+ aidl::android::legacy2aidl_uint32_echoDelay_Parameter_aec(value));
break;
}
case AEC_PARAM_MOBILE_MODE: {
aidlParam = VALUE_OR_RETURN_STATUS(
- aidl::android::legacy2aidl_uint32_mobileMode_Parameter(value));
+ aidl::android::legacy2aidl_uint32_mobileMode_Parameter_aec(value));
break;
}
default: {
- ALOGW("%s unknown param %08x value %08x", __func__, type, value);
+ ALOGW("%s unknown param %s", __func__, param.toString().c_str());
return BAD_VALUE;
}
}
- return mEffect->setParameter(aidlParam).getStatus();
+ return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
}
-status_t EffectConversionHelperAidl::getAecParameter(effect_param_t& param) {
- const auto psize = sizeof(uint32_t);
- const auto vsize = sizeof(uint32_t);
- if (!validatePVsize(param, psize, vsize)) {
- return param.status = BAD_VALUE;
+status_t EffectConversionHelperAidl::getAecParameter(EffectParamWriter& param) {
+ uint32_t type = 0, value = 0;
+ if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
+ OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
+ param.setStatus(BAD_VALUE);
+ ALOGW("%s invalid param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
}
-
- uint32_t value = 0;
- status_t status = BAD_VALUE;
- const auto& type = *(uint32_t*)param.data;
+ Parameter aidlParam;
switch (type) {
case AEC_PARAM_ECHO_DELAY:
FALLTHROUGH_INTENDED;
case AEC_PARAM_PROPERTIES: {
- Parameter aidlParam;
- Parameter::Id id = Parameter::Id::make<Parameter::Id::acousticEchoCancelerTag>(
- AcousticEchoCanceler::Id::make<AcousticEchoCanceler::Id::commonTag>(
- AcousticEchoCanceler::echoDelayUs));
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(AcousticEchoCanceler,
+ acousticEchoCancelerTag, echoDelayUs);
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
value = VALUE_OR_RETURN_STATUS(
- aidl::android::aidl2legacy_Parameter_uint32_echoDelay(aidlParam));
+ aidl::android::aidl2legacy_Parameter_aec_uint32_echoDelay(aidlParam));
break;
}
case AEC_PARAM_MOBILE_MODE: {
- Parameter aidlParam;
- Parameter::Id id = Parameter::Id::make<Parameter::Id::acousticEchoCancelerTag>(
- AcousticEchoCanceler::Id::make<AcousticEchoCanceler::Id::commonTag>(
- AcousticEchoCanceler::mobileMode));
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(AcousticEchoCanceler,
+ acousticEchoCancelerTag, mobileMode);
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
value = VALUE_OR_RETURN_STATUS(
- aidl::android::aidl2legacy_Parameter_uint32_mobileMode(aidlParam));
+ aidl::android::aidl2legacy_Parameter_aec_uint32_mobileMode(aidlParam));
break;
}
default:
- ALOGW("%s unknown param %08x", __func__, type);
+ ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ param.writeToValue(&value);
+ return OK;
+}
+
+status_t EffectConversionHelperAidl::setAgcParameter(EffectParamReader& param) {
+ uint32_t type = 0, value = 0;
+ if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
+ OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
+ ALOGW("%s invalid param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ Parameter aidlParam;
+ switch (type) {
+ case AGC2_PARAM_FIXED_DIGITAL_GAIN: {
+ aidlParam = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_uint32_fixedDigitalGain_Parameter_agc(value));
break;
+ }
+ case AGC2_PARAM_ADAPT_DIGI_LEVEL_ESTIMATOR: {
+ aidlParam = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_uint32_levelEstimator_Parameter_agc(value));
+ break;
+ }
+ case AGC2_PARAM_ADAPT_DIGI_EXTRA_SATURATION_MARGIN: {
+ aidlParam = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_uint32_saturationMargin_Parameter_agc(value));
+ break;
+ }
+ default: {
+ ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
}
- *(uint32_t*)(param.data + psize) = value;
- return param.status = status;
+ return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
+}
+
+status_t EffectConversionHelperAidl::getAgcParameter(EffectParamWriter& param) {
+ uint32_t type = 0, value = 0;
+ if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
+ OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
+ ALOGW("%s invalid param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ Parameter aidlParam;
+ switch (type) {
+ case AGC2_PARAM_FIXED_DIGITAL_GAIN: {
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(
+ AutomaticGainControl, automaticGainControlTag, fixedDigitalGainMb);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ value = VALUE_OR_RETURN_STATUS(
+ aidl::android::aidl2legacy_Parameter_agc_uint32_fixedDigitalGain(aidlParam));
+ break;
+ }
+ case AGC2_PARAM_ADAPT_DIGI_LEVEL_ESTIMATOR: {
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(AutomaticGainControl,
+ automaticGainControlTag, levelEstimator);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ value = VALUE_OR_RETURN_STATUS(
+ aidl::android::aidl2legacy_Parameter_agc_uint32_levelEstimator(aidlParam));
+ break;
+ }
+ case AGC2_PARAM_ADAPT_DIGI_EXTRA_SATURATION_MARGIN: {
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(
+ AutomaticGainControl, automaticGainControlTag, saturationMarginMb);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ value = VALUE_OR_RETURN_STATUS(
+ aidl::android::aidl2legacy_Parameter_agc_uint32_saturationMargin(aidlParam));
+ break;
+ }
+ default: {
+ ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ }
+
+ param.writeToValue(&value);
+ return OK;
+}
+
+status_t EffectConversionHelperAidl::setBassBoostParameter(EffectParamReader& param) {
+ uint32_t type = 0;
+ uint16_t value = 0;
+ if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint16_t)) ||
+ OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
+ ALOGW("%s invalid param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ Parameter aidlParam;
+ switch (type) {
+ case BASSBOOST_PARAM_STRENGTH: {
+ aidlParam = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_uint16_strengthPm_Parameter_BassBoost(value));
+ break;
+ }
+ case BASSBOOST_PARAM_STRENGTH_SUPPORTED: {
+ ALOGW("%s set BASSBOOST_PARAM_STRENGTH_SUPPORTED not supported", __func__);
+ return BAD_VALUE;
+ }
+ default: {
+ ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ }
+
+ return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
+}
+
+status_t EffectConversionHelperAidl::getBassBoostParameter(EffectParamWriter& param) {
+ uint32_t type = 0, value = 0;
+ if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
+ OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
+ ALOGW("%s invalid param %s", __func__, param.toString().c_str());
+ param.setStatus(BAD_VALUE);
+ return BAD_VALUE;
+ }
+ Parameter aidlParam;
+ switch (type) {
+ case BASSBOOST_PARAM_STRENGTH: {
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(BassBoost, bassBoostTag, strengthPm);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ value = VALUE_OR_RETURN_STATUS(
+ aidl::android::aidl2legacy_Parameter_BassBoost_uint16_strengthPm(aidlParam));
+ break;
+ }
+ case BASSBOOST_PARAM_STRENGTH_SUPPORTED: {
+ const auto& cap =
+ VALUE_OR_RETURN_STATUS(aidl::android::UNION_GET(mDesc.capability, bassBoost));
+ value = VALUE_OR_RETURN_STATUS(
+ aidl::android::convertIntegral<uint32_t>(cap.strengthSupported));
+ break;
+ }
+ default: {
+ ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ }
+
+ param.writeToValue(&value);
+ return OK;
+}
+
+status_t EffectConversionHelperAidl::setDownmixParameter(EffectParamReader& param) {
+ uint32_t type = 0;
+ int16_t value = 0;
+ if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(int16_t)) ||
+ OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
+ ALOGW("%s invalid param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ Parameter aidlParam;
+ switch (type) {
+ case DOWNMIX_PARAM_TYPE: {
+ aidlParam = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_int16_type_Parameter_Downmix(value));
+ break;
+ }
+ default: {
+ ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ }
+
+ return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
+}
+
+status_t EffectConversionHelperAidl::getDownmixParameter(EffectParamWriter& param) {
+ int16_t value = 0;
+ uint32_t type = 0;
+ if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint16_t)) ||
+ OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
+ param.setStatus(BAD_VALUE);
+ return BAD_VALUE;
+ }
+ Parameter aidlParam;
+ switch (type) {
+ case DOWNMIX_PARAM_TYPE: {
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(Downmix, downmixTag, type);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ value = VALUE_OR_RETURN_STATUS(
+ aidl::android::aidl2legacy_Parameter_Downmix_int16_type(aidlParam));
+ break;
+ }
+ default: {
+ ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ }
+
+ param.writeToValue(&value);
+ return OK;
}
} // namespace effect
diff --git a/media/libaudiohal/impl/EffectConversionHelperAidl.h b/media/libaudiohal/impl/EffectConversionHelperAidl.h
index 5d7c1d6..35249f5 100644
--- a/media/libaudiohal/impl/EffectConversionHelperAidl.h
+++ b/media/libaudiohal/impl/EffectConversionHelperAidl.h
@@ -25,28 +25,17 @@
#include <media/AidlConversionNdk.h>
#include <system/audio_effect.h>
-#include <system/audio_effects/effect_aec.h>
-#include <system/audio_effects/effect_downmix.h>
-#include <system/audio_effects/effect_dynamicsprocessing.h>
-#include <system/audio_effects/effect_hapticgenerator.h>
-#include <system/audio_effects/effect_ns.h>
-#include <system/audio_effects/effect_visualizer.h>
+#include <system/audio_effects/audio_effects_utils.h>
namespace android {
namespace effect {
-static const size_t kEffectParamSize = sizeof(effect_param_t);
-static const size_t kEffectConfigSize = sizeof(effect_config_t);
-
class EffectConversionHelperAidl {
protected:
EffectConversionHelperAidl(
std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> effect,
- int32_t sessionId, int32_t ioId, ::aidl::android::media::audio::common::AudioUuid uuid)
- : mSessionId(sessionId),
- mIoId(ioId),
- mTypeUuid(std::move(uuid)),
- mEffect(std::move(effect)) {}
+ int32_t sessionId, int32_t ioId,
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc);
status_t handleCommand(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData, uint32_t* replySize,
void* pReplyData);
@@ -54,9 +43,25 @@
private:
const int32_t mSessionId;
const int32_t mIoId;
+ const ::aidl::android::hardware::audio::effect::Descriptor mDesc;
::aidl::android::media::audio::common::AudioUuid mTypeUuid;
const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> mEffect;
+ ::aidl::android::hardware::audio::effect::IEffect::OpenEffectReturn mOpenReturn;
+ ::aidl::android::hardware::audio::effect::Parameter::Common mCommon;
+ const aidl::android::media::audio::common::AudioFormatDescription kDefaultFormatDescription = {
+ .type = aidl::android::media::audio::common::AudioFormatType::PCM,
+ .pcm = aidl::android::media::audio::common::PcmType::FLOAT_32_BIT};
+
+ static constexpr int kDefaultframeCount = 0x100;
+
+ using AudioChannelLayout = aidl::android::media::audio::common::AudioChannelLayout;
+ const aidl::android::media::audio::common::AudioConfig kDefaultAudioConfig = {
+ .base = {.sampleRate = 44100,
+ .channelMask = AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
+ AudioChannelLayout::LAYOUT_STEREO),
+ .format = kDefaultFormatDescription},
+ .frameCount = kDefaultframeCount};
// command handler map
typedef status_t (EffectConversionHelperAidl::*CommandHandler)(uint32_t /* cmdSize */,
const void* /* pCmdData */,
@@ -65,23 +70,14 @@
static const std::map<uint32_t /* effect_command_e */, CommandHandler> mCommandHandlerMap;
// parameter set/get handler map
- typedef status_t (EffectConversionHelperAidl::*SetParameter)(const effect_param_t& param);
- typedef status_t (EffectConversionHelperAidl::*GetParameter)(effect_param_t& param);
+ typedef status_t (EffectConversionHelperAidl::*SetParameter)(
+ android::effect::utils::EffectParamReader& param);
+ typedef status_t (EffectConversionHelperAidl::*GetParameter)(
+ android::effect::utils::EffectParamWriter& param);
static const std::map<::aidl::android::media::audio::common::AudioUuid /* TypeUUID */,
std::pair<SetParameter, GetParameter>>
mParameterHandlerMap;
- // align to 32 bit boundary
- static constexpr size_t padding(size_t size) {
- return ((size - 1) / sizeof(int) + 1) * sizeof(int);
- }
- static constexpr bool validatePVsize(const effect_param_t& param, size_t p, size_t v) {
- return padding(param.psize) == p && param.vsize == v;
- }
- static constexpr bool validateCommandSize(const effect_param_t& param, size_t size) {
- return padding(param.psize) + param.vsize + kEffectParamSize <= size;
- }
-
status_t handleInit(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
void* pReplyData);
status_t handleSetParameter(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
@@ -107,9 +103,15 @@
status_t handleFirstPriority(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
void* pReplyData);
- // AEC parameter handler
- status_t setAecParameter(const effect_param_t& param);
- status_t getAecParameter(effect_param_t& param);
+ // set/get parameter handler
+ status_t setAecParameter(android::effect::utils::EffectParamReader& param);
+ status_t getAecParameter(android::effect::utils::EffectParamWriter& param);
+ status_t setAgcParameter(android::effect::utils::EffectParamReader& param);
+ status_t getAgcParameter(android::effect::utils::EffectParamWriter& param);
+ status_t setBassBoostParameter(android::effect::utils::EffectParamReader& param);
+ status_t getBassBoostParameter(android::effect::utils::EffectParamWriter& param);
+ status_t setDownmixParameter(android::effect::utils::EffectParamReader& param);
+ status_t getDownmixParameter(android::effect::utils::EffectParamWriter& param);
};
} // namespace effect
diff --git a/media/libaudiohal/impl/EffectHalAidl.cpp b/media/libaudiohal/impl/EffectHalAidl.cpp
index 3346459..0c37552 100644
--- a/media/libaudiohal/impl/EffectHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectHalAidl.cpp
@@ -42,21 +42,30 @@
using ::aidl::android::hardware::audio::effect::CommandId;
using ::aidl::android::hardware::audio::effect::Descriptor;
using ::aidl::android::hardware::audio::effect::IEffect;
+using ::aidl::android::hardware::audio::effect::IFactory;
using ::aidl::android::hardware::audio::effect::Parameter;
namespace android {
namespace effect {
-EffectHalAidl::EffectHalAidl(const std::shared_ptr<IEffect>& effect, uint64_t effectId,
- int32_t sessionId, int32_t ioId, const Descriptor& desc)
- : EffectConversionHelperAidl(effect, sessionId, ioId, desc.common.id.type),
+EffectHalAidl::EffectHalAidl(
+ const std::shared_ptr<::aidl::android::hardware::audio::effect::IFactory>& factory,
+ const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& effect,
+ uint64_t effectId, int32_t sessionId, int32_t ioId,
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc)
+ : EffectConversionHelperAidl(effect, sessionId, ioId, desc),
+ mFactory(factory),
+ mEffect(effect),
mEffectId(effectId),
mSessionId(sessionId),
mIoId(ioId),
- mEffect(effect),
mDesc(desc) {}
-EffectHalAidl::~EffectHalAidl() {}
+EffectHalAidl::~EffectHalAidl() {
+ if (mFactory) {
+ mFactory->destroyEffect(mEffect);
+ }
+}
status_t EffectHalAidl::setInBuffer(const sp<EffectBufferHalInterface>& buffer) {
if (buffer == nullptr) {
@@ -105,8 +114,7 @@
}
status_t EffectHalAidl::close() {
- RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->close()));
- return OK;
+ return statusTFromBinderStatus(mEffect->close());
}
status_t EffectHalAidl::dump(int fd) {
diff --git a/media/libaudiohal/impl/EffectHalAidl.h b/media/libaudiohal/impl/EffectHalAidl.h
index 1ba262c..6a1ec1c 100644
--- a/media/libaudiohal/impl/EffectHalAidl.h
+++ b/media/libaudiohal/impl/EffectHalAidl.h
@@ -17,6 +17,7 @@
#pragma once
#include <aidl/android/hardware/audio/effect/IEffect.h>
+#include <aidl/android/hardware/audio/effect/IFactory.h>
#include <media/audiohal/EffectHalInterface.h>
#include <system/audio_effect.h>
@@ -64,19 +65,22 @@
private:
friend class sp<EffectHalAidl>;
+ const std::shared_ptr<::aidl::android::hardware::audio::effect::IFactory> mFactory;
+ const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> mEffect;
const uint64_t mEffectId;
const int32_t mSessionId;
const int32_t mIoId;
- const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> mEffect;
const ::aidl::android::hardware::audio::effect::Descriptor mDesc;
sp<EffectBufferHalInterface> mInBuffer, mOutBuffer;
effect_config_t mConfig;
// Can not be constructed directly by clients.
- EffectHalAidl(const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& effect,
- uint64_t effectId, int32_t sessionId, int32_t ioId,
- const ::aidl::android::hardware::audio::effect::Descriptor& desc);
+ EffectHalAidl(
+ const std::shared_ptr<::aidl::android::hardware::audio::effect::IFactory>& factory,
+ const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& effect,
+ uint64_t effectId, int32_t sessionId, int32_t ioId,
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc);
bool setEffectReverse(bool reverse);
// The destructor automatically releases the effect.
diff --git a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
index 96ea861..878c19e 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
@@ -134,7 +134,7 @@
effectId = ++mEffectIdCounter;
}
- *effect = sp<EffectHalAidl>::make(aidlEffect, effectId, sessionId, ioId, desc);
+ *effect = sp<EffectHalAidl>::make(mFactory, aidlEffect, effectId, sessionId, ioId, desc);
return OK;
}
diff --git a/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp b/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp
index 83c7809..c2e2ba7 100644
--- a/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp
+++ b/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp
@@ -20,11 +20,17 @@
#include <media/audiohal/EffectsFactoryHalInterface.h>
+#include <system/audio_effects/audio_effects_utils.h>
+#include <system/audio_effects/effect_aec.h>
+#include <system/audio_effect.h>
+
#include <gtest/gtest.h>
#include <utils/RefBase.h>
namespace android {
+using effect::utils::EffectParamWriter;
+
// EffectsFactoryHalInterface
TEST(libAudioHalTest, createEffectsFactoryHalInterface) {
ASSERT_NE(nullptr, EffectsFactoryHalInterface::create());
@@ -78,6 +84,81 @@
EXPECT_NE(0, version.getMajorVersion());
}
+static char testDataBuffer[sizeof(effect_param_t) + 0xff] = {};
+static char testResponseBuffer[sizeof(effect_param_t) + 0xff] = {};
+TEST(libAudioHalTest, agcNotInit) {
+ auto factory = EffectsFactoryHalInterface::create();
+ ASSERT_NE(nullptr, factory);
+
+ std::vector<effect_descriptor_t> descs;
+ EXPECT_EQ(OK, factory->getDescriptors(&FX_IID_AEC_, &descs));
+ for (const auto& desc : descs) {
+ ASSERT_EQ(0, std::memcmp(&desc.type, &FX_IID_AEC_, sizeof(FX_IID_AEC_)));
+ sp<EffectHalInterface> interface;
+ EXPECT_EQ(OK, factory->createEffect(&desc.uuid, 1 /* sessionId */, 1 /* ioId */,
+ 1 /* deviceId */, &interface));
+ EXPECT_NE(nullptr, interface);
+ effect_param_t* param = (effect_param_t*)testDataBuffer;
+ uint32_t type = AEC_PARAM_ECHO_DELAY, value = 0xbead;
+ param->psize = sizeof(type);
+ param->vsize = sizeof(value);
+ //EXPECT_EQ(1, 0) << param->psize << " " << param->vsize;
+ EffectParamWriter writer(*param);
+ EXPECT_EQ(OK, writer.writeToParameter(&type)) << writer.toString();
+ EXPECT_EQ(OK, writer.writeToValue(&value)) << writer.toString();
+ status_t reply = 0;
+ uint32_t replySize = sizeof(reply);
+ EXPECT_NE(OK, interface->command(EFFECT_CMD_SET_PARAM, (uint32_t)writer.getTotalSize(),
+ param, &replySize, &reply));
+ EXPECT_EQ(replySize, sizeof(reply));
+ EXPECT_NE(OK, reply);
+ }
+}
+
+// TODO: rethink about this test case to make it general for all types of effects
+TEST(libAudioHalTest, aecInitSetAndGet) {
+ auto factory = EffectsFactoryHalInterface::create();
+ ASSERT_NE(nullptr, factory);
+
+ std::vector<effect_descriptor_t> descs;
+ EXPECT_EQ(OK, factory->getDescriptors(&FX_IID_AEC_, &descs));
+ static constexpr uint32_t delayValue = 0x20;
+ for (const auto& desc : descs) {
+ ASSERT_EQ(0, std::memcmp(&desc.type, &FX_IID_AEC_, sizeof(FX_IID_AEC_)));
+ sp<EffectHalInterface> interface;
+ EXPECT_EQ(OK, factory->createEffect(&desc.uuid, 1 /* sessionId */, 1 /* ioId */,
+ 1 /* deviceId */, &interface));
+ EXPECT_NE(nullptr, interface);
+ effect_param_t* param = (effect_param_t*)testDataBuffer;
+ uint32_t type = AEC_PARAM_ECHO_DELAY, value = delayValue;
+ param->psize = sizeof(type);
+ param->vsize = sizeof(value);
+ //EXPECT_EQ(1, 0) << param->psize << " " << param->vsize;
+ EffectParamWriter writer(*param);
+ EXPECT_EQ(OK, writer.writeToParameter(&type)) << writer.toString();
+ EXPECT_EQ(OK, writer.writeToValue(&value)) << writer.toString();
+ status_t reply = 0;
+ uint32_t replySize = sizeof(reply);
+ EXPECT_EQ(OK, interface->command(EFFECT_CMD_INIT, 0, nullptr, &replySize, &reply));
+ EXPECT_EQ(OK, interface->command(EFFECT_CMD_SET_PARAM, (uint32_t)writer.getTotalSize(),
+ param, &replySize, &reply));
+ EXPECT_EQ(replySize, sizeof(reply));
+ EXPECT_EQ(OK, reply);
+
+ effect_param_t* responseParam = (effect_param_t*)testResponseBuffer;
+ param->psize = sizeof(type);
+ param->vsize = sizeof(value);
+ EffectParamWriter response(*param);
+ EXPECT_EQ(OK, response.writeToParameter(&type)) << response.toString();
+ replySize = response.getTotalSize();
+ EXPECT_EQ(OK, interface->command(EFFECT_CMD_GET_PARAM, (uint32_t)writer.getTotalSize(),
+ param, &replySize, responseParam));
+ EXPECT_EQ(replySize, response.getTotalSize());
+ EXPECT_EQ(OK, response.readFromValue(&value));
+ EXPECT_EQ(delayValue, value);
+ }
+}
+
// TODO: b/263986405 Add multi-thread testing
} // namespace android
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index c0e612d..9837574 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -3535,9 +3535,9 @@
if (result != OK) return result;
#ifdef FLOAT_EFFECT_CHAIN
- buffer = halInBuffer->audioBuffer()->f32;
+ buffer = halInBuffer ? halInBuffer->audioBuffer()->f32 : buffer;
#else
- buffer = halInBuffer->audioBuffer()->s16;
+ buffer = halInBuffer ? halInBuffer->audioBuffer()->s16 : buffer;
#endif
ALOGV("addEffectChain_l() creating new input buffer %p session %d",
buffer, session);
@@ -3566,7 +3566,8 @@
halOutBuffer = halInBuffer;
ALOGV("addEffectChain_l() %p on thread %p for session %d", chain.get(), this, session);
if (!audio_is_global_session(session)) {
- buffer = reinterpret_cast<effect_buffer_t*>(halInBuffer->externalData());
+ buffer = halInBuffer ? reinterpret_cast<effect_buffer_t*>(halInBuffer->externalData())
+ : buffer;
// Only one effect chain can be present in direct output thread and it uses
// the sink buffer as input
if (mType != DIRECT) {
@@ -3578,9 +3579,9 @@
&halInBuffer);
if (result != OK) return result;
#ifdef FLOAT_EFFECT_CHAIN
- buffer = halInBuffer->audioBuffer()->f32;
+ buffer = halInBuffer ? halInBuffer->audioBuffer()->f32 : buffer;
#else
- buffer = halInBuffer->audioBuffer()->s16;
+ buffer = halInBuffer ? halInBuffer->audioBuffer()->s16 : buffer;
#endif
ALOGV("addEffectChain_l() creating new input buffer %p session %d",
buffer, session);