From 9c47719bf7dc83ad27670937602c6429b20db944 Mon Sep 17 00:00:00 2001 From: Ram Mohan Date: Tue, 28 Mar 2023 05:54:11 +0530 Subject: [PATCH] Add utils for checking range limits of effect config params Bug: 272195502 Test: Build Change-Id: I1ff5af7d25e9410c58f323b6d12dbe6764e40073 --- audio/aidl/common/Android.bp | 14 ++ audio/aidl/common/EffectRangeSpecific.cpp | 161 ++++++++++++++++++ .../aidl/common/include/EffectRangeSpecific.h | 28 +++ .../default/include/effect-impl/EffectRange.h | 48 ++++++ 4 files changed, 251 insertions(+) create mode 100644 audio/aidl/common/EffectRangeSpecific.cpp create mode 100644 audio/aidl/common/include/EffectRangeSpecific.h create mode 100644 audio/aidl/default/include/effect-impl/EffectRange.h diff --git a/audio/aidl/common/Android.bp b/audio/aidl/common/Android.bp index a3f7f0b578..4c6a74e563 100644 --- a/audio/aidl/common/Android.bp +++ b/audio/aidl/common/Android.bp @@ -41,6 +41,20 @@ cc_library { ], } +cc_library { + name: "libaudioaidlranges", + host_supported: true, + vendor_available: true, + static_libs: [ + "android.hardware.audio.effect-V1-ndk", + ], + export_include_dirs: ["include"], + header_libs: ["libaudioaidl_headers"], + srcs: [ + "EffectRangeSpecific.cpp", + ], +} + cc_test { name: "libaudioaidlcommon_test", host_supported: true, diff --git a/audio/aidl/common/EffectRangeSpecific.cpp b/audio/aidl/common/EffectRangeSpecific.cpp new file mode 100644 index 0000000000..bd78ea0252 --- /dev/null +++ b/audio/aidl/common/EffectRangeSpecific.cpp @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "EffectRangeSpecific.h" +#include "effect-impl/EffectRange.h" + +namespace aidl::android::hardware::audio::effect { + +namespace DynamicsProcessingRanges { + +static bool isInputGainConfigInRange(const std::vector& cfgs, + const DynamicsProcessing::InputGain& min, + const DynamicsProcessing::InputGain& max) { + auto func = [](const DynamicsProcessing::InputGain& arg) { + return std::make_tuple(arg.channel, arg.gainDb); + }; + return isTupleInRange(cfgs, min, max, func); +} + +static bool isLimiterConfigInRange(const std::vector& cfgs, + const DynamicsProcessing::LimiterConfig& min, + const DynamicsProcessing::LimiterConfig& max) { + auto func = [](const DynamicsProcessing::LimiterConfig& arg) { + return std::make_tuple(arg.channel, arg.enable, arg.linkGroup, arg.attackTimeMs, + arg.releaseTimeMs, arg.ratio, arg.thresholdDb, arg.postGainDb); + }; + return isTupleInRange(cfgs, min, max, func); +} + +static bool isMbcBandConfigInRange(const std::vector& cfgs, + const DynamicsProcessing::MbcBandConfig& min, + const DynamicsProcessing::MbcBandConfig& max) { + auto func = [](const DynamicsProcessing::MbcBandConfig& arg) { + return std::make_tuple(arg.channel, arg.band, arg.enable, arg.cutoffFrequencyHz, + arg.attackTimeMs, arg.releaseTimeMs, arg.ratio, arg.thresholdDb, + arg.kneeWidthDb, arg.noiseGateThresholdDb, arg.expanderRatio, + arg.preGainDb, arg.postGainDb); + }; + return isTupleInRange(cfgs, min, max, func); +} + +static bool isEqBandConfigInRange(const std::vector& cfgs, + const DynamicsProcessing::EqBandConfig& min, + const DynamicsProcessing::EqBandConfig& max) { + auto func = [](const DynamicsProcessing::EqBandConfig& arg) { + return std::make_tuple(arg.channel, arg.band, arg.enable, arg.cutoffFrequencyHz, + arg.gainDb); + }; + return isTupleInRange(cfgs, min, max, func); +} + +static bool isChannelConfigInRange(const std::vector& cfgs, + const DynamicsProcessing::ChannelConfig& min, + const DynamicsProcessing::ChannelConfig& max) { + auto func = [](const DynamicsProcessing::ChannelConfig& arg) { + return std::make_tuple(arg.channel, arg.enable); + }; + return isTupleInRange(cfgs, min, max, func); +} + +static bool isEngineConfigInRange(const DynamicsProcessing::EngineArchitecture& cfg, + const DynamicsProcessing::EngineArchitecture& min, + const DynamicsProcessing::EngineArchitecture& max) { + auto func = [](const DynamicsProcessing::EngineArchitecture& arg) { + return std::make_tuple(arg.resolutionPreference, arg.preferredProcessingDurationMs, + arg.preEqStage.inUse, arg.preEqStage.bandCount, + arg.postEqStage.inUse, arg.postEqStage.bandCount, arg.mbcStage.inUse, + arg.mbcStage.bandCount, arg.limiterInUse); + }; + return isTupleInRange(func(cfg), func(min), func(max)); +} + +static int locateMinMaxForTag(DynamicsProcessing::Tag tag, + const std::vector& ranges) { + for (int i = 0; i < (int)ranges.size(); i++) { + if (tag == ranges[i].min.getTag() && tag == ranges[i].max.getTag()) { + return i; + } + } + return -1; +} + +bool isParamInRange(const DynamicsProcessing& dp, + const std::vector& ranges) { + auto tag = dp.getTag(); + int i = locateMinMaxForTag(tag, ranges); + if (i == -1) return true; + + switch (tag) { + case DynamicsProcessing::engineArchitecture: { + return isEngineConfigInRange( + dp.get(), + ranges[i].min.get(), + ranges[i].max.get()); + } + case DynamicsProcessing::preEq: { + return isChannelConfigInRange(dp.get(), + ranges[i].min.get()[0], + ranges[i].max.get()[0]); + } + case DynamicsProcessing::postEq: { + return isChannelConfigInRange(dp.get(), + ranges[i].min.get()[0], + ranges[i].max.get()[0]); + } + case DynamicsProcessing::mbc: { + return isChannelConfigInRange(dp.get(), + ranges[i].min.get()[0], + ranges[i].max.get()[0]); + } + case DynamicsProcessing::preEqBand: { + return isEqBandConfigInRange(dp.get(), + ranges[i].min.get()[0], + ranges[i].max.get()[0]); + } + case DynamicsProcessing::postEqBand: { + return isEqBandConfigInRange(dp.get(), + ranges[i].min.get()[0], + ranges[i].max.get()[0]); + } + case DynamicsProcessing::mbcBand: { + return isMbcBandConfigInRange(dp.get(), + ranges[i].min.get()[0], + ranges[i].max.get()[0]); + } + case DynamicsProcessing::limiter: { + return isLimiterConfigInRange(dp.get(), + ranges[i].min.get()[0], + ranges[i].max.get()[0]); + } + case DynamicsProcessing::inputGain: { + return isInputGainConfigInRange(dp.get(), + ranges[i].min.get()[0], + ranges[i].max.get()[0]); + } + default: { + return true; + } + } + return true; +} + +} // namespace DynamicsProcessingRanges + +} // namespace aidl::android::hardware::audio::effect \ No newline at end of file diff --git a/audio/aidl/common/include/EffectRangeSpecific.h b/audio/aidl/common/include/EffectRangeSpecific.h new file mode 100644 index 0000000000..c7262bbfce --- /dev/null +++ b/audio/aidl/common/include/EffectRangeSpecific.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +namespace aidl::android::hardware::audio::effect { + +namespace DynamicsProcessingRanges { + +bool isParamInRange(const DynamicsProcessing& dp, + const std::vector& ranges); + +} // namespace DynamicsProcessingRanges + +} // namespace aidl::android::hardware::audio::effect \ No newline at end of file diff --git a/audio/aidl/default/include/effect-impl/EffectRange.h b/audio/aidl/default/include/effect-impl/EffectRange.h new file mode 100644 index 0000000000..a3ea01f699 --- /dev/null +++ b/audio/aidl/default/include/effect-impl/EffectRange.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include + +namespace aidl::android::hardware::audio::effect { + +template +bool isInRange(const T& value, const T& low, const T& high) { + return (value >= low) && (value <= high); +} + +template +bool isTupleInRange(const T& test, const T& min, const T& max, std::index_sequence) { + return (isInRange(std::get(test), std::get(min), std::get(max)) && ...); +} + +template > +bool isTupleInRange(const T& test, const T& min, const T& max) { + return isTupleInRange(test, min, max, std::make_index_sequence{}); +} + +template +bool isTupleInRange(const std::vector& cfgs, const T& min, const T& max, const F& func) { + auto minT = func(min), maxT = func(max); + return std::all_of(cfgs.cbegin(), cfgs.cend(), + [&](const T& cfg) { return isTupleInRange(func(cfg), minT, maxT); }); +} + +} // namespace aidl::android::hardware::audio::effect