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