blob: 6e8d4108b62023d89aefabfdddd1be451525eca0 [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#define LOG_TAG "VtsHalDynamicsProcessingTest"
22#include <android-base/logging.h>
Sneha Patilabc94642024-11-13 08:41:05 +000023#include <audio_utils/power.h>
24#include <audio_utils/primitives.h>
Mikhail Naganov872d4a62023-03-09 18:19:01 -080025
Ram Mohane4064ce2022-12-20 18:05:14 +053026#include <Utils.h>
Mikhail Naganov872d4a62023-03-09 18:19:01 -080027
Ram Mohane4064ce2022-12-20 18:05:14 +053028#include "EffectHelper.h"
Ram Mohanafdf90b2023-03-23 08:48:25 +053029#include "EffectRangeSpecific.h"
Ram Mohane4064ce2022-12-20 18:05:14 +053030
31using namespace android;
Ram Mohanafdf90b2023-03-23 08:48:25 +053032using namespace aidl::android::hardware::audio::effect::DynamicsProcessingRanges;
Ram Mohane4064ce2022-12-20 18:05:14 +053033
Ram Mohane4064ce2022-12-20 18:05:14 +053034using aidl::android::hardware::audio::effect::Descriptor;
35using aidl::android::hardware::audio::effect::DynamicsProcessing;
Shunkai Yaof8be1ac2023-03-06 18:41:27 +000036using aidl::android::hardware::audio::effect::getEffectTypeUuidDynamicsProcessing;
Ram Mohane4064ce2022-12-20 18:05:14 +053037using aidl::android::hardware::audio::effect::IEffect;
38using aidl::android::hardware::audio::effect::IFactory;
Ram Mohane4064ce2022-12-20 18:05:14 +053039using aidl::android::hardware::audio::effect::Parameter;
Jaideep Sharma74498412023-09-13 15:25:25 +053040using android::hardware::audio::common::testing::detail::TestExecutionTracer;
Ram Mohane4064ce2022-12-20 18:05:14 +053041
42/**
43 * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
44 * VtsAudioEffectTargetTest.
45 */
46class DynamicsProcessingTestHelper : public EffectHelper {
47 public:
48 DynamicsProcessingTestHelper(std::pair<std::shared_ptr<IFactory>, Descriptor> pair,
Sneha Patilabc94642024-11-13 08:41:05 +000049 int32_t channelLayOut = AudioChannelLayout::LAYOUT_STEREO)
50 : mChannelLayout(channelLayOut),
51 mChannelCount(::aidl::android::hardware::audio::common::getChannelCount(
52 AudioChannelLayout::make<AudioChannelLayout::layoutMask>(mChannelLayout))) {
Ram Mohane4064ce2022-12-20 18:05:14 +053053 std::tie(mFactory, mDescriptor) = pair;
Ram Mohane4064ce2022-12-20 18:05:14 +053054 }
55
56 // setup
57 void SetUpDynamicsProcessingEffect() {
58 ASSERT_NE(nullptr, mFactory);
59 ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
Ram Mohane4064ce2022-12-20 18:05:14 +053060 Parameter::Specific specific = getDefaultParamSpecific();
Shunkai Yao61f9dd22024-05-08 22:34:36 +000061 Parameter::Common common = createParamCommon(
Sneha Patilabc94642024-11-13 08:41:05 +000062 0 /* session */, 1 /* ioHandle */, kSamplingFrequency /* iSampleRate */,
63 kSamplingFrequency /* oSampleRate */, kFrameCount /* iFrameCount */,
64 kFrameCount /* oFrameCount */,
Ram Mohane4064ce2022-12-20 18:05:14 +053065 AudioChannelLayout::make<AudioChannelLayout::layoutMask>(mChannelLayout),
66 AudioChannelLayout::make<AudioChannelLayout::layoutMask>(mChannelLayout));
Sneha Patilabc94642024-11-13 08:41:05 +000067 ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &mOpenEffectReturn, EX_NONE));
Ram Mohane4064ce2022-12-20 18:05:14 +053068 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
Sneha Patilabc94642024-11-13 08:41:05 +0000117 bool isAllParamsValid();
118
Ram Mohane4064ce2022-12-20 18:05:14 +0530119 // enqueue test parameters
120 void addEngineConfig(const DynamicsProcessing::EngineArchitecture& cfg);
121 void addPreEqChannelConfig(const std::vector<DynamicsProcessing::ChannelConfig>& cfg);
122 void addPostEqChannelConfig(const std::vector<DynamicsProcessing::ChannelConfig>& cfg);
123 void addMbcChannelConfig(const std::vector<DynamicsProcessing::ChannelConfig>& cfg);
124 void addPreEqBandConfigs(const std::vector<DynamicsProcessing::EqBandConfig>& cfgs);
125 void addPostEqBandConfigs(const std::vector<DynamicsProcessing::EqBandConfig>& cfgs);
126 void addMbcBandConfigs(const std::vector<DynamicsProcessing::MbcBandConfig>& cfgs);
127 void addLimiterConfig(const std::vector<DynamicsProcessing::LimiterConfig>& cfg);
128 void addInputGain(const std::vector<DynamicsProcessing::InputGain>& inputGain);
129
130 static constexpr float kPreferredProcessingDurationMs = 10.0f;
131 static constexpr int kBandCount = 5;
Sneha Patilabc94642024-11-13 08:41:05 +0000132 static constexpr int kSamplingFrequency = 44100;
133 static constexpr int kFrameCount = 2048;
Ram Mohane4064ce2022-12-20 18:05:14 +0530134 std::shared_ptr<IFactory> mFactory;
135 std::shared_ptr<IEffect> mEffect;
136 Descriptor mDescriptor;
Sneha Patilabc94642024-11-13 08:41:05 +0000137 IEffect::OpenEffectReturn mOpenEffectReturn;
Ram Mohane4064ce2022-12-20 18:05:14 +0530138 DynamicsProcessing::EngineArchitecture mEngineConfigApplied;
139 DynamicsProcessing::EngineArchitecture mEngineConfigPreset{
140 .resolutionPreference =
141 DynamicsProcessing::ResolutionPreference::FAVOR_FREQUENCY_RESOLUTION,
142 .preferredProcessingDurationMs = kPreferredProcessingDurationMs,
143 .preEqStage = {.inUse = true, .bandCount = kBandCount},
144 .postEqStage = {.inUse = true, .bandCount = kBandCount},
145 .mbcStage = {.inUse = true, .bandCount = kBandCount},
146 .limiterInUse = true,
147 };
148
149 std::unordered_set<int /* channelId */> mPreEqChannelEnable;
150 std::unordered_set<int /* channelId */> mPostEqChannelEnable;
151 std::unordered_set<int /* channelId */> mMbcChannelEnable;
152 std::unordered_set<int /* channelId */> mLimiterChannelEnable;
153 static const std::set<std::vector<DynamicsProcessing::ChannelConfig>> kChannelConfigTestSet;
154 static const std::set<DynamicsProcessing::StageEnablement> kStageEnablementTestSet;
155 static const std::set<std::vector<DynamicsProcessing::InputGain>> kInputGainTestSet;
156
157 private:
Sneha Patilabc94642024-11-13 08:41:05 +0000158 const int32_t mChannelLayout;
Ram Mohane4064ce2022-12-20 18:05:14 +0530159 std::vector<std::pair<DynamicsProcessing::Tag, DynamicsProcessing>> mTags;
Sneha Patilabc94642024-11-13 08:41:05 +0000160
161 protected:
162 const int mChannelCount;
Ram Mohane4064ce2022-12-20 18:05:14 +0530163 void CleanUp() {
164 mTags.clear();
165 mPreEqChannelEnable.clear();
166 mPostEqChannelEnable.clear();
167 mMbcChannelEnable.clear();
168 mLimiterChannelEnable.clear();
169 }
170};
171
172// test value set for DynamicsProcessing::StageEnablement
173const std::set<DynamicsProcessing::StageEnablement>
174 DynamicsProcessingTestHelper::kStageEnablementTestSet = {
175 {.inUse = true, .bandCount = DynamicsProcessingTestHelper::kBandCount},
176 {.inUse = true, .bandCount = 0},
177 {.inUse = true, .bandCount = -1},
Ram Mohanafdf90b2023-03-23 08:48:25 +0530178 {.inUse = false, .bandCount = 0},
179 {.inUse = false, .bandCount = -1},
Ram Mohane4064ce2022-12-20 18:05:14 +0530180 {.inUse = false, .bandCount = DynamicsProcessingTestHelper::kBandCount}};
181
182// test value set for DynamicsProcessing::ChannelConfig
183const std::set<std::vector<DynamicsProcessing::ChannelConfig>>
184 DynamicsProcessingTestHelper::kChannelConfigTestSet = {
185 {{.channel = -1, .enable = false},
186 {.channel = 0, .enable = true},
187 {.channel = 1, .enable = false},
188 {.channel = 2, .enable = true}},
Ram Mohane4064ce2022-12-20 18:05:14 +0530189 {{.channel = -1, .enable = false}, {.channel = 2, .enable = true}},
Ram Mohane4064ce2022-12-20 18:05:14 +0530190 {{.channel = 0, .enable = true}, {.channel = 1, .enable = true}}};
191
192// test value set for DynamicsProcessing::InputGain
193const std::set<std::vector<DynamicsProcessing::InputGain>>
194 DynamicsProcessingTestHelper::kInputGainTestSet = {
195 {{.channel = 0, .gainDb = 10.f},
196 {.channel = 1, .gainDb = 0.f},
197 {.channel = 2, .gainDb = -10.f}},
Ram Mohane4064ce2022-12-20 18:05:14 +0530198 {{.channel = -1, .gainDb = -10.f}, {.channel = -2, .gainDb = 10.f}},
Ram Mohanafdf90b2023-03-23 08:48:25 +0530199 {{.channel = -1, .gainDb = 10.f}, {.channel = 0, .gainDb = -10.f}},
200 {{.channel = 0, .gainDb = 10.f}, {.channel = 1, .gainDb = -10.f}}};
Ram Mohane4064ce2022-12-20 18:05:14 +0530201
Ram Mohanafdf90b2023-03-23 08:48:25 +0530202template <typename T>
203bool DynamicsProcessingTestHelper::isBandConfigValid(const std::vector<T>& cfgs, int bandCount) {
Shunkai Yao53238b12024-03-29 23:09:04 +0000204 std::unordered_set<int> freqs;
Ram Mohanafdf90b2023-03-23 08:48:25 +0530205 for (auto cfg : cfgs) {
206 if (cfg.channel < 0 || cfg.channel >= mChannelCount) return false;
207 if (cfg.band < 0 || cfg.band >= bandCount) return false;
Shunkai Yao53238b12024-03-29 23:09:04 +0000208 // duplicated band index
209 if (freqs.find(cfg.band) != freqs.end()) return false;
210 freqs.insert(cfg.band);
Ram Mohanafdf90b2023-03-23 08:48:25 +0530211 }
Shunkai Yao53238b12024-03-29 23:09:04 +0000212 return true;
Ram Mohanafdf90b2023-03-23 08:48:25 +0530213}
214
215bool DynamicsProcessingTestHelper::isParamValid(const DynamicsProcessing::Tag& tag,
216 const DynamicsProcessing& dp) {
217 switch (tag) {
218 case DynamicsProcessing::preEq: {
Ram Mohanafdf90b2023-03-23 08:48:25 +0530219 return isChannelConfigValid(dp.get<DynamicsProcessing::preEq>());
220 }
221 case DynamicsProcessing::postEq: {
Ram Mohanafdf90b2023-03-23 08:48:25 +0530222 return isChannelConfigValid(dp.get<DynamicsProcessing::postEq>());
223 }
224 case DynamicsProcessing::mbc: {
Ram Mohanafdf90b2023-03-23 08:48:25 +0530225 return isChannelConfigValid(dp.get<DynamicsProcessing::mbc>());
226 }
227 case DynamicsProcessing::preEqBand: {
Ram Mohanafdf90b2023-03-23 08:48:25 +0530228 return isBandConfigValid(dp.get<DynamicsProcessing::preEqBand>(),
229 mEngineConfigApplied.preEqStage.bandCount);
230 }
231 case DynamicsProcessing::postEqBand: {
Ram Mohanafdf90b2023-03-23 08:48:25 +0530232 return isBandConfigValid(dp.get<DynamicsProcessing::postEqBand>(),
233 mEngineConfigApplied.postEqStage.bandCount);
234 }
235 case DynamicsProcessing::mbcBand: {
Ram Mohanafdf90b2023-03-23 08:48:25 +0530236 return isBandConfigValid(dp.get<DynamicsProcessing::mbcBand>(),
237 mEngineConfigApplied.mbcStage.bandCount);
238 }
239 case DynamicsProcessing::limiter: {
Ram Mohanafdf90b2023-03-23 08:48:25 +0530240 return isChannelConfigValid(dp.get<DynamicsProcessing::limiter>());
241 }
242 case DynamicsProcessing::inputGain: {
243 return isChannelConfigValid(dp.get<DynamicsProcessing::inputGain>());
244 }
245 default: {
246 return true;
247 }
248 }
249 return true;
250}
Ram Mohane4064ce2022-12-20 18:05:14 +0530251
Ram Mohane4064ce2022-12-20 18:05:14 +0530252bool DynamicsProcessingTestHelper::isParamEqual(const DynamicsProcessing::Tag& tag,
253 const DynamicsProcessing& dpRef,
254 const DynamicsProcessing& dpTest) {
255 switch (tag) {
256 case DynamicsProcessing::engineArchitecture: {
257 return isEngineConfigEqual(dpRef.get<DynamicsProcessing::engineArchitecture>(),
258 dpTest.get<DynamicsProcessing::engineArchitecture>());
259 }
260 case DynamicsProcessing::preEq: {
261 const auto& source = dpRef.get<DynamicsProcessing::preEq>();
262 const auto& target = dpTest.get<DynamicsProcessing::preEq>();
263 return isAidlVectorEqualAfterFilter<DynamicsProcessing::ChannelConfig>(source, target);
264 }
265 case DynamicsProcessing::postEq: {
266 return isAidlVectorEqualAfterFilter<DynamicsProcessing::ChannelConfig>(
267 dpRef.get<DynamicsProcessing::postEq>(),
268 dpTest.get<DynamicsProcessing::postEq>());
269 }
270 case DynamicsProcessing::mbc: {
271 return isAidlVectorEqualAfterFilter<DynamicsProcessing::ChannelConfig>(
272 dpRef.get<DynamicsProcessing::mbc>(), dpTest.get<DynamicsProcessing::mbc>());
273 }
274 case DynamicsProcessing::preEqBand: {
275 return isAidlVectorEqualAfterFilter<DynamicsProcessing::EqBandConfig>(
276 dpRef.get<DynamicsProcessing::preEqBand>(),
277 dpTest.get<DynamicsProcessing::preEqBand>());
278 }
279 case DynamicsProcessing::postEqBand: {
280 return isAidlVectorEqualAfterFilter<DynamicsProcessing::EqBandConfig>(
281 dpRef.get<DynamicsProcessing::postEqBand>(),
282 dpTest.get<DynamicsProcessing::postEqBand>());
283 }
284 case DynamicsProcessing::mbcBand: {
285 return isAidlVectorEqualAfterFilter<DynamicsProcessing::MbcBandConfig>(
286 dpRef.get<DynamicsProcessing::mbcBand>(),
287 dpTest.get<DynamicsProcessing::mbcBand>());
288 }
289 case DynamicsProcessing::limiter: {
290 return isAidlVectorEqualAfterFilter<DynamicsProcessing::LimiterConfig>(
291 dpRef.get<DynamicsProcessing::limiter>(),
292 dpTest.get<DynamicsProcessing::limiter>());
293 }
294 case DynamicsProcessing::inputGain: {
295 return isAidlVectorEqual<DynamicsProcessing::InputGain>(
296 dpRef.get<DynamicsProcessing::inputGain>(),
297 dpTest.get<DynamicsProcessing::inputGain>());
298 }
Shunkai Yaob2325e52023-03-03 19:34:47 +0000299 case DynamicsProcessing::vendor: {
Ram Mohane4064ce2022-12-20 18:05:14 +0530300 return false;
301 }
302 }
303}
304
Ram Mohane4064ce2022-12-20 18:05:14 +0530305bool DynamicsProcessingTestHelper::isEngineConfigEqual(
306 const DynamicsProcessing::EngineArchitecture& ref,
307 const DynamicsProcessing::EngineArchitecture& test) {
308 return ref == test;
309}
310
311template <typename T>
312std::vector<T> DynamicsProcessingTestHelper::filterEnabledVector(const std::vector<T>& vec) {
313 std::vector<T> ret;
314 std::copy_if(vec.begin(), vec.end(), std::back_inserter(ret),
315 [](const auto& v) { return v.enable; });
316 return ret;
317}
318
319template <typename T>
320bool DynamicsProcessingTestHelper::isAidlVectorEqual(const std::vector<T>& source,
321 const std::vector<T>& target) {
322 if (source.size() != target.size()) return false;
323
324 auto tempS = source;
325 auto tempT = target;
326 std::sort(tempS.begin(), tempS.end());
327 std::sort(tempT.begin(), tempT.end());
328 return tempS == tempT;
329}
330
331template <typename T>
332bool DynamicsProcessingTestHelper::isAidlVectorEqualAfterFilter(const std::vector<T>& source,
333 const std::vector<T>& target) {
334 return isAidlVectorEqual<T>(filterEnabledVector<T>(source), filterEnabledVector<T>(target));
335}
336
337void DynamicsProcessingTestHelper::SetAndGetDynamicsProcessingParameters() {
Sneha Patilabc94642024-11-13 08:41:05 +0000338 for (const auto& [tag, dp] : mTags) {
Ram Mohane4064ce2022-12-20 18:05:14 +0530339 // validate parameter
340 Descriptor desc;
341 ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
Ram Mohanafdf90b2023-03-23 08:48:25 +0530342 bool valid = isParamInRange(dp, desc.capability.range.get<Range::dynamicsProcessing>());
343 if (valid) valid = isParamValid(tag, dp);
Ram Mohane4064ce2022-12-20 18:05:14 +0530344 const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
345
346 // set parameter
347 Parameter expectParam;
348 Parameter::Specific specific;
349 specific.set<Parameter::Specific::dynamicsProcessing>(dp);
350 expectParam.set<Parameter::specific>(specific);
Shunkai Yao0a0c45e2023-02-13 17:41:11 +0000351 ASSERT_STATUS(expected, mEffect->setParameter(expectParam))
352 << "\n"
353 << expectParam.toString() << "\n"
354 << desc.toString();
Ram Mohane4064ce2022-12-20 18:05:14 +0530355
356 // only get if parameter in range and set success
357 if (expected == EX_NONE) {
358 Parameter getParam;
359 Parameter::Id id;
360 DynamicsProcessing::Id dpId;
361 dpId.set<DynamicsProcessing::Id::commonTag>(tag);
362 id.set<Parameter::Id::dynamicsProcessingTag>(dpId);
363 // if set success, then get should match
364 EXPECT_STATUS(expected, mEffect->getParameter(id, &getParam));
365 Parameter::Specific specificTest = getParam.get<Parameter::specific>();
366 const auto& target = specificTest.get<Parameter::Specific::dynamicsProcessing>();
367 EXPECT_TRUE(isParamEqual(tag, dp, target)) << dp.toString() << "\n"
368 << target.toString();
369 // update mEngineConfigApplied after setting successfully
370 if (tag == DynamicsProcessing::engineArchitecture) {
371 mEngineConfigApplied = target.get<DynamicsProcessing::engineArchitecture>();
372 }
373 }
374 }
375}
376
Sneha Patilabc94642024-11-13 08:41:05 +0000377bool DynamicsProcessingTestHelper::isAllParamsValid() {
378 if (mTags.empty()) {
379 return false;
380 }
381 for (const auto& [tag, dp] : mTags) {
382 // validate parameter
383 if (!isParamInRange(dp, mDescriptor.capability.range.get<Range::dynamicsProcessing>())) {
384 return false;
385 }
386 if (!isParamValid(tag, dp)) {
387 return false;
388 }
389 }
390 return true;
391}
392
Ram Mohane4064ce2022-12-20 18:05:14 +0530393void DynamicsProcessingTestHelper::addEngineConfig(
394 const DynamicsProcessing::EngineArchitecture& cfg) {
395 DynamicsProcessing dp;
396 dp.set<DynamicsProcessing::engineArchitecture>(cfg);
397 mTags.push_back({DynamicsProcessing::engineArchitecture, dp});
398}
399
400void DynamicsProcessingTestHelper::addPreEqChannelConfig(
401 const std::vector<DynamicsProcessing::ChannelConfig>& cfgs) {
402 DynamicsProcessing dp;
403 dp.set<DynamicsProcessing::preEq>(cfgs);
404 mTags.push_back({DynamicsProcessing::preEq, dp});
405 for (auto& cfg : cfgs) {
406 if (cfg.enable) mPreEqChannelEnable.insert(cfg.channel);
407 }
408}
409
410void DynamicsProcessingTestHelper::addPostEqChannelConfig(
411 const std::vector<DynamicsProcessing::ChannelConfig>& cfgs) {
412 DynamicsProcessing dp;
413 dp.set<DynamicsProcessing::postEq>(cfgs);
414 mTags.push_back({DynamicsProcessing::postEq, dp});
415 for (auto& cfg : cfgs) {
416 if (cfg.enable) mPostEqChannelEnable.insert(cfg.channel);
417 }
418}
419
420void DynamicsProcessingTestHelper::addMbcChannelConfig(
421 const std::vector<DynamicsProcessing::ChannelConfig>& cfgs) {
422 DynamicsProcessing dp;
423 dp.set<DynamicsProcessing::mbc>(cfgs);
424 mTags.push_back({DynamicsProcessing::mbc, dp});
425 for (auto& cfg : cfgs) {
426 if (cfg.enable) mMbcChannelEnable.insert(cfg.channel);
427 }
428}
429
430void DynamicsProcessingTestHelper::addPreEqBandConfigs(
431 const std::vector<DynamicsProcessing::EqBandConfig>& cfgs) {
432 DynamicsProcessing dp;
433 dp.set<DynamicsProcessing::preEqBand>(cfgs);
434 mTags.push_back({DynamicsProcessing::preEqBand, dp});
435}
436
437void DynamicsProcessingTestHelper::addPostEqBandConfigs(
438 const std::vector<DynamicsProcessing::EqBandConfig>& cfgs) {
439 DynamicsProcessing dp;
440 dp.set<DynamicsProcessing::postEqBand>(cfgs);
441 mTags.push_back({DynamicsProcessing::postEqBand, dp});
442}
443
444void DynamicsProcessingTestHelper::addMbcBandConfigs(
445 const std::vector<DynamicsProcessing::MbcBandConfig>& cfgs) {
446 DynamicsProcessing dp;
447 dp.set<DynamicsProcessing::mbcBand>(cfgs);
448 mTags.push_back({DynamicsProcessing::mbcBand, dp});
449}
450
451void DynamicsProcessingTestHelper::addLimiterConfig(
452 const std::vector<DynamicsProcessing::LimiterConfig>& cfgs) {
453 DynamicsProcessing dp;
454 dp.set<DynamicsProcessing::limiter>(cfgs);
455 mTags.push_back({DynamicsProcessing::limiter, dp});
456 for (auto& cfg : cfgs) {
457 if (cfg.enable) mLimiterChannelEnable.insert(cfg.channel);
458 }
459}
460
461void DynamicsProcessingTestHelper::addInputGain(
462 const std::vector<DynamicsProcessing::InputGain>& inputGains) {
463 DynamicsProcessing dp;
464 dp.set<DynamicsProcessing::inputGain>(inputGains);
465 mTags.push_back({DynamicsProcessing::inputGain, dp});
466}
467
Sneha Patilabc94642024-11-13 08:41:05 +0000468void fillLimiterConfig(std::vector<DynamicsProcessing::LimiterConfig>& limiterConfigList,
469 int channelIndex, bool enable, int linkGroup, float attackTime,
470 float releaseTime, float ratio, float threshold, float postGain) {
471 DynamicsProcessing::LimiterConfig cfg;
472 cfg.channel = channelIndex;
473 cfg.enable = enable;
474 cfg.linkGroup = linkGroup;
475 cfg.attackTimeMs = attackTime;
476 cfg.releaseTimeMs = releaseTime;
477 cfg.ratio = ratio;
478 cfg.thresholdDb = threshold;
479 cfg.postGainDb = postGain;
480 limiterConfigList.push_back(cfg);
481}
482
Ram Mohane4064ce2022-12-20 18:05:14 +0530483/**
484 * Test DynamicsProcessing Engine Configuration
485 */
486enum EngineArchitectureTestParamName {
487 ENGINE_TEST_INSTANCE_NAME,
488 ENGINE_TEST_RESOLUTION_PREFERENCE,
489 ENGINE_TEST_PREFERRED_DURATION,
Shunkai Yaof137ba42024-04-11 17:11:03 +0000490 ENGINE_TEST_STAGE_ENABLEMENT
Ram Mohane4064ce2022-12-20 18:05:14 +0530491};
492using EngineArchitectureTestParams = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
493 DynamicsProcessing::ResolutionPreference, float,
Shunkai Yaof137ba42024-04-11 17:11:03 +0000494 DynamicsProcessing::StageEnablement>;
Ram Mohane4064ce2022-12-20 18:05:14 +0530495
496void fillEngineArchConfig(DynamicsProcessing::EngineArchitecture& cfg,
497 const EngineArchitectureTestParams& params) {
498 cfg.resolutionPreference = std::get<ENGINE_TEST_RESOLUTION_PREFERENCE>(params);
499 cfg.preferredProcessingDurationMs = std::get<ENGINE_TEST_PREFERRED_DURATION>(params);
500 cfg.preEqStage = cfg.postEqStage = cfg.mbcStage =
501 std::get<ENGINE_TEST_STAGE_ENABLEMENT>(params);
Shunkai Yaof137ba42024-04-11 17:11:03 +0000502 cfg.limiterInUse = true;
Ram Mohane4064ce2022-12-20 18:05:14 +0530503}
504
505class DynamicsProcessingTestEngineArchitecture
506 : public ::testing::TestWithParam<EngineArchitectureTestParams>,
507 public DynamicsProcessingTestHelper {
508 public:
509 DynamicsProcessingTestEngineArchitecture()
510 : DynamicsProcessingTestHelper(std::get<ENGINE_TEST_INSTANCE_NAME>(GetParam())) {
511 fillEngineArchConfig(mCfg, GetParam());
512 };
513
514 void SetUp() override { SetUpDynamicsProcessingEffect(); }
515
516 void TearDown() override { TearDownDynamicsProcessingEffect(); }
517
518 DynamicsProcessing::EngineArchitecture mCfg;
519};
520
521TEST_P(DynamicsProcessingTestEngineArchitecture, SetAndGetEngineArch) {
522 EXPECT_NO_FATAL_FAILURE(addEngineConfig(mCfg));
Sneha Patilabc94642024-11-13 08:41:05 +0000523 ASSERT_NO_FATAL_FAILURE(SetAndGetDynamicsProcessingParameters());
Ram Mohane4064ce2022-12-20 18:05:14 +0530524}
525
526INSTANTIATE_TEST_SUITE_P(
527 DynamicsProcessingTest, DynamicsProcessingTestEngineArchitecture,
528 ::testing::Combine(
529 testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
Shunkai Yaof8be1ac2023-03-06 18:41:27 +0000530 IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
Ram Mohanafdf90b2023-03-23 08:48:25 +0530531 testing::Values(
532 DynamicsProcessing::ResolutionPreference::FAVOR_TIME_RESOLUTION,
533 DynamicsProcessing::ResolutionPreference::FAVOR_FREQUENCY_RESOLUTION,
534 static_cast<DynamicsProcessing::ResolutionPreference>(-1)), // variant
535 testing::Values(-10.f, 0.f, 10.f), // processing duration
Ram Mohane4064ce2022-12-20 18:05:14 +0530536 testing::ValuesIn(
Shunkai Yaof137ba42024-04-11 17:11:03 +0000537 DynamicsProcessingTestHelper::kStageEnablementTestSet) // preEQ/postEQ/mbc
538 ),
Ram Mohane4064ce2022-12-20 18:05:14 +0530539 [](const auto& info) {
540 auto descriptor = std::get<ENGINE_TEST_INSTANCE_NAME>(info.param).second;
541 DynamicsProcessing::EngineArchitecture cfg;
542 fillEngineArchConfig(cfg, info.param);
Jaideep Sharmae4c7a962023-06-14 19:14:44 +0530543 std::string name = getPrefix(descriptor) + "_Cfg_" + cfg.toString();
Ram Mohane4064ce2022-12-20 18:05:14 +0530544 std::replace_if(
545 name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
546 return name;
547 });
548GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingTestEngineArchitecture);
549
550/**
551 * Test DynamicsProcessing Input Gain
552 */
553enum InputGainTestParamName {
554 INPUT_GAIN_INSTANCE_NAME,
555 INPUT_GAIN_PARAM,
556};
557class DynamicsProcessingTestInputGain
558 : public ::testing::TestWithParam<std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
559 std::vector<DynamicsProcessing::InputGain>>>,
560 public DynamicsProcessingTestHelper {
561 public:
562 DynamicsProcessingTestInputGain()
563 : DynamicsProcessingTestHelper(std::get<INPUT_GAIN_INSTANCE_NAME>(GetParam())),
Sneha Patilabc94642024-11-13 08:41:05 +0000564 mInputGain(std::get<INPUT_GAIN_PARAM>(GetParam())) {};
Ram Mohane4064ce2022-12-20 18:05:14 +0530565
566 void SetUp() override { SetUpDynamicsProcessingEffect(); }
567
568 void TearDown() override { TearDownDynamicsProcessingEffect(); }
569
570 const std::vector<DynamicsProcessing::InputGain> mInputGain;
571};
572
573TEST_P(DynamicsProcessingTestInputGain, SetAndGetInputGain) {
574 EXPECT_NO_FATAL_FAILURE(addInputGain(mInputGain));
Sneha Patilabc94642024-11-13 08:41:05 +0000575 ASSERT_NO_FATAL_FAILURE(SetAndGetDynamicsProcessingParameters());
Ram Mohane4064ce2022-12-20 18:05:14 +0530576}
577
578INSTANTIATE_TEST_SUITE_P(
579 DynamicsProcessingTest, DynamicsProcessingTestInputGain,
580 ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
Shunkai Yaof8be1ac2023-03-06 18:41:27 +0000581 IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
Ram Mohane4064ce2022-12-20 18:05:14 +0530582 testing::ValuesIn(DynamicsProcessingTestInputGain::kInputGainTestSet)),
583 [](const auto& info) {
584 auto descriptor = std::get<INPUT_GAIN_INSTANCE_NAME>(info.param).second;
585 std::string gains =
586 ::android::internal::ToString(std::get<INPUT_GAIN_PARAM>(info.param));
587 std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
588 descriptor.common.name + "_UUID_" +
Shunkai Yao6f822452024-03-29 18:45:30 +0000589 toString(descriptor.common.id.uuid) + "_inputGains_" + gains;
Ram Mohane4064ce2022-12-20 18:05:14 +0530590 std::replace_if(
591 name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
592 return name;
593 });
594GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingTestInputGain);
595
596/**
597 * Test DynamicsProcessing Limiter Config
598 */
599enum LimiterConfigTestParamName {
600 LIMITER_INSTANCE_NAME,
601 LIMITER_CHANNEL,
Ram Mohane4064ce2022-12-20 18:05:14 +0530602 LIMITER_LINK_GROUP,
Ram Mohane4064ce2022-12-20 18:05:14 +0530603 LIMITER_ATTACK_TIME,
604 LIMITER_RELEASE_TIME,
605 LIMITER_RATIO,
606 LIMITER_THRESHOLD,
607 LIMITER_POST_GAIN,
Ram Mohane4064ce2022-12-20 18:05:14 +0530608};
Ram Mohane4064ce2022-12-20 18:05:14 +0530609
Shunkai Yaof137ba42024-04-11 17:11:03 +0000610using LimiterConfigTestParams = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
Sneha Patilabc94642024-11-13 08:41:05 +0000611 int32_t, int32_t, float, float, float, float, float>;
Ram Mohane4064ce2022-12-20 18:05:14 +0530612
Sneha Patilabc94642024-11-13 08:41:05 +0000613void fillLimiterConfig(std::vector<DynamicsProcessing::LimiterConfig>& cfg,
Ram Mohane4064ce2022-12-20 18:05:14 +0530614 const LimiterConfigTestParams& params) {
Sneha Patilabc94642024-11-13 08:41:05 +0000615 fillLimiterConfig(cfg, std::get<LIMITER_CHANNEL>(params), true,
616 std::get<LIMITER_LINK_GROUP>(params), std::get<LIMITER_ATTACK_TIME>(params),
617 std::get<LIMITER_RELEASE_TIME>(params), std::get<LIMITER_RATIO>(params),
618 std::get<LIMITER_THRESHOLD>(params), std::get<LIMITER_POST_GAIN>(params));
Ram Mohane4064ce2022-12-20 18:05:14 +0530619}
620
621class DynamicsProcessingTestLimiterConfig
622 : public ::testing::TestWithParam<LimiterConfigTestParams>,
623 public DynamicsProcessingTestHelper {
624 public:
625 DynamicsProcessingTestLimiterConfig()
Shunkai Yaof137ba42024-04-11 17:11:03 +0000626 : DynamicsProcessingTestHelper(std::get<LIMITER_INSTANCE_NAME>(GetParam())) {
Sneha Patilabc94642024-11-13 08:41:05 +0000627 fillLimiterConfig(mLimiterConfigList, GetParam());
Ram Mohane4064ce2022-12-20 18:05:14 +0530628 }
629
630 void SetUp() override { SetUpDynamicsProcessingEffect(); }
631
632 void TearDown() override { TearDownDynamicsProcessingEffect(); }
633
634 DynamicsProcessing::LimiterConfig mCfg;
Sneha Patilabc94642024-11-13 08:41:05 +0000635 std::vector<DynamicsProcessing::LimiterConfig> mLimiterConfigList;
Ram Mohane4064ce2022-12-20 18:05:14 +0530636};
637
638TEST_P(DynamicsProcessingTestLimiterConfig, SetAndGetLimiterConfig) {
Ram Mohane4064ce2022-12-20 18:05:14 +0530639 EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
Sneha Patilabc94642024-11-13 08:41:05 +0000640 EXPECT_NO_FATAL_FAILURE(addLimiterConfig(mLimiterConfigList));
641 ASSERT_NO_FATAL_FAILURE(SetAndGetDynamicsProcessingParameters());
Ram Mohane4064ce2022-12-20 18:05:14 +0530642}
643
644INSTANTIATE_TEST_SUITE_P(
645 DynamicsProcessingTest, DynamicsProcessingTestLimiterConfig,
646 ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
Shunkai Yaof8be1ac2023-03-06 18:41:27 +0000647 IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
Sneha Patilabc94642024-11-13 08:41:05 +0000648 testing::Values(-1, 0, 1, 2), // channel index
649 testing::Values(3), // link group
650 testing::Values(-1, 1), // attackTime
651 testing::Values(-60, 60), // releaseTime
652 testing::Values(-2.5, 2.5), // ratio
653 testing::Values(-2, 2), // thresh
654 testing::Values(-3.14, 3.14) // postGain
655 ),
Ram Mohane4064ce2022-12-20 18:05:14 +0530656 [](const auto& info) {
657 auto descriptor = std::get<LIMITER_INSTANCE_NAME>(info.param).second;
Sneha Patilabc94642024-11-13 08:41:05 +0000658 std::vector<DynamicsProcessing::LimiterConfig> cfg;
Ram Mohane4064ce2022-12-20 18:05:14 +0530659 fillLimiterConfig(cfg, info.param);
Sneha Patilabc94642024-11-13 08:41:05 +0000660 std::string name =
661 "Implementer_" + getPrefix(descriptor) + "_limiterConfig_" + cfg[0].toString();
Ram Mohane4064ce2022-12-20 18:05:14 +0530662 std::replace_if(
663 name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
664 return name;
665 });
666GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingTestLimiterConfig);
667
Sneha Patilabc94642024-11-13 08:41:05 +0000668using LimiterConfigDataTestParams = std::pair<std::shared_ptr<IFactory>, Descriptor>;
669
670class DynamicsProcessingLimiterConfigDataTest
671 : public ::testing::TestWithParam<LimiterConfigDataTestParams>,
672 public DynamicsProcessingTestHelper {
673 public:
674 DynamicsProcessingLimiterConfigDataTest()
675 : DynamicsProcessingTestHelper(GetParam(), AudioChannelLayout::LAYOUT_MONO) {
676 mBufferSize = kFrameCount * mChannelCount;
677 mInput.resize(mBufferSize);
678 generateSineWave(1000 /*Input Frequency*/, mInput);
679 mInputDb = calculateDb(mInput);
680 }
681
682 void SetUp() override {
683 SetUpDynamicsProcessingEffect();
684 SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
685 }
686
687 void TearDown() override { TearDownDynamicsProcessingEffect(); }
688
689 float calculateDb(std::vector<float> input, size_t start = 0) {
690 return audio_utils_compute_power_mono(input.data() + start, AUDIO_FORMAT_PCM_FLOAT,
691 input.size() - start);
692 }
693
694 void computeThreshold(float ratio, float outputDb, float& threshold) {
695 EXPECT_NE(ratio, 0);
696 threshold = (mInputDb - (ratio * outputDb)) / (1 - ratio);
697 }
698
699 void computeRatio(float threshold, float outputDb, float& ratio) {
700 float inputOverThreshold = mInputDb - threshold;
701 float outputOverThreshold = outputDb - threshold;
702 EXPECT_NE(outputOverThreshold, 0);
703 ratio = inputOverThreshold / outputOverThreshold;
704 }
705
706 void setParamsAndProcess(std::vector<float>& output) {
707 EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
708 EXPECT_NO_FATAL_FAILURE(addLimiterConfig(mLimiterConfigList));
709 ASSERT_NO_FATAL_FAILURE(SetAndGetDynamicsProcessingParameters());
710 if (isAllParamsValid()) {
711 ASSERT_NO_FATAL_FAILURE(
712 processAndWriteToOutput(mInput, output, mEffect, &mOpenEffectReturn));
713 EXPECT_GT(output.size(), kStartIndex);
714 }
715 cleanUpLimiterConfig();
716 }
717
718 void cleanUpLimiterConfig() {
719 CleanUp();
720 mLimiterConfigList.clear();
721 }
722 static constexpr float kDefaultLinkerGroup = 3;
723 static constexpr float kDefaultAttackTime = 0;
724 static constexpr float kDefaultReleaseTime = 0;
725 static constexpr float kDefaultRatio = 4;
726 static constexpr float kDefaultThreshold = 0;
727 static constexpr float kDefaultPostGain = 0;
728 static constexpr int kInputFrequency = 1000;
729 static constexpr size_t kStartIndex = 15 * kSamplingFrequency / 1000; // skip 15ms
730 std::vector<DynamicsProcessing::LimiterConfig> mLimiterConfigList;
731 std::vector<float> mInput;
732 float mInputDb;
733 int mBufferSize;
734};
735
736TEST_P(DynamicsProcessingLimiterConfigDataTest, IncreasingThresholdDb) {
737 std::vector<float> thresholdValues = {-200, -150, -100, -50, -5, 0};
738 std::vector<float> output(mInput.size());
739 float previousThreshold = -FLT_MAX;
740 for (float threshold : thresholdValues) {
741 for (int i = 0; i < mChannelCount; i++) {
742 fillLimiterConfig(mLimiterConfigList, i, true, kDefaultLinkerGroup, kDefaultAttackTime,
743 kDefaultReleaseTime, kDefaultRatio, threshold, kDefaultPostGain);
744 }
745 EXPECT_NO_FATAL_FAILURE(setParamsAndProcess(output));
746 if (!isAllParamsValid()) {
747 continue;
748 }
749 float outputDb = calculateDb(output, kStartIndex);
750 if (threshold >= mInputDb || kDefaultRatio == 1) {
751 EXPECT_EQ(std::round(mInputDb), std::round(outputDb));
752 } else {
753 float calculatedThreshold = 0;
754 EXPECT_NO_FATAL_FAILURE(computeThreshold(kDefaultRatio, outputDb, calculatedThreshold));
755 ASSERT_GT(calculatedThreshold, previousThreshold);
756 previousThreshold = calculatedThreshold;
757 }
758 }
759}
760
761TEST_P(DynamicsProcessingLimiterConfigDataTest, IncreasingRatio) {
762 std::vector<float> ratioValues = {1, 10, 20, 30, 40, 50};
763 std::vector<float> output(mInput.size());
764 float threshold = -10;
765 float previousRatio = 0;
766 for (float ratio : ratioValues) {
767 for (int i = 0; i < mChannelCount; i++) {
768 fillLimiterConfig(mLimiterConfigList, i, true, kDefaultLinkerGroup, kDefaultAttackTime,
769 kDefaultReleaseTime, ratio, threshold, kDefaultPostGain);
770 }
771 EXPECT_NO_FATAL_FAILURE(setParamsAndProcess(output));
772 if (!isAllParamsValid()) {
773 continue;
774 }
775 float outputDb = calculateDb(output, kStartIndex);
776
777 if (threshold >= mInputDb) {
778 EXPECT_EQ(std::round(mInputDb), std::round(outputDb));
779 } else {
780 float calculatedRatio = 0;
781 EXPECT_NO_FATAL_FAILURE(computeRatio(threshold, outputDb, calculatedRatio));
782 ASSERT_GT(calculatedRatio, previousRatio);
783 previousRatio = calculatedRatio;
784 }
785 }
786}
787
788TEST_P(DynamicsProcessingLimiterConfigDataTest, LimiterEnableDisable) {
789 std::vector<bool> limiterEnableValues = {false, true};
790 std::vector<float> output(mInput.size());
791 for (bool isEnabled : limiterEnableValues) {
792 for (int i = 0; i < mChannelCount; i++) {
793 // Set non-default values
794 fillLimiterConfig(mLimiterConfigList, i, isEnabled, kDefaultLinkerGroup,
795 5 /*attack time*/, 5 /*release time*/, 10 /*ratio*/,
796 -10 /*threshold*/, 5 /*postgain*/);
797 }
798 EXPECT_NO_FATAL_FAILURE(setParamsAndProcess(output));
799 if (!isAllParamsValid()) {
800 continue;
801 }
802 if (isEnabled) {
803 EXPECT_NE(mInputDb, calculateDb(output, kStartIndex));
804 } else {
805 EXPECT_NEAR(mInputDb, calculateDb(output, kStartIndex), 0.05);
806 }
807 }
808}
809
810INSTANTIATE_TEST_SUITE_P(DynamicsProcessingTest, DynamicsProcessingLimiterConfigDataTest,
811 testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
812 IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
813 [](const auto& info) {
814 auto descriptor = info.param;
815 std::string name = getPrefix(descriptor.second);
816 std::replace_if(
817 name.begin(), name.end(),
818 [](const char c) { return !std::isalnum(c); }, '_');
819 return name;
820 });
Sneha Patild341d6f2024-11-28 06:27:19 +0000821GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingLimiterConfigDataTest);
Sneha Patilabc94642024-11-13 08:41:05 +0000822
Ram Mohane4064ce2022-12-20 18:05:14 +0530823/**
824 * Test DynamicsProcessing ChannelConfig
825 */
826enum ChannelConfigTestParamName {
827 BAND_CHANNEL_TEST_INSTANCE_NAME,
Shunkai Yaof137ba42024-04-11 17:11:03 +0000828 BAND_CHANNEL_TEST_CHANNEL_CONFIG
Ram Mohane4064ce2022-12-20 18:05:14 +0530829};
830using ChannelConfigTestParams = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
Shunkai Yaof137ba42024-04-11 17:11:03 +0000831 std::vector<DynamicsProcessing::ChannelConfig>>;
Ram Mohane4064ce2022-12-20 18:05:14 +0530832
833class DynamicsProcessingTestChannelConfig
834 : public ::testing::TestWithParam<ChannelConfigTestParams>,
835 public DynamicsProcessingTestHelper {
836 public:
837 DynamicsProcessingTestChannelConfig()
838 : DynamicsProcessingTestHelper(std::get<BAND_CHANNEL_TEST_INSTANCE_NAME>(GetParam())),
Shunkai Yaof137ba42024-04-11 17:11:03 +0000839 mCfg(std::get<BAND_CHANNEL_TEST_CHANNEL_CONFIG>(GetParam())) {}
Ram Mohane4064ce2022-12-20 18:05:14 +0530840
841 void SetUp() override { SetUpDynamicsProcessingEffect(); }
842
843 void TearDown() override { TearDownDynamicsProcessingEffect(); }
844
845 std::vector<DynamicsProcessing::ChannelConfig> mCfg;
Ram Mohane4064ce2022-12-20 18:05:14 +0530846};
847
848TEST_P(DynamicsProcessingTestChannelConfig, SetAndGetPreEqChannelConfig) {
Ram Mohane4064ce2022-12-20 18:05:14 +0530849 EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
850 EXPECT_NO_FATAL_FAILURE(addPreEqChannelConfig(mCfg));
Sneha Patilabc94642024-11-13 08:41:05 +0000851 ASSERT_NO_FATAL_FAILURE(SetAndGetDynamicsProcessingParameters());
Ram Mohane4064ce2022-12-20 18:05:14 +0530852}
853
854TEST_P(DynamicsProcessingTestChannelConfig, SetAndGetPostEqChannelConfig) {
Ram Mohane4064ce2022-12-20 18:05:14 +0530855 EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
856 EXPECT_NO_FATAL_FAILURE(addPostEqChannelConfig(mCfg));
Sneha Patilabc94642024-11-13 08:41:05 +0000857 ASSERT_NO_FATAL_FAILURE(SetAndGetDynamicsProcessingParameters());
Ram Mohane4064ce2022-12-20 18:05:14 +0530858}
859
860TEST_P(DynamicsProcessingTestChannelConfig, SetAndGetMbcChannelConfig) {
Ram Mohane4064ce2022-12-20 18:05:14 +0530861 EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
862 EXPECT_NO_FATAL_FAILURE(addMbcChannelConfig(mCfg));
Sneha Patilabc94642024-11-13 08:41:05 +0000863 ASSERT_NO_FATAL_FAILURE(SetAndGetDynamicsProcessingParameters());
Ram Mohane4064ce2022-12-20 18:05:14 +0530864}
865
866INSTANTIATE_TEST_SUITE_P(
867 DynamicsProcessingTest, DynamicsProcessingTestChannelConfig,
868 ::testing::Combine(
869 testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
Shunkai Yaof8be1ac2023-03-06 18:41:27 +0000870 IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
Ram Mohane4064ce2022-12-20 18:05:14 +0530871 testing::ValuesIn(
Shunkai Yaof137ba42024-04-11 17:11:03 +0000872 DynamicsProcessingTestHelper::kChannelConfigTestSet)), // channel config
Ram Mohane4064ce2022-12-20 18:05:14 +0530873 [](const auto& info) {
874 auto descriptor = std::get<BAND_CHANNEL_TEST_INSTANCE_NAME>(info.param).second;
Ram Mohane4064ce2022-12-20 18:05:14 +0530875 std::string channelConfig = ::android::internal::ToString(
876 std::get<BAND_CHANNEL_TEST_CHANNEL_CONFIG>(info.param));
877
878 std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
879 descriptor.common.name + "_UUID_" +
Shunkai Yaof137ba42024-04-11 17:11:03 +0000880 toString(descriptor.common.id.uuid) + "_" + channelConfig;
Ram Mohane4064ce2022-12-20 18:05:14 +0530881 std::replace_if(
882 name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
883 return name;
884 });
885GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingTestChannelConfig);
886
887/**
888 * Test DynamicsProcessing EqBandConfig
889 */
890enum EqBandConfigTestParamName {
891 EQ_BAND_INSTANCE_NAME,
892 EQ_BAND_CHANNEL,
Ram Mohane4064ce2022-12-20 18:05:14 +0530893 EQ_BAND_CUT_OFF_FREQ,
Shunkai Yaof137ba42024-04-11 17:11:03 +0000894 EQ_BAND_GAIN
Ram Mohane4064ce2022-12-20 18:05:14 +0530895};
896using EqBandConfigTestParams = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t,
Sneha Patilabc94642024-11-13 08:41:05 +0000897 std::vector<std::pair<int, float>>, float>;
Ram Mohane4064ce2022-12-20 18:05:14 +0530898
899void fillEqBandConfig(std::vector<DynamicsProcessing::EqBandConfig>& cfgs,
900 const EqBandConfigTestParams& params) {
901 const std::vector<std::pair<int, float>> cutOffFreqs = std::get<EQ_BAND_CUT_OFF_FREQ>(params);
902 int bandCount = cutOffFreqs.size();
903 cfgs.resize(bandCount);
904 for (int i = 0; i < bandCount; i++) {
905 cfgs[i].channel = std::get<EQ_BAND_CHANNEL>(params);
906 cfgs[i].band = cutOffFreqs[i].first;
Sneha Patilabc94642024-11-13 08:41:05 +0000907 cfgs[i].enable = true /*Eqband Enable*/;
Ram Mohane4064ce2022-12-20 18:05:14 +0530908 cfgs[i].cutoffFrequencyHz = cutOffFreqs[i].second;
909 cfgs[i].gainDb = std::get<EQ_BAND_GAIN>(params);
910 }
911}
912
913class DynamicsProcessingTestEqBandConfig : public ::testing::TestWithParam<EqBandConfigTestParams>,
914 public DynamicsProcessingTestHelper {
915 public:
916 DynamicsProcessingTestEqBandConfig()
Shunkai Yaof137ba42024-04-11 17:11:03 +0000917 : DynamicsProcessingTestHelper(std::get<EQ_BAND_INSTANCE_NAME>(GetParam())) {
Ram Mohane4064ce2022-12-20 18:05:14 +0530918 fillEqBandConfig(mCfgs, GetParam());
919 }
920
921 void SetUp() override { SetUpDynamicsProcessingEffect(); }
922
923 void TearDown() override { TearDownDynamicsProcessingEffect(); }
924
925 std::vector<DynamicsProcessing::EqBandConfig> mCfgs;
Ram Mohane4064ce2022-12-20 18:05:14 +0530926};
927
928TEST_P(DynamicsProcessingTestEqBandConfig, SetAndGetPreEqBandConfig) {
Ram Mohane4064ce2022-12-20 18:05:14 +0530929 mEngineConfigPreset.preEqStage.bandCount = mCfgs.size();
930 EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
Ram Mohanafdf90b2023-03-23 08:48:25 +0530931 std::vector<DynamicsProcessing::ChannelConfig> cfgs(mChannelCount);
932 for (int i = 0; i < mChannelCount; i++) {
933 cfgs[i].channel = i;
934 cfgs[i].enable = true;
935 }
936 EXPECT_NO_FATAL_FAILURE(addPreEqChannelConfig(cfgs));
Ram Mohane4064ce2022-12-20 18:05:14 +0530937 EXPECT_NO_FATAL_FAILURE(addPreEqBandConfigs(mCfgs));
Sneha Patilabc94642024-11-13 08:41:05 +0000938 ASSERT_NO_FATAL_FAILURE(SetAndGetDynamicsProcessingParameters());
Ram Mohane4064ce2022-12-20 18:05:14 +0530939}
940
941TEST_P(DynamicsProcessingTestEqBandConfig, SetAndGetPostEqBandConfig) {
Ram Mohane4064ce2022-12-20 18:05:14 +0530942 mEngineConfigPreset.postEqStage.bandCount = mCfgs.size();
943 EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
Ram Mohanafdf90b2023-03-23 08:48:25 +0530944 std::vector<DynamicsProcessing::ChannelConfig> cfgs(mChannelCount);
945 for (int i = 0; i < mChannelCount; i++) {
946 cfgs[i].channel = i;
947 cfgs[i].enable = true;
948 }
949 EXPECT_NO_FATAL_FAILURE(addPostEqChannelConfig(cfgs));
Ram Mohane4064ce2022-12-20 18:05:14 +0530950 EXPECT_NO_FATAL_FAILURE(addPostEqBandConfigs(mCfgs));
Sneha Patilabc94642024-11-13 08:41:05 +0000951 ASSERT_NO_FATAL_FAILURE(SetAndGetDynamicsProcessingParameters());
Ram Mohane4064ce2022-12-20 18:05:14 +0530952}
953
954std::vector<std::vector<std::pair<int, float>>> kBands{
955 {
956 {0, 600},
957 {1, 2000},
958 {2, 6000},
959 {3, 10000},
960 {4, 16000},
961 }, // 5 bands
962 {
963 {0, 800},
964 {3, 15000},
965 {2, 6000},
966 {1, 2000},
967 }, // 4 bands, unsorted
968 {
969 {0, 650},
970 {1, 2000},
971 {2, 6000},
972 {3, 10000},
973 {3, 16000},
974 }, // 5 bands, missing band
975 {
976 {0, 900},
977 {1, 8000},
978 {2, 4000},
979 {3, 12000},
980 }, // 4 bands, cutoff freq not increasing
981 {
982 {0, 450},
983 {1, 2000},
984 {7, 6000},
985 {3, 10000},
986 {4, 16000},
987 }, // bad band index
988 {
989 {0, 1},
990 {1, 8000},
991 }, // too low cutoff freq
992 {
993 {0, 1200},
994 {1, 80000},
995 }, // too high cutoff freq
996};
997
998INSTANTIATE_TEST_SUITE_P(
999 DynamicsProcessingTest, DynamicsProcessingTestEqBandConfig,
Ram Mohanafdf90b2023-03-23 08:48:25 +05301000 ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
1001 IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
Sneha Patilabc94642024-11-13 08:41:05 +00001002 testing::Values(-1, 0, 10), // channel index
1003 testing::ValuesIn(kBands), // band index, cut off frequencies
Shunkai Yaof137ba42024-04-11 17:11:03 +00001004 testing::Values(-3.14f, 3.14f) // gain
1005 ),
Ram Mohane4064ce2022-12-20 18:05:14 +05301006 [](const auto& info) {
1007 auto descriptor = std::get<EQ_BAND_INSTANCE_NAME>(info.param).second;
1008 std::vector<DynamicsProcessing::EqBandConfig> cfgs;
1009 fillEqBandConfig(cfgs, info.param);
Ram Mohane4064ce2022-12-20 18:05:14 +05301010 std::string bands = ::android::internal::ToString(cfgs);
Ram Mohane4064ce2022-12-20 18:05:14 +05301011 std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
1012 descriptor.common.name + "_UUID_" +
Shunkai Yaof137ba42024-04-11 17:11:03 +00001013 toString(descriptor.common.id.uuid) + "_bands_" + bands;
Ram Mohane4064ce2022-12-20 18:05:14 +05301014 std::replace_if(
1015 name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
1016 return name;
1017 });
1018GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingTestEqBandConfig);
1019
1020/**
1021 * Test DynamicsProcessing MbcBandConfig
1022 */
1023
1024enum MbcBandConfigParamName {
1025 MBC_BAND_INSTANCE_NAME,
1026 MBC_BAND_CHANNEL,
Ram Mohane4064ce2022-12-20 18:05:14 +05301027 MBC_BAND_CUTOFF_FREQ,
Ram Mohane4064ce2022-12-20 18:05:14 +05301028 MBC_BAND_ADDITIONAL
1029};
1030enum MbcBandConfigAdditional {
1031 MBC_ADD_ATTACK_TIME,
1032 MBC_ADD_RELEASE_TIME,
1033 MBC_ADD_RATIO,
1034 MBC_ADD_THRESHOLD,
1035 MBC_ADD_KNEE_WIDTH,
1036 MBC_ADD_NOISE_GATE_THRESHOLD,
1037 MBC_ADD_EXPENDER_RATIO,
1038 MBC_ADD_PRE_GAIN,
1039 MBC_ADD_POST_GAIN,
1040 MBC_ADD_MAX_NUM
1041};
1042using TestParamsMbcBandConfigAdditional = std::array<float, MBC_ADD_MAX_NUM>;
1043
Ram Mohanafdf90b2023-03-23 08:48:25 +05301044// attackTime, releaseTime, ratio, thresh, kneeWidth, noise, expander, preGain, postGain
Ram Mohane4064ce2022-12-20 18:05:14 +05301045static constexpr std::array<TestParamsMbcBandConfigAdditional, 4> kMbcBandConfigAdditionalParam = {
1046 {{-3, -10, -2, -2, -5, -90, -2.5, -2, -2},
1047 {0, 0, 0, 0, 0, 0, 0, 0, 0},
1048 {-3, 10, -2, 2, -5, 90, -2.5, 2, -2},
Ram Mohanafdf90b2023-03-23 08:48:25 +05301049 {3, 10, 2, -2, -5, 90, 2.5, 2, 2}}};
Ram Mohane4064ce2022-12-20 18:05:14 +05301050
1051using TestParamsMbcBandConfig =
Sneha Patilabc94642024-11-13 08:41:05 +00001052 std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t,
Shunkai Yaof137ba42024-04-11 17:11:03 +00001053 std::vector<std::pair<int, float>>, TestParamsMbcBandConfigAdditional>;
Ram Mohane4064ce2022-12-20 18:05:14 +05301054
1055void fillMbcBandConfig(std::vector<DynamicsProcessing::MbcBandConfig>& cfgs,
1056 const TestParamsMbcBandConfig& params) {
1057 const std::vector<std::pair<int, float>> cutOffFreqs = std::get<MBC_BAND_CUTOFF_FREQ>(params);
1058 const std::array<float, MBC_ADD_MAX_NUM> additional = std::get<MBC_BAND_ADDITIONAL>(params);
1059 int bandCount = cutOffFreqs.size();
1060 cfgs.resize(bandCount);
1061 for (int i = 0; i < bandCount; i++) {
1062 cfgs[i] = DynamicsProcessing::MbcBandConfig{
1063 .channel = std::get<MBC_BAND_CHANNEL>(params),
1064 .band = cutOffFreqs[i].first,
Sneha Patilabc94642024-11-13 08:41:05 +00001065 .enable = true /*Mbc Band Enable*/,
Ram Mohane4064ce2022-12-20 18:05:14 +05301066 .cutoffFrequencyHz = cutOffFreqs[i].second,
1067 .attackTimeMs = additional[MBC_ADD_ATTACK_TIME],
1068 .releaseTimeMs = additional[MBC_ADD_RELEASE_TIME],
1069 .ratio = additional[MBC_ADD_RATIO],
1070 .thresholdDb = additional[MBC_ADD_THRESHOLD],
1071 .kneeWidthDb = additional[MBC_ADD_KNEE_WIDTH],
1072 .noiseGateThresholdDb = additional[MBC_ADD_NOISE_GATE_THRESHOLD],
1073 .expanderRatio = additional[MBC_ADD_EXPENDER_RATIO],
1074 .preGainDb = additional[MBC_ADD_PRE_GAIN],
1075 .postGainDb = additional[MBC_ADD_POST_GAIN]};
1076 }
1077}
1078
1079class DynamicsProcessingTestMbcBandConfig
1080 : public ::testing::TestWithParam<TestParamsMbcBandConfig>,
1081 public DynamicsProcessingTestHelper {
1082 public:
1083 DynamicsProcessingTestMbcBandConfig()
Shunkai Yaof137ba42024-04-11 17:11:03 +00001084 : DynamicsProcessingTestHelper(std::get<MBC_BAND_INSTANCE_NAME>(GetParam())) {
Ram Mohane4064ce2022-12-20 18:05:14 +05301085 fillMbcBandConfig(mCfgs, GetParam());
1086 }
1087
1088 void SetUp() override { SetUpDynamicsProcessingEffect(); }
1089
1090 void TearDown() override { TearDownDynamicsProcessingEffect(); }
1091
1092 std::vector<DynamicsProcessing::MbcBandConfig> mCfgs;
Ram Mohane4064ce2022-12-20 18:05:14 +05301093};
1094
1095TEST_P(DynamicsProcessingTestMbcBandConfig, SetAndGetMbcBandConfig) {
Ram Mohane4064ce2022-12-20 18:05:14 +05301096 mEngineConfigPreset.mbcStage.bandCount = mCfgs.size();
1097 EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
Ram Mohanafdf90b2023-03-23 08:48:25 +05301098 std::vector<DynamicsProcessing::ChannelConfig> cfgs(mChannelCount);
1099 for (int i = 0; i < mChannelCount; i++) {
1100 cfgs[i].channel = i;
1101 cfgs[i].enable = true;
1102 }
1103 EXPECT_NO_FATAL_FAILURE(addMbcChannelConfig(cfgs));
Ram Mohane4064ce2022-12-20 18:05:14 +05301104 EXPECT_NO_FATAL_FAILURE(addMbcBandConfigs(mCfgs));
Sneha Patilabc94642024-11-13 08:41:05 +00001105 ASSERT_NO_FATAL_FAILURE(SetAndGetDynamicsProcessingParameters());
Ram Mohane4064ce2022-12-20 18:05:14 +05301106}
1107
1108INSTANTIATE_TEST_SUITE_P(
1109 DynamicsProcessingTest, DynamicsProcessingTestMbcBandConfig,
Ram Mohanafdf90b2023-03-23 08:48:25 +05301110 ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
1111 IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
Sneha Patilabc94642024-11-13 08:41:05 +00001112 testing::Values(-1, 0, 10), // channel index
1113 testing::ValuesIn(kBands), // band index, cut off frequencies
Ram Mohanafdf90b2023-03-23 08:48:25 +05301114 testing::ValuesIn(kMbcBandConfigAdditionalParam)), // Additional
Ram Mohane4064ce2022-12-20 18:05:14 +05301115 [](const auto& info) {
1116 auto descriptor = std::get<MBC_BAND_INSTANCE_NAME>(info.param).second;
1117 std::vector<DynamicsProcessing::MbcBandConfig> cfgs;
1118 fillMbcBandConfig(cfgs, info.param);
Ram Mohane4064ce2022-12-20 18:05:14 +05301119 std::string mbcBands = ::android::internal::ToString(cfgs);
Ram Mohane4064ce2022-12-20 18:05:14 +05301120 std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
1121 descriptor.common.name + "_UUID_" +
Shunkai Yaof137ba42024-04-11 17:11:03 +00001122 toString(descriptor.common.id.uuid) + "_bands_" + mbcBands;
Ram Mohane4064ce2022-12-20 18:05:14 +05301123 std::replace_if(
1124 name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
1125 return name;
1126 });
1127GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingTestMbcBandConfig);
1128
1129int main(int argc, char** argv) {
1130 ::testing::InitGoogleTest(&argc, argv);
Jaideep Sharma74498412023-09-13 15:25:25 +05301131 ::testing::UnitTest::GetInstance()->listeners().Append(new TestExecutionTracer());
Ram Mohane4064ce2022-12-20 18:05:14 +05301132 ABinderProcess_setThreadPoolMaxThreadCount(1);
1133 ABinderProcess_startThreadPool();
1134 return RUN_ALL_TESTS();
1135}