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