• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <audio_utils/power.h>
24 #include <audio_utils/primitives.h>
25 
26 #include <Utils.h>
27 
28 #include "EffectHelper.h"
29 #include "EffectRangeSpecific.h"
30 
31 using namespace android;
32 using namespace aidl::android::hardware::audio::effect::DynamicsProcessingRanges;
33 
34 using aidl::android::hardware::audio::effect::Descriptor;
35 using aidl::android::hardware::audio::effect::DynamicsProcessing;
36 using aidl::android::hardware::audio::effect::getEffectTypeUuidDynamicsProcessing;
37 using aidl::android::hardware::audio::effect::IEffect;
38 using aidl::android::hardware::audio::effect::IFactory;
39 using aidl::android::hardware::audio::effect::Parameter;
40 using android::hardware::audio::common::testing::detail::TestExecutionTracer;
41 
42 constexpr int32_t kMinDataTestHalVersion = 3;
43 
44 /**
45  * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
46  * VtsAudioEffectTargetTest.
47  */
48 class DynamicsProcessingTestHelper : public EffectHelper {
49   public:
DynamicsProcessingTestHelper(std::pair<std::shared_ptr<IFactory>,Descriptor> pair,int32_t channelLayout=kDefaultChannelLayout)50     DynamicsProcessingTestHelper(std::pair<std::shared_ptr<IFactory>, Descriptor> pair,
51                                  int32_t channelLayout = kDefaultChannelLayout)
52         : mChannelLayout(channelLayout),
53           mChannelCount(::aidl::android::hardware::audio::common::getChannelCount(
54                   AudioChannelLayout::make<AudioChannelLayout::layoutMask>(mChannelLayout))) {
55         std::tie(mFactory, mDescriptor) = pair;
56     }
57 
58     // setup
SetUpDynamicsProcessingEffect()59     void SetUpDynamicsProcessingEffect() {
60         ASSERT_NE(nullptr, mFactory);
61         ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
62         Parameter::Specific specific = getDefaultParamSpecific();
63         Parameter::Common common = createParamCommon(
64                 0 /* session */, 1 /* ioHandle */, kSamplingFrequency /* iSampleRate */,
65                 kSamplingFrequency /* oSampleRate */, kFrameCount /* iFrameCount */,
66                 kFrameCount /* oFrameCount */,
67                 AudioChannelLayout::make<AudioChannelLayout::layoutMask>(mChannelLayout),
68                 AudioChannelLayout::make<AudioChannelLayout::layoutMask>(mChannelLayout));
69         ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &mOpenEffectReturn, EX_NONE));
70         ASSERT_NE(nullptr, mEffect);
71         mEngineConfigApplied = mEngineConfigPreset;
72     }
73 
getDefaultParamSpecific()74     Parameter::Specific getDefaultParamSpecific() {
75         DynamicsProcessing dp = DynamicsProcessing::make<DynamicsProcessing::engineArchitecture>(
76                 mEngineConfigPreset);
77         Parameter::Specific specific =
78                 Parameter::Specific::make<Parameter::Specific::dynamicsProcessing>(dp);
79         return specific;
80     }
81 
82     // teardown
TearDownDynamicsProcessingEffect()83     void TearDownDynamicsProcessingEffect() {
84         ASSERT_NO_FATAL_FAILURE(close(mEffect));
85         ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
86     }
87 
88     // utils functions for parameter checking
89     bool isParamEqual(const DynamicsProcessing::Tag& tag, const DynamicsProcessing& dpRef,
90                       const DynamicsProcessing& dpTest);
91     bool isEngineConfigEqual(const DynamicsProcessing::EngineArchitecture& refCfg,
92                              const DynamicsProcessing::EngineArchitecture& testCfg);
93 
94     template <typename T>
95     std::vector<T> filterEnabledVector(const std::vector<T>& vec);
96 
97     template <typename T>
98     bool isAidlVectorEqualAfterFilter(const std::vector<T>& source, const std::vector<T>& target);
99 
100     template <typename T>
101     bool isAidlVectorEqual(const std::vector<T>& source, const std::vector<T>& target);
102 
103     template <typename T>
isChannelConfigValid(const std::vector<T> & cfgs)104     bool isChannelConfigValid(const std::vector<T>& cfgs) {
105         auto& channelCount = mChannelCount;
106         return std::all_of(cfgs.cbegin(), cfgs.cend(), [channelCount](const T& cfg) {
107             return (cfg.channel >= 0 && cfg.channel < channelCount);
108         });
109     }
110 
111     template <typename T>
112     bool isBandConfigValid(const std::vector<T>& cfgs, int bandCount);
113 
114     bool isParamValid(const DynamicsProcessing::Tag& tag, const DynamicsProcessing& dp);
115 
116     // get set params and validate
117     void SetAndGetDynamicsProcessingParameters();
118 
119     bool isAllParamsValid();
120 
121     void setParamsAndProcess(std::vector<float>& input, std::vector<float>& output);
122 
123     float calculateDb(const std::vector<float>& input, size_t startSamplePos);
124 
125     void getMagnitudeValue(const std::vector<float>& output, std::vector<float>& bufferMag);
126 
127     void checkInputAndOutputEquality(const std::vector<float>& outputMag);
128 
129     void setUpDataTest(const std::vector<int>& testFrequencies, float fullScaleSineDb);
130     void tearDownDataTest();
131 
132     void createChannelConfig();
133 
134     // enqueue test parameters
135     void addEngineConfig(const DynamicsProcessing::EngineArchitecture& cfg);
136     void addPreEqChannelConfig(const std::vector<DynamicsProcessing::ChannelConfig>& cfg);
137     void addPostEqChannelConfig(const std::vector<DynamicsProcessing::ChannelConfig>& cfg);
138     void addMbcChannelConfig(const std::vector<DynamicsProcessing::ChannelConfig>& cfg);
139     void addPreEqBandConfigs(const std::vector<DynamicsProcessing::EqBandConfig>& cfgs);
140     void addPostEqBandConfigs(const std::vector<DynamicsProcessing::EqBandConfig>& cfgs);
141     void addMbcBandConfigs(const std::vector<DynamicsProcessing::MbcBandConfig>& cfgs);
142     void addLimiterConfig(const std::vector<DynamicsProcessing::LimiterConfig>& cfg);
143     void addInputGain(const std::vector<DynamicsProcessing::InputGain>& inputGain);
144 
145     static constexpr float kPreferredProcessingDurationMs = 10.0f;
146     static constexpr int kBandCount = 5;
147     static constexpr int kSamplingFrequency = 44100;
148     static constexpr int kFrameCount = 2048;
149     static constexpr int kInputFrequency = 1000;
150     static constexpr size_t kStartIndex = 15 * kSamplingFrequency / 1000;  // skip 15ms
151     static constexpr float kToleranceDb = 0.5;
152     static constexpr int kNPointFFT = 1024;
153     static constexpr float kBinWidth = (float)kSamplingFrequency / kNPointFFT;
154     // Full scale sine wave with 1000 Hz frequency is -3 dB
155     static constexpr float kSineFullScaleDb = -3;
156     // Full scale sine wave with 100 Hz and 1000 Hz frequency is -6 dB
157     static constexpr float kSineMultitoneFullScaleDb = -6;
158     const std::vector<int> kCutoffFreqHz = {200 /*0th band cutoff*/, 2000 /*1st band cutoff*/};
159     std::vector<int> mMultitoneTestFrequencies = {100, 1000};
160     // Calculating normalizing factor by dividing the number of FFT points by half and the number of
161     // test frequencies. The normalization accounts for the FFT splitting the signal into positive
162     // and negative frequencies. Additionally, during multi-tone input generation, sample values are
163     // normalized to the range [-1, 1] by dividing them by the number of test frequencies.
164     float mNormalizingFactor = (kNPointFFT / (2 * mMultitoneTestFrequencies.size()));
165     std::vector<int> mBinOffsets;
166     std::vector<DynamicsProcessing::ChannelConfig> mChannelConfig;
167     std::vector<float> mInput;
168     float mInputDb;
169     std::shared_ptr<IFactory> mFactory;
170     std::shared_ptr<IEffect> mEffect;
171     Descriptor mDescriptor;
172     IEffect::OpenEffectReturn mOpenEffectReturn;
173     DynamicsProcessing::EngineArchitecture mEngineConfigApplied;
174     DynamicsProcessing::EngineArchitecture mEngineConfigPreset{
175             .resolutionPreference =
176                     DynamicsProcessing::ResolutionPreference::FAVOR_FREQUENCY_RESOLUTION,
177             .preferredProcessingDurationMs = kPreferredProcessingDurationMs,
178             .preEqStage = {.inUse = true, .bandCount = kBandCount},
179             .postEqStage = {.inUse = true, .bandCount = kBandCount},
180             .mbcStage = {.inUse = true, .bandCount = kBandCount},
181             .limiterInUse = true,
182     };
183 
184     std::unordered_set<int /* channelId */> mPreEqChannelEnable;
185     std::unordered_set<int /* channelId */> mPostEqChannelEnable;
186     std::unordered_set<int /* channelId */> mMbcChannelEnable;
187     std::unordered_set<int /* channelId */> mLimiterChannelEnable;
188     static const std::set<std::vector<DynamicsProcessing::ChannelConfig>> kChannelConfigTestSet;
189     static const std::set<DynamicsProcessing::StageEnablement> kStageEnablementTestSet;
190     static const std::set<std::vector<DynamicsProcessing::InputGain>> kInputGainTestSet;
191 
192   private:
193     std::vector<std::pair<DynamicsProcessing::Tag, DynamicsProcessing>> mTags;
194 
195   protected:
196     const int32_t mChannelLayout;
197     const int mChannelCount;
198 
CleanUp()199     void CleanUp() {
200         mTags.clear();
201         mPreEqChannelEnable.clear();
202         mPostEqChannelEnable.clear();
203         mMbcChannelEnable.clear();
204         mLimiterChannelEnable.clear();
205     }
206 };
207 
208 // test value set for DynamicsProcessing::StageEnablement
209 const std::set<DynamicsProcessing::StageEnablement>
210         DynamicsProcessingTestHelper::kStageEnablementTestSet = {
211                 {.inUse = true, .bandCount = DynamicsProcessingTestHelper::kBandCount},
212                 {.inUse = true, .bandCount = 0},
213                 {.inUse = true, .bandCount = -1},
214                 {.inUse = false, .bandCount = 0},
215                 {.inUse = false, .bandCount = -1},
216                 {.inUse = false, .bandCount = DynamicsProcessingTestHelper::kBandCount}};
217 
218 // test value set for DynamicsProcessing::ChannelConfig
219 const std::set<std::vector<DynamicsProcessing::ChannelConfig>>
220         DynamicsProcessingTestHelper::kChannelConfigTestSet = {
221                 {{.channel = -1, .enable = false},
222                  {.channel = 0, .enable = true},
223                  {.channel = 1, .enable = false},
224                  {.channel = 2, .enable = true}},
225                 {{.channel = -1, .enable = false}, {.channel = 2, .enable = true}},
226                 {{.channel = 0, .enable = true}, {.channel = 1, .enable = true}}};
227 
228 // test value set for DynamicsProcessing::InputGain
229 const std::set<std::vector<DynamicsProcessing::InputGain>>
230         DynamicsProcessingTestHelper::kInputGainTestSet = {
231                 {{.channel = 0, .gainDb = 10.f},
232                  {.channel = 1, .gainDb = 0.f},
233                  {.channel = 2, .gainDb = -10.f}},
234                 {{.channel = -1, .gainDb = -10.f}, {.channel = -2, .gainDb = 10.f}},
235                 {{.channel = -1, .gainDb = 10.f}, {.channel = 0, .gainDb = -10.f}},
236                 {{.channel = 0, .gainDb = 10.f}, {.channel = 1, .gainDb = -10.f}}};
237 
238 template <typename T>
isBandConfigValid(const std::vector<T> & cfgs,int bandCount)239 bool DynamicsProcessingTestHelper::isBandConfigValid(const std::vector<T>& cfgs, int bandCount) {
240     std::unordered_set<int> freqs;
241     for (auto cfg : cfgs) {
242         if (cfg.channel < 0 || cfg.channel >= mChannelCount) return false;
243         if (cfg.band < 0 || cfg.band >= bandCount) return false;
244         // duplicated band index
245         if (freqs.find(cfg.band) != freqs.end()) return false;
246         freqs.insert(cfg.band);
247     }
248     return true;
249 }
250 
isParamValid(const DynamicsProcessing::Tag & tag,const DynamicsProcessing & dp)251 bool DynamicsProcessingTestHelper::isParamValid(const DynamicsProcessing::Tag& tag,
252                                                 const DynamicsProcessing& dp) {
253     switch (tag) {
254         case DynamicsProcessing::preEq: {
255             return isChannelConfigValid(dp.get<DynamicsProcessing::preEq>());
256         }
257         case DynamicsProcessing::postEq: {
258             return isChannelConfigValid(dp.get<DynamicsProcessing::postEq>());
259         }
260         case DynamicsProcessing::mbc: {
261             return isChannelConfigValid(dp.get<DynamicsProcessing::mbc>());
262         }
263         case DynamicsProcessing::preEqBand: {
264             return isBandConfigValid(dp.get<DynamicsProcessing::preEqBand>(),
265                                      mEngineConfigApplied.preEqStage.bandCount);
266         }
267         case DynamicsProcessing::postEqBand: {
268             return isBandConfigValid(dp.get<DynamicsProcessing::postEqBand>(),
269                                      mEngineConfigApplied.postEqStage.bandCount);
270         }
271         case DynamicsProcessing::mbcBand: {
272             return isBandConfigValid(dp.get<DynamicsProcessing::mbcBand>(),
273                                      mEngineConfigApplied.mbcStage.bandCount);
274         }
275         case DynamicsProcessing::limiter: {
276             return isChannelConfigValid(dp.get<DynamicsProcessing::limiter>());
277         }
278         case DynamicsProcessing::inputGain: {
279             return isChannelConfigValid(dp.get<DynamicsProcessing::inputGain>());
280         }
281         default: {
282             return true;
283         }
284     }
285     return true;
286 }
287 
isParamEqual(const DynamicsProcessing::Tag & tag,const DynamicsProcessing & dpRef,const DynamicsProcessing & dpTest)288 bool DynamicsProcessingTestHelper::isParamEqual(const DynamicsProcessing::Tag& tag,
289                                                 const DynamicsProcessing& dpRef,
290                                                 const DynamicsProcessing& dpTest) {
291     switch (tag) {
292         case DynamicsProcessing::engineArchitecture: {
293             return isEngineConfigEqual(dpRef.get<DynamicsProcessing::engineArchitecture>(),
294                                        dpTest.get<DynamicsProcessing::engineArchitecture>());
295         }
296         case DynamicsProcessing::preEq: {
297             const auto& source = dpRef.get<DynamicsProcessing::preEq>();
298             const auto& target = dpTest.get<DynamicsProcessing::preEq>();
299             return isAidlVectorEqualAfterFilter<DynamicsProcessing::ChannelConfig>(source, target);
300         }
301         case DynamicsProcessing::postEq: {
302             return isAidlVectorEqualAfterFilter<DynamicsProcessing::ChannelConfig>(
303                     dpRef.get<DynamicsProcessing::postEq>(),
304                     dpTest.get<DynamicsProcessing::postEq>());
305         }
306         case DynamicsProcessing::mbc: {
307             return isAidlVectorEqualAfterFilter<DynamicsProcessing::ChannelConfig>(
308                     dpRef.get<DynamicsProcessing::mbc>(), dpTest.get<DynamicsProcessing::mbc>());
309         }
310         case DynamicsProcessing::preEqBand: {
311             return isAidlVectorEqualAfterFilter<DynamicsProcessing::EqBandConfig>(
312                     dpRef.get<DynamicsProcessing::preEqBand>(),
313                     dpTest.get<DynamicsProcessing::preEqBand>());
314         }
315         case DynamicsProcessing::postEqBand: {
316             return isAidlVectorEqualAfterFilter<DynamicsProcessing::EqBandConfig>(
317                     dpRef.get<DynamicsProcessing::postEqBand>(),
318                     dpTest.get<DynamicsProcessing::postEqBand>());
319         }
320         case DynamicsProcessing::mbcBand: {
321             return isAidlVectorEqualAfterFilter<DynamicsProcessing::MbcBandConfig>(
322                     dpRef.get<DynamicsProcessing::mbcBand>(),
323                     dpTest.get<DynamicsProcessing::mbcBand>());
324         }
325         case DynamicsProcessing::limiter: {
326             return isAidlVectorEqualAfterFilter<DynamicsProcessing::LimiterConfig>(
327                     dpRef.get<DynamicsProcessing::limiter>(),
328                     dpTest.get<DynamicsProcessing::limiter>());
329         }
330         case DynamicsProcessing::inputGain: {
331             return isAidlVectorEqual<DynamicsProcessing::InputGain>(
332                     dpRef.get<DynamicsProcessing::inputGain>(),
333                     dpTest.get<DynamicsProcessing::inputGain>());
334         }
335         case DynamicsProcessing::vendor: {
336             return false;
337         }
338     }
339 }
340 
isEngineConfigEqual(const DynamicsProcessing::EngineArchitecture & ref,const DynamicsProcessing::EngineArchitecture & test)341 bool DynamicsProcessingTestHelper::isEngineConfigEqual(
342         const DynamicsProcessing::EngineArchitecture& ref,
343         const DynamicsProcessing::EngineArchitecture& test) {
344     return ref == test;
345 }
346 
347 template <typename T>
filterEnabledVector(const std::vector<T> & vec)348 std::vector<T> DynamicsProcessingTestHelper::filterEnabledVector(const std::vector<T>& vec) {
349     std::vector<T> ret;
350     std::copy_if(vec.begin(), vec.end(), std::back_inserter(ret),
351                  [](const auto& v) { return v.enable; });
352     return ret;
353 }
354 
355 template <typename T>
isAidlVectorEqual(const std::vector<T> & source,const std::vector<T> & target)356 bool DynamicsProcessingTestHelper::isAidlVectorEqual(const std::vector<T>& source,
357                                                      const std::vector<T>& target) {
358     if (source.size() != target.size()) return false;
359 
360     auto tempS = source;
361     auto tempT = target;
362     std::sort(tempS.begin(), tempS.end());
363     std::sort(tempT.begin(), tempT.end());
364     return tempS == tempT;
365 }
366 
367 template <typename T>
isAidlVectorEqualAfterFilter(const std::vector<T> & source,const std::vector<T> & target)368 bool DynamicsProcessingTestHelper::isAidlVectorEqualAfterFilter(const std::vector<T>& source,
369                                                                 const std::vector<T>& target) {
370     return isAidlVectorEqual<T>(filterEnabledVector<T>(source), filterEnabledVector<T>(target));
371 }
372 
SetAndGetDynamicsProcessingParameters()373 void DynamicsProcessingTestHelper::SetAndGetDynamicsProcessingParameters() {
374     for (const auto& [tag, dp] : mTags) {
375         // validate parameter
376         Descriptor desc;
377         ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
378         bool valid = isParamInRange(dp, desc.capability.range.get<Range::dynamicsProcessing>());
379         if (valid) valid = isParamValid(tag, dp);
380         const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
381 
382         // set parameter
383         Parameter expectParam;
384         Parameter::Specific specific;
385         specific.set<Parameter::Specific::dynamicsProcessing>(dp);
386         expectParam.set<Parameter::specific>(specific);
387         ASSERT_STATUS(expected, mEffect->setParameter(expectParam))
388                 << "\n"
389                 << expectParam.toString() << "\n"
390                 << desc.toString();
391 
392         // only get if parameter in range and set success
393         if (expected == EX_NONE) {
394             Parameter getParam;
395             Parameter::Id id;
396             DynamicsProcessing::Id dpId;
397             dpId.set<DynamicsProcessing::Id::commonTag>(tag);
398             id.set<Parameter::Id::dynamicsProcessingTag>(dpId);
399             // if set success, then get should match
400             EXPECT_STATUS(expected, mEffect->getParameter(id, &getParam));
401             Parameter::Specific specificTest = getParam.get<Parameter::specific>();
402             const auto& target = specificTest.get<Parameter::Specific::dynamicsProcessing>();
403             EXPECT_TRUE(isParamEqual(tag, dp, target)) << dp.toString() << "\n"
404                                                        << target.toString();
405             // update mEngineConfigApplied after setting successfully
406             if (tag == DynamicsProcessing::engineArchitecture) {
407                 mEngineConfigApplied = target.get<DynamicsProcessing::engineArchitecture>();
408             }
409         }
410     }
411 }
412 
isAllParamsValid()413 bool DynamicsProcessingTestHelper::isAllParamsValid() {
414     if (mTags.empty()) {
415         return false;
416     }
417     for (const auto& [tag, dp] : mTags) {
418         // validate parameter
419         if (!isParamInRange(dp, mDescriptor.capability.range.get<Range::dynamicsProcessing>())) {
420             return false;
421         }
422         if (!isParamValid(tag, dp)) {
423             return false;
424         }
425     }
426     return true;
427 }
428 
429 // This function calculates power for both and mono and stereo data as the total power for
430 // interleaved multichannel data can be calculated by treating it as a continuous mono input.
calculateDb(const std::vector<float> & input,size_t startSamplePos=0)431 float DynamicsProcessingTestHelper::calculateDb(const std::vector<float>& input,
432                                                 size_t startSamplePos = 0) {
433     return audio_utils_compute_power_mono(input.data() + startSamplePos, AUDIO_FORMAT_PCM_FLOAT,
434                                           input.size() - startSamplePos);
435 }
436 
setParamsAndProcess(std::vector<float> & input,std::vector<float> & output)437 void DynamicsProcessingTestHelper::setParamsAndProcess(std::vector<float>& input,
438                                                        std::vector<float>& output) {
439     ASSERT_NO_FATAL_FAILURE(SetAndGetDynamicsProcessingParameters());
440     if (isAllParamsValid()) {
441         ASSERT_NO_FATAL_FAILURE(
442                 processAndWriteToOutput(input, output, mEffect, &mOpenEffectReturn));
443         ASSERT_GT(output.size(), kStartIndex);
444     }
445 }
446 
getMagnitudeValue(const std::vector<float> & output,std::vector<float> & bufferMag)447 void DynamicsProcessingTestHelper::getMagnitudeValue(const std::vector<float>& output,
448                                                      std::vector<float>& bufferMag) {
449     std::vector<float> subOutput(output.begin() + kStartIndex, output.end());
450     EXPECT_NO_FATAL_FAILURE(calculateMagnitudeMono(bufferMag, subOutput, mBinOffsets, kNPointFFT));
451 }
452 
checkInputAndOutputEquality(const std::vector<float> & outputMag)453 void DynamicsProcessingTestHelper::checkInputAndOutputEquality(
454         const std::vector<float>& outputMag) {
455     std::vector<float> inputMag(mBinOffsets.size());
456     EXPECT_NO_FATAL_FAILURE(getMagnitudeValue(mInput, inputMag));
457     for (size_t i = 0; i < inputMag.size(); i++) {
458         EXPECT_NEAR(calculateDb({inputMag[i] / mNormalizingFactor}),
459                     calculateDb({outputMag[i] / mNormalizingFactor}), kToleranceDb);
460     }
461 }
462 
setUpDataTest(const std::vector<int> & testFrequencies,float fullScaleSineDb)463 void DynamicsProcessingTestHelper::setUpDataTest(const std::vector<int>& testFrequencies,
464                                                  float fullScaleSineDb) {
465     ASSERT_NO_FATAL_FAILURE(SetUpDynamicsProcessingEffect());
466     SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
467     SKIP_TEST_IF_VERSION_UNSUPPORTED(mEffect, kMinDataTestHalVersion);
468 
469     mInput.resize(kFrameCount * mChannelCount);
470     ASSERT_NO_FATAL_FAILURE(
471             generateSineWave(testFrequencies, mInput, 1.0, kSamplingFrequency, mChannelLayout));
472     mInputDb = calculateDb(mInput);
473     ASSERT_NEAR(mInputDb, fullScaleSineDb, kToleranceDb);
474 }
475 
tearDownDataTest()476 void DynamicsProcessingTestHelper::tearDownDataTest() {
477     ASSERT_NO_FATAL_FAILURE(TearDownDynamicsProcessingEffect());
478 }
479 
createChannelConfig()480 void DynamicsProcessingTestHelper::createChannelConfig() {
481     for (int i = 0; i < mChannelCount; i++) {
482         mChannelConfig.push_back(DynamicsProcessing::ChannelConfig(i, true));
483     }
484 }
485 
addEngineConfig(const DynamicsProcessing::EngineArchitecture & cfg)486 void DynamicsProcessingTestHelper::addEngineConfig(
487         const DynamicsProcessing::EngineArchitecture& cfg) {
488     DynamicsProcessing dp;
489     dp.set<DynamicsProcessing::engineArchitecture>(cfg);
490     mTags.push_back({DynamicsProcessing::engineArchitecture, dp});
491 }
492 
addPreEqChannelConfig(const std::vector<DynamicsProcessing::ChannelConfig> & cfgs)493 void DynamicsProcessingTestHelper::addPreEqChannelConfig(
494         const std::vector<DynamicsProcessing::ChannelConfig>& cfgs) {
495     DynamicsProcessing dp;
496     dp.set<DynamicsProcessing::preEq>(cfgs);
497     mTags.push_back({DynamicsProcessing::preEq, dp});
498     for (auto& cfg : cfgs) {
499         if (cfg.enable) mPreEqChannelEnable.insert(cfg.channel);
500     }
501 }
502 
addPostEqChannelConfig(const std::vector<DynamicsProcessing::ChannelConfig> & cfgs)503 void DynamicsProcessingTestHelper::addPostEqChannelConfig(
504         const std::vector<DynamicsProcessing::ChannelConfig>& cfgs) {
505     DynamicsProcessing dp;
506     dp.set<DynamicsProcessing::postEq>(cfgs);
507     mTags.push_back({DynamicsProcessing::postEq, dp});
508     for (auto& cfg : cfgs) {
509         if (cfg.enable) mPostEqChannelEnable.insert(cfg.channel);
510     }
511 }
512 
addMbcChannelConfig(const std::vector<DynamicsProcessing::ChannelConfig> & cfgs)513 void DynamicsProcessingTestHelper::addMbcChannelConfig(
514         const std::vector<DynamicsProcessing::ChannelConfig>& cfgs) {
515     DynamicsProcessing dp;
516     dp.set<DynamicsProcessing::mbc>(cfgs);
517     mTags.push_back({DynamicsProcessing::mbc, dp});
518     for (auto& cfg : cfgs) {
519         if (cfg.enable) mMbcChannelEnable.insert(cfg.channel);
520     }
521 }
522 
addPreEqBandConfigs(const std::vector<DynamicsProcessing::EqBandConfig> & cfgs)523 void DynamicsProcessingTestHelper::addPreEqBandConfigs(
524         const std::vector<DynamicsProcessing::EqBandConfig>& cfgs) {
525     DynamicsProcessing dp;
526     dp.set<DynamicsProcessing::preEqBand>(cfgs);
527     mTags.push_back({DynamicsProcessing::preEqBand, dp});
528 }
529 
addPostEqBandConfigs(const std::vector<DynamicsProcessing::EqBandConfig> & cfgs)530 void DynamicsProcessingTestHelper::addPostEqBandConfigs(
531         const std::vector<DynamicsProcessing::EqBandConfig>& cfgs) {
532     DynamicsProcessing dp;
533     dp.set<DynamicsProcessing::postEqBand>(cfgs);
534     mTags.push_back({DynamicsProcessing::postEqBand, dp});
535 }
536 
addMbcBandConfigs(const std::vector<DynamicsProcessing::MbcBandConfig> & cfgs)537 void DynamicsProcessingTestHelper::addMbcBandConfigs(
538         const std::vector<DynamicsProcessing::MbcBandConfig>& cfgs) {
539     DynamicsProcessing dp;
540     dp.set<DynamicsProcessing::mbcBand>(cfgs);
541     mTags.push_back({DynamicsProcessing::mbcBand, dp});
542 }
543 
addLimiterConfig(const std::vector<DynamicsProcessing::LimiterConfig> & cfgs)544 void DynamicsProcessingTestHelper::addLimiterConfig(
545         const std::vector<DynamicsProcessing::LimiterConfig>& cfgs) {
546     DynamicsProcessing dp;
547     dp.set<DynamicsProcessing::limiter>(cfgs);
548     mTags.push_back({DynamicsProcessing::limiter, dp});
549     for (auto& cfg : cfgs) {
550         if (cfg.enable) mLimiterChannelEnable.insert(cfg.channel);
551     }
552 }
553 
addInputGain(const std::vector<DynamicsProcessing::InputGain> & inputGains)554 void DynamicsProcessingTestHelper::addInputGain(
555         const std::vector<DynamicsProcessing::InputGain>& inputGains) {
556     DynamicsProcessing dp;
557     dp.set<DynamicsProcessing::inputGain>(inputGains);
558     mTags.push_back({DynamicsProcessing::inputGain, dp});
559 }
560 
fillLimiterConfig(std::vector<DynamicsProcessing::LimiterConfig> & limiterConfigList,int channelIndex,bool enable,int linkGroup,float attackTime,float releaseTime,float ratio,float threshold,float postGain)561 void fillLimiterConfig(std::vector<DynamicsProcessing::LimiterConfig>& limiterConfigList,
562                        int channelIndex, bool enable, int linkGroup, float attackTime,
563                        float releaseTime, float ratio, float threshold, float postGain) {
564     DynamicsProcessing::LimiterConfig cfg;
565     cfg.channel = channelIndex;
566     cfg.enable = enable;
567     cfg.linkGroup = linkGroup;
568     cfg.attackTimeMs = attackTime;
569     cfg.releaseTimeMs = releaseTime;
570     cfg.ratio = ratio;
571     cfg.thresholdDb = threshold;
572     cfg.postGainDb = postGain;
573     limiterConfigList.push_back(cfg);
574 }
575 
createMbcBandConfig(int channel,int band,float cutoffFreqHz,float attackTimeMs,float releaseTimeMs,float ratio,float thresholdDb,float kneeWidthDb,float noiseGate,float expanderRatio,float preGainDb,float postGainDb)576 DynamicsProcessing::MbcBandConfig createMbcBandConfig(int channel, int band, float cutoffFreqHz,
577                                                       float attackTimeMs, float releaseTimeMs,
578                                                       float ratio, float thresholdDb,
579                                                       float kneeWidthDb, float noiseGate,
580                                                       float expanderRatio, float preGainDb,
581                                                       float postGainDb) {
582     return DynamicsProcessing::MbcBandConfig{.channel = channel,
583                                              .band = band,
584                                              .enable = true,
585                                              .cutoffFrequencyHz = cutoffFreqHz,
586                                              .attackTimeMs = attackTimeMs,
587                                              .releaseTimeMs = releaseTimeMs,
588                                              .ratio = ratio,
589                                              .thresholdDb = thresholdDb,
590                                              .kneeWidthDb = kneeWidthDb,
591                                              .noiseGateThresholdDb = noiseGate,
592                                              .expanderRatio = expanderRatio,
593                                              .preGainDb = preGainDb,
594                                              .postGainDb = postGainDb};
595 }
596 
creatEqBandConfig(int channel,int band,float cutOffFreqHz,float gainDb,bool enable)597 DynamicsProcessing::EqBandConfig creatEqBandConfig(int channel, int band, float cutOffFreqHz,
598                                                    float gainDb, bool enable) {
599     return DynamicsProcessing::EqBandConfig{.channel = channel,
600                                             .band = band,
601                                             .enable = enable,
602                                             .cutoffFrequencyHz = cutOffFreqHz,
603                                             .gainDb = gainDb};
604 }
605 
606 /**
607  * Test DynamicsProcessing Engine Configuration
608  */
609 enum EngineArchitectureTestParamName {
610     ENGINE_TEST_INSTANCE_NAME,
611     ENGINE_TEST_RESOLUTION_PREFERENCE,
612     ENGINE_TEST_PREFERRED_DURATION,
613     ENGINE_TEST_STAGE_ENABLEMENT
614 };
615 using EngineArchitectureTestParams = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
616                                                 DynamicsProcessing::ResolutionPreference, float,
617                                                 DynamicsProcessing::StageEnablement>;
618 
fillEngineArchConfig(DynamicsProcessing::EngineArchitecture & cfg,const EngineArchitectureTestParams & params)619 void fillEngineArchConfig(DynamicsProcessing::EngineArchitecture& cfg,
620                           const EngineArchitectureTestParams& params) {
621     cfg.resolutionPreference = std::get<ENGINE_TEST_RESOLUTION_PREFERENCE>(params);
622     cfg.preferredProcessingDurationMs = std::get<ENGINE_TEST_PREFERRED_DURATION>(params);
623     cfg.preEqStage = cfg.postEqStage = cfg.mbcStage =
624             std::get<ENGINE_TEST_STAGE_ENABLEMENT>(params);
625     cfg.limiterInUse = true;
626 }
627 
628 class DynamicsProcessingTestEngineArchitecture
629     : public ::testing::TestWithParam<EngineArchitectureTestParams>,
630       public DynamicsProcessingTestHelper {
631   public:
DynamicsProcessingTestEngineArchitecture()632     DynamicsProcessingTestEngineArchitecture()
633         : DynamicsProcessingTestHelper(std::get<ENGINE_TEST_INSTANCE_NAME>(GetParam())) {
634         fillEngineArchConfig(mCfg, GetParam());
635     };
636 
SetUp()637     void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpDynamicsProcessingEffect()); }
638 
TearDown()639     void TearDown() override { TearDownDynamicsProcessingEffect(); }
640 
641     DynamicsProcessing::EngineArchitecture mCfg;
642 };
643 
TEST_P(DynamicsProcessingTestEngineArchitecture,SetAndGetEngineArch)644 TEST_P(DynamicsProcessingTestEngineArchitecture, SetAndGetEngineArch) {
645     addEngineConfig(mCfg);
646     ASSERT_NO_FATAL_FAILURE(SetAndGetDynamicsProcessingParameters());
647 }
648 
649 INSTANTIATE_TEST_SUITE_P(
650         DynamicsProcessingTest, DynamicsProcessingTestEngineArchitecture,
651         ::testing::Combine(
652                 testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
653                         IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
654                 testing::Values(
655                         DynamicsProcessing::ResolutionPreference::FAVOR_TIME_RESOLUTION,
656                         DynamicsProcessing::ResolutionPreference::FAVOR_FREQUENCY_RESOLUTION,
657                         static_cast<DynamicsProcessing::ResolutionPreference>(-1)),  // variant
658                 testing::Values(-10.f, 0.f, 10.f),  // processing duration
659                 testing::ValuesIn(
660                         DynamicsProcessingTestHelper::kStageEnablementTestSet)  // preEQ/postEQ/mbc
661                 ),
__anon6e9317b30302(const auto& info) 662         [](const auto& info) {
663             auto descriptor = std::get<ENGINE_TEST_INSTANCE_NAME>(info.param).second;
664             DynamicsProcessing::EngineArchitecture cfg;
665             fillEngineArchConfig(cfg, info.param);
666             std::string name = getPrefix(descriptor) + "_Cfg_" + cfg.toString();
667             std::replace_if(
668                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
669             return name;
670         });
671 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingTestEngineArchitecture);
672 
673 /**
674  * Test DynamicsProcessing Input Gain
675  */
676 enum InputGainTestParamName {
677     INPUT_GAIN_INSTANCE_NAME,
678     INPUT_GAIN_PARAM,
679 };
680 class DynamicsProcessingTestInputGain
681     : public ::testing::TestWithParam<std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
682                                                  std::vector<DynamicsProcessing::InputGain>>>,
683       public DynamicsProcessingTestHelper {
684   public:
DynamicsProcessingTestInputGain()685     DynamicsProcessingTestInputGain()
686         : DynamicsProcessingTestHelper(std::get<INPUT_GAIN_INSTANCE_NAME>(GetParam())),
687           mInputGain(std::get<INPUT_GAIN_PARAM>(GetParam())) {};
688 
SetUp()689     void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpDynamicsProcessingEffect()); }
690 
TearDown()691     void TearDown() override { TearDownDynamicsProcessingEffect(); }
692 
693     const std::vector<DynamicsProcessing::InputGain> mInputGain;
694 };
695 
TEST_P(DynamicsProcessingTestInputGain,SetAndGetInputGain)696 TEST_P(DynamicsProcessingTestInputGain, SetAndGetInputGain) {
697     addInputGain(mInputGain);
698     ASSERT_NO_FATAL_FAILURE(SetAndGetDynamicsProcessingParameters());
699 }
700 
701 INSTANTIATE_TEST_SUITE_P(
702         DynamicsProcessingTest, DynamicsProcessingTestInputGain,
703         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
704                                    IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
705                            testing::ValuesIn(DynamicsProcessingTestInputGain::kInputGainTestSet)),
__anon6e9317b30502(const auto& info) 706         [](const auto& info) {
707             auto descriptor = std::get<INPUT_GAIN_INSTANCE_NAME>(info.param).second;
708             std::string gains =
709                     ::android::internal::ToString(std::get<INPUT_GAIN_PARAM>(info.param));
710             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
711                                descriptor.common.name + "_UUID_" +
712                                toString(descriptor.common.id.uuid) + "_inputGains_" + gains;
713             std::replace_if(
714                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
715             return name;
716         });
717 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingTestInputGain);
718 
719 class DynamicsProcessingInputGainDataTest
720     : public ::testing::TestWithParam<std::pair<std::shared_ptr<IFactory>, Descriptor>>,
721       public DynamicsProcessingTestHelper {
722   public:
DynamicsProcessingInputGainDataTest()723     DynamicsProcessingInputGainDataTest()
724         : DynamicsProcessingTestHelper((GetParam()), AudioChannelLayout::LAYOUT_MONO) {}
725 
SetUp()726     void SetUp() override {
727         ASSERT_NO_FATAL_FAILURE(setUpDataTest({kInputFrequency}, kSineFullScaleDb));
728     }
729 
TearDown()730     void TearDown() override { ASSERT_NO_FATAL_FAILURE(tearDownDataTest()); }
731 
cleanUpInputGainConfig()732     void cleanUpInputGainConfig() {
733         CleanUp();
734         mInputGain.clear();
735     }
736 
737     std::vector<DynamicsProcessing::InputGain> mInputGain;
738 };
739 
TEST_P(DynamicsProcessingInputGainDataTest,SetAndGetInputGain)740 TEST_P(DynamicsProcessingInputGainDataTest, SetAndGetInputGain) {
741     std::vector<float> gainDbValues = {-85, -40, 0, 40, 85};
742     for (float gainDb : gainDbValues) {
743         cleanUpInputGainConfig();
744         for (int i = 0; i < mChannelCount; i++) {
745             mInputGain.push_back(DynamicsProcessing::InputGain(i, gainDb));
746         }
747         std::vector<float> output(mInput.size());
748         addInputGain(mInputGain);
749         EXPECT_NO_FATAL_FAILURE(setParamsAndProcess(mInput, output));
750         if (!isAllParamsValid()) {
751             continue;
752         }
753         float outputDb = calculateDb(output, kStartIndex);
754         EXPECT_NEAR(outputDb, mInputDb + gainDb, kToleranceDb)
755                 << "InputGain: " << gainDb << ", OutputDb: " << outputDb;
756     }
757 }
758 
759 INSTANTIATE_TEST_SUITE_P(DynamicsProcessingTest, DynamicsProcessingInputGainDataTest,
760                          testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
761                                  IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
__anon6e9317b30702(const auto& info) 762                          [](const auto& info) {
763                              auto descriptor = info.param;
764                              std::string name = getPrefix(descriptor.second);
765                              std::replace_if(
766                                      name.begin(), name.end(),
767                                      [](const char c) { return !std::isalnum(c); }, '_');
768                              return name;
769                          });
770 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingInputGainDataTest);
771 
772 /**
773  * Test DynamicsProcessing Limiter Config
774  */
775 enum LimiterConfigTestParamName {
776     LIMITER_INSTANCE_NAME,
777     LIMITER_CHANNEL,
778     LIMITER_LINK_GROUP,
779     LIMITER_ATTACK_TIME,
780     LIMITER_RELEASE_TIME,
781     LIMITER_RATIO,
782     LIMITER_THRESHOLD,
783     LIMITER_POST_GAIN,
784 };
785 
786 using LimiterConfigTestParams = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
787                                            int32_t, int32_t, float, float, float, float, float>;
788 
fillLimiterConfig(std::vector<DynamicsProcessing::LimiterConfig> & cfg,const LimiterConfigTestParams & params)789 void fillLimiterConfig(std::vector<DynamicsProcessing::LimiterConfig>& cfg,
790                        const LimiterConfigTestParams& params) {
791     fillLimiterConfig(cfg, std::get<LIMITER_CHANNEL>(params), true,
792                       std::get<LIMITER_LINK_GROUP>(params), std::get<LIMITER_ATTACK_TIME>(params),
793                       std::get<LIMITER_RELEASE_TIME>(params), std::get<LIMITER_RATIO>(params),
794                       std::get<LIMITER_THRESHOLD>(params), std::get<LIMITER_POST_GAIN>(params));
795 }
796 
797 class DynamicsProcessingTestLimiterConfig
798     : public ::testing::TestWithParam<LimiterConfigTestParams>,
799       public DynamicsProcessingTestHelper {
800   public:
DynamicsProcessingTestLimiterConfig()801     DynamicsProcessingTestLimiterConfig()
802         : DynamicsProcessingTestHelper(std::get<LIMITER_INSTANCE_NAME>(GetParam())) {
803         fillLimiterConfig(mLimiterConfigList, GetParam());
804     }
805 
SetUp()806     void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpDynamicsProcessingEffect()); }
807 
TearDown()808     void TearDown() override { TearDownDynamicsProcessingEffect(); }
809 
810     DynamicsProcessing::LimiterConfig mCfg;
811     std::vector<DynamicsProcessing::LimiterConfig> mLimiterConfigList;
812 };
813 
TEST_P(DynamicsProcessingTestLimiterConfig,SetAndGetLimiterConfig)814 TEST_P(DynamicsProcessingTestLimiterConfig, SetAndGetLimiterConfig) {
815     addEngineConfig(mEngineConfigPreset);
816     addLimiterConfig(mLimiterConfigList);
817     ASSERT_NO_FATAL_FAILURE(SetAndGetDynamicsProcessingParameters());
818 }
819 
820 INSTANTIATE_TEST_SUITE_P(
821         DynamicsProcessingTest, DynamicsProcessingTestLimiterConfig,
822         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
823                                    IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
824                            testing::Values(-1, 0, 1, 2),  // channel index
825                            testing::Values(3),            // link group
826                            testing::Values(-1, 1),        // attackTime
827                            testing::Values(-60, 60),      // releaseTime
828                            testing::Values(-2.5, 2.5),    // ratio
829                            testing::Values(-2, 2),        // thresh
830                            testing::Values(-3.14, 3.14)   // postGain
831                            ),
__anon6e9317b30902(const auto& info) 832         [](const auto& info) {
833             auto descriptor = std::get<LIMITER_INSTANCE_NAME>(info.param).second;
834             std::vector<DynamicsProcessing::LimiterConfig> cfg;
835             fillLimiterConfig(cfg, info.param);
836             std::string name =
837                     "Implementer_" + getPrefix(descriptor) + "_limiterConfig_" + cfg[0].toString();
838             std::replace_if(
839                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
840             return name;
841         });
842 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingTestLimiterConfig);
843 
844 using LimiterConfigDataTestParams = std::pair<std::shared_ptr<IFactory>, Descriptor>;
845 
846 class DynamicsProcessingLimiterConfigDataTest
847     : public ::testing::TestWithParam<LimiterConfigDataTestParams>,
848       public DynamicsProcessingTestHelper {
849   public:
DynamicsProcessingLimiterConfigDataTest(LimiterConfigDataTestParams param=GetParam (),int32_t layout=AudioChannelLayout::LAYOUT_MONO)850     DynamicsProcessingLimiterConfigDataTest(LimiterConfigDataTestParams param = GetParam(),
851                                             int32_t layout = AudioChannelLayout::LAYOUT_MONO)
852         : DynamicsProcessingTestHelper(param, layout) {}
853 
SetUp()854     void SetUp() override {
855         ASSERT_NO_FATAL_FAILURE(setUpDataTest({kInputFrequency}, kSineFullScaleDb));
856     }
857 
TearDown()858     void TearDown() override { ASSERT_NO_FATAL_FAILURE(tearDownDataTest()); }
859 
computeThreshold(float ratio,float outputDb,float & threshold)860     void computeThreshold(float ratio, float outputDb, float& threshold) {
861         EXPECT_NE(ratio, 0);
862         threshold = (mInputDb - (ratio * outputDb)) / (1 - ratio);
863     }
864 
computeRatio(float threshold,float outputDb,float & ratio)865     void computeRatio(float threshold, float outputDb, float& ratio) {
866         float inputOverThreshold = mInputDb - threshold;
867         float outputOverThreshold = outputDb - threshold;
868         EXPECT_NE(outputOverThreshold, 0);
869         ratio = inputOverThreshold / outputOverThreshold;
870     }
871 
setLimiterParamsAndProcess(std::vector<float> & input,std::vector<float> & output,bool isEngineLimiterEnabled=true)872     void setLimiterParamsAndProcess(std::vector<float>& input, std::vector<float>& output,
873                                     bool isEngineLimiterEnabled = true) {
874         mEngineConfigPreset.limiterInUse = isEngineLimiterEnabled;
875         addEngineConfig(mEngineConfigPreset);
876         addLimiterConfig(mLimiterConfigList);
877         EXPECT_NO_FATAL_FAILURE(setParamsAndProcess(input, output));
878     }
879 
testEnableDisableConfiguration(bool isLimiterEnabled,bool isEngineLimiterEnabled)880     void testEnableDisableConfiguration(bool isLimiterEnabled, bool isEngineLimiterEnabled) {
881         cleanUpLimiterConfig();
882         std::vector<float> output(mInput.size());
883         for (int i = 0; i < mChannelCount; i++) {
884             // Set non-default values
885             fillLimiterConfig(mLimiterConfigList, i, isLimiterEnabled, kDefaultLinkerGroup,
886                               5 /*attack time*/, 5 /*release time*/, 10 /*ratio*/,
887                               -20 /*threshold*/, 5 /*postgain*/);
888         }
889         ASSERT_NO_FATAL_FAILURE(setLimiterParamsAndProcess(mInput, output, isEngineLimiterEnabled));
890         float outputdB = calculateDb(output, kStartIndex);
891         if (isAllParamsValid()) {
892             if (isLimiterEnabled && isEngineLimiterEnabled) {
893                 EXPECT_GT(std::abs(mInputDb - outputdB), kMinDifferenceDb)
894                         << "Input level: " << mInputDb << " Output level: " << outputdB;
895             } else {
896                 EXPECT_NEAR(mInputDb, outputdB, kLimiterTestToleranceDb);
897             }
898         }
899     }
900 
cleanUpLimiterConfig()901     void cleanUpLimiterConfig() {
902         CleanUp();
903         mLimiterConfigList.clear();
904     }
905     static constexpr float kDefaultLinkerGroup = 3;
906     static constexpr float kDefaultAttackTime = 0;
907     static constexpr float kDefaultReleaseTime = 0;
908     static constexpr float kDefaultRatio = 4;
909     static constexpr float kDefaultThreshold = -10;
910     static constexpr float kDefaultPostGain = 0;
911     static constexpr float kLimiterTestToleranceDb = 0.05;
912     static constexpr float kMinDifferenceDb = 5;
913     const std::vector<bool> kEnableValues = {true, false, true};
914     std::vector<DynamicsProcessing::LimiterConfig> mLimiterConfigList;
915     int mBufferSize;
916 };
917 
TEST_P(DynamicsProcessingLimiterConfigDataTest,IncreasingThresholdDb)918 TEST_P(DynamicsProcessingLimiterConfigDataTest, IncreasingThresholdDb) {
919     std::vector<float> thresholdValues = {-200, -150, -100, -50, -5, 0};
920     std::vector<float> output(mInput.size());
921     float previousThreshold = -FLT_MAX;
922     for (float threshold : thresholdValues) {
923         cleanUpLimiterConfig();
924         for (int i = 0; i < mChannelCount; i++) {
925             fillLimiterConfig(mLimiterConfigList, i, true, kDefaultLinkerGroup, kDefaultAttackTime,
926                               kDefaultReleaseTime, kDefaultRatio, threshold, kDefaultPostGain);
927         }
928         ASSERT_NO_FATAL_FAILURE(setLimiterParamsAndProcess(mInput, output));
929         if (!isAllParamsValid()) {
930             continue;
931         }
932         float outputDb = calculateDb(output, kStartIndex);
933         if (threshold >= mInputDb || kDefaultRatio == 1) {
934             EXPECT_NEAR(mInputDb, outputDb, kLimiterTestToleranceDb);
935         } else {
936             float calculatedThreshold = 0;
937             ASSERT_NO_FATAL_FAILURE(computeThreshold(kDefaultRatio, outputDb, calculatedThreshold));
938             ASSERT_GT(calculatedThreshold, previousThreshold);
939             previousThreshold = calculatedThreshold;
940         }
941     }
942 }
943 
TEST_P(DynamicsProcessingLimiterConfigDataTest,IncreasingRatio)944 TEST_P(DynamicsProcessingLimiterConfigDataTest, IncreasingRatio) {
945     std::vector<float> ratioValues = {1, 10, 20, 30, 40, 50};
946     std::vector<float> output(mInput.size());
947     float previousRatio = 0;
948     for (float ratio : ratioValues) {
949         cleanUpLimiterConfig();
950         for (int i = 0; i < mChannelCount; i++) {
951             fillLimiterConfig(mLimiterConfigList, i, true, kDefaultLinkerGroup, kDefaultAttackTime,
952                               kDefaultReleaseTime, ratio, kDefaultThreshold, kDefaultPostGain);
953         }
954         ASSERT_NO_FATAL_FAILURE(setLimiterParamsAndProcess(mInput, output));
955         if (!isAllParamsValid()) {
956             continue;
957         }
958         float outputDb = calculateDb(output, kStartIndex);
959 
960         if (kDefaultThreshold >= mInputDb) {
961             EXPECT_NEAR(mInputDb, outputDb, kLimiterTestToleranceDb);
962         } else {
963             float calculatedRatio = 0;
964             ASSERT_NO_FATAL_FAILURE(computeRatio(kDefaultThreshold, outputDb, calculatedRatio));
965             ASSERT_GT(calculatedRatio, previousRatio);
966             previousRatio = calculatedRatio;
967         }
968     }
969 }
970 
TEST_P(DynamicsProcessingLimiterConfigDataTest,IncreasingPostGain)971 TEST_P(DynamicsProcessingLimiterConfigDataTest, IncreasingPostGain) {
972     std::vector<float> postGainDbValues = {-85, -40, 0, 40, 85};
973     std::vector<float> output(mInput.size());
974     for (float postGainDb : postGainDbValues) {
975         cleanUpLimiterConfig();
976         ASSERT_NO_FATAL_FAILURE(generateSineWave(kInputFrequency, mInput, dBToAmplitude(postGainDb),
977                                                  kSamplingFrequency, mChannelLayout));
978         mInputDb = calculateDb(mInput);
979         EXPECT_NEAR(mInputDb, kSineFullScaleDb - postGainDb, kLimiterTestToleranceDb);
980         for (int i = 0; i < mChannelCount; i++) {
981             fillLimiterConfig(mLimiterConfigList, i, true, kDefaultLinkerGroup, kDefaultAttackTime,
982                               kDefaultReleaseTime, 1, kDefaultThreshold, postGainDb);
983         }
984         ASSERT_NO_FATAL_FAILURE(setLimiterParamsAndProcess(mInput, output));
985         if (!isAllParamsValid()) {
986             continue;
987         }
988         float outputDb = calculateDb(output, kStartIndex);
989         EXPECT_NEAR(outputDb, mInputDb + postGainDb, kLimiterTestToleranceDb)
990                 << "PostGain: " << postGainDb << ", OutputDb: " << outputDb;
991     }
992 }
993 
TEST_P(DynamicsProcessingLimiterConfigDataTest,LimiterEnableDisable)994 TEST_P(DynamicsProcessingLimiterConfigDataTest, LimiterEnableDisable) {
995     for (bool isLimiterEnabled : kEnableValues) {
996         ASSERT_NO_FATAL_FAILURE(
997                 testEnableDisableConfiguration(isLimiterEnabled, true /*Engine Enabled*/));
998     }
999 }
1000 
TEST_P(DynamicsProcessingLimiterConfigDataTest,LimiterEnableDisableViaEngine)1001 TEST_P(DynamicsProcessingLimiterConfigDataTest, LimiterEnableDisableViaEngine) {
1002     for (bool isEngineLimiterEnabled : kEnableValues) {
1003         ASSERT_NO_FATAL_FAILURE(
1004                 testEnableDisableConfiguration(true /*Limiter Enabled*/, isEngineLimiterEnabled));
1005     }
1006 }
1007 
1008 INSTANTIATE_TEST_SUITE_P(DynamicsProcessingTest, DynamicsProcessingLimiterConfigDataTest,
1009                          testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
1010                                  IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
__anon6e9317b30b02(const auto& info) 1011                          [](const auto& info) {
1012                              auto descriptor = info.param;
1013                              std::string name = getPrefix(descriptor.second);
1014                              std::replace_if(
1015                                      name.begin(), name.end(),
1016                                      [](const char c) { return !std::isalnum(c); }, '_');
1017                              return name;
1018                          });
1019 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingLimiterConfigDataTest);
1020 
1021 class DynamicsProcessingLimiterLinkerDataTest : public DynamicsProcessingLimiterConfigDataTest {
1022   public:
DynamicsProcessingLimiterLinkerDataTest()1023     DynamicsProcessingLimiterLinkerDataTest()
1024         : DynamicsProcessingLimiterConfigDataTest(GetParam(), AudioChannelLayout::LAYOUT_STEREO) {}
1025 
calculateExpectedOutputDb(std::vector<float> & expectedOutputDb)1026     void calculateExpectedOutputDb(std::vector<float>& expectedOutputDb) {
1027         std::vector<float> inputDbValues = calculateStereoDb(mInput, kStartIndex);
1028         ASSERT_EQ(inputDbValues.size(), kRatioThresholdPairValues.size());
1029         EXPECT_NEAR(inputDbValues[0], inputDbValues[1], kToleranceDb);
1030         for (size_t i = 0; i < kRatioThresholdPairValues.size(); i++) {
1031             const auto& [ratio, threshold] = kRatioThresholdPairValues[i];
1032             expectedOutputDb.push_back((inputDbValues[i] - threshold) / ratio + threshold);
1033         }
1034     }
1035 
calculateStereoDb(const std::vector<float> & input,size_t startSamplePos=0)1036     std::vector<float> calculateStereoDb(const std::vector<float>& input,
1037                                          size_t startSamplePos = 0) {
1038         std::vector<float> leftChannel;
1039         std::vector<float> rightChannel;
1040         for (size_t i = 0; i < input.size(); i += 2) {
1041             leftChannel.push_back(input[i]);
1042             if (i + 1 < input.size()) {
1043                 rightChannel.push_back(input[i + 1]);
1044             }
1045         }
1046         return {calculateDb(leftChannel, startSamplePos),
1047                 calculateDb(rightChannel, startSamplePos)};
1048     }
1049 
setLinkGroupAndProcess(std::vector<float> & output,bool hasSameLinkGroup)1050     void setLinkGroupAndProcess(std::vector<float>& output, bool hasSameLinkGroup) {
1051         for (int i = 0; i < mChannelCount; i++) {
1052             const auto& [ratio, threshold] = kRatioThresholdPairValues[i];
1053             ASSERT_NE(ratio, 0);
1054             int linkGroup = hasSameLinkGroup ? kDefaultLinkerGroup : i;
1055             fillLimiterConfig(mLimiterConfigList, i, true, linkGroup, kDefaultAttackTime,
1056                               kDefaultReleaseTime, ratio, threshold, kDefaultPostGain);
1057         }
1058 
1059         ASSERT_NO_FATAL_FAILURE(setLimiterParamsAndProcess(mInput, output));
1060 
1061         if (!isAllParamsValid()) {
1062             GTEST_SKIP() << "Invalid parameters. Skipping the test\n";
1063         }
1064     }
1065 
1066     const std::vector<std::pair<float, float>> kRatioThresholdPairValues = {{2, -10}, {5, -20}};
1067 };
1068 
TEST_P(DynamicsProcessingLimiterLinkerDataTest,SameLinkGroupDifferentConfigs)1069 TEST_P(DynamicsProcessingLimiterLinkerDataTest, SameLinkGroupDifferentConfigs) {
1070     std::vector<float> output(mInput.size());
1071 
1072     ASSERT_NO_FATAL_FAILURE(setLinkGroupAndProcess(output, true));
1073 
1074     std::vector<float> outputDbValues = calculateStereoDb(output, kStartIndex);
1075 
1076     std::vector<float> expectedOutputDbValues;
1077     ASSERT_NO_FATAL_FAILURE(calculateExpectedOutputDb(expectedOutputDbValues));
1078 
1079     // Verify that the actual output dB is same as the calculated maximum attenuation.
1080     float expectedOutputDb = std::min(expectedOutputDbValues[0], expectedOutputDbValues[1]);
1081     EXPECT_NEAR(outputDbValues[0], expectedOutputDb, kToleranceDb);
1082     EXPECT_NEAR(outputDbValues[1], expectedOutputDb, kToleranceDb);
1083 }
1084 
TEST_P(DynamicsProcessingLimiterLinkerDataTest,DifferentLinkGroupDifferentConfigs)1085 TEST_P(DynamicsProcessingLimiterLinkerDataTest, DifferentLinkGroupDifferentConfigs) {
1086     std::vector<float> output(mInput.size());
1087 
1088     ASSERT_NO_FATAL_FAILURE(setLinkGroupAndProcess(output, false));
1089 
1090     std::vector<float> outputDbValues = calculateStereoDb(output, kStartIndex);
1091 
1092     std::vector<float> expectedOutputDbValues;
1093     ASSERT_NO_FATAL_FAILURE(calculateExpectedOutputDb(expectedOutputDbValues));
1094 
1095     // Verify that both channels have different compression levels
1096     EXPECT_GT(abs(expectedOutputDbValues[0] - expectedOutputDbValues[1]), kMinDifferenceDb)
1097             << "Left channel level: " << expectedOutputDbValues[0]
1098             << " Right channel level: " << expectedOutputDbValues[1];
1099 
1100     // Verify that the actual output and the calculated dB values are same
1101     EXPECT_NEAR(outputDbValues[0], expectedOutputDbValues[0], kToleranceDb);
1102     EXPECT_NEAR(outputDbValues[1], expectedOutputDbValues[1], kToleranceDb);
1103 }
1104 
1105 INSTANTIATE_TEST_SUITE_P(DynamicsProcessingTest, DynamicsProcessingLimiterLinkerDataTest,
1106                          testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
1107                                  IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
__anon6e9317b30d02(const auto& info) 1108                          [](const auto& info) {
1109                              auto descriptor = info.param;
1110                              std::string name = getPrefix(descriptor.second);
1111                              std::replace_if(
1112                                      name.begin(), name.end(),
1113                                      [](const char c) { return !std::isalnum(c); }, '_');
1114                              return name;
1115                          });
1116 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingLimiterLinkerDataTest);
1117 
1118 /**
1119  * Test DynamicsProcessing ChannelConfig
1120  */
1121 enum ChannelConfigTestParamName {
1122     BAND_CHANNEL_TEST_INSTANCE_NAME,
1123     BAND_CHANNEL_TEST_CHANNEL_CONFIG
1124 };
1125 using ChannelConfigTestParams = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
1126                                            std::vector<DynamicsProcessing::ChannelConfig>>;
1127 
1128 class DynamicsProcessingTestChannelConfig
1129     : public ::testing::TestWithParam<ChannelConfigTestParams>,
1130       public DynamicsProcessingTestHelper {
1131   public:
DynamicsProcessingTestChannelConfig()1132     DynamicsProcessingTestChannelConfig()
1133         : DynamicsProcessingTestHelper(std::get<BAND_CHANNEL_TEST_INSTANCE_NAME>(GetParam())),
1134           mCfg(std::get<BAND_CHANNEL_TEST_CHANNEL_CONFIG>(GetParam())) {}
1135 
SetUp()1136     void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpDynamicsProcessingEffect()); }
1137 
TearDown()1138     void TearDown() override { TearDownDynamicsProcessingEffect(); }
1139 
1140     std::vector<DynamicsProcessing::ChannelConfig> mCfg;
1141 };
1142 
TEST_P(DynamicsProcessingTestChannelConfig,SetAndGetPreEqChannelConfig)1143 TEST_P(DynamicsProcessingTestChannelConfig, SetAndGetPreEqChannelConfig) {
1144     addEngineConfig(mEngineConfigPreset);
1145     addPreEqChannelConfig(mCfg);
1146     ASSERT_NO_FATAL_FAILURE(SetAndGetDynamicsProcessingParameters());
1147 }
1148 
TEST_P(DynamicsProcessingTestChannelConfig,SetAndGetPostEqChannelConfig)1149 TEST_P(DynamicsProcessingTestChannelConfig, SetAndGetPostEqChannelConfig) {
1150     addEngineConfig(mEngineConfigPreset);
1151     addPostEqChannelConfig(mCfg);
1152     ASSERT_NO_FATAL_FAILURE(SetAndGetDynamicsProcessingParameters());
1153 }
1154 
TEST_P(DynamicsProcessingTestChannelConfig,SetAndGetMbcChannelConfig)1155 TEST_P(DynamicsProcessingTestChannelConfig, SetAndGetMbcChannelConfig) {
1156     addEngineConfig(mEngineConfigPreset);
1157     addMbcChannelConfig(mCfg);
1158     ASSERT_NO_FATAL_FAILURE(SetAndGetDynamicsProcessingParameters());
1159 }
1160 
1161 INSTANTIATE_TEST_SUITE_P(
1162         DynamicsProcessingTest, DynamicsProcessingTestChannelConfig,
1163         ::testing::Combine(
1164                 testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
1165                         IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
1166                 testing::ValuesIn(
1167                         DynamicsProcessingTestHelper::kChannelConfigTestSet)),  // channel config
__anon6e9317b30f02(const auto& info) 1168         [](const auto& info) {
1169             auto descriptor = std::get<BAND_CHANNEL_TEST_INSTANCE_NAME>(info.param).second;
1170             std::string channelConfig = ::android::internal::ToString(
1171                     std::get<BAND_CHANNEL_TEST_CHANNEL_CONFIG>(info.param));
1172 
1173             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
1174                                descriptor.common.name + "_UUID_" +
1175                                toString(descriptor.common.id.uuid) + "_" + channelConfig;
1176             std::replace_if(
1177                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
1178             return name;
1179         });
1180 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingTestChannelConfig);
1181 
1182 /**
1183  * Test DynamicsProcessing EqBandConfig
1184  */
1185 enum EqBandConfigTestParamName {
1186     EQ_BAND_INSTANCE_NAME,
1187     EQ_BAND_CHANNEL,
1188     EQ_BAND_CUT_OFF_FREQ,
1189     EQ_BAND_GAIN
1190 };
1191 using EqBandConfigTestParams = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t,
1192                                           std::vector<std::pair<int, float>>, float>;
1193 
fillEqBandConfig(std::vector<DynamicsProcessing::EqBandConfig> & cfgs,const EqBandConfigTestParams & params)1194 void fillEqBandConfig(std::vector<DynamicsProcessing::EqBandConfig>& cfgs,
1195                       const EqBandConfigTestParams& params) {
1196     const std::vector<std::pair<int, float>> cutOffFreqs = std::get<EQ_BAND_CUT_OFF_FREQ>(params);
1197     int bandCount = cutOffFreqs.size();
1198     for (int i = 0; i < bandCount; i++) {
1199         cfgs.push_back(creatEqBandConfig(std::get<EQ_BAND_CHANNEL>(params), cutOffFreqs[i].first,
1200                                          cutOffFreqs[i].second, std::get<EQ_BAND_GAIN>(params),
1201                                          true));
1202     }
1203 }
1204 
1205 class DynamicsProcessingTestEqBandConfig : public ::testing::TestWithParam<EqBandConfigTestParams>,
1206                                            public DynamicsProcessingTestHelper {
1207   public:
DynamicsProcessingTestEqBandConfig()1208     DynamicsProcessingTestEqBandConfig()
1209         : DynamicsProcessingTestHelper(std::get<EQ_BAND_INSTANCE_NAME>(GetParam())) {
1210         fillEqBandConfig(mCfgs, GetParam());
1211     }
1212 
SetUp()1213     void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpDynamicsProcessingEffect()); }
1214 
TearDown()1215     void TearDown() override { TearDownDynamicsProcessingEffect(); }
1216 
1217     std::vector<DynamicsProcessing::EqBandConfig> mCfgs;
1218 };
1219 
TEST_P(DynamicsProcessingTestEqBandConfig,SetAndGetPreEqBandConfig)1220 TEST_P(DynamicsProcessingTestEqBandConfig, SetAndGetPreEqBandConfig) {
1221     mEngineConfigPreset.preEqStage.bandCount = mCfgs.size();
1222     addEngineConfig(mEngineConfigPreset);
1223     std::vector<DynamicsProcessing::ChannelConfig> cfgs(mChannelCount);
1224     for (int i = 0; i < mChannelCount; i++) {
1225         cfgs[i].channel = i;
1226         cfgs[i].enable = true;
1227     }
1228     addPreEqChannelConfig(cfgs);
1229     addPreEqBandConfigs(mCfgs);
1230     ASSERT_NO_FATAL_FAILURE(SetAndGetDynamicsProcessingParameters());
1231 }
1232 
TEST_P(DynamicsProcessingTestEqBandConfig,SetAndGetPostEqBandConfig)1233 TEST_P(DynamicsProcessingTestEqBandConfig, SetAndGetPostEqBandConfig) {
1234     SKIP_TEST_IF_VERSION_UNSUPPORTED(mEffect, kMinDataTestHalVersion);
1235 
1236     mEngineConfigPreset.postEqStage.bandCount = mCfgs.size();
1237     addEngineConfig(mEngineConfigPreset);
1238     std::vector<DynamicsProcessing::ChannelConfig> cfgs(mChannelCount);
1239     for (int i = 0; i < mChannelCount; i++) {
1240         cfgs[i].channel = i;
1241         cfgs[i].enable = true;
1242     }
1243     addPostEqChannelConfig(cfgs);
1244     addPostEqBandConfigs(mCfgs);
1245     ASSERT_NO_FATAL_FAILURE(SetAndGetDynamicsProcessingParameters());
1246 }
1247 
1248 std::vector<std::vector<std::pair<int, float>>> kBands{
1249         {
1250                 {0, 600},
1251                 {1, 2000},
1252                 {2, 6000},
1253                 {3, 10000},
1254                 {4, 16000},
1255                 {5, 20000},
1256                 {6, 26000},
1257                 {7, 30000},
1258                 {8, 36000},
1259                 {9, 40000},
1260         },  // 10 bands
1261         {
1262                 {0, 800},
1263                 {3, 15000},
1264                 {2, 6000},
1265                 {1, 2000},
1266         },  // 4 bands, unsorted
1267         {
1268                 {0, 650},
1269                 {1, 2000},
1270                 {2, 6000},
1271                 {3, 10000},
1272                 {3, 16000},
1273         },  // 5 bands, missing band
1274         {
1275                 {0, 900},
1276                 {1, 8000},
1277                 {2, 4000},
1278                 {3, 12000},
1279         },  // 4 bands, cutoff freq not increasing
1280         {
1281                 {0, 450},
1282                 {1, 2000},
1283                 {7, 6000},
1284                 {3, 10000},
1285                 {4, 16000},
1286         },  // bad band index
1287         {
1288                 {0, 1},
1289                 {1, 8000},
1290         },  // too low cutoff freq
1291         {
1292                 {0, 1200},
1293                 {1, 80000},
1294         },  // too high cutoff freq
1295 };
1296 
1297 INSTANTIATE_TEST_SUITE_P(
1298         DynamicsProcessingTest, DynamicsProcessingTestEqBandConfig,
1299         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
1300                                    IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
1301                            testing::Values(-1, 0, 10),     // channel index
1302                            testing::ValuesIn(kBands),      // band index, cut off frequencies
1303                            testing::Values(-3.14f, 3.14f)  // gain
1304                            ),
__anon6e9317b31102(const auto& info) 1305         [](const auto& info) {
1306             auto descriptor = std::get<EQ_BAND_INSTANCE_NAME>(info.param).second;
1307             std::vector<DynamicsProcessing::EqBandConfig> cfgs;
1308             fillEqBandConfig(cfgs, info.param);
1309             std::string bands = ::android::internal::ToString(cfgs);
1310             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
1311                                descriptor.common.name + "_UUID_" +
1312                                toString(descriptor.common.id.uuid) + "_bands_" + bands;
1313             std::replace_if(
1314                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
1315             return name;
1316         });
1317 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingTestEqBandConfig);
1318 
1319 class DynamicsProcessingEqBandConfigDataTest
1320     : public ::testing::TestWithParam<std::pair<std::shared_ptr<IFactory>, Descriptor>>,
1321       public DynamicsProcessingTestHelper {
1322   public:
DynamicsProcessingEqBandConfigDataTest()1323     DynamicsProcessingEqBandConfigDataTest()
1324         : DynamicsProcessingTestHelper(GetParam(), AudioChannelLayout::LAYOUT_MONO) {
1325         mBinOffsets.resize(mMultitoneTestFrequencies.size());
1326     }
1327 
SetUp()1328     void SetUp() override {
1329         ASSERT_NO_FATAL_FAILURE(
1330                 setUpDataTest(mMultitoneTestFrequencies, kSineMultitoneFullScaleDb));
1331     }
1332 
TearDown()1333     void TearDown() override { ASSERT_NO_FATAL_FAILURE(tearDownDataTest()); }
1334 
addEqParam(bool isPreEq)1335     void addEqParam(bool isPreEq) {
1336         createChannelConfig();
1337         auto stage = isPreEq ? mEngineConfigPreset.preEqStage : mEngineConfigPreset.postEqStage;
1338         stage.bandCount = mCfgs.size();
1339         addEngineConfig(mEngineConfigPreset);
1340         isPreEq ? addPreEqChannelConfig(mChannelConfig) : addPostEqChannelConfig(mChannelConfig);
1341         isPreEq ? addPreEqBandConfigs(mCfgs) : addPostEqBandConfigs(mCfgs);
1342     }
1343 
setEqParamAndProcess(std::vector<float> & output,bool isPreEq)1344     void setEqParamAndProcess(std::vector<float>& output, bool isPreEq) {
1345         addEqParam(isPreEq);
1346         ASSERT_NO_FATAL_FAILURE(setParamsAndProcess(mInput, output));
1347     }
1348 
fillEqBandConfig(std::vector<DynamicsProcessing::EqBandConfig> & cfgs,int channelIndex,int bandIndex,int cutOffFreqHz,float gainDb,bool enable)1349     void fillEqBandConfig(std::vector<DynamicsProcessing::EqBandConfig>& cfgs, int channelIndex,
1350                           int bandIndex, int cutOffFreqHz, float gainDb, bool enable) {
1351         cfgs.push_back(creatEqBandConfig(channelIndex, bandIndex, static_cast<float>(cutOffFreqHz),
1352                                          gainDb, enable));
1353     }
1354 
validateOutput(const std::vector<float> & output,float gainDb,size_t bandIndex,bool enable)1355     void validateOutput(const std::vector<float>& output, float gainDb, size_t bandIndex,
1356                         bool enable) {
1357         std::vector<float> outputMag(mBinOffsets.size());
1358         EXPECT_NO_FATAL_FAILURE(getMagnitudeValue(output, outputMag));
1359         if (gainDb == 0 || !enable) {
1360             EXPECT_NO_FATAL_FAILURE(checkInputAndOutputEquality(outputMag));
1361         } else if (gainDb > 0) {
1362             // For positive gain, current band's magnitude is greater than the other band's
1363             // magnitude
1364             EXPECT_GT(outputMag[bandIndex], outputMag[bandIndex ^ 1]);
1365         } else {
1366             // For negative gain, current band's magnitude is less than the other band's magnitude
1367             EXPECT_LT(outputMag[bandIndex], outputMag[bandIndex ^ 1]);
1368         }
1369     }
1370 
analyseMultiBandOutput(float gainDb,bool isPreEq,bool enable=true)1371     void analyseMultiBandOutput(float gainDb, bool isPreEq, bool enable = true) {
1372         std::vector<float> output(mInput.size());
1373         roundToFreqCenteredToFftBin(mMultitoneTestFrequencies, mBinOffsets, kBinWidth);
1374         // Set Equalizer values for two bands
1375         for (size_t i = 0; i < kCutoffFreqHz.size(); i++) {
1376             for (int channelIndex = 0; channelIndex < mChannelCount; channelIndex++) {
1377                 fillEqBandConfig(mCfgs, channelIndex, i, kCutoffFreqHz[i], gainDb, enable);
1378                 fillEqBandConfig(mCfgs, channelIndex, i ^ 1, kCutoffFreqHz[i ^ 1], 0, enable);
1379             }
1380             ASSERT_NO_FATAL_FAILURE(setEqParamAndProcess(output, isPreEq));
1381 
1382             if (isAllParamsValid()) {
1383                 ASSERT_NO_FATAL_FAILURE(validateOutput(output, gainDb, i, enable));
1384             }
1385             cleanUpEqConfig();
1386         }
1387     }
1388 
cleanUpEqConfig()1389     void cleanUpEqConfig() {
1390         CleanUp();
1391         mCfgs.clear();
1392         mChannelConfig.clear();
1393     }
1394 
1395     const std::vector<float> kTestGainDbValues = {-200, -100, 0, 100, 200};
1396     std::vector<DynamicsProcessing::EqBandConfig> mCfgs;
1397 };
1398 
TEST_P(DynamicsProcessingEqBandConfigDataTest,IncreasingPreEqGain)1399 TEST_P(DynamicsProcessingEqBandConfigDataTest, IncreasingPreEqGain) {
1400     for (float gainDb : kTestGainDbValues) {
1401         ASSERT_NO_FATAL_FAILURE(generateSineWave(mMultitoneTestFrequencies, mInput,
1402                                                  dBToAmplitude(gainDb), kSamplingFrequency,
1403                                                  mChannelLayout));
1404         cleanUpEqConfig();
1405         ASSERT_NO_FATAL_FAILURE(analyseMultiBandOutput(gainDb, true /*pre-equalizer*/));
1406     }
1407 }
1408 
TEST_P(DynamicsProcessingEqBandConfigDataTest,IncreasingPostEqGain)1409 TEST_P(DynamicsProcessingEqBandConfigDataTest, IncreasingPostEqGain) {
1410     for (float gainDb : kTestGainDbValues) {
1411         ASSERT_NO_FATAL_FAILURE(generateSineWave(mMultitoneTestFrequencies, mInput,
1412                                                  dBToAmplitude(gainDb), kSamplingFrequency,
1413                                                  mChannelLayout));
1414         cleanUpEqConfig();
1415         ASSERT_NO_FATAL_FAILURE(analyseMultiBandOutput(gainDb, false /*post-equalizer*/));
1416     }
1417 }
1418 
TEST_P(DynamicsProcessingEqBandConfigDataTest,PreEqEnableDisable)1419 TEST_P(DynamicsProcessingEqBandConfigDataTest, PreEqEnableDisable) {
1420     ASSERT_NO_FATAL_FAILURE(analyseMultiBandOutput(10 /*gain dB*/, true /*pre-equalizer*/,
1421                                                    false /*disable equalizer*/));
1422 }
1423 
TEST_P(DynamicsProcessingEqBandConfigDataTest,PostEqEnableDisable)1424 TEST_P(DynamicsProcessingEqBandConfigDataTest, PostEqEnableDisable) {
1425     ASSERT_NO_FATAL_FAILURE(analyseMultiBandOutput(10 /*gain dB*/, false /*post-equalizer*/,
1426                                                    false /*disable equalizer*/));
1427 }
1428 
1429 INSTANTIATE_TEST_SUITE_P(DynamicsProcessingTest, DynamicsProcessingEqBandConfigDataTest,
1430                          testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
1431                                  IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
__anon6e9317b31302(const auto& info) 1432                          [](const auto& info) {
1433                              auto descriptor = info.param;
1434                              std::string name = getPrefix(descriptor.second);
1435                              std::replace_if(
1436                                      name.begin(), name.end(),
1437                                      [](const char c) { return !std::isalnum(c); }, '_');
1438                              return name;
1439                          });
1440 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingEqBandConfigDataTest);
1441 
1442 /**
1443  * Test DynamicsProcessing MbcBandConfig
1444  */
1445 
1446 enum MbcBandConfigParamName {
1447     MBC_BAND_INSTANCE_NAME,
1448     MBC_BAND_CHANNEL,
1449     MBC_BAND_CUTOFF_FREQ,
1450     MBC_BAND_ADDITIONAL
1451 };
1452 enum MbcBandConfigAdditional {
1453     MBC_ADD_ATTACK_TIME,
1454     MBC_ADD_RELEASE_TIME,
1455     MBC_ADD_RATIO,
1456     MBC_ADD_THRESHOLD,
1457     MBC_ADD_KNEE_WIDTH,
1458     MBC_ADD_NOISE_GATE_THRESHOLD,
1459     MBC_ADD_EXPENDER_RATIO,
1460     MBC_ADD_PRE_GAIN,
1461     MBC_ADD_POST_GAIN,
1462     MBC_ADD_MAX_NUM
1463 };
1464 using TestParamsMbcBandConfigAdditional = std::array<float, MBC_ADD_MAX_NUM>;
1465 
1466 // attackTime, releaseTime, ratio, thresh, kneeWidth, noise, expander, preGain, postGain
1467 static constexpr std::array<TestParamsMbcBandConfigAdditional, 4> kMbcBandConfigAdditionalParam = {
1468         {{-3, -10, -2, -2, -5, -90, -2.5, -2, -2},
1469          {0, 0, 0, 0, 0, 0, 0, 0, 0},
1470          {-3, 10, -2, 2, -5, 90, -2.5, 2, -2},
1471          {3, 10, 2, -2, -5, 90, 2.5, 2, 2}}};
1472 
1473 using TestParamsMbcBandConfig =
1474         std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t,
1475                    std::vector<std::pair<int, float>>, TestParamsMbcBandConfigAdditional>;
1476 
fillMbcBandConfig(std::vector<DynamicsProcessing::MbcBandConfig> & cfgs,const TestParamsMbcBandConfig & params)1477 void fillMbcBandConfig(std::vector<DynamicsProcessing::MbcBandConfig>& cfgs,
1478                        const TestParamsMbcBandConfig& params) {
1479     const auto& cutOffFreqs = std::get<MBC_BAND_CUTOFF_FREQ>(params);
1480     const auto& additional = std::get<MBC_BAND_ADDITIONAL>(params);
1481 
1482     cfgs.resize(cutOffFreqs.size());
1483 
1484     for (size_t i = 0; i < cutOffFreqs.size(); ++i) {
1485         cfgs[i] = createMbcBandConfig(std::get<MBC_BAND_CHANNEL>(params),
1486                                       cutOffFreqs[i].first,   // band channel
1487                                       cutOffFreqs[i].second,  // band cutoff frequency
1488                                       additional[MBC_ADD_ATTACK_TIME],
1489                                       additional[MBC_ADD_RELEASE_TIME], additional[MBC_ADD_RATIO],
1490                                       additional[MBC_ADD_THRESHOLD], additional[MBC_ADD_KNEE_WIDTH],
1491                                       additional[MBC_ADD_NOISE_GATE_THRESHOLD],
1492                                       additional[MBC_ADD_EXPENDER_RATIO],
1493                                       additional[MBC_ADD_PRE_GAIN], additional[MBC_ADD_POST_GAIN]);
1494     }
1495 }
1496 
1497 class DynamicsProcessingTestMbcBandConfig
1498     : public ::testing::TestWithParam<TestParamsMbcBandConfig>,
1499       public DynamicsProcessingTestHelper {
1500   public:
DynamicsProcessingTestMbcBandConfig()1501     DynamicsProcessingTestMbcBandConfig()
1502         : DynamicsProcessingTestHelper(std::get<MBC_BAND_INSTANCE_NAME>(GetParam())) {
1503         fillMbcBandConfig(mCfgs, GetParam());
1504     }
1505 
SetUp()1506     void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpDynamicsProcessingEffect()); }
1507 
TearDown()1508     void TearDown() override { TearDownDynamicsProcessingEffect(); }
1509 
1510     std::vector<DynamicsProcessing::MbcBandConfig> mCfgs;
1511 };
1512 
TEST_P(DynamicsProcessingTestMbcBandConfig,SetAndGetMbcBandConfig)1513 TEST_P(DynamicsProcessingTestMbcBandConfig, SetAndGetMbcBandConfig) {
1514     mEngineConfigPreset.mbcStage.bandCount = mCfgs.size();
1515     addEngineConfig(mEngineConfigPreset);
1516     std::vector<DynamicsProcessing::ChannelConfig> cfgs(mChannelCount);
1517     for (int i = 0; i < mChannelCount; i++) {
1518         cfgs[i].channel = i;
1519         cfgs[i].enable = true;
1520     }
1521     addMbcChannelConfig(cfgs);
1522     addMbcBandConfigs(mCfgs);
1523     ASSERT_NO_FATAL_FAILURE(SetAndGetDynamicsProcessingParameters());
1524 }
1525 
1526 INSTANTIATE_TEST_SUITE_P(
1527         DynamicsProcessingTest, DynamicsProcessingTestMbcBandConfig,
1528         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
1529                                    IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
1530                            testing::Values(-1, 0, 10),  // channel index
1531                            testing::ValuesIn(kBands),   // band index, cut off frequencies
1532                            testing::ValuesIn(kMbcBandConfigAdditionalParam)),  // Additional
__anon6e9317b31502(const auto& info) 1533         [](const auto& info) {
1534             auto descriptor = std::get<MBC_BAND_INSTANCE_NAME>(info.param).second;
1535             std::vector<DynamicsProcessing::MbcBandConfig> cfgs;
1536             fillMbcBandConfig(cfgs, info.param);
1537             std::string mbcBands = ::android::internal::ToString(cfgs);
1538             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
1539                                descriptor.common.name + "_UUID_" +
1540                                toString(descriptor.common.id.uuid) + "_bands_" + mbcBands;
1541             std::replace_if(
1542                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
1543             return name;
1544         });
1545 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingTestMbcBandConfig);
1546 
1547 class DynamicsProcessingMbcBandConfigDataTest
1548     : public ::testing::TestWithParam<std::pair<std::shared_ptr<IFactory>, Descriptor>>,
1549       public DynamicsProcessingTestHelper {
1550   public:
DynamicsProcessingMbcBandConfigDataTest()1551     DynamicsProcessingMbcBandConfigDataTest()
1552         : DynamicsProcessingTestHelper(GetParam(), AudioChannelLayout::LAYOUT_MONO) {
1553         mBinOffsets.resize(mMultitoneTestFrequencies.size());
1554     }
1555 
SetUp()1556     void SetUp() override {
1557         ASSERT_NO_FATAL_FAILURE(
1558                 setUpDataTest(mMultitoneTestFrequencies, kSineMultitoneFullScaleDb));
1559     }
1560 
TearDown()1561     void TearDown() override { ASSERT_NO_FATAL_FAILURE(tearDownDataTest()); }
1562 
setMbcParamsAndProcess(std::vector<float> & output)1563     void setMbcParamsAndProcess(std::vector<float>& output) {
1564         createChannelConfig();
1565         mEngineConfigPreset.mbcStage.bandCount = mCfgs.size();
1566         addEngineConfig(mEngineConfigPreset);
1567         addMbcChannelConfig(mChannelConfig);
1568         addMbcBandConfigs(mCfgs);
1569         ASSERT_NO_FATAL_FAILURE(setParamsAndProcess(mInput, output));
1570     }
1571 
fillMbcBandConfig(std::vector<DynamicsProcessing::MbcBandConfig> & cfgs,int channelIndex,float threshold,float ratio,float noiseGate,float expanderRatio,int bandIndex,int cutoffFreqHz,float preGain,float postGain)1572     void fillMbcBandConfig(std::vector<DynamicsProcessing::MbcBandConfig>& cfgs, int channelIndex,
1573                            float threshold, float ratio, float noiseGate, float expanderRatio,
1574                            int bandIndex, int cutoffFreqHz, float preGain, float postGain) {
1575         cfgs.push_back(createMbcBandConfig(channelIndex, bandIndex,
1576                                            static_cast<float>(cutoffFreqHz), kDefaultAttackTime,
1577                                            kDefaultReleaseTime, ratio, threshold, kDefaultKneeWidth,
1578                                            noiseGate, expanderRatio, preGain, postGain));
1579     }
1580 
validateOutput(const std::vector<float> & output,float threshold,float ratio,size_t bandIndex)1581     void validateOutput(const std::vector<float>& output, float threshold, float ratio,
1582                         size_t bandIndex) {
1583         std::vector<float> outputMag(mBinOffsets.size());
1584         EXPECT_NO_FATAL_FAILURE(getMagnitudeValue(output, outputMag));
1585         if (threshold >= mInputDb || ratio == 1) {
1586             EXPECT_NO_FATAL_FAILURE(checkInputAndOutputEquality(outputMag));
1587         } else {
1588             // Current band's magnitude is less than the other band's magnitude
1589             EXPECT_LT(outputMag[bandIndex], outputMag[bandIndex ^ 1]);
1590         }
1591     }
1592 
analyseMultiBandOutput(float threshold,float ratio)1593     void analyseMultiBandOutput(float threshold, float ratio) {
1594         std::vector<float> output(mInput.size());
1595         roundToFreqCenteredToFftBin(mMultitoneTestFrequencies, mBinOffsets, kBinWidth);
1596         // Set MBC values for two bands
1597         for (size_t i = 0; i < kCutoffFreqHz.size(); i++) {
1598             for (int channelIndex = 0; channelIndex < mChannelCount; channelIndex++) {
1599                 fillMbcBandConfig(mCfgs, channelIndex, threshold, ratio, kDefaultNoiseGateDb,
1600                                   kDefaultExpanderRatio, i, kCutoffFreqHz[i], kDefaultPreGainDb,
1601                                   kDefaultPostGainDb);
1602                 fillMbcBandConfig(mCfgs, channelIndex, kDefaultThresholdDb, kDefaultRatio,
1603                                   kDefaultNoiseGateDb, kDefaultExpanderRatio, i ^ 1,
1604                                   kCutoffFreqHz[i ^ 1], kDefaultPreGainDb, kDefaultPostGainDb);
1605             }
1606             ASSERT_NO_FATAL_FAILURE(setMbcParamsAndProcess(output));
1607 
1608             if (isAllParamsValid()) {
1609                 ASSERT_NO_FATAL_FAILURE(validateOutput(output, threshold, ratio, i));
1610             }
1611             cleanUpMbcConfig();
1612         }
1613     }
1614 
cleanUpMbcConfig()1615     void cleanUpMbcConfig() {
1616         CleanUp();
1617         mCfgs.clear();
1618         mChannelConfig.clear();
1619     }
1620 
1621     static constexpr float kDefaultPostGainDb = 0;
1622     static constexpr float kDefaultPreGainDb = 0;
1623     static constexpr float kDefaultAttackTime = 0;
1624     static constexpr float kDefaultReleaseTime = 0;
1625     static constexpr float kDefaultKneeWidth = 0;
1626     static constexpr float kDefaultThresholdDb = 0;
1627     static constexpr float kDefaultNoiseGateDb = -10;
1628     static constexpr float kDefaultExpanderRatio = 1;
1629     static constexpr float kDefaultRatio = 1;
1630     std::vector<DynamicsProcessing::MbcBandConfig> mCfgs;
1631 };
1632 
TEST_P(DynamicsProcessingMbcBandConfigDataTest,IncreasingThreshold)1633 TEST_P(DynamicsProcessingMbcBandConfigDataTest, IncreasingThreshold) {
1634     float ratio = 20;
1635     std::vector<float> thresholdValues = {-200, -100, 0, 100, 200};
1636 
1637     for (float threshold : thresholdValues) {
1638         cleanUpMbcConfig();
1639         ASSERT_NO_FATAL_FAILURE(analyseMultiBandOutput(threshold, ratio));
1640     }
1641 }
1642 
TEST_P(DynamicsProcessingMbcBandConfigDataTest,IncreasingRatio)1643 TEST_P(DynamicsProcessingMbcBandConfigDataTest, IncreasingRatio) {
1644     float threshold = -20;
1645     std::vector<float> ratioValues = {1, 10, 20, 30, 40, 50};
1646 
1647     for (float ratio : ratioValues) {
1648         cleanUpMbcConfig();
1649         ASSERT_NO_FATAL_FAILURE(analyseMultiBandOutput(threshold, ratio));
1650     }
1651 }
1652 
TEST_P(DynamicsProcessingMbcBandConfigDataTest,IncreasingPostGain)1653 TEST_P(DynamicsProcessingMbcBandConfigDataTest, IncreasingPostGain) {
1654     std::vector<float> postGainDbValues = {-55, -30, 0, 30, 55};
1655     std::vector<float> output(mInput.size());
1656     for (float postGainDb : postGainDbValues) {
1657         ASSERT_NO_FATAL_FAILURE(generateSineWave(mMultitoneTestFrequencies, mInput,
1658                                                  dBToAmplitude(postGainDb), kSamplingFrequency,
1659                                                  mChannelLayout));
1660         mInputDb = calculateDb(mInput);
1661         EXPECT_NEAR(mInputDb, kSineMultitoneFullScaleDb - postGainDb, kToleranceDb);
1662         cleanUpMbcConfig();
1663         for (int i = 0; i < mChannelCount; i++) {
1664             fillMbcBandConfig(mCfgs, i, kDefaultThresholdDb, kDefaultRatio, kDefaultNoiseGateDb,
1665                               kDefaultExpanderRatio, 0 /*band index*/, 2000 /*cutoffFrequency*/,
1666                               kDefaultPreGainDb, postGainDb);
1667         }
1668         EXPECT_NO_FATAL_FAILURE(setMbcParamsAndProcess(output));
1669         if (!isAllParamsValid()) {
1670             continue;
1671         }
1672         float outputDb = calculateDb(output, kStartIndex);
1673         EXPECT_NEAR(outputDb, mInputDb + postGainDb, kToleranceDb)
1674                 << "PostGain: " << postGainDb << ", OutputDb: " << outputDb;
1675     }
1676 }
1677 
TEST_P(DynamicsProcessingMbcBandConfigDataTest,IncreasingPreGain)1678 TEST_P(DynamicsProcessingMbcBandConfigDataTest, IncreasingPreGain) {
1679     /*
1680     Depending on the pregain values, samples undergo either compression or expansion process.
1681     At -6 dB input,
1682     - Expansion is expected at -60 dB,
1683     - Compression at 10, 34 and 60 dB
1684     - No compression or expansion at -34, -10, -1 dB.
1685      */
1686     std::vector<float> preGainDbValues = {-60, -34, -10, -1, 10, 34, 60};
1687     std::vector<float> output(mInput.size());
1688     float thresholdDb = -7;
1689     float noiseGateDb = -40;
1690     std::vector<float> ratioValues = {1, 1.5, 2, 2.5, 3};
1691     for (float ratio : ratioValues) {
1692         for (float preGainDb : preGainDbValues) {
1693             float expectedOutputDb;
1694             float inputWithPreGain = mInputDb + preGainDb;
1695             if (inputWithPreGain > thresholdDb) {
1696                 SCOPED_TRACE("Compressor ratio: " + std::to_string(ratio));
1697                 expectedOutputDb =
1698                         (inputWithPreGain - thresholdDb) / ratio + thresholdDb - preGainDb;
1699             } else if (inputWithPreGain < noiseGateDb) {
1700                 SCOPED_TRACE("Expander ratio: " + std::to_string(ratio));
1701                 expectedOutputDb =
1702                         (inputWithPreGain - noiseGateDb) * ratio + noiseGateDb - preGainDb;
1703             } else {
1704                 expectedOutputDb = mInputDb;
1705             }
1706             cleanUpMbcConfig();
1707             for (int i = 0; i < mChannelCount; i++) {
1708                 fillMbcBandConfig(mCfgs, i, thresholdDb, ratio /*compressor ratio*/, noiseGateDb,
1709                                   ratio /*expander ratio*/, 0 /*band index*/,
1710                                   2000 /*cutoffFrequency*/, preGainDb, kDefaultPostGainDb);
1711             }
1712             EXPECT_NO_FATAL_FAILURE(setMbcParamsAndProcess(output));
1713             if (!isAllParamsValid()) {
1714                 continue;
1715             }
1716             float outputDb = calculateDb(output, kStartIndex);
1717             EXPECT_NEAR(outputDb, expectedOutputDb, kToleranceDb)
1718                     << "PreGain: " << preGainDb << ", OutputDb: " << outputDb;
1719         }
1720     }
1721 }
1722 
1723 INSTANTIATE_TEST_SUITE_P(DynamicsProcessingTest, DynamicsProcessingMbcBandConfigDataTest,
1724                          testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
1725                                  IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
__anon6e9317b31702(const auto& info) 1726                          [](const auto& info) {
1727                              auto descriptor = info.param;
1728                              std::string name = getPrefix(descriptor.second);
1729                              std::replace_if(
1730                                      name.begin(), name.end(),
1731                                      [](const char c) { return !std::isalnum(c); }, '_');
1732                              return name;
1733                          });
1734 
1735 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingMbcBandConfigDataTest);
1736 
main(int argc,char ** argv)1737 int main(int argc, char** argv) {
1738     ::testing::InitGoogleTest(&argc, argv);
1739     ::testing::UnitTest::GetInstance()->listeners().Append(new TestExecutionTracer());
1740     ABinderProcess_setThreadPoolMaxThreadCount(1);
1741     ABinderProcess_startThreadPool();
1742     return RUN_ALL_TESTS();
1743 }
1744