diff --git a/audio/aidl/TEST_MAPPING b/audio/aidl/TEST_MAPPING index b68fab2001..a166e61872 100644 --- a/audio/aidl/TEST_MAPPING +++ b/audio/aidl/TEST_MAPPING @@ -12,6 +12,9 @@ { "name": "VtsHalDownmixTargetTest" }, + { + "name": "VtsHalEnvironmentalReverbTargetTest" + }, { "name": "VtsHalEqualizerTargetTest" }, diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/EnvironmentalReverb.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/EnvironmentalReverb.aidl index fcf08c369f..0e61932c96 100644 --- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/EnvironmentalReverb.aidl +++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/EnvironmentalReverb.aidl @@ -44,6 +44,22 @@ union EnvironmentalReverb { int diffusionPm; int densityPm; boolean bypass; + const int MIN_ROOM_LEVEL_MB = -6000; + const int MAX_ROOM_LEVEL_MB = 0; + const int MIN_ROOM_HF_LEVEL_MB = -4000; + const int MAX_ROOM_HF_LEVEL_MB = 0; + const int MIN_DECAY_TIME_MS = 100; + const int MAX_DECAY_TIME_MS = 20000; + const int MIN_DECAY_HF_RATIO_PM = 100; + const int MAX_DECAY_HF_RATIO_PM = 1000; + const int MIN_LEVEL_MB = -6000; + const int MAX_LEVEL_MB = 0; + const int MIN_DELAY_MS = 0; + const int MAX_DELAY_MS = 65; + const int MIN_DIFFUSION_PM = 0; + const int MAX_DIFFUSION_PM = 1000; + const int MIN_DENSITY_PM = 0; + const int MAX_DENSITY_PM = 1000; @VintfStability union Id { int vendorExtensionTag; diff --git a/audio/aidl/android/hardware/audio/effect/EnvironmentalReverb.aidl b/audio/aidl/android/hardware/audio/effect/EnvironmentalReverb.aidl index 3df0d27ec9..81c0dde8f8 100644 --- a/audio/aidl/android/hardware/audio/effect/EnvironmentalReverb.aidl +++ b/audio/aidl/android/hardware/audio/effect/EnvironmentalReverb.aidl @@ -55,38 +55,110 @@ union EnvironmentalReverb { int maxDecayTimeMs; } + /** + * Minimal possible room level in millibels. + */ + const int MIN_ROOM_LEVEL_MB = -6000; + /** + * Maximum possible room level in millibels. + */ + const int MAX_ROOM_LEVEL_MB = 0; /** * Room level apply to the reverb effect in millibels. */ int roomLevelMb; + + /** + * Minimal possible room hf level in millibels. + */ + const int MIN_ROOM_HF_LEVEL_MB = -4000; + /** + * Maximum possible room hf level in millibels. + */ + const int MAX_ROOM_HF_LEVEL_MB = 0; /** * Room HF level apply to the reverb effect in millibels. */ int roomHfLevelMb; + + /** + * Minimal possible decay time in milliseconds. + */ + const int MIN_DECAY_TIME_MS = 100; + /** + * Maximum possible decay time in milliseconds. + */ + const int MAX_DECAY_TIME_MS = 20000; /** * Delay time apply to the reverb effect in milliseconds. */ int decayTimeMs; + + /** + * Minimal possible per mille decay hf ratio. + */ + const int MIN_DECAY_HF_RATIO_PM = 100; + /** + * Maximum possible per mille decay hf ratio. + */ + const int MAX_DECAY_HF_RATIO_PM = 1000; /** * HF decay ratio in permilles. */ int decayHfRatioPm; + + /** + * Minimal possible room level in millibels. + */ + const int MIN_LEVEL_MB = -6000; + /** + * Maximum possible room level in millibels. + */ + const int MAX_LEVEL_MB = 0; /** * Reverb level in millibels. */ int levelMb; + + /** + * Minimal possible delay time in milliseconds. + */ + const int MIN_DELAY_MS = 0; + /** + * Maximum possible delay time in milliseconds. + */ + const int MAX_DELAY_MS = 65; /** * Reverb delay in milliseconds. */ int delayMs; + + /** + * Minimal possible per mille diffusion. + */ + const int MIN_DIFFUSION_PM = 0; + /** + * Maximum possible per mille diffusion. + */ + const int MAX_DIFFUSION_PM = 1000; /** * Diffusion in permilles. */ int diffusionPm; + + /** + * Minimal possible per mille density. + */ + const int MIN_DENSITY_PM = 0; + /** + * Maximum possible per mille density. + */ + const int MAX_DENSITY_PM = 1000; /** * Density in permilles. */ int densityPm; + /** * Bypass reverb and copy input to output if set to true. */ diff --git a/audio/aidl/default/envReverb/EnvReverbSw.cpp b/audio/aidl/default/envReverb/EnvReverbSw.cpp index a107064235..9d7159a452 100644 --- a/audio/aidl/default/envReverb/EnvReverbSw.cpp +++ b/audio/aidl/default/envReverb/EnvReverbSw.cpp @@ -60,7 +60,8 @@ extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descrip namespace aidl::android::hardware::audio::effect { const std::string EnvReverbSw::kEffectName = "EnvReverbSw"; -const EnvironmentalReverb::Capability EnvReverbSw::kCapability; +const EnvironmentalReverb::Capability EnvReverbSw::kCapability = { + .maxDecayTimeMs = EnvironmentalReverb::MAX_DECAY_TIME_MS}; const Descriptor EnvReverbSw::kDescriptor = { .common = {.id = {.type = kEnvReverbTypeUUID, .uuid = kEnvReverbSwImplUUID, @@ -82,16 +83,140 @@ ndk::ScopedAStatus EnvReverbSw::setParameterSpecific(const Parameter::Specific& RETURN_IF(Parameter::Specific::environmentalReverb != specific.getTag(), EX_ILLEGAL_ARGUMENT, "EffectNotSupported"); - mSpecificParam = specific.get(); - LOG(DEBUG) << __func__ << " success with: " << specific.toString(); - return ndk::ScopedAStatus::ok(); + auto& erParam = specific.get(); + auto tag = erParam.getTag(); + + switch (tag) { + case EnvironmentalReverb::roomLevelMb: { + RETURN_IF(mContext->setErRoomLevel(erParam.get()) != + RetCode::SUCCESS, + EX_ILLEGAL_ARGUMENT, "setRoomLevelFailed"); + return ndk::ScopedAStatus::ok(); + } + case EnvironmentalReverb::roomHfLevelMb: { + RETURN_IF( + mContext->setErRoomHfLevel(erParam.get()) != + RetCode::SUCCESS, + EX_ILLEGAL_ARGUMENT, "setRoomHfLevelFailed"); + return ndk::ScopedAStatus::ok(); + } + case EnvironmentalReverb::decayTimeMs: { + RETURN_IF(mContext->setErDecayTime(erParam.get()) != + RetCode::SUCCESS, + EX_ILLEGAL_ARGUMENT, "setDecayTimeFailed"); + return ndk::ScopedAStatus::ok(); + } + case EnvironmentalReverb::decayHfRatioPm: { + RETURN_IF( + mContext->setErDecayHfRatio( + erParam.get()) != RetCode::SUCCESS, + EX_ILLEGAL_ARGUMENT, "setDecayHfRatioFailed"); + return ndk::ScopedAStatus::ok(); + } + case EnvironmentalReverb::levelMb: { + RETURN_IF(mContext->setErLevel(erParam.get()) != + RetCode::SUCCESS, + EX_ILLEGAL_ARGUMENT, "setLevelFailed"); + return ndk::ScopedAStatus::ok(); + } + case EnvironmentalReverb::delayMs: { + RETURN_IF(mContext->setErDelay(erParam.get()) != + RetCode::SUCCESS, + EX_ILLEGAL_ARGUMENT, "setDelayFailed"); + return ndk::ScopedAStatus::ok(); + } + case EnvironmentalReverb::diffusionPm: { + RETURN_IF(mContext->setErDiffusion(erParam.get()) != + RetCode::SUCCESS, + EX_ILLEGAL_ARGUMENT, "setDiffusionFailed"); + return ndk::ScopedAStatus::ok(); + } + case EnvironmentalReverb::densityPm: { + RETURN_IF(mContext->setErDensity(erParam.get()) != + RetCode::SUCCESS, + EX_ILLEGAL_ARGUMENT, "setDensityFailed"); + return ndk::ScopedAStatus::ok(); + } + case EnvironmentalReverb::bypass: { + RETURN_IF(mContext->setErBypass(erParam.get()) != + RetCode::SUCCESS, + EX_ILLEGAL_ARGUMENT, "setBypassFailed"); + return ndk::ScopedAStatus::ok(); + } + default: { + LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag); + return ndk::ScopedAStatus::fromExceptionCodeWithMessage( + EX_ILLEGAL_ARGUMENT, "EnvironmentalReverbTagNotSupported"); + } + } } ndk::ScopedAStatus EnvReverbSw::getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific) { auto tag = id.getTag(); RETURN_IF(Parameter::Id::environmentalReverbTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag"); - specific->set(mSpecificParam); + auto erId = id.get(); + auto erIdTag = erId.getTag(); + switch (erIdTag) { + case EnvironmentalReverb::Id::commonTag: + return getParameterEnvironmentalReverb(erId.get(), + specific); + default: + LOG(ERROR) << __func__ << " unsupported tag: " << toString(erIdTag); + return ndk::ScopedAStatus::fromExceptionCodeWithMessage( + EX_ILLEGAL_ARGUMENT, "EnvironmentalReverbTagNotSupported"); + } +} + +ndk::ScopedAStatus EnvReverbSw::getParameterEnvironmentalReverb(const EnvironmentalReverb::Tag& tag, + Parameter::Specific* specific) { + RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext"); + EnvironmentalReverb erParam; + switch (tag) { + case EnvironmentalReverb::roomLevelMb: { + erParam.set(mContext->getErRoomLevel()); + break; + } + case EnvironmentalReverb::roomHfLevelMb: { + erParam.set(mContext->getErRoomHfLevel()); + break; + } + case EnvironmentalReverb::decayTimeMs: { + erParam.set(mContext->getErDecayTime()); + break; + } + case EnvironmentalReverb::decayHfRatioPm: { + erParam.set(mContext->getErDecayHfRatio()); + break; + } + case EnvironmentalReverb::levelMb: { + erParam.set(mContext->getErLevel()); + break; + } + case EnvironmentalReverb::delayMs: { + erParam.set(mContext->getErDelay()); + break; + } + case EnvironmentalReverb::diffusionPm: { + erParam.set(mContext->getErDiffusion()); + break; + } + case EnvironmentalReverb::densityPm: { + erParam.set(mContext->getErDensity()); + break; + } + case EnvironmentalReverb::bypass: { + erParam.set(mContext->getErBypass()); + break; + } + default: { + LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag); + return ndk::ScopedAStatus::fromExceptionCodeWithMessage( + EX_ILLEGAL_ARGUMENT, "EnvironmentalReverbTagNotSupported"); + } + } + + specific->set(erParam); return ndk::ScopedAStatus::ok(); } diff --git a/audio/aidl/default/envReverb/EnvReverbSw.h b/audio/aidl/default/envReverb/EnvReverbSw.h index b8761a6c66..f52121597a 100644 --- a/audio/aidl/default/envReverb/EnvReverbSw.h +++ b/audio/aidl/default/envReverb/EnvReverbSw.h @@ -32,7 +32,120 @@ class EnvReverbSwContext final : public EffectContext { : EffectContext(statusDepth, common) { LOG(DEBUG) << __func__; } - // TODO: add specific context here + + RetCode setErRoomLevel(int roomLevel) { + if (roomLevel < EnvironmentalReverb::MIN_ROOM_LEVEL_MB || + roomLevel > EnvironmentalReverb::MAX_ROOM_LEVEL_MB) { + LOG(ERROR) << __func__ << " invalid roomLevel: " << roomLevel; + return RetCode::ERROR_ILLEGAL_PARAMETER; + } + // TODO : Add implementation to apply new room level + mRoomLevel = roomLevel; + return RetCode::SUCCESS; + } + int getErRoomLevel() const { return mRoomLevel; } + + RetCode setErRoomHfLevel(int roomHfLevel) { + if (roomHfLevel < EnvironmentalReverb::MIN_ROOM_HF_LEVEL_MB || + roomHfLevel > EnvironmentalReverb::MAX_ROOM_HF_LEVEL_MB) { + LOG(ERROR) << __func__ << " invalid roomHfLevel: " << roomHfLevel; + return RetCode::ERROR_ILLEGAL_PARAMETER; + } + // TODO : Add implementation to apply new room HF level + mRoomHfLevel = roomHfLevel; + return RetCode::SUCCESS; + } + int getErRoomHfLevel() const { return mRoomHfLevel; } + + RetCode setErDecayTime(int decayTime) { + if (decayTime < EnvironmentalReverb::MIN_DECAY_TIME_MS || + decayTime > EnvironmentalReverb::MAX_DECAY_TIME_MS) { + LOG(ERROR) << __func__ << " invalid decayTime: " << decayTime; + return RetCode::ERROR_ILLEGAL_PARAMETER; + } + // TODO : Add implementation to apply new decay time + mDecayTime = decayTime; + return RetCode::SUCCESS; + } + int getErDecayTime() const { return mDecayTime; } + + RetCode setErDecayHfRatio(int decayHfRatio) { + if (decayHfRatio < EnvironmentalReverb::MIN_DECAY_HF_RATIO_PM || + decayHfRatio > EnvironmentalReverb::MAX_DECAY_HF_RATIO_PM) { + LOG(ERROR) << __func__ << " invalid decayHfRatio: " << decayHfRatio; + return RetCode::ERROR_ILLEGAL_PARAMETER; + } + // TODO : Add implementation to apply new decay HF ratio + mDecayHfRatio = decayHfRatio; + return RetCode::SUCCESS; + } + int getErDecayHfRatio() const { return mDecayHfRatio; } + + RetCode setErLevel(int level) { + if (level < EnvironmentalReverb::MIN_LEVEL_MB || + level > EnvironmentalReverb::MAX_LEVEL_MB) { + LOG(ERROR) << __func__ << " invalid level: " << level; + return RetCode::ERROR_ILLEGAL_PARAMETER; + } + // TODO : Add implementation to apply new level + mLevel = level; + return RetCode::SUCCESS; + } + int getErLevel() const { return mLevel; } + + RetCode setErDelay(int delay) { + if (delay < EnvironmentalReverb::MIN_DELAY_MS || + delay > EnvironmentalReverb::MAX_DELAY_MS) { + LOG(ERROR) << __func__ << " invalid delay: " << delay; + return RetCode::ERROR_ILLEGAL_PARAMETER; + } + // TODO : Add implementation to apply new delay + mDelay = delay; + return RetCode::SUCCESS; + } + int getErDelay() const { return mDelay; } + + RetCode setErDiffusion(int diffusion) { + if (diffusion < EnvironmentalReverb::MIN_DIFFUSION_PM || + diffusion > EnvironmentalReverb::MAX_DIFFUSION_PM) { + LOG(ERROR) << __func__ << " invalid diffusion: " << diffusion; + return RetCode::ERROR_ILLEGAL_PARAMETER; + } + // TODO : Add implementation to apply new diffusion + mDiffusion = diffusion; + return RetCode::SUCCESS; + } + int getErDiffusion() const { return mDiffusion; } + + RetCode setErDensity(int density) { + if (density < EnvironmentalReverb::MIN_DENSITY_PM || + density > EnvironmentalReverb::MAX_DENSITY_PM) { + LOG(ERROR) << __func__ << " invalid density: " << density; + return RetCode::ERROR_ILLEGAL_PARAMETER; + } + // TODO : Add implementation to apply new density + mDensity = density; + return RetCode::SUCCESS; + } + int getErDensity() const { return mDensity; } + + RetCode setErBypass(bool bypass) { + // TODO : Add implementation to apply new bypass + mBypass = bypass; + return RetCode::SUCCESS; + } + bool getErBypass() const { return mBypass; } + + private: + int mRoomLevel = EnvironmentalReverb::MIN_ROOM_LEVEL_MB; // Default room level + int mRoomHfLevel = EnvironmentalReverb::MAX_ROOM_HF_LEVEL_MB; // Default room hf level + int mDecayTime = 1000; // Default decay time + int mDecayHfRatio = 500; // Default decay hf ratio + int mLevel = EnvironmentalReverb::MIN_LEVEL_MB; // Default level + int mDelay = 40; // Default delay + int mDiffusion = EnvironmentalReverb::MAX_DIFFUSION_PM; // Default diffusion + int mDensity = EnvironmentalReverb::MAX_DENSITY_PM; // Default density + bool mBypass = false; // Default bypass }; class EnvReverbSw final : public EffectImpl { @@ -60,7 +173,7 @@ class EnvReverbSw final : public EffectImpl { private: std::shared_ptr mContext; - /* parameters */ - EnvironmentalReverb mSpecificParam; + ndk::ScopedAStatus getParameterEnvironmentalReverb(const EnvironmentalReverb::Tag& tag, + Parameter::Specific* specific); }; } // namespace aidl::android::hardware::audio::effect diff --git a/audio/aidl/vts/Android.bp b/audio/aidl/vts/Android.bp index 96e9971d2e..5e6f53d8e4 100644 --- a/audio/aidl/vts/Android.bp +++ b/audio/aidl/vts/Android.bp @@ -79,6 +79,12 @@ cc_test { srcs: ["VtsHalDownmixTargetTest.cpp"], } +cc_test { + name: "VtsHalEnvironmentalReverbTargetTest", + defaults: ["VtsHalAudioTargetTestDefaults"], + srcs: ["VtsHalEnvironmentalReverbTargetTest.cpp"], +} + cc_test { name: "VtsHalEqualizerTargetTest", defaults: ["VtsHalAudioTargetTestDefaults"], diff --git a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp new file mode 100644 index 0000000000..e99c4a449e --- /dev/null +++ b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp @@ -0,0 +1,629 @@ +/* + * Copyright (C) 2022 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. + */ + +#define LOG_TAG "VtsHalEnvironmentalReverbTest" + +#include +#include +#include "EffectHelper.h" + +using namespace android; + +using aidl::android::hardware::audio::effect::Capability; +using aidl::android::hardware::audio::effect::Descriptor; +using aidl::android::hardware::audio::effect::EnvironmentalReverb; +using aidl::android::hardware::audio::effect::IEffect; +using aidl::android::hardware::audio::effect::IFactory; +using aidl::android::hardware::audio::effect::kEnvReverbTypeUUID; +using aidl::android::hardware::audio::effect::Parameter; + +/** + * Here we focus on specific parameter checking, general IEffect interfaces testing performed in + * VtsAudioEffectTargetTest. + * Testing parameter range, assuming the parameter supported by effect is in this range. + * This range is verified with IEffect.getDescriptor() and range defined in the documentation, for + * any index supported value test expects EX_NONE from IEffect.setParameter(), otherwise expects + * EX_ILLEGAL_ARGUMENT. + */ +const std::vector kRoomLevelValues = { + EnvironmentalReverb::MIN_ROOM_LEVEL_MB - 1, EnvironmentalReverb::MIN_ROOM_LEVEL_MB, + EnvironmentalReverb::MAX_ROOM_LEVEL_MB, EnvironmentalReverb::MAX_ROOM_LEVEL_MB + 1}; +const std::vector kRoomHfLevelValues = { + EnvironmentalReverb::MIN_ROOM_HF_LEVEL_MB - 1, EnvironmentalReverb::MIN_ROOM_HF_LEVEL_MB, + EnvironmentalReverb::MAX_ROOM_HF_LEVEL_MB, EnvironmentalReverb::MAX_ROOM_HF_LEVEL_MB + 1}; +const std::vector kDecayTimeValues = { + EnvironmentalReverb::MIN_DECAY_TIME_MS - 1, EnvironmentalReverb::MIN_DECAY_TIME_MS, + EnvironmentalReverb::MAX_DECAY_TIME_MS, EnvironmentalReverb::MAX_DECAY_TIME_MS + 1}; +const std::vector kDecayHfRatioValues = { + EnvironmentalReverb::MIN_DECAY_HF_RATIO_PM - 1, EnvironmentalReverb::MIN_DECAY_HF_RATIO_PM, + EnvironmentalReverb::MAX_DECAY_HF_RATIO_PM, EnvironmentalReverb::MAX_DECAY_HF_RATIO_PM + 1}; +const std::vector kLevelValues = { + EnvironmentalReverb::MIN_LEVEL_MB - 1, EnvironmentalReverb::MIN_LEVEL_MB, + EnvironmentalReverb::MAX_LEVEL_MB, EnvironmentalReverb::MAX_LEVEL_MB + 1}; +const std::vector kDelayValues = { + EnvironmentalReverb::MIN_DELAY_MS - 1, EnvironmentalReverb::MIN_DELAY_MS, + EnvironmentalReverb::MAX_DELAY_MS, EnvironmentalReverb::MAX_DELAY_MS + 1}; +const std::vector kDiffusionValues = { + EnvironmentalReverb::MIN_DIFFUSION_PM - 1, EnvironmentalReverb::MIN_DIFFUSION_PM, + EnvironmentalReverb::MAX_DIFFUSION_PM, EnvironmentalReverb::MAX_DIFFUSION_PM + 1}; +const std::vector kDensityValues = { + EnvironmentalReverb::MIN_DENSITY_PM - 1, EnvironmentalReverb::MIN_DENSITY_PM, + EnvironmentalReverb::MAX_DENSITY_PM, EnvironmentalReverb::MAX_DENSITY_PM + 1}; + +class EnvironmentalReverbHelper : public EffectHelper { + public: + EnvironmentalReverbHelper(std::pair, Descriptor> pair) { + std::tie(mFactory, mDescriptor) = pair; + } + + void SetUpReverb() { + ASSERT_NE(nullptr, mFactory); + ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor)); + + Parameter::Specific specific = getDefaultParamSpecific(); + Parameter::Common common = EffectHelper::createParamCommon( + 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */, + kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */); + IEffect::OpenEffectReturn ret; + ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE)); + ASSERT_NE(nullptr, mEffect); + } + + void TearDownReverb() { + ASSERT_NO_FATAL_FAILURE(close(mEffect)); + ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect)); + } + + Parameter::Specific getDefaultParamSpecific() { + EnvironmentalReverb er = EnvironmentalReverb::make( + EnvironmentalReverb::MIN_ROOM_LEVEL_MB); + Parameter::Specific specific = + Parameter::Specific::make(er); + return specific; + } + + static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100; + std::shared_ptr mFactory; + std::shared_ptr mEffect; + Descriptor mDescriptor; + int mRoomLevel = EnvironmentalReverb::MIN_ROOM_LEVEL_MB; + int mRoomHfLevel = EnvironmentalReverb::MAX_ROOM_HF_LEVEL_MB; + int mDecayTime = 1000; + int mDecayHfRatio = 500; + int mLevel = EnvironmentalReverb::MIN_LEVEL_MB; + int mDelay = 40; + int mDiffusion = EnvironmentalReverb::MAX_DIFFUSION_PM; + int mDensity = EnvironmentalReverb::MAX_DENSITY_PM; + bool mBypass = false; + + void SetAndGetReverbParameters() { + for (auto& it : mTags) { + auto& tag = it.first; + auto& er = it.second; + + // validate parameter + Descriptor desc; + ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc)); + const bool valid = isTagInRange(it.first, it.second, desc); + const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT; + + // set + Parameter expectParam; + Parameter::Specific specific; + specific.set(er); + expectParam.set(specific); + EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString(); + + // only get if parameter in range and set success + if (expected == EX_NONE) { + Parameter getParam; + Parameter::Id id; + EnvironmentalReverb::Id erId; + erId.set(tag); + id.set(erId); + // if set success, then get should match + EXPECT_STATUS(expected, mEffect->getParameter(id, &getParam)); + EXPECT_EQ(expectParam, getParam); + } + } + } + + void addRoomLevelParam() { + EnvironmentalReverb er; + er.set(mRoomLevel); + mTags.push_back({EnvironmentalReverb::roomLevelMb, er}); + } + + void addRoomHfLevelParam(int roomHfLevel) { + EnvironmentalReverb er; + er.set(roomHfLevel); + mTags.push_back({EnvironmentalReverb::roomHfLevelMb, er}); + } + + void addDecayTimeParam(int decayTime) { + EnvironmentalReverb er; + er.set(decayTime); + mTags.push_back({EnvironmentalReverb::decayTimeMs, er}); + } + + void addDecayHfRatioParam(int decayHfRatio) { + EnvironmentalReverb er; + er.set(decayHfRatio); + mTags.push_back({EnvironmentalReverb::decayHfRatioPm, er}); + } + + void addLevelParam(int level) { + EnvironmentalReverb er; + er.set(level); + mTags.push_back({EnvironmentalReverb::levelMb, er}); + } + + void addDelayParam(int delay) { + EnvironmentalReverb er; + er.set(delay); + mTags.push_back({EnvironmentalReverb::delayMs, er}); + } + + void addDiffusionParam(int diffusion) { + EnvironmentalReverb er; + er.set(diffusion); + mTags.push_back({EnvironmentalReverb::diffusionPm, er}); + } + + void addDensityParam(int density) { + EnvironmentalReverb er; + er.set(density); + mTags.push_back({EnvironmentalReverb::densityPm, er}); + } + + void addBypassParam(bool bypass) { + EnvironmentalReverb er; + er.set(bypass); + mTags.push_back({EnvironmentalReverb::bypass, er}); + } + + bool isTagInRange(const EnvironmentalReverb::Tag& tag, const EnvironmentalReverb er, + const Descriptor& desc) const { + const EnvironmentalReverb::Capability& erCap = + desc.capability.get(); + switch (tag) { + case EnvironmentalReverb::roomLevelMb: { + int roomLevel = er.get(); + return isRoomLevelInRange(roomLevel); + } + case EnvironmentalReverb::roomHfLevelMb: { + int roomHfLevel = er.get(); + return isRoomHfLevelInRange(roomHfLevel); + } + case EnvironmentalReverb::decayTimeMs: { + int decayTime = er.get(); + return isDecayTimeInRange(erCap, decayTime); + } + case EnvironmentalReverb::decayHfRatioPm: { + int decayHfRatio = er.get(); + return isDecayHfRatioInRange(decayHfRatio); + } + case EnvironmentalReverb::levelMb: { + int level = er.get(); + return isLevelInRange(level); + } + case EnvironmentalReverb::delayMs: { + int delay = er.get(); + return isDelayInRange(delay); + } + case EnvironmentalReverb::diffusionPm: { + int diffusion = er.get(); + return isDiffusionInRange(diffusion); + } + case EnvironmentalReverb::densityPm: { + int density = er.get(); + return isDensityInRange(density); + } + case EnvironmentalReverb::bypass: { + return true; + } + default: + return false; + } + return false; + } + + bool isRoomLevelInRange(int roomLevel) const { + return roomLevel >= EnvironmentalReverb::MIN_ROOM_LEVEL_MB && + roomLevel <= EnvironmentalReverb::MAX_ROOM_LEVEL_MB; + } + + bool isRoomHfLevelInRange(int roomHfLevel) const { + return roomHfLevel >= EnvironmentalReverb::MIN_ROOM_HF_LEVEL_MB && + roomHfLevel <= EnvironmentalReverb::MAX_ROOM_HF_LEVEL_MB; + } + + bool isDecayTimeInRange(const EnvironmentalReverb::Capability& cap, int decayTime) const { + return decayTime >= EnvironmentalReverb::MIN_DECAY_TIME_MS && + decayTime <= EnvironmentalReverb::MAX_DECAY_TIME_MS && + decayTime <= cap.maxDecayTimeMs; + } + + bool isDecayHfRatioInRange(int decayHfRatio) const { + return decayHfRatio >= EnvironmentalReverb::MIN_DECAY_HF_RATIO_PM && + decayHfRatio <= EnvironmentalReverb::MAX_DECAY_HF_RATIO_PM; + } + + bool isLevelInRange(int level) const { + return level >= EnvironmentalReverb::MIN_LEVEL_MB && + level <= EnvironmentalReverb::MAX_LEVEL_MB; + } + + bool isDelayInRange(int delay) const { + return delay >= EnvironmentalReverb::MIN_DELAY_MS && + delay <= EnvironmentalReverb::MAX_DELAY_MS; + } + + bool isDiffusionInRange(int diffusion) const { + return diffusion >= EnvironmentalReverb::MIN_DIFFUSION_PM && + diffusion <= EnvironmentalReverb::MAX_DIFFUSION_PM; + } + + bool isDensityInRange(int density) const { + return density >= EnvironmentalReverb::MIN_DENSITY_PM && + density <= EnvironmentalReverb::MAX_DENSITY_PM; + } + + private: + std::vector> mTags; + void CleanUp() { mTags.clear(); } +}; + +class EnvironmentalReverbRoomLevelTest + : public ::testing::TestWithParam< + std::tuple, Descriptor>, int>>, + public EnvironmentalReverbHelper { + public: + EnvironmentalReverbRoomLevelTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) { + mRoomLevel = std::get<1>(GetParam()); + } + + void SetUp() override { SetUpReverb(); } + + void TearDown() override { TearDownReverb(); } +}; + +TEST_P(EnvironmentalReverbRoomLevelTest, SetAndGetRoomLevel) { + EXPECT_NO_FATAL_FAILURE(addRoomLevelParam()); + SetAndGetReverbParameters(); +} + +INSTANTIATE_TEST_SUITE_P( + EnvironmentalReverbTest, EnvironmentalReverbRoomLevelTest, + ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors( + IFactory::descriptor, kEnvReverbTypeUUID)), + testing::ValuesIn(kRoomLevelValues)), + [](const testing::TestParamInfo& info) { + auto descriptor = std::get<0>(info.param).second; + std::string roomLevel = std::to_string(std::get<1>(info.param)); + + std::string name = "Implementor_" + descriptor.common.implementor + "_name_" + + descriptor.common.name + "_UUID_" + + descriptor.common.id.uuid.toString() + "_roomLevel" + roomLevel; + std::replace_if( + name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_'); + return name; + }); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbRoomLevelTest); + +class EnvironmentalReverbRoomHfLevelTest + : public ::testing::TestWithParam< + std::tuple, Descriptor>, int>>, + public EnvironmentalReverbHelper { + public: + EnvironmentalReverbRoomHfLevelTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) { + mRoomHfLevel = std::get<1>(GetParam()); + } + + void SetUp() override { SetUpReverb(); } + + void TearDown() override { TearDownReverb(); } +}; + +TEST_P(EnvironmentalReverbRoomHfLevelTest, SetAndGetRoomHfLevel) { + EXPECT_NO_FATAL_FAILURE(addRoomHfLevelParam(mRoomHfLevel)); + SetAndGetReverbParameters(); +} + +INSTANTIATE_TEST_SUITE_P( + EnvironmentalReverbTest, EnvironmentalReverbRoomHfLevelTest, + ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors( + IFactory::descriptor, kEnvReverbTypeUUID)), + testing::ValuesIn(kRoomHfLevelValues)), + [](const testing::TestParamInfo& info) { + auto descriptor = std::get<0>(info.param).second; + std::string roomHfLevel = std::to_string(std::get<1>(info.param)); + + std::string name = "Implementor_" + descriptor.common.implementor + "_name_" + + descriptor.common.name + "_UUID_" + + descriptor.common.id.uuid.toString() + "_roomHfLevel" + roomHfLevel; + std::replace_if( + name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_'); + return name; + }); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbRoomHfLevelTest); + +class EnvironmentalReverbDecayTimeTest + : public ::testing::TestWithParam< + std::tuple, Descriptor>, int>>, + public EnvironmentalReverbHelper { + public: + EnvironmentalReverbDecayTimeTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) { + mDecayTime = std::get<1>(GetParam()); + } + + void SetUp() override { SetUpReverb(); } + + void TearDown() override { TearDownReverb(); } +}; + +TEST_P(EnvironmentalReverbDecayTimeTest, SetAndGetDecayTime) { + EXPECT_NO_FATAL_FAILURE(addDecayTimeParam(mDecayTime)); + SetAndGetReverbParameters(); +} + +INSTANTIATE_TEST_SUITE_P( + EnvironmentalReverbTest, EnvironmentalReverbDecayTimeTest, + ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors( + IFactory::descriptor, kEnvReverbTypeUUID)), + testing::ValuesIn(kDecayTimeValues)), + [](const testing::TestParamInfo& info) { + auto descriptor = std::get<0>(info.param).second; + std::string decayTime = std::to_string(std::get<1>(info.param)); + + std::string name = "Implementor_" + descriptor.common.implementor + "_name_" + + descriptor.common.name + "_UUID_" + + descriptor.common.id.uuid.toString() + "_decayTime" + decayTime; + std::replace_if( + name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_'); + return name; + }); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbDecayTimeTest); + +class EnvironmentalReverbDecayHfRatioTest + : public ::testing::TestWithParam< + std::tuple, Descriptor>, int>>, + public EnvironmentalReverbHelper { + public: + EnvironmentalReverbDecayHfRatioTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) { + mDecayHfRatio = std::get<1>(GetParam()); + } + + void SetUp() override { SetUpReverb(); } + + void TearDown() override { TearDownReverb(); } +}; + +TEST_P(EnvironmentalReverbDecayHfRatioTest, SetAndGetDecayHfRatio) { + EXPECT_NO_FATAL_FAILURE(addDecayHfRatioParam(mDecayHfRatio)); + SetAndGetReverbParameters(); +} + +INSTANTIATE_TEST_SUITE_P( + EnvironmentalReverbTest, EnvironmentalReverbDecayHfRatioTest, + ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors( + IFactory::descriptor, kEnvReverbTypeUUID)), + testing::ValuesIn(kDecayHfRatioValues)), + [](const testing::TestParamInfo& info) { + auto descriptor = std::get<0>(info.param).second; + std::string decayHfRatio = std::to_string(std::get<1>(info.param)); + + std::string name = "Implementor_" + descriptor.common.implementor + "_name_" + + descriptor.common.name + "_UUID_" + + descriptor.common.id.uuid.toString() + "_decayHfRatio" + + decayHfRatio; + std::replace_if( + name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_'); + return name; + }); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbDecayHfRatioTest); + +class EnvironmentalReverbLevelTest + : public ::testing::TestWithParam< + std::tuple, Descriptor>, int>>, + public EnvironmentalReverbHelper { + public: + EnvironmentalReverbLevelTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) { + mLevel = std::get<1>(GetParam()); + } + + void SetUp() override { SetUpReverb(); } + + void TearDown() override { TearDownReverb(); } +}; + +TEST_P(EnvironmentalReverbLevelTest, SetAndGetLevel) { + EXPECT_NO_FATAL_FAILURE(addLevelParam(mLevel)); + SetAndGetReverbParameters(); +} + +INSTANTIATE_TEST_SUITE_P( + EnvironmentalReverbTest, EnvironmentalReverbLevelTest, + ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors( + IFactory::descriptor, kEnvReverbTypeUUID)), + testing::ValuesIn(kLevelValues)), + [](const testing::TestParamInfo& info) { + auto descriptor = std::get<0>(info.param).second; + std::string level = std::to_string(std::get<1>(info.param)); + + std::string name = "Implementor_" + descriptor.common.implementor + "_name_" + + descriptor.common.name + "_UUID_" + + descriptor.common.id.uuid.toString() + "_level" + level; + std::replace_if( + name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_'); + return name; + }); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbLevelTest); + +class EnvironmentalReverbDelayTest + : public ::testing::TestWithParam< + std::tuple, Descriptor>, int>>, + public EnvironmentalReverbHelper { + public: + EnvironmentalReverbDelayTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) { + mDelay = std::get<1>(GetParam()); + } + + void SetUp() override { SetUpReverb(); } + + void TearDown() override { TearDownReverb(); } +}; + +TEST_P(EnvironmentalReverbDelayTest, SetAndGetDelay) { + EXPECT_NO_FATAL_FAILURE(addDelayParam(mDelay)); + SetAndGetReverbParameters(); +} + +INSTANTIATE_TEST_SUITE_P( + EnvironmentalReverbTest, EnvironmentalReverbDelayTest, + ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors( + IFactory::descriptor, kEnvReverbTypeUUID)), + testing::ValuesIn(kDelayValues)), + [](const testing::TestParamInfo& info) { + auto descriptor = std::get<0>(info.param).second; + std::string delay = std::to_string(std::get<1>(info.param)); + + std::string name = "Implementor_" + descriptor.common.implementor + "_name_" + + descriptor.common.name + "_UUID_" + + descriptor.common.id.uuid.toString() + "_delay" + delay; + std::replace_if( + name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_'); + return name; + }); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbDelayTest); + +class EnvironmentalReverbDiffusionTest + : public ::testing::TestWithParam< + std::tuple, Descriptor>, int>>, + public EnvironmentalReverbHelper { + public: + EnvironmentalReverbDiffusionTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) { + mDiffusion = std::get<1>(GetParam()); + } + + void SetUp() override { SetUpReverb(); } + + void TearDown() override { TearDownReverb(); } +}; + +TEST_P(EnvironmentalReverbDiffusionTest, SetAndGetDiffusion) { + EXPECT_NO_FATAL_FAILURE(addDiffusionParam(mDiffusion)); + SetAndGetReverbParameters(); +} + +INSTANTIATE_TEST_SUITE_P( + EnvironmentalReverbTest, EnvironmentalReverbDiffusionTest, + ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors( + IFactory::descriptor, kEnvReverbTypeUUID)), + testing::ValuesIn(kDiffusionValues)), + [](const testing::TestParamInfo& info) { + auto descriptor = std::get<0>(info.param).second; + std::string diffusion = std::to_string(std::get<1>(info.param)); + + std::string name = "Implementor_" + descriptor.common.implementor + "_name_" + + descriptor.common.name + "_UUID_" + + descriptor.common.id.uuid.toString() + "_diffusion" + diffusion; + std::replace_if( + name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_'); + return name; + }); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbDiffusionTest); + +class EnvironmentalReverbDensityTest + : public ::testing::TestWithParam< + std::tuple, Descriptor>, int>>, + public EnvironmentalReverbHelper { + public: + EnvironmentalReverbDensityTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) { + mDensity = std::get<1>(GetParam()); + } + + void SetUp() override { SetUpReverb(); } + + void TearDown() override { TearDownReverb(); } +}; + +TEST_P(EnvironmentalReverbDensityTest, SetAndGetDensity) { + EXPECT_NO_FATAL_FAILURE(addDensityParam(mDensity)); + SetAndGetReverbParameters(); +} + +INSTANTIATE_TEST_SUITE_P( + EnvironmentalReverbTest, EnvironmentalReverbDensityTest, + ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors( + IFactory::descriptor, kEnvReverbTypeUUID)), + testing::ValuesIn(kDensityValues)), + [](const testing::TestParamInfo& info) { + auto descriptor = std::get<0>(info.param).second; + std::string density = std::to_string(std::get<1>(info.param)); + + std::string name = "Implementor_" + descriptor.common.implementor + "_name_" + + descriptor.common.name + "_UUID_" + + descriptor.common.id.uuid.toString() + "_density" + density; + std::replace_if( + name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_'); + return name; + }); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbDensityTest); + +class EnvironmentalReverbBypassTest + : public ::testing::TestWithParam< + std::tuple, Descriptor>, bool>>, + public EnvironmentalReverbHelper { + public: + EnvironmentalReverbBypassTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) { + mBypass = std::get<1>(GetParam()); + } + + void SetUp() override { SetUpReverb(); } + + void TearDown() override { TearDownReverb(); } +}; + +TEST_P(EnvironmentalReverbBypassTest, SetAndGetBypass) { + EXPECT_NO_FATAL_FAILURE(addBypassParam(mBypass)); + SetAndGetReverbParameters(); +} + +INSTANTIATE_TEST_SUITE_P( + EnvironmentalReverbTest, EnvironmentalReverbBypassTest, + ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors( + IFactory::descriptor, kEnvReverbTypeUUID)), + testing::Bool()), + [](const testing::TestParamInfo& info) { + auto descriptor = std::get<0>(info.param).second; + std::string bypass = std::to_string(std::get<1>(info.param)); + + std::string name = "Implementor_" + descriptor.common.implementor + "_name_" + + descriptor.common.name + "_UUID_" + + descriptor.common.id.uuid.toString() + "_bypass" + bypass; + std::replace_if( + name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_'); + return name; + }); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbBypassTest); + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + ABinderProcess_setThreadPoolMaxThreadCount(1); + ABinderProcess_startThreadPool(); + return RUN_ALL_TESTS(); +}