xref: /aosp_15_r20/hardware/interfaces/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "VtsHalPresetReverbTargetTest"
18 #include <android-base/logging.h>
19 #include <android/binder_enums.h>
20 #include <audio_utils/power.h>
21 #include <system/audio.h>
22 
23 #include "EffectHelper.h"
24 
25 using namespace android;
26 
27 using aidl::android::hardware::audio::common::getChannelCount;
28 using aidl::android::hardware::audio::effect::Descriptor;
29 using aidl::android::hardware::audio::effect::getEffectTypeUuidPresetReverb;
30 using aidl::android::hardware::audio::effect::IEffect;
31 using aidl::android::hardware::audio::effect::IFactory;
32 using aidl::android::hardware::audio::effect::Parameter;
33 using aidl::android::hardware::audio::effect::PresetReverb;
34 using android::hardware::audio::common::testing::detail::TestExecutionTracer;
35 
36 class PresetReverbHelper : public EffectHelper {
37   public:
SetUpPresetReverb()38     void SetUpPresetReverb() {
39         ASSERT_NE(nullptr, mFactory);
40         ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
41         Parameter::Specific specific = getDefaultParamSpecific();
42         Parameter::Common common = createParamCommon(
43                 0 /* session */, 1 /* ioHandle */, kSamplingFrequency /* iSampleRate */,
44                 kSamplingFrequency /* oSampleRate */, mFrameCount /* iFrameCount */,
45                 mFrameCount /* oFrameCount */);
46         ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &mOpenEffectReturn, EX_NONE));
47         ASSERT_NE(nullptr, mEffect);
48     }
49 
TearDownPresetReverb()50     void TearDownPresetReverb() {
51         ASSERT_NO_FATAL_FAILURE(close(mEffect));
52         ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
53         mOpenEffectReturn = IEffect::OpenEffectReturn{};
54     }
55 
getDefaultParamSpecific()56     Parameter::Specific getDefaultParamSpecific() {
57         PresetReverb pr = PresetReverb::make<PresetReverb::preset>(kDefaultPreset);
58         Parameter::Specific specific =
59                 Parameter::Specific::make<Parameter::Specific::presetReverb>(pr);
60         return specific;
61     }
62 
createPresetReverbParam(const PresetReverb::Presets & param)63     Parameter createPresetReverbParam(const PresetReverb::Presets& param) {
64         return Parameter::make<Parameter::specific>(
65                 Parameter::Specific::make<Parameter::Specific::presetReverb>(
66                         PresetReverb::make<PresetReverb::preset>(param)));
67     }
68 
setAndVerifyPreset(const PresetReverb::Presets & param)69     void setAndVerifyPreset(const PresetReverb::Presets& param) {
70         auto expectedParam = createPresetReverbParam(param);
71         EXPECT_STATUS(EX_NONE, mEffect->setParameter(expectedParam)) << expectedParam.toString();
72 
73         PresetReverb::Id revId =
74                 PresetReverb::Id::make<PresetReverb::Id::commonTag>(PresetReverb::preset);
75 
76         auto id = Parameter::Id::make<Parameter::Id::presetReverbTag>(revId);
77         // get parameter
78         Parameter getParam;
79         EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
80         EXPECT_EQ(expectedParam, getParam) << "\nexpectedParam:" << expectedParam.toString()
81                                            << "\ngetParam:" << getParam.toString();
82     }
83 
84     static constexpr int kDurationMilliSec = 500;
85     static constexpr int kBufferSize = kSamplingFrequency * kDurationMilliSec / 1000;
86     int mStereoChannelCount =
87             getChannelCount(AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
88                     AudioChannelLayout::LAYOUT_STEREO));
89     PresetReverb::Presets kDefaultPreset = PresetReverb::Presets::NONE;
90     int mFrameCount = kBufferSize / mStereoChannelCount;
91     std::shared_ptr<IFactory> mFactory;
92     std::shared_ptr<IEffect> mEffect;
93     IEffect::OpenEffectReturn mOpenEffectReturn;
94     Descriptor mDescriptor;
95 };
96 
97 /**
98  * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
99  * VtsAudioEffectTargetTest.
100  */
101 enum ParamName { PARAM_INSTANCE_NAME, PARAM_PRESETS };
102 using PresetReverbParamTestParam =
103         std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, PresetReverb::Presets>;
104 
105 // Testing for enum values
106 const std::vector<PresetReverb::Presets> kPresetsValues{
107         ndk::enum_range<PresetReverb::Presets>().begin(),
108         ndk::enum_range<PresetReverb::Presets>().end()};
109 
110 class PresetReverbParamTest : public ::testing::TestWithParam<PresetReverbParamTestParam>,
111                               public PresetReverbHelper {
112   public:
PresetReverbParamTest()113     PresetReverbParamTest() : mParamPreset(std::get<PARAM_PRESETS>(GetParam())) {
114         std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
115     }
116 
SetUp()117     void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpPresetReverb()); }
118 
TearDown()119     void TearDown() override { TearDownPresetReverb(); }
120 
121     const PresetReverb::Presets mParamPreset;
122 };
123 
TEST_P(PresetReverbParamTest,SetAndGetPresets)124 TEST_P(PresetReverbParamTest, SetAndGetPresets) {
125     ASSERT_NO_FATAL_FAILURE(setAndVerifyPreset(mParamPreset));
126 }
127 
128 using PresetReverbProcessTestParam = std::pair<std::shared_ptr<IFactory>, Descriptor>;
129 
130 class PresetReverbProcessTest : public ::testing::TestWithParam<PresetReverbProcessTestParam>,
131                                 public PresetReverbHelper {
132   public:
PresetReverbProcessTest()133     PresetReverbProcessTest() {
134         std::tie(mFactory, mDescriptor) = GetParam();
135         mInput.resize(kBufferSize);
136         generateSineWave(1000 /*Input Frequency*/, mInput);
137     }
138 
SetUp()139     void SetUp() override {
140         SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
141         ASSERT_NO_FATAL_FAILURE(SetUpPresetReverb());
142     }
TearDown()143     void TearDown() override {
144         SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
145         ASSERT_NO_FATAL_FAILURE(TearDownPresetReverb());
146     }
147 
isAuxiliary()148     bool isAuxiliary() {
149         return mDescriptor.common.flags.type ==
150                aidl::android::hardware::audio::effect::Flags::Type::AUXILIARY;
151     }
152 
computeReverbOutputEnergy(std::vector<float> output)153     float computeReverbOutputEnergy(std::vector<float> output) {
154         if (!isAuxiliary()) {
155             // Extract auxiliary output
156             for (size_t i = 0; i < output.size(); i++) {
157                 output[i] -= mInput[i];
158             }
159         }
160         return (audio_utils_compute_energy_mono(output.data(), AUDIO_FORMAT_PCM_FLOAT,
161                                                 output.size()));
162     }
163 
setPresetAndProcess(const PresetReverb::Presets & preset,std::vector<float> & output)164     void setPresetAndProcess(const PresetReverb::Presets& preset, std::vector<float>& output) {
165         ASSERT_NO_FATAL_FAILURE(setAndVerifyPreset(preset));
166         ASSERT_NO_FATAL_FAILURE(
167                 processAndWriteToOutput(mInput, output, mEffect, &mOpenEffectReturn));
168     }
169 
validateIncreasingEnergy(const std::vector<PresetReverb::Presets> & presets)170     void validateIncreasingEnergy(const std::vector<PresetReverb::Presets>& presets) {
171         float baseOutputEnergy = 0;
172 
173         for (PresetReverb::Presets preset : presets) {
174             std::vector<float> output(kBufferSize);
175             setPresetAndProcess(preset, output);
176             float outputEnergy = computeReverbOutputEnergy(output);
177 
178             ASSERT_GT(outputEnergy, baseOutputEnergy);
179             baseOutputEnergy = outputEnergy;
180         }
181     }
182 
183     std::vector<float> mInput;
184 };
185 
TEST_P(PresetReverbProcessTest,DecreasingRoomSize)186 TEST_P(PresetReverbProcessTest, DecreasingRoomSize) {
187     std::vector<PresetReverb::Presets> roomPresets = {PresetReverb::Presets::LARGEROOM,
188                                                       PresetReverb::Presets::MEDIUMROOM,
189                                                       PresetReverb::Presets::SMALLROOM};
190     validateIncreasingEnergy(roomPresets);
191 }
192 
TEST_P(PresetReverbProcessTest,DecreasingHallSize)193 TEST_P(PresetReverbProcessTest, DecreasingHallSize) {
194     std::vector<PresetReverb::Presets> hallPresets = {PresetReverb::Presets::LARGEHALL,
195                                                       PresetReverb::Presets::MEDIUMHALL};
196     validateIncreasingEnergy(hallPresets);
197 }
198 
TEST_P(PresetReverbProcessTest,PresetPlate)199 TEST_P(PresetReverbProcessTest, PresetPlate) {
200     std::vector<float> output(kBufferSize);
201 
202     setPresetAndProcess(PresetReverb::Presets::PLATE, output);
203     float outputEnergy = computeReverbOutputEnergy(output);
204     // Since there is no comparator preset, validating it is greater than zero
205     ASSERT_GT(outputEnergy, 0);
206 }
207 
TEST_P(PresetReverbProcessTest,PresetNone)208 TEST_P(PresetReverbProcessTest, PresetNone) {
209     std::vector<float> output(kBufferSize);
210 
211     setPresetAndProcess(kDefaultPreset, output);
212     float outputEnergy = computeReverbOutputEnergy(output);
213     // NONE type doesn't create reverb effect
214     ASSERT_EQ(outputEnergy, 0);
215 }
216 
217 INSTANTIATE_TEST_SUITE_P(
218         PresetReverbTest, PresetReverbParamTest,
219         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
220                                    IFactory::descriptor, getEffectTypeUuidPresetReverb())),
221                            testing::ValuesIn(kPresetsValues)),
__anon4356e2de0102(const testing::TestParamInfo<PresetReverbParamTest::ParamType>& info) 222         [](const testing::TestParamInfo<PresetReverbParamTest::ParamType>& info) {
223             auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
224             std::string preset =
225                     std::to_string(static_cast<int>(std::get<PARAM_PRESETS>(info.param)));
226             std::string name = getPrefix(descriptor) + "_preset" + preset;
227             std::replace_if(
228                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
229             return name;
230         });
231 
232 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PresetReverbParamTest);
233 
234 INSTANTIATE_TEST_SUITE_P(
235         PresetReverbTest, PresetReverbProcessTest,
236         testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
237                 IFactory::descriptor, getEffectTypeUuidPresetReverb())),
__anon4356e2de0302(const testing::TestParamInfo<PresetReverbProcessTest::ParamType>& info) 238         [](const testing::TestParamInfo<PresetReverbProcessTest::ParamType>& info) {
239             auto descriptor = info.param;
240             return getPrefix(descriptor.second);
241         });
242 
243 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PresetReverbProcessTest);
244 
main(int argc,char ** argv)245 int main(int argc, char** argv) {
246     ::testing::InitGoogleTest(&argc, argv);
247     ::testing::UnitTest::GetInstance()->listeners().Append(new TestExecutionTracer());
248     ABinderProcess_setThreadPoolMaxThreadCount(1);
249     ABinderProcess_startThreadPool();
250     return RUN_ALL_TESTS();
251 }
252