blob: 3e6fa7a7c29c9fa5bc697053996dea2511db6de5 [file] [log] [blame]
Ram Mohane4064ce2022-12-20 18:05:14 +05301/*
2 * Copyright (C) 2023 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#include <aidl/Vintf.h>
18
19#define LOG_TAG "VtsHalDynamicsProcessingTest"
20
21#include <set>
22#include <string>
23#include <unordered_map>
24#include <unordered_set>
25
26#include <Utils.h>
27#include "EffectHelper.h"
28
29using namespace android;
30
Ram Mohane4064ce2022-12-20 18:05:14 +053031using aidl::android::hardware::audio::effect::Descriptor;
32using aidl::android::hardware::audio::effect::DynamicsProcessing;
33using aidl::android::hardware::audio::effect::IEffect;
34using aidl::android::hardware::audio::effect::IFactory;
35using aidl::android::hardware::audio::effect::kDynamicsProcessingTypeUUID;
36using aidl::android::hardware::audio::effect::Parameter;
37
38/**
39 * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
40 * VtsAudioEffectTargetTest.
41 */
42class DynamicsProcessingTestHelper : public EffectHelper {
43 public:
44 DynamicsProcessingTestHelper(std::pair<std::shared_ptr<IFactory>, Descriptor> pair,
45 int32_t channelLayOut = AudioChannelLayout::LAYOUT_STEREO) {
46 std::tie(mFactory, mDescriptor) = pair;
47 mChannelLayout = channelLayOut;
48 mChannelCount = ::android::hardware::audio::common::getChannelCount(
49 AudioChannelLayout::make<AudioChannelLayout::layoutMask>(mChannelLayout));
50 }
51
52 // setup
53 void SetUpDynamicsProcessingEffect() {
54 ASSERT_NE(nullptr, mFactory);
55 ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
56
57 Parameter::Specific specific = getDefaultParamSpecific();
58 Parameter::Common common = EffectHelper::createParamCommon(
59 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
60 0x100 /* iFrameCount */, 0x100 /* oFrameCount */,
61 AudioChannelLayout::make<AudioChannelLayout::layoutMask>(mChannelLayout),
62 AudioChannelLayout::make<AudioChannelLayout::layoutMask>(mChannelLayout));
63 IEffect::OpenEffectReturn ret;
64 ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
65 ASSERT_NE(nullptr, mEffect);
66 mEngineConfigApplied = mEngineConfigPreset;
67 }
68
69 Parameter::Specific getDefaultParamSpecific() {
70 DynamicsProcessing dp = DynamicsProcessing::make<DynamicsProcessing::engineArchitecture>(
71 mEngineConfigPreset);
72 Parameter::Specific specific =
73 Parameter::Specific::make<Parameter::Specific::dynamicsProcessing>(dp);
74 return specific;
75 }
76
77 // teardown
78 void TearDownDynamicsProcessingEffect() {
79 ASSERT_NO_FATAL_FAILURE(close(mEffect));
80 ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
81 }
82
83 // utils functions for parameter checking
Ram Mohane4064ce2022-12-20 18:05:14 +053084 bool isParamEqual(const DynamicsProcessing::Tag& tag, const DynamicsProcessing& dpRef,
85 const DynamicsProcessing& dpTest);
Ram Mohane4064ce2022-12-20 18:05:14 +053086 bool isEngineConfigEqual(const DynamicsProcessing::EngineArchitecture& refCfg,
87 const DynamicsProcessing::EngineArchitecture& testCfg);
88
89 template <typename T>
90 std::vector<T> filterEnabledVector(const std::vector<T>& vec);
91
92 template <typename T>
93 bool isAidlVectorEqualAfterFilter(const std::vector<T>& source, const std::vector<T>& target);
94
95 template <typename T>
96 bool isAidlVectorEqual(const std::vector<T>& source, const std::vector<T>& target);
97
98 // get set params and validate
99 void SetAndGetDynamicsProcessingParameters();
100
101 // enqueue test parameters
102 void addEngineConfig(const DynamicsProcessing::EngineArchitecture& cfg);
103 void addPreEqChannelConfig(const std::vector<DynamicsProcessing::ChannelConfig>& cfg);
104 void addPostEqChannelConfig(const std::vector<DynamicsProcessing::ChannelConfig>& cfg);
105 void addMbcChannelConfig(const std::vector<DynamicsProcessing::ChannelConfig>& cfg);
106 void addPreEqBandConfigs(const std::vector<DynamicsProcessing::EqBandConfig>& cfgs);
107 void addPostEqBandConfigs(const std::vector<DynamicsProcessing::EqBandConfig>& cfgs);
108 void addMbcBandConfigs(const std::vector<DynamicsProcessing::MbcBandConfig>& cfgs);
109 void addLimiterConfig(const std::vector<DynamicsProcessing::LimiterConfig>& cfg);
110 void addInputGain(const std::vector<DynamicsProcessing::InputGain>& inputGain);
111
112 static constexpr float kPreferredProcessingDurationMs = 10.0f;
113 static constexpr int kBandCount = 5;
114 std::shared_ptr<IFactory> mFactory;
115 std::shared_ptr<IEffect> mEffect;
116 Descriptor mDescriptor;
117 DynamicsProcessing::EngineArchitecture mEngineConfigApplied;
118 DynamicsProcessing::EngineArchitecture mEngineConfigPreset{
119 .resolutionPreference =
120 DynamicsProcessing::ResolutionPreference::FAVOR_FREQUENCY_RESOLUTION,
121 .preferredProcessingDurationMs = kPreferredProcessingDurationMs,
122 .preEqStage = {.inUse = true, .bandCount = kBandCount},
123 .postEqStage = {.inUse = true, .bandCount = kBandCount},
124 .mbcStage = {.inUse = true, .bandCount = kBandCount},
125 .limiterInUse = true,
126 };
127
128 std::unordered_set<int /* channelId */> mPreEqChannelEnable;
129 std::unordered_set<int /* channelId */> mPostEqChannelEnable;
130 std::unordered_set<int /* channelId */> mMbcChannelEnable;
131 std::unordered_set<int /* channelId */> mLimiterChannelEnable;
132 static const std::set<std::vector<DynamicsProcessing::ChannelConfig>> kChannelConfigTestSet;
133 static const std::set<DynamicsProcessing::StageEnablement> kStageEnablementTestSet;
134 static const std::set<std::vector<DynamicsProcessing::InputGain>> kInputGainTestSet;
135
136 private:
137 int32_t mChannelLayout;
138 int mChannelCount;
139 std::vector<std::pair<DynamicsProcessing::Tag, DynamicsProcessing>> mTags;
140 void CleanUp() {
141 mTags.clear();
142 mPreEqChannelEnable.clear();
143 mPostEqChannelEnable.clear();
144 mMbcChannelEnable.clear();
145 mLimiterChannelEnable.clear();
146 }
147};
148
149// test value set for DynamicsProcessing::StageEnablement
150const std::set<DynamicsProcessing::StageEnablement>
151 DynamicsProcessingTestHelper::kStageEnablementTestSet = {
152 {.inUse = true, .bandCount = DynamicsProcessingTestHelper::kBandCount},
153 {.inUse = true, .bandCount = 0},
154 {.inUse = true, .bandCount = -1},
155 {.inUse = false, .bandCount = DynamicsProcessingTestHelper::kBandCount}};
156
157// test value set for DynamicsProcessing::ChannelConfig
158const std::set<std::vector<DynamicsProcessing::ChannelConfig>>
159 DynamicsProcessingTestHelper::kChannelConfigTestSet = {
160 {{.channel = -1, .enable = false},
161 {.channel = 0, .enable = true},
162 {.channel = 1, .enable = false},
163 {.channel = 2, .enable = true}},
164
165 {{.channel = -1, .enable = false}, {.channel = 2, .enable = true}},
166
167 {{.channel = 0, .enable = true}, {.channel = 1, .enable = true}}};
168
169// test value set for DynamicsProcessing::InputGain
170const std::set<std::vector<DynamicsProcessing::InputGain>>
171 DynamicsProcessingTestHelper::kInputGainTestSet = {
172 {{.channel = 0, .gainDb = 10.f},
173 {.channel = 1, .gainDb = 0.f},
174 {.channel = 2, .gainDb = -10.f}},
175
176 {{.channel = -1, .gainDb = -10.f}, {.channel = -2, .gainDb = 10.f}},
177
178 {{.channel = -1, .gainDb = 10.f}, {.channel = 0, .gainDb = -10.f}}};
179
Ram Mohane4064ce2022-12-20 18:05:14 +0530180bool DynamicsProcessingTestHelper::isParamEqual(const DynamicsProcessing::Tag& tag,
181 const DynamicsProcessing& dpRef,
182 const DynamicsProcessing& dpTest) {
183 switch (tag) {
184 case DynamicsProcessing::engineArchitecture: {
185 return isEngineConfigEqual(dpRef.get<DynamicsProcessing::engineArchitecture>(),
186 dpTest.get<DynamicsProcessing::engineArchitecture>());
187 }
188 case DynamicsProcessing::preEq: {
189 const auto& source = dpRef.get<DynamicsProcessing::preEq>();
190 const auto& target = dpTest.get<DynamicsProcessing::preEq>();
191 return isAidlVectorEqualAfterFilter<DynamicsProcessing::ChannelConfig>(source, target);
192 }
193 case DynamicsProcessing::postEq: {
194 return isAidlVectorEqualAfterFilter<DynamicsProcessing::ChannelConfig>(
195 dpRef.get<DynamicsProcessing::postEq>(),
196 dpTest.get<DynamicsProcessing::postEq>());
197 }
198 case DynamicsProcessing::mbc: {
199 return isAidlVectorEqualAfterFilter<DynamicsProcessing::ChannelConfig>(
200 dpRef.get<DynamicsProcessing::mbc>(), dpTest.get<DynamicsProcessing::mbc>());
201 }
202 case DynamicsProcessing::preEqBand: {
203 return isAidlVectorEqualAfterFilter<DynamicsProcessing::EqBandConfig>(
204 dpRef.get<DynamicsProcessing::preEqBand>(),
205 dpTest.get<DynamicsProcessing::preEqBand>());
206 }
207 case DynamicsProcessing::postEqBand: {
208 return isAidlVectorEqualAfterFilter<DynamicsProcessing::EqBandConfig>(
209 dpRef.get<DynamicsProcessing::postEqBand>(),
210 dpTest.get<DynamicsProcessing::postEqBand>());
211 }
212 case DynamicsProcessing::mbcBand: {
213 return isAidlVectorEqualAfterFilter<DynamicsProcessing::MbcBandConfig>(
214 dpRef.get<DynamicsProcessing::mbcBand>(),
215 dpTest.get<DynamicsProcessing::mbcBand>());
216 }
217 case DynamicsProcessing::limiter: {
218 return isAidlVectorEqualAfterFilter<DynamicsProcessing::LimiterConfig>(
219 dpRef.get<DynamicsProcessing::limiter>(),
220 dpTest.get<DynamicsProcessing::limiter>());
221 }
222 case DynamicsProcessing::inputGain: {
223 return isAidlVectorEqual<DynamicsProcessing::InputGain>(
224 dpRef.get<DynamicsProcessing::inputGain>(),
225 dpTest.get<DynamicsProcessing::inputGain>());
226 }
Shunkai Yaob2325e52023-03-03 19:34:47 +0000227 case DynamicsProcessing::vendor: {
Ram Mohane4064ce2022-12-20 18:05:14 +0530228 return false;
229 }
230 }
231}
232
Ram Mohane4064ce2022-12-20 18:05:14 +0530233bool DynamicsProcessingTestHelper::isEngineConfigEqual(
234 const DynamicsProcessing::EngineArchitecture& ref,
235 const DynamicsProcessing::EngineArchitecture& test) {
236 return ref == test;
237}
238
239template <typename T>
240std::vector<T> DynamicsProcessingTestHelper::filterEnabledVector(const std::vector<T>& vec) {
241 std::vector<T> ret;
242 std::copy_if(vec.begin(), vec.end(), std::back_inserter(ret),
243 [](const auto& v) { return v.enable; });
244 return ret;
245}
246
247template <typename T>
248bool DynamicsProcessingTestHelper::isAidlVectorEqual(const std::vector<T>& source,
249 const std::vector<T>& target) {
250 if (source.size() != target.size()) return false;
251
252 auto tempS = source;
253 auto tempT = target;
254 std::sort(tempS.begin(), tempS.end());
255 std::sort(tempT.begin(), tempT.end());
256 return tempS == tempT;
257}
258
259template <typename T>
260bool DynamicsProcessingTestHelper::isAidlVectorEqualAfterFilter(const std::vector<T>& source,
261 const std::vector<T>& target) {
262 return isAidlVectorEqual<T>(filterEnabledVector<T>(source), filterEnabledVector<T>(target));
263}
264
265void DynamicsProcessingTestHelper::SetAndGetDynamicsProcessingParameters() {
266 for (auto& it : mTags) {
267 auto& tag = it.first;
268 auto& dp = it.second;
269
270 // validate parameter
271 Descriptor desc;
272 ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
Shunkai Yao0a0c45e2023-02-13 17:41:11 +0000273 const bool valid =
274 isParameterValid<DynamicsProcessing, Range::dynamicsProcessing>(dp, desc);
Ram Mohane4064ce2022-12-20 18:05:14 +0530275 const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
276
277 // set parameter
278 Parameter expectParam;
279 Parameter::Specific specific;
280 specific.set<Parameter::Specific::dynamicsProcessing>(dp);
281 expectParam.set<Parameter::specific>(specific);
Shunkai Yao0a0c45e2023-02-13 17:41:11 +0000282 ASSERT_STATUS(expected, mEffect->setParameter(expectParam))
283 << "\n"
284 << expectParam.toString() << "\n"
285 << desc.toString();
Ram Mohane4064ce2022-12-20 18:05:14 +0530286
287 // only get if parameter in range and set success
288 if (expected == EX_NONE) {
289 Parameter getParam;
290 Parameter::Id id;
291 DynamicsProcessing::Id dpId;
292 dpId.set<DynamicsProcessing::Id::commonTag>(tag);
293 id.set<Parameter::Id::dynamicsProcessingTag>(dpId);
294 // if set success, then get should match
295 EXPECT_STATUS(expected, mEffect->getParameter(id, &getParam));
296 Parameter::Specific specificTest = getParam.get<Parameter::specific>();
297 const auto& target = specificTest.get<Parameter::Specific::dynamicsProcessing>();
298 EXPECT_TRUE(isParamEqual(tag, dp, target)) << dp.toString() << "\n"
299 << target.toString();
300 // update mEngineConfigApplied after setting successfully
301 if (tag == DynamicsProcessing::engineArchitecture) {
302 mEngineConfigApplied = target.get<DynamicsProcessing::engineArchitecture>();
303 }
304 }
305 }
306}
307
308void DynamicsProcessingTestHelper::addEngineConfig(
309 const DynamicsProcessing::EngineArchitecture& cfg) {
310 DynamicsProcessing dp;
311 dp.set<DynamicsProcessing::engineArchitecture>(cfg);
312 mTags.push_back({DynamicsProcessing::engineArchitecture, dp});
313}
314
315void DynamicsProcessingTestHelper::addPreEqChannelConfig(
316 const std::vector<DynamicsProcessing::ChannelConfig>& cfgs) {
317 DynamicsProcessing dp;
318 dp.set<DynamicsProcessing::preEq>(cfgs);
319 mTags.push_back({DynamicsProcessing::preEq, dp});
320 for (auto& cfg : cfgs) {
321 if (cfg.enable) mPreEqChannelEnable.insert(cfg.channel);
322 }
323}
324
325void DynamicsProcessingTestHelper::addPostEqChannelConfig(
326 const std::vector<DynamicsProcessing::ChannelConfig>& cfgs) {
327 DynamicsProcessing dp;
328 dp.set<DynamicsProcessing::postEq>(cfgs);
329 mTags.push_back({DynamicsProcessing::postEq, dp});
330 for (auto& cfg : cfgs) {
331 if (cfg.enable) mPostEqChannelEnable.insert(cfg.channel);
332 }
333}
334
335void DynamicsProcessingTestHelper::addMbcChannelConfig(
336 const std::vector<DynamicsProcessing::ChannelConfig>& cfgs) {
337 DynamicsProcessing dp;
338 dp.set<DynamicsProcessing::mbc>(cfgs);
339 mTags.push_back({DynamicsProcessing::mbc, dp});
340 for (auto& cfg : cfgs) {
341 if (cfg.enable) mMbcChannelEnable.insert(cfg.channel);
342 }
343}
344
345void DynamicsProcessingTestHelper::addPreEqBandConfigs(
346 const std::vector<DynamicsProcessing::EqBandConfig>& cfgs) {
347 DynamicsProcessing dp;
348 dp.set<DynamicsProcessing::preEqBand>(cfgs);
349 mTags.push_back({DynamicsProcessing::preEqBand, dp});
350}
351
352void DynamicsProcessingTestHelper::addPostEqBandConfigs(
353 const std::vector<DynamicsProcessing::EqBandConfig>& cfgs) {
354 DynamicsProcessing dp;
355 dp.set<DynamicsProcessing::postEqBand>(cfgs);
356 mTags.push_back({DynamicsProcessing::postEqBand, dp});
357}
358
359void DynamicsProcessingTestHelper::addMbcBandConfigs(
360 const std::vector<DynamicsProcessing::MbcBandConfig>& cfgs) {
361 DynamicsProcessing dp;
362 dp.set<DynamicsProcessing::mbcBand>(cfgs);
363 mTags.push_back({DynamicsProcessing::mbcBand, dp});
364}
365
366void DynamicsProcessingTestHelper::addLimiterConfig(
367 const std::vector<DynamicsProcessing::LimiterConfig>& cfgs) {
368 DynamicsProcessing dp;
369 dp.set<DynamicsProcessing::limiter>(cfgs);
370 mTags.push_back({DynamicsProcessing::limiter, dp});
371 for (auto& cfg : cfgs) {
372 if (cfg.enable) mLimiterChannelEnable.insert(cfg.channel);
373 }
374}
375
376void DynamicsProcessingTestHelper::addInputGain(
377 const std::vector<DynamicsProcessing::InputGain>& inputGains) {
378 DynamicsProcessing dp;
379 dp.set<DynamicsProcessing::inputGain>(inputGains);
380 mTags.push_back({DynamicsProcessing::inputGain, dp});
381}
382
383/**
384 * Test DynamicsProcessing Engine Configuration
385 */
386enum EngineArchitectureTestParamName {
387 ENGINE_TEST_INSTANCE_NAME,
388 ENGINE_TEST_RESOLUTION_PREFERENCE,
389 ENGINE_TEST_PREFERRED_DURATION,
390 ENGINE_TEST_STAGE_ENABLEMENT,
391 ENGINE_TEST_LIMITER_IN_USE
392};
393using EngineArchitectureTestParams = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
394 DynamicsProcessing::ResolutionPreference, float,
395 DynamicsProcessing::StageEnablement, bool>;
396
397void fillEngineArchConfig(DynamicsProcessing::EngineArchitecture& cfg,
398 const EngineArchitectureTestParams& params) {
399 cfg.resolutionPreference = std::get<ENGINE_TEST_RESOLUTION_PREFERENCE>(params);
400 cfg.preferredProcessingDurationMs = std::get<ENGINE_TEST_PREFERRED_DURATION>(params);
401 cfg.preEqStage = cfg.postEqStage = cfg.mbcStage =
402 std::get<ENGINE_TEST_STAGE_ENABLEMENT>(params);
403 cfg.limiterInUse = std::get<ENGINE_TEST_LIMITER_IN_USE>(params);
404}
405
406class DynamicsProcessingTestEngineArchitecture
407 : public ::testing::TestWithParam<EngineArchitectureTestParams>,
408 public DynamicsProcessingTestHelper {
409 public:
410 DynamicsProcessingTestEngineArchitecture()
411 : DynamicsProcessingTestHelper(std::get<ENGINE_TEST_INSTANCE_NAME>(GetParam())) {
412 fillEngineArchConfig(mCfg, GetParam());
413 };
414
415 void SetUp() override { SetUpDynamicsProcessingEffect(); }
416
417 void TearDown() override { TearDownDynamicsProcessingEffect(); }
418
419 DynamicsProcessing::EngineArchitecture mCfg;
420};
421
422TEST_P(DynamicsProcessingTestEngineArchitecture, SetAndGetEngineArch) {
423 EXPECT_NO_FATAL_FAILURE(addEngineConfig(mCfg));
424 SetAndGetDynamicsProcessingParameters();
425}
426
427INSTANTIATE_TEST_SUITE_P(
428 DynamicsProcessingTest, DynamicsProcessingTestEngineArchitecture,
429 ::testing::Combine(
430 testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
431 IFactory::descriptor, kDynamicsProcessingTypeUUID)),
432 testing::Values(DynamicsProcessing::ResolutionPreference::FAVOR_TIME_RESOLUTION,
433 DynamicsProcessing::ResolutionPreference::
434 FAVOR_FREQUENCY_RESOLUTION), // variant
435 testing::Values(-10.f, 0.f, 10.f), // processing duration
436 testing::ValuesIn(
437 DynamicsProcessingTestHelper::kStageEnablementTestSet), // preEQ/postEQ/mbc
438 testing::Bool()), // limiter enable
439 [](const auto& info) {
440 auto descriptor = std::get<ENGINE_TEST_INSTANCE_NAME>(info.param).second;
441 DynamicsProcessing::EngineArchitecture cfg;
442 fillEngineArchConfig(cfg, info.param);
443 std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
444 descriptor.common.name + "_UUID_" +
445 descriptor.common.id.uuid.toString() + "_Cfg_" + cfg.toString();
446 std::replace_if(
447 name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
448 return name;
449 });
450GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingTestEngineArchitecture);
451
452/**
453 * Test DynamicsProcessing Input Gain
454 */
455enum InputGainTestParamName {
456 INPUT_GAIN_INSTANCE_NAME,
457 INPUT_GAIN_PARAM,
458};
459class DynamicsProcessingTestInputGain
460 : public ::testing::TestWithParam<std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
461 std::vector<DynamicsProcessing::InputGain>>>,
462 public DynamicsProcessingTestHelper {
463 public:
464 DynamicsProcessingTestInputGain()
465 : DynamicsProcessingTestHelper(std::get<INPUT_GAIN_INSTANCE_NAME>(GetParam())),
466 mInputGain(std::get<INPUT_GAIN_PARAM>(GetParam())){};
467
468 void SetUp() override { SetUpDynamicsProcessingEffect(); }
469
470 void TearDown() override { TearDownDynamicsProcessingEffect(); }
471
472 const std::vector<DynamicsProcessing::InputGain> mInputGain;
473};
474
475TEST_P(DynamicsProcessingTestInputGain, SetAndGetInputGain) {
476 EXPECT_NO_FATAL_FAILURE(addInputGain(mInputGain));
477 SetAndGetDynamicsProcessingParameters();
478}
479
480INSTANTIATE_TEST_SUITE_P(
481 DynamicsProcessingTest, DynamicsProcessingTestInputGain,
482 ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
483 IFactory::descriptor, kDynamicsProcessingTypeUUID)),
484 testing::ValuesIn(DynamicsProcessingTestInputGain::kInputGainTestSet)),
485 [](const auto& info) {
486 auto descriptor = std::get<INPUT_GAIN_INSTANCE_NAME>(info.param).second;
487 std::string gains =
488 ::android::internal::ToString(std::get<INPUT_GAIN_PARAM>(info.param));
489 std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
490 descriptor.common.name + "_UUID_" +
491 descriptor.common.id.uuid.toString() + "_inputGains_" + gains;
492 std::replace_if(
493 name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
494 return name;
495 });
496GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingTestInputGain);
497
498/**
499 * Test DynamicsProcessing Limiter Config
500 */
501enum LimiterConfigTestParamName {
502 LIMITER_INSTANCE_NAME,
503 LIMITER_CHANNEL,
504 LIMITER_ENABLE,
505 LIMITER_LINK_GROUP,
506 LIMITER_ENGINE_IN_USE,
507 LIMITER_ADDITIONAL,
508};
509enum LimiterConfigTestAdditionalParam {
510 LIMITER_ATTACK_TIME,
511 LIMITER_RELEASE_TIME,
512 LIMITER_RATIO,
513 LIMITER_THRESHOLD,
514 LIMITER_POST_GAIN,
515 LIMITER_MAX_NUM,
516};
517using LimiterConfigTestAdditional = std::array<float, LIMITER_MAX_NUM>;
518// attachTime, releaseTime, ratio, thresh, postGain
519static constexpr std::array<LimiterConfigTestAdditional, 4> kLimiterConfigTestAdditionalParam = {
520 {{-1, -60, -2.5, -2, -3.14},
521 {-1, 60, -2.5, 2, -3.14},
522 {1, -60, 2.5, -2, 3.14},
523 {1, 60, 2.5, 2, 3.14}}};
524
525using LimiterConfigTestParams =
526 std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t, bool, int32_t, bool,
527 LimiterConfigTestAdditional>;
528
529void fillLimiterConfig(DynamicsProcessing::LimiterConfig& cfg,
530 const LimiterConfigTestParams& params) {
531 const std::array<float, LIMITER_MAX_NUM> additional = std::get<LIMITER_ADDITIONAL>(params);
532 cfg.channel = std::get<LIMITER_CHANNEL>(params);
533 cfg.enable = std::get<LIMITER_ENABLE>(params);
534 cfg.linkGroup = std::get<LIMITER_LINK_GROUP>(params);
535 cfg.attackTimeMs = additional[LIMITER_ATTACK_TIME];
536 cfg.releaseTimeMs = additional[LIMITER_RELEASE_TIME];
537 cfg.ratio = additional[LIMITER_RATIO];
538 cfg.thresholdDb = additional[LIMITER_THRESHOLD];
539 cfg.postGainDb = additional[LIMITER_POST_GAIN];
540}
541
542class DynamicsProcessingTestLimiterConfig
543 : public ::testing::TestWithParam<LimiterConfigTestParams>,
544 public DynamicsProcessingTestHelper {
545 public:
546 DynamicsProcessingTestLimiterConfig()
547 : DynamicsProcessingTestHelper(std::get<LIMITER_INSTANCE_NAME>(GetParam())),
548 mLimiterInUseEngine(std::get<LIMITER_ENGINE_IN_USE>(GetParam())) {
549 fillLimiterConfig(mCfg, GetParam());
550 }
551
552 void SetUp() override { SetUpDynamicsProcessingEffect(); }
553
554 void TearDown() override { TearDownDynamicsProcessingEffect(); }
555
556 DynamicsProcessing::LimiterConfig mCfg;
557 bool mLimiterInUseEngine;
558};
559
560TEST_P(DynamicsProcessingTestLimiterConfig, SetAndGetLimiterConfig) {
561 mEngineConfigPreset.limiterInUse = mLimiterInUseEngine;
562 EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
563 EXPECT_NO_FATAL_FAILURE(addLimiterConfig({mCfg}));
564 SetAndGetDynamicsProcessingParameters();
565}
566
567INSTANTIATE_TEST_SUITE_P(
568 DynamicsProcessingTest, DynamicsProcessingTestLimiterConfig,
569 ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
570 IFactory::descriptor, kDynamicsProcessingTypeUUID)),
571 testing::Values(-1, 0, 1, 2), // channel count
572 testing::Bool(), // enable
573 testing::Values(3), // link group
574 testing::Bool(), // engine limiter enable
575 testing::ValuesIn(kLimiterConfigTestAdditionalParam)), // Additional
576 [](const auto& info) {
577 auto descriptor = std::get<LIMITER_INSTANCE_NAME>(info.param).second;
578 DynamicsProcessing::LimiterConfig cfg;
579 fillLimiterConfig(cfg, info.param);
580 std::string engineLimiterInUse =
581 std::to_string(std::get<LIMITER_ENGINE_IN_USE>(info.param));
582 std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
583 descriptor.common.name + "_UUID_" +
584 descriptor.common.id.uuid.toString() + "_limiterConfig_" +
585 cfg.toString() + "_engineSetting_" + engineLimiterInUse;
586 std::replace_if(
587 name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
588 return name;
589 });
590GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingTestLimiterConfig);
591
592/**
593 * Test DynamicsProcessing ChannelConfig
594 */
595enum ChannelConfigTestParamName {
596 BAND_CHANNEL_TEST_INSTANCE_NAME,
597 BAND_CHANNEL_TEST_CHANNEL_CONFIG,
598 BAND_CHANNEL_TEST_ENGINE_IN_USE
599};
600using ChannelConfigTestParams = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
601 std::vector<DynamicsProcessing::ChannelConfig>, bool>;
602
603class DynamicsProcessingTestChannelConfig
604 : public ::testing::TestWithParam<ChannelConfigTestParams>,
605 public DynamicsProcessingTestHelper {
606 public:
607 DynamicsProcessingTestChannelConfig()
608 : DynamicsProcessingTestHelper(std::get<BAND_CHANNEL_TEST_INSTANCE_NAME>(GetParam())),
609 mCfg(std::get<BAND_CHANNEL_TEST_CHANNEL_CONFIG>(GetParam())),
610 mInUseEngine(std::get<BAND_CHANNEL_TEST_ENGINE_IN_USE>(GetParam())) {}
611
612 void SetUp() override { SetUpDynamicsProcessingEffect(); }
613
614 void TearDown() override { TearDownDynamicsProcessingEffect(); }
615
616 std::vector<DynamicsProcessing::ChannelConfig> mCfg;
617 const bool mInUseEngine;
618};
619
620TEST_P(DynamicsProcessingTestChannelConfig, SetAndGetPreEqChannelConfig) {
621 mEngineConfigPreset.preEqStage.inUse = mInUseEngine;
622 EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
623 EXPECT_NO_FATAL_FAILURE(addPreEqChannelConfig(mCfg));
624 SetAndGetDynamicsProcessingParameters();
625}
626
627TEST_P(DynamicsProcessingTestChannelConfig, SetAndGetPostEqChannelConfig) {
628 mEngineConfigPreset.postEqStage.inUse = mInUseEngine;
629 EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
630 EXPECT_NO_FATAL_FAILURE(addPostEqChannelConfig(mCfg));
631 SetAndGetDynamicsProcessingParameters();
632}
633
634TEST_P(DynamicsProcessingTestChannelConfig, SetAndGetMbcChannelConfig) {
635 mEngineConfigPreset.mbcStage.inUse = mInUseEngine;
636 EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
637 EXPECT_NO_FATAL_FAILURE(addMbcChannelConfig(mCfg));
638 SetAndGetDynamicsProcessingParameters();
639}
640
641INSTANTIATE_TEST_SUITE_P(
642 DynamicsProcessingTest, DynamicsProcessingTestChannelConfig,
643 ::testing::Combine(
644 testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
645 IFactory::descriptor, kDynamicsProcessingTypeUUID)),
646 testing::ValuesIn(
647 DynamicsProcessingTestHelper::kChannelConfigTestSet), // channel config
648 testing::Bool()), // Engine inUse
649 [](const auto& info) {
650 auto descriptor = std::get<BAND_CHANNEL_TEST_INSTANCE_NAME>(info.param).second;
651 std::string engineInUse =
652 std::to_string(std::get<BAND_CHANNEL_TEST_ENGINE_IN_USE>(info.param));
653 std::string channelConfig = ::android::internal::ToString(
654 std::get<BAND_CHANNEL_TEST_CHANNEL_CONFIG>(info.param));
655
656 std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
657 descriptor.common.name + "_UUID_" +
658 descriptor.common.id.uuid.toString() + "_" + channelConfig +
659 "_engineInUse_" + engineInUse;
660 std::replace_if(
661 name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
662 return name;
663 });
664GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingTestChannelConfig);
665
666/**
667 * Test DynamicsProcessing EqBandConfig
668 */
669enum EqBandConfigTestParamName {
670 EQ_BAND_INSTANCE_NAME,
671 EQ_BAND_CHANNEL,
672 EQ_BAND_CHANNEL_ENABLE,
673 EQ_BAND_ENABLE,
674 EQ_BAND_CUT_OFF_FREQ,
675 EQ_BAND_GAIN,
676 EQ_BAND_STAGE_IN_USE
677};
678using EqBandConfigTestParams = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t,
679 std::vector<DynamicsProcessing::ChannelConfig>, bool,
680 std::vector<std::pair<int, float>>, float, bool>;
681
682void fillEqBandConfig(std::vector<DynamicsProcessing::EqBandConfig>& cfgs,
683 const EqBandConfigTestParams& params) {
684 const std::vector<std::pair<int, float>> cutOffFreqs = std::get<EQ_BAND_CUT_OFF_FREQ>(params);
685 int bandCount = cutOffFreqs.size();
686 cfgs.resize(bandCount);
687 for (int i = 0; i < bandCount; i++) {
688 cfgs[i].channel = std::get<EQ_BAND_CHANNEL>(params);
689 cfgs[i].band = cutOffFreqs[i].first;
690 cfgs[i].enable = std::get<EQ_BAND_ENABLE>(params);
691 cfgs[i].cutoffFrequencyHz = cutOffFreqs[i].second;
692 cfgs[i].gainDb = std::get<EQ_BAND_GAIN>(params);
693 }
694}
695
696class DynamicsProcessingTestEqBandConfig : public ::testing::TestWithParam<EqBandConfigTestParams>,
697 public DynamicsProcessingTestHelper {
698 public:
699 DynamicsProcessingTestEqBandConfig()
700 : DynamicsProcessingTestHelper(std::get<EQ_BAND_INSTANCE_NAME>(GetParam())),
701 mStageInUse(std::get<EQ_BAND_STAGE_IN_USE>(GetParam())),
702 mChannelConfig(std::get<EQ_BAND_CHANNEL_ENABLE>(GetParam())) {
703 fillEqBandConfig(mCfgs, GetParam());
704 }
705
706 void SetUp() override { SetUpDynamicsProcessingEffect(); }
707
708 void TearDown() override { TearDownDynamicsProcessingEffect(); }
709
710 std::vector<DynamicsProcessing::EqBandConfig> mCfgs;
711 const bool mStageInUse;
712 const std::vector<DynamicsProcessing::ChannelConfig> mChannelConfig;
713};
714
715TEST_P(DynamicsProcessingTestEqBandConfig, SetAndGetPreEqBandConfig) {
716 mEngineConfigPreset.preEqStage.inUse = mStageInUse;
717 mEngineConfigPreset.preEqStage.bandCount = mCfgs.size();
718 EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
719 EXPECT_NO_FATAL_FAILURE(addPreEqChannelConfig(mChannelConfig));
720 EXPECT_NO_FATAL_FAILURE(addPreEqBandConfigs(mCfgs));
721 SetAndGetDynamicsProcessingParameters();
722}
723
724TEST_P(DynamicsProcessingTestEqBandConfig, SetAndGetPostEqBandConfig) {
725 mEngineConfigPreset.postEqStage.inUse = mStageInUse;
726 mEngineConfigPreset.postEqStage.bandCount = mCfgs.size();
727 EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
728 EXPECT_NO_FATAL_FAILURE(addPostEqChannelConfig(mChannelConfig));
729 EXPECT_NO_FATAL_FAILURE(addPostEqBandConfigs(mCfgs));
730 SetAndGetDynamicsProcessingParameters();
731}
732
733std::vector<std::vector<std::pair<int, float>>> kBands{
734 {
735 {0, 600},
736 {1, 2000},
737 {2, 6000},
738 {3, 10000},
739 {4, 16000},
740 }, // 5 bands
741 {
742 {0, 800},
743 {3, 15000},
744 {2, 6000},
745 {1, 2000},
746 }, // 4 bands, unsorted
747 {
748 {0, 650},
749 {1, 2000},
750 {2, 6000},
751 {3, 10000},
752 {3, 16000},
753 }, // 5 bands, missing band
754 {
755 {0, 900},
756 {1, 8000},
757 {2, 4000},
758 {3, 12000},
759 }, // 4 bands, cutoff freq not increasing
760 {
761 {0, 450},
762 {1, 2000},
763 {7, 6000},
764 {3, 10000},
765 {4, 16000},
766 }, // bad band index
767 {
768 {0, 1},
769 {1, 8000},
770 }, // too low cutoff freq
771 {
772 {0, 1200},
773 {1, 80000},
774 }, // too high cutoff freq
775};
776
777INSTANTIATE_TEST_SUITE_P(
778 DynamicsProcessingTest, DynamicsProcessingTestEqBandConfig,
779 ::testing::Combine(
780 testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
781 IFactory::descriptor, kDynamicsProcessingTypeUUID)),
782 testing::Values(-1, 0, 10), // channel ID
783 testing::ValuesIn(
784 DynamicsProcessingTestHelper::kChannelConfigTestSet), // channel enable
785 testing::Bool(), // band enable
786 testing::ValuesIn(kBands), // cut off frequencies
787 testing::Values(-3.14f, 3.14f), // gain
788 testing::Bool()), // stage in use
789 [](const auto& info) {
790 auto descriptor = std::get<EQ_BAND_INSTANCE_NAME>(info.param).second;
791 std::vector<DynamicsProcessing::EqBandConfig> cfgs;
792 fillEqBandConfig(cfgs, info.param);
793 std::string enable =
794 ::android::internal::ToString(std::get<EQ_BAND_CHANNEL_ENABLE>(info.param));
795 std::string bands = ::android::internal::ToString(cfgs);
796 std::string stageInUse = std::to_string(std::get<EQ_BAND_STAGE_IN_USE>(info.param));
797 std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
798 descriptor.common.name + "_UUID_" +
799 descriptor.common.id.uuid.toString() + "_" + enable + "_bands_" +
800 bands + "_stageInUse_" + stageInUse;
801 std::replace_if(
802 name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
803 return name;
804 });
805GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingTestEqBandConfig);
806
807/**
808 * Test DynamicsProcessing MbcBandConfig
809 */
810
811enum MbcBandConfigParamName {
812 MBC_BAND_INSTANCE_NAME,
813 MBC_BAND_CHANNEL,
814 MBC_BAND_CHANNEL_CONFIG,
815 MBC_BAND_ENABLE,
816 MBC_BAND_CUTOFF_FREQ,
817 MBC_BAND_STAGE_IN_USE,
818 MBC_BAND_ADDITIONAL
819};
820enum MbcBandConfigAdditional {
821 MBC_ADD_ATTACK_TIME,
822 MBC_ADD_RELEASE_TIME,
823 MBC_ADD_RATIO,
824 MBC_ADD_THRESHOLD,
825 MBC_ADD_KNEE_WIDTH,
826 MBC_ADD_NOISE_GATE_THRESHOLD,
827 MBC_ADD_EXPENDER_RATIO,
828 MBC_ADD_PRE_GAIN,
829 MBC_ADD_POST_GAIN,
830 MBC_ADD_MAX_NUM
831};
832using TestParamsMbcBandConfigAdditional = std::array<float, MBC_ADD_MAX_NUM>;
833
834// attachTime, releaseTime, ratio, thresh, kneeWidth, noise, expander, preGain, postGain
835static constexpr std::array<TestParamsMbcBandConfigAdditional, 4> kMbcBandConfigAdditionalParam = {
836 {{-3, -10, -2, -2, -5, -90, -2.5, -2, -2},
837 {0, 0, 0, 0, 0, 0, 0, 0, 0},
838 {-3, 10, -2, 2, -5, 90, -2.5, 2, -2},
839 {3, 10, 2, 2, 5, 90, 2.5, 2, 2}}};
840
841using TestParamsMbcBandConfig =
842 std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t,
843 std::vector<DynamicsProcessing::ChannelConfig>, bool,
844 std::vector<std::pair<int, float>>, bool, TestParamsMbcBandConfigAdditional>;
845
846void fillMbcBandConfig(std::vector<DynamicsProcessing::MbcBandConfig>& cfgs,
847 const TestParamsMbcBandConfig& params) {
848 const std::vector<std::pair<int, float>> cutOffFreqs = std::get<MBC_BAND_CUTOFF_FREQ>(params);
849 const std::array<float, MBC_ADD_MAX_NUM> additional = std::get<MBC_BAND_ADDITIONAL>(params);
850 int bandCount = cutOffFreqs.size();
851 cfgs.resize(bandCount);
852 for (int i = 0; i < bandCount; i++) {
853 cfgs[i] = DynamicsProcessing::MbcBandConfig{
854 .channel = std::get<MBC_BAND_CHANNEL>(params),
855 .band = cutOffFreqs[i].first,
856 .enable = std::get<MBC_BAND_ENABLE>(params),
857 .cutoffFrequencyHz = cutOffFreqs[i].second,
858 .attackTimeMs = additional[MBC_ADD_ATTACK_TIME],
859 .releaseTimeMs = additional[MBC_ADD_RELEASE_TIME],
860 .ratio = additional[MBC_ADD_RATIO],
861 .thresholdDb = additional[MBC_ADD_THRESHOLD],
862 .kneeWidthDb = additional[MBC_ADD_KNEE_WIDTH],
863 .noiseGateThresholdDb = additional[MBC_ADD_NOISE_GATE_THRESHOLD],
864 .expanderRatio = additional[MBC_ADD_EXPENDER_RATIO],
865 .preGainDb = additional[MBC_ADD_PRE_GAIN],
866 .postGainDb = additional[MBC_ADD_POST_GAIN]};
867 }
868}
869
870class DynamicsProcessingTestMbcBandConfig
871 : public ::testing::TestWithParam<TestParamsMbcBandConfig>,
872 public DynamicsProcessingTestHelper {
873 public:
874 DynamicsProcessingTestMbcBandConfig()
875 : DynamicsProcessingTestHelper(std::get<MBC_BAND_INSTANCE_NAME>(GetParam())),
876 mStageInUse(std::get<MBC_BAND_STAGE_IN_USE>(GetParam())),
877 mChannelConfig(std::get<MBC_BAND_CHANNEL_CONFIG>(GetParam())) {
878 fillMbcBandConfig(mCfgs, GetParam());
879 }
880
881 void SetUp() override { SetUpDynamicsProcessingEffect(); }
882
883 void TearDown() override { TearDownDynamicsProcessingEffect(); }
884
885 std::vector<DynamicsProcessing::MbcBandConfig> mCfgs;
886 const bool mStageInUse;
887 const std::vector<DynamicsProcessing::ChannelConfig> mChannelConfig;
888};
889
890TEST_P(DynamicsProcessingTestMbcBandConfig, SetAndGetMbcBandConfig) {
891 mEngineConfigPreset.mbcStage.inUse = mStageInUse;
892 mEngineConfigPreset.mbcStage.bandCount = mCfgs.size();
893 EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
894 EXPECT_NO_FATAL_FAILURE(addMbcChannelConfig(mChannelConfig));
895 EXPECT_NO_FATAL_FAILURE(addMbcBandConfigs(mCfgs));
896 SetAndGetDynamicsProcessingParameters();
897}
898
899INSTANTIATE_TEST_SUITE_P(
900 DynamicsProcessingTest, DynamicsProcessingTestMbcBandConfig,
901 ::testing::Combine(
902 testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
903 IFactory::descriptor, kDynamicsProcessingTypeUUID)),
904 testing::Values(-1, 0, 10), // channel count
905 testing::ValuesIn(
906 DynamicsProcessingTestHelper::kChannelConfigTestSet), // channel config
907 testing::Bool(), // enable
908 testing::ValuesIn(kBands), // cut off frequencies
909 testing::Bool(), // stage in use
910 testing::ValuesIn(kMbcBandConfigAdditionalParam)), // Additional
911 [](const auto& info) {
912 auto descriptor = std::get<MBC_BAND_INSTANCE_NAME>(info.param).second;
913 std::vector<DynamicsProcessing::MbcBandConfig> cfgs;
914 fillMbcBandConfig(cfgs, info.param);
915 std::string enable =
916 ::android::internal::ToString(std::get<MBC_BAND_CHANNEL_CONFIG>(info.param));
917 std::string mbcBands = ::android::internal::ToString(cfgs);
918 std::string stageInUse = std::to_string(std::get<MBC_BAND_STAGE_IN_USE>(info.param));
919 std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
920 descriptor.common.name + "_UUID_" +
921 descriptor.common.id.uuid.toString() + "_enable_" + enable +
922 "_bands_" + mbcBands + "_stageInUse_" + stageInUse;
923 std::replace_if(
924 name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
925 return name;
926 });
927GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingTestMbcBandConfig);
928
929int main(int argc, char** argv) {
930 ::testing::InitGoogleTest(&argc, argv);
931 ABinderProcess_setThreadPoolMaxThreadCount(1);
932 ABinderProcess_startThreadPool();
933 return RUN_ALL_TESTS();
934}