DynamicsProcessing: Add test for link group parameter
These tests verify the outputs for :
1. Same link group with different threshold and ratio configs-
Validate that the output has max attenuation.
2. Different link groups with different threshold and ratio configs-
Validate that each channel has different attenuation levels.
Bug: 305866207
Test: atest VtsHalDynamicsProcessingTargetTest
Change-Id: Iebdb4816b0019189e91cf28eba83babf002ae431
diff --git a/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
index 2ce7b51..ddb920d 100644
--- a/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
+++ b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
@@ -465,6 +465,7 @@
float fullScaleSineDb) {
ASSERT_NO_FATAL_FAILURE(SetUpDynamicsProcessingEffect());
SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+ mInput.resize(kFrameCount * mChannelCount);
ASSERT_NO_FATAL_FAILURE(
generateSineWave(testFrequencies, mInput, 1.0, kSamplingFrequency, mChannelLayout));
mInputDb = calculateDb(mInput);
@@ -722,13 +723,10 @@
public DynamicsProcessingTestHelper {
public:
DynamicsProcessingInputGainDataTest()
- : DynamicsProcessingTestHelper((GetParam()), AudioChannelLayout::LAYOUT_MONO) {
- mInput.resize(kFrameCount * mChannelCount);
- }
+ : DynamicsProcessingTestHelper((GetParam()), AudioChannelLayout::LAYOUT_MONO) {}
void SetUp() override {
- ASSERT_NO_FATAL_FAILURE(
- setUpDataTest({static_cast<int>(kInputFrequency)}, kSineFullScaleDb));
+ ASSERT_NO_FATAL_FAILURE(setUpDataTest({kInputFrequency}, kSineFullScaleDb));
}
void TearDown() override { TearDownDynamicsProcessingEffect(); }
@@ -851,15 +849,12 @@
: public ::testing::TestWithParam<LimiterConfigDataTestParams>,
public DynamicsProcessingTestHelper {
public:
- DynamicsProcessingLimiterConfigDataTest()
- : DynamicsProcessingTestHelper(GetParam(), AudioChannelLayout::LAYOUT_MONO) {
- mBufferSize = kFrameCount * mChannelCount;
- mInput.resize(mBufferSize);
- }
+ DynamicsProcessingLimiterConfigDataTest(LimiterConfigDataTestParams param = GetParam(),
+ int32_t layout = AudioChannelLayout::LAYOUT_MONO)
+ : DynamicsProcessingTestHelper(param, layout) {}
void SetUp() override {
- ASSERT_NO_FATAL_FAILURE(
- setUpDataTest({static_cast<int>(kInputFrequency)}, kSineFullScaleDb));
+ ASSERT_NO_FATAL_FAILURE(setUpDataTest({kInputFrequency}, kSineFullScaleDb));
}
void TearDown() override { TearDownDynamicsProcessingEffect(); }
@@ -892,7 +887,6 @@
static constexpr float kDefaultRatio = 4;
static constexpr float kDefaultThreshold = -10;
static constexpr float kDefaultPostGain = 0;
- static constexpr float kInputFrequency = 1000;
static constexpr float kLimiterTestToleranceDb = 0.05;
std::vector<DynamicsProcessing::LimiterConfig> mLimiterConfigList;
int mBufferSize;
@@ -1010,6 +1004,104 @@
});
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingLimiterConfigDataTest);
+class DynamicsProcessingLimiterLinkerDataTest : public DynamicsProcessingLimiterConfigDataTest {
+ public:
+ DynamicsProcessingLimiterLinkerDataTest()
+ : DynamicsProcessingLimiterConfigDataTest(GetParam(), AudioChannelLayout::LAYOUT_STEREO) {}
+
+ void calculateExpectedOutputDb(std::vector<float>& expectedOutputDb) {
+ std::vector<float> inputDbValues = calculateStereoDb(mInput, kStartIndex);
+ ASSERT_EQ(inputDbValues.size(), kRatioThresholdPairValues.size());
+ EXPECT_NEAR(inputDbValues[0], inputDbValues[1], kToleranceDb);
+ for (size_t i = 0; i < kRatioThresholdPairValues.size(); i++) {
+ const auto& [ratio, threshold] = kRatioThresholdPairValues[i];
+ expectedOutputDb.push_back((inputDbValues[i] - threshold) / ratio + threshold);
+ }
+ }
+
+ std::vector<float> calculateStereoDb(const std::vector<float>& input,
+ size_t startSamplePos = 0) {
+ std::vector<float> leftChannel;
+ std::vector<float> rightChannel;
+ for (size_t i = 0; i < input.size(); i += 2) {
+ leftChannel.push_back(input[i]);
+ if (i + 1 < input.size()) {
+ rightChannel.push_back(input[i + 1]);
+ }
+ }
+ return {calculateDb(leftChannel, startSamplePos),
+ calculateDb(rightChannel, startSamplePos)};
+ }
+
+ void setLinkGroupAndProcess(std::vector<float>& output, bool hasSameLinkGroup) {
+ for (int i = 0; i < mChannelCount; i++) {
+ const auto& [ratio, threshold] = kRatioThresholdPairValues[i];
+ ASSERT_NE(ratio, 0);
+ int linkGroup = hasSameLinkGroup ? kDefaultLinkerGroup : i;
+ fillLimiterConfig(mLimiterConfigList, i, true, linkGroup, kDefaultAttackTime,
+ kDefaultReleaseTime, ratio, threshold, kDefaultPostGain);
+ }
+
+ ASSERT_NO_FATAL_FAILURE(setLimiterParamsAndProcess(mInput, output));
+
+ if (!isAllParamsValid()) {
+ GTEST_SKIP() << "Invalid parameters. Skipping the test\n";
+ }
+ }
+
+ static constexpr float kMinDifferenceDb = 5;
+ const std::vector<std::pair<float, float>> kRatioThresholdPairValues = {{2, -10}, {5, -20}};
+};
+
+TEST_P(DynamicsProcessingLimiterLinkerDataTest, SameLinkGroupDifferentConfigs) {
+ std::vector<float> output(mInput.size());
+
+ ASSERT_NO_FATAL_FAILURE(setLinkGroupAndProcess(output, true));
+
+ std::vector<float> outputDbValues = calculateStereoDb(output, kStartIndex);
+
+ std::vector<float> expectedOutputDbValues;
+ ASSERT_NO_FATAL_FAILURE(calculateExpectedOutputDb(expectedOutputDbValues));
+
+ // Verify that the actual output dB is same as the calculated maximum attenuation.
+ float expectedOutputDb = std::min(expectedOutputDbValues[0], expectedOutputDbValues[1]);
+ EXPECT_NEAR(outputDbValues[0], expectedOutputDb, kToleranceDb);
+ EXPECT_NEAR(outputDbValues[1], expectedOutputDb, kToleranceDb);
+}
+
+TEST_P(DynamicsProcessingLimiterLinkerDataTest, DifferentLinkGroupDifferentConfigs) {
+ std::vector<float> output(mInput.size());
+
+ ASSERT_NO_FATAL_FAILURE(setLinkGroupAndProcess(output, false));
+
+ std::vector<float> outputDbValues = calculateStereoDb(output, kStartIndex);
+
+ std::vector<float> expectedOutputDbValues;
+ ASSERT_NO_FATAL_FAILURE(calculateExpectedOutputDb(expectedOutputDbValues));
+
+ // Verify that both channels have different compression levels
+ EXPECT_GT(abs(expectedOutputDbValues[0] - expectedOutputDbValues[1]), kMinDifferenceDb)
+ << "Left channel level: " << expectedOutputDbValues[0]
+ << " Right channel level: " << expectedOutputDbValues[1];
+
+ // Verify that the actual output and the calculated dB values are same
+ EXPECT_NEAR(outputDbValues[0], expectedOutputDbValues[0], kToleranceDb);
+ EXPECT_NEAR(outputDbValues[1], expectedOutputDbValues[1], kToleranceDb);
+}
+
+INSTANTIATE_TEST_SUITE_P(DynamicsProcessingTest, DynamicsProcessingLimiterLinkerDataTest,
+ testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
+ [](const auto& info) {
+ auto descriptor = info.param;
+ std::string name = getPrefix(descriptor.second);
+ std::replace_if(
+ name.begin(), name.end(),
+ [](const char c) { return !std::isalnum(c); }, '_');
+ return name;
+ });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingLimiterLinkerDataTest);
+
/**
* Test DynamicsProcessing ChannelConfig
*/
@@ -1215,7 +1307,6 @@
public:
DynamicsProcessingEqBandConfigDataTest()
: DynamicsProcessingTestHelper(GetParam(), AudioChannelLayout::LAYOUT_MONO) {
- mInput.resize(kFrameCount * mChannelCount);
mBinOffsets.resize(mMultitoneTestFrequencies.size());
}
@@ -1444,7 +1535,6 @@
public:
DynamicsProcessingMbcBandConfigDataTest()
: DynamicsProcessingTestHelper(GetParam(), AudioChannelLayout::LAYOUT_MONO) {
- mInput.resize(kFrameCount * mChannelCount);
mBinOffsets.resize(mMultitoneTestFrequencies.size());
}