Merge "Effect AIDL: Add back some effect parameters."

This commit is contained in:
Shunkai Yao 2023-02-08 02:42:25 +00:00 committed by Gerrit Code Review
commit 903e6d8264
14 changed files with 208 additions and 18 deletions

View file

@ -37,6 +37,7 @@ union Equalizer {
android.hardware.audio.effect.VendorExtension vendorExtension;
android.hardware.audio.effect.Equalizer.BandLevel[] bandLevels;
int preset;
int[] centerFreqMh;
@VintfStability
union Id {
int vendorExtensionTag;

View file

@ -48,9 +48,9 @@ union HapticGenerator {
}
@Backing(type="int") @VintfStability
enum VibratorScale {
MUTE = (-100),
VERY_LOW = (-2),
LOW = (-1),
MUTE = (-100) /* -100 */,
VERY_LOW = (-2) /* -2 */,
LOW = (-1) /* -1 */,
NONE = 0,
HIGH = 1,
VERY_HIGH = 2,

View file

@ -36,6 +36,7 @@ package android.hardware.audio.effect;
union NoiseSuppression {
android.hardware.audio.effect.VendorExtension vendor;
android.hardware.audio.effect.NoiseSuppression.Level level;
android.hardware.audio.effect.NoiseSuppression.Type type;
@VintfStability
union Id {
int vendorExtensionTag;
@ -52,4 +53,9 @@ union NoiseSuppression {
HIGH,
VERY_HIGH,
}
@Backing(type="int") @VintfStability
enum Type {
SINGLE_CHANNEL,
MULTI_CHANNEL,
}
}

View file

@ -36,10 +36,18 @@ package android.hardware.audio.effect;
union Virtualizer {
android.hardware.audio.effect.VendorExtension vendor;
int strengthPm;
android.hardware.audio.effect.Virtualizer.ChannelAngle[] speakerAngles;
android.media.audio.common.AudioDeviceDescription device;
@VintfStability
union Id {
int vendorExtensionTag;
android.hardware.audio.effect.Virtualizer.Tag commonTag;
android.hardware.audio.effect.Virtualizer.SpeakerAnglesPayload speakerAnglesPayload;
}
@VintfStability
parcelable SpeakerAnglesPayload {
android.media.audio.common.AudioChannelLayout layout;
android.media.audio.common.AudioDeviceDescription device;
}
@VintfStability
parcelable Capability {
@ -47,4 +55,10 @@ union Virtualizer {
int maxStrengthPm;
boolean strengthSupported;
}
@VintfStability
parcelable ChannelAngle {
int channel;
int azimuthDegree;
int elevationDegree;
}
}

View file

@ -72,7 +72,7 @@ union Equalizer {
}
/**
* Supported minimal and maximal frequency for each band in millihertz.
* Supported minimal and maximal frequency for each band in milliHertz.
*/
@VintfStability
parcelable BandFrequency {
@ -97,8 +97,14 @@ union Equalizer {
* Level for each band.
*/
BandLevel[] bandLevels;
/**
* Index of current preset.
*/
int preset;
/**
* Get only parameter, get the center frequency for all bands in milliHertz.
*/
int[] centerFreqMh;
}

View file

@ -68,4 +68,11 @@ union NoiseSuppression {
* The NS level.
*/
Level level;
/**
* Noise suppression type.
*/
@VintfStability @Backing(type="int") enum Type { SINGLE_CHANNEL, MULTI_CHANNEL }
Type type;
}

View file

@ -17,6 +17,8 @@
package android.hardware.audio.effect;
import android.hardware.audio.effect.VendorExtension;
import android.media.audio.common.AudioChannelLayout;
import android.media.audio.common.AudioDeviceDescription;
/**
* Virtualizer specific definitions. An audio virtualizer is a general name for an effect to
@ -35,6 +37,7 @@ union Virtualizer {
union Id {
int vendorExtensionTag;
Virtualizer.Tag commonTag;
SpeakerAnglesPayload speakerAnglesPayload;
}
/**
@ -42,6 +45,25 @@ union Virtualizer {
*/
VendorExtension vendor;
/**
* Payload to query speaker angles for the given channel position mask and device.
* The Virtualizer implementation must return EX_ILLEGAL_ARGUMENT if the given payload not
* supported.
*/
@VintfStability
parcelable SpeakerAnglesPayload {
/**
* Audio channel position definition. See
* android.media.audio.common.AudioChannelLayout.aidl. Only the channel position "CHANNEL_*"
* in AudioChannelLayout be used.
*/
AudioChannelLayout layout;
/**
* Audio device type. See android.media.audio.common.AudioDeviceDescription.aidl.
*/
AudioDeviceDescription device;
}
/**
* Capability supported by Virtualizer implementation.
*/
@ -74,4 +96,39 @@ union Virtualizer {
* the 'maxStrengthPm' capability.
*/
int strengthPm;
/**
* All angles are expressed in degrees and are relative to the listener.
*/
@VintfStability
parcelable ChannelAngle {
/**
* Audio channel layout, CHANNEL_* constants defined in
* android.media.audio.common.AudioChannelLayout.
*/
int channel;
/**
* 0 is the direction the listener faces, 180 is behind the listener, and -90 is left of
* the listener.
*/
int azimuthDegree;
/**
* 0 is the horizontal plane, +90 is above the listener, -90 is below.
*/
int elevationDegree;
}
/**
* Get only parameter.
* A vector of angles per channel represented by azimuth and elevation (in degrees), client must
* set Parameter.Id to SpeakerAnglesPayload to get speakerAngles.
*/
ChannelAngle[] speakerAngles;
/**
* The audio device on which virtualzation mode is forced.
*/
AudioDeviceDescription device;
}

View file

@ -150,6 +150,10 @@ ndk::ScopedAStatus EqualizerSw::getParameterEqualizer(const Equalizer::Tag& tag,
eqParam.set<Equalizer::preset>(mContext->getEqPreset());
break;
}
case Equalizer::centerFreqMh: {
eqParam.set<Equalizer::centerFreqMh>(mContext->getCenterFreqs());
break;
}
default: {
LOG(ERROR) << __func__ << " not handled tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,

View file

@ -68,10 +68,16 @@ class EqualizerSwContext final : public EffectContext {
return bandLevels;
}
std::vector<int> getCenterFreqs() {
return {std::begin(kPresetsFrequencies), std::end(kPresetsFrequencies)};
}
private:
static const int NUM_OF_BANDS = 5;
static const int NUM_OF_PRESETS = 10;
static const int PRESET_CUSTOM = -1;
static constexpr std::array<uint16_t, NUM_OF_BANDS> kPresetsFrequencies = {60, 230, 910, 3600,
14000};
// preset band level
int mPreset = PRESET_CUSTOM;
int32_t mBandLevels[NUM_OF_BANDS] = {3, 0, 0, 0, 3};

View file

@ -90,10 +90,15 @@ ndk::ScopedAStatus NoiseSuppressionSw::setParameterSpecific(const Parameter::Spe
switch (tag) {
case NoiseSuppression::level: {
RETURN_IF(mContext->setLevel(param.get<NoiseSuppression::level>()) != RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "levelSupported");
EX_ILLEGAL_ARGUMENT, "levelNotSupported");
return ndk::ScopedAStatus::ok();
}
default: {
case NoiseSuppression::type: {
RETURN_IF(mContext->setType(param.get<NoiseSuppression::type>()) != RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "typeNotSupported");
return ndk::ScopedAStatus::ok();
}
case NoiseSuppression::vendor: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "NoiseSuppressionTagNotSupported");
@ -111,10 +116,11 @@ ndk::ScopedAStatus NoiseSuppressionSw::getParameterSpecific(const Parameter::Id&
case NoiseSuppression::Id::commonTag:
return getParameterNoiseSuppression(specificId.get<NoiseSuppression::Id::commonTag>(),
specific);
default:
case NoiseSuppression::Id::vendorExtensionTag: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "NoiseSuppressionTagNotSupported");
}
}
}
@ -127,7 +133,11 @@ ndk::ScopedAStatus NoiseSuppressionSw::getParameterNoiseSuppression(
param.set<NoiseSuppression::level>(mContext->getLevel());
break;
}
default: {
case NoiseSuppression::type: {
param.set<NoiseSuppression::type>(mContext->getType());
break;
}
case NoiseSuppression::vendor: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "NoiseSuppressionTagNotSupported");
@ -177,4 +187,9 @@ NoiseSuppression::Level NoiseSuppressionSwContext::getLevel() {
return mLevel;
}
RetCode NoiseSuppressionSwContext::setType(NoiseSuppression::Type type) {
mType = type;
return RetCode::SUCCESS;
}
} // namespace aidl::android::hardware::audio::effect

View file

@ -35,9 +35,12 @@ class NoiseSuppressionSwContext final : public EffectContext {
RetCode setLevel(NoiseSuppression::Level level);
NoiseSuppression::Level getLevel();
RetCode setType(NoiseSuppression::Type type);
NoiseSuppression::Type getType() { return mType; }
private:
NoiseSuppression::Level mLevel = NoiseSuppression::Level::LOW;
NoiseSuppression::Type mType = NoiseSuppression::Type::SINGLE_CHANNEL;
};
class NoiseSuppressionSw final : public EffectImpl {

View file

@ -30,6 +30,8 @@ using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::kVirtualizerSwImplUUID;
using aidl::android::hardware::audio::effect::State;
using aidl::android::hardware::audio::effect::VirtualizerSw;
using aidl::android::media::audio::common::AudioChannelLayout;
using aidl::android::media::audio::common::AudioDeviceDescription;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
@ -93,10 +95,18 @@ ndk::ScopedAStatus VirtualizerSw::setParameterSpecific(const Parameter::Specific
RETURN_IF(mContext->setVrStrength(vrParam.get<Virtualizer::strengthPm>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "strengthPmNotSupported");
EX_ILLEGAL_ARGUMENT, "setStrengthPmFailed");
return ndk::ScopedAStatus::ok();
}
default: {
case Virtualizer::device: {
RETURN_IF(mContext->setForcedDevice(vrParam.get<Virtualizer::device>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "setDeviceFailed");
return ndk::ScopedAStatus::ok();
}
case Virtualizer::speakerAngles:
FALLTHROUGH_INTENDED;
case Virtualizer::vendor: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"VirtualizerTagNotSupported");
@ -113,10 +123,13 @@ ndk::ScopedAStatus VirtualizerSw::getParameterSpecific(const Parameter::Id& id,
switch (vrIdTag) {
case Virtualizer::Id::commonTag:
return getParameterVirtualizer(vrId.get<Virtualizer::Id::commonTag>(), specific);
default:
case Virtualizer::Id::speakerAnglesPayload:
return getSpeakerAngles(vrId.get<Virtualizer::Id::speakerAnglesPayload>(), specific);
case Virtualizer::Id::vendorExtensionTag: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"VirtualizerTagNotSupported");
}
}
}
@ -130,7 +143,13 @@ ndk::ScopedAStatus VirtualizerSw::getParameterVirtualizer(const Virtualizer::Tag
vrParam.set<Virtualizer::strengthPm>(mContext->getVrStrength());
break;
}
default: {
case Virtualizer::device: {
vrParam.set<Virtualizer::device>(mContext->getForcedDevice());
break;
}
case Virtualizer::speakerAngles:
FALLTHROUGH_INTENDED;
case Virtualizer::vendor: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"VirtualizerTagNotSupported");
@ -141,6 +160,27 @@ ndk::ScopedAStatus VirtualizerSw::getParameterVirtualizer(const Virtualizer::Tag
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus VirtualizerSw::getSpeakerAngles(const Virtualizer::SpeakerAnglesPayload payload,
Parameter::Specific* specific) {
std::vector<Virtualizer::ChannelAngle> angles;
if (::android::hardware::audio::common::getChannelCount(payload.layout) == 1) {
angles = {{.channel = (int32_t)AudioChannelLayout::CHANNEL_FRONT_LEFT,
.azimuthDegree = 0,
.elevationDegree = 0}};
} else {
angles = {{.channel = (int32_t)AudioChannelLayout::CHANNEL_FRONT_LEFT,
.azimuthDegree = -90,
.elevationDegree = 0},
{.channel = (int32_t)AudioChannelLayout::CHANNEL_FRONT_RIGHT,
.azimuthDegree = 90,
.elevationDegree = 0}};
}
Virtualizer param = Virtualizer::make<Virtualizer::speakerAngles>(angles);
specific->set<Parameter::Specific::virtualizer>(param);
return ndk::ScopedAStatus::ok();
}
std::shared_ptr<EffectContext> VirtualizerSw::createContext(const Parameter::Common& common) {
if (mContext) {
LOG(DEBUG) << __func__ << " context already exist";

View file

@ -34,9 +34,18 @@ class VirtualizerSwContext final : public EffectContext {
}
RetCode setVrStrength(int strength);
int getVrStrength() const { return mStrength; }
RetCode setForcedDevice(
const ::aidl::android::media::audio::common::AudioDeviceDescription& device) {
mForceDevice = device;
return RetCode::SUCCESS;
}
aidl::android::media::audio::common::AudioDeviceDescription getForcedDevice() const {
return mForceDevice;
}
private:
int mStrength = 0;
::aidl::android::media::audio::common::AudioDeviceDescription mForceDevice;
};
class VirtualizerSw final : public EffectImpl {
@ -68,5 +77,7 @@ class VirtualizerSw final : public EffectImpl {
ndk::ScopedAStatus getParameterVirtualizer(const Virtualizer::Tag& tag,
Parameter::Specific* specific);
ndk::ScopedAStatus getSpeakerAngles(const Virtualizer::SpeakerAnglesPayload payload,
Parameter::Specific* specific);
};
} // namespace aidl::android::hardware::audio::effect

View file

@ -34,13 +34,14 @@ using aidl::android::hardware::audio::effect::kNoiseSuppressionTypeUUID;
using aidl::android::hardware::audio::effect::NoiseSuppression;
using aidl::android::hardware::audio::effect::Parameter;
enum ParamName { PARAM_INSTANCE_NAME, PARAM_LEVEL };
using NSParamTestParam =
std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, NoiseSuppression::Level>;
enum ParamName { PARAM_INSTANCE_NAME, PARAM_LEVEL, PARAM_TYPE };
using NSParamTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
NoiseSuppression::Level, NoiseSuppression::Type>;
class NSParamTest : public ::testing::TestWithParam<NSParamTestParam>, public EffectHelper {
public:
NSParamTest() : mLevel(std::get<PARAM_LEVEL>(GetParam())) {
NSParamTest()
: mLevel(std::get<PARAM_LEVEL>(GetParam())), mType(std::get<PARAM_TYPE>(GetParam())) {
std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
}
@ -75,6 +76,7 @@ class NSParamTest : public ::testing::TestWithParam<NSParamTestParam>, public Ef
std::shared_ptr<IEffect> mEffect;
Descriptor mDescriptor;
NoiseSuppression::Level mLevel;
NoiseSuppression::Type mType;
void SetAndGetParameters() {
for (auto& it : mTags) {
@ -113,10 +115,19 @@ class NSParamTest : public ::testing::TestWithParam<NSParamTestParam>, public Ef
ns.set<NoiseSuppression::level>(level);
mTags.push_back({NoiseSuppression::level, ns});
}
void addTypeParam(NoiseSuppression::Type type) {
NoiseSuppression ns;
ns.set<NoiseSuppression::type>(type);
mTags.push_back({NoiseSuppression::type, ns});
}
static std::unordered_set<NoiseSuppression::Level> getLevelValues() {
return {ndk::enum_range<NoiseSuppression::Level>().begin(),
ndk::enum_range<NoiseSuppression::Level>().end()};
}
static std::unordered_set<NoiseSuppression::Type> getTypeValues() {
return {ndk::enum_range<NoiseSuppression::Type>().begin(),
ndk::enum_range<NoiseSuppression::Type>().end()};
}
private:
std::vector<std::pair<NoiseSuppression::Tag, NoiseSuppression>> mTags;
@ -128,18 +139,27 @@ TEST_P(NSParamTest, SetAndGetLevel) {
SetAndGetParameters();
}
TEST_P(NSParamTest, SetAndGetType) {
EXPECT_NO_FATAL_FAILURE(addLevelParam(mLevel));
SetAndGetParameters();
}
INSTANTIATE_TEST_SUITE_P(
NSParamTest, NSParamTest,
::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
IFactory::descriptor, kNoiseSuppressionTypeUUID)),
testing::ValuesIn(NSParamTest::getLevelValues())),
testing::ValuesIn(NSParamTest::getLevelValues()),
testing::ValuesIn(NSParamTest::getTypeValues())),
[](const testing::TestParamInfo<NSParamTest::ParamType>& info) {
auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
std::string level = aidl::android::hardware::audio::effect::toString(
std::get<PARAM_LEVEL>(info.param));
std::string type = aidl::android::hardware::audio::effect::toString(
std::get<PARAM_TYPE>(info.param));
std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
descriptor.common.name + "_UUID_" +
descriptor.common.id.uuid.toString() + "_level_" + level;
descriptor.common.id.uuid.toString() + "_level_" + level + "_type_" +
type;
std::replace_if(
name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
return name;