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