Merge "LoudnessEnhancer: Added test cases to validate effect processing." into main am: 309d65f0c4
am: 735bab03bf
am: c2c32252dd
Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/2792432 Change-Id: If5d19d6dec369d747165dac671356e02574cdd88 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
commit
3baa9d34d6
1 changed files with 241 additions and 56 deletions
|
@ -32,27 +32,19 @@ using aidl::android::hardware::audio::effect::LoudnessEnhancer;
|
|||
using aidl::android::hardware::audio::effect::Parameter;
|
||||
using android::hardware::audio::common::testing::detail::TestExecutionTracer;
|
||||
|
||||
/**
|
||||
* Here we focus on specific parameter checking, general IEffect interfaces testing performed in
|
||||
* VtsAudioEffectTargetTest.
|
||||
*/
|
||||
enum ParamName { PARAM_INSTANCE_NAME, PARAM_GAIN_MB };
|
||||
using LoudnessEnhancerParamTestParam =
|
||||
std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>;
|
||||
static constexpr float kMaxAudioSample = 1;
|
||||
static constexpr int kZeroGain = 0;
|
||||
static constexpr int kMaxGain = std::numeric_limits<int>::max();
|
||||
static constexpr int kMinGain = std::numeric_limits<int>::min();
|
||||
static constexpr float kAbsError = 0.0001;
|
||||
|
||||
// Every int 32 bit value is a valid gain, so testing the corner cases and one regular value.
|
||||
// TODO : Update the test values once range/capability is updated by implementation.
|
||||
const std::vector<int> kGainMbValues = {std::numeric_limits<int>::min(), 100,
|
||||
std::numeric_limits<int>::max()};
|
||||
static const std::vector<int> kGainMbValues = {kMinGain, -100, -50, kZeroGain, 50, 100, kMaxGain};
|
||||
|
||||
class LoudnessEnhancerParamTest : public ::testing::TestWithParam<LoudnessEnhancerParamTestParam>,
|
||||
public EffectHelper {
|
||||
class LoudnessEnhancerEffectHelper : public EffectHelper {
|
||||
public:
|
||||
LoudnessEnhancerParamTest() : mParamGainMb(std::get<PARAM_GAIN_MB>(GetParam())) {
|
||||
std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
|
||||
}
|
||||
|
||||
void SetUp() override {
|
||||
void SetUpLoudnessEnhancer() {
|
||||
ASSERT_NE(nullptr, mFactory);
|
||||
ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
|
||||
|
||||
|
@ -60,13 +52,14 @@ class LoudnessEnhancerParamTest : public ::testing::TestWithParam<LoudnessEnhanc
|
|||
Parameter::Common common = EffectHelper::createParamCommon(
|
||||
0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
|
||||
kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
|
||||
IEffect::OpenEffectReturn ret;
|
||||
ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
|
||||
ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &mOpenEffectReturn, EX_NONE));
|
||||
ASSERT_NE(nullptr, mEffect);
|
||||
}
|
||||
void TearDown() override {
|
||||
|
||||
void TearDownLoudnessEnhancer() {
|
||||
ASSERT_NO_FATAL_FAILURE(close(mEffect));
|
||||
ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
|
||||
mOpenEffectReturn = IEffect::OpenEffectReturn{};
|
||||
}
|
||||
|
||||
Parameter::Specific getDefaultParamSpecific() {
|
||||
|
@ -76,52 +69,230 @@ class LoudnessEnhancerParamTest : public ::testing::TestWithParam<LoudnessEnhanc
|
|||
return specific;
|
||||
}
|
||||
|
||||
static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
|
||||
std::shared_ptr<IFactory> mFactory;
|
||||
std::shared_ptr<IEffect> mEffect;
|
||||
Descriptor mDescriptor;
|
||||
int mParamGainMb = 0;
|
||||
Parameter createLoudnessParam(int gainMb) {
|
||||
LoudnessEnhancer le;
|
||||
le.set<LoudnessEnhancer::gainMb>(gainMb);
|
||||
Parameter param;
|
||||
Parameter::Specific specific;
|
||||
specific.set<Parameter::Specific::loudnessEnhancer>(le);
|
||||
param.set<Parameter::specific>(specific);
|
||||
return param;
|
||||
}
|
||||
|
||||
void SetAndGetParameters() {
|
||||
for (auto& it : mTags) {
|
||||
auto& tag = it.first;
|
||||
auto& le = it.second;
|
||||
|
||||
// set parameter
|
||||
Parameter expectParam;
|
||||
Parameter::Specific specific;
|
||||
specific.set<Parameter::Specific::loudnessEnhancer>(le);
|
||||
expectParam.set<Parameter::specific>(specific);
|
||||
// All values are valid, set parameter should succeed
|
||||
EXPECT_STATUS(EX_NONE, mEffect->setParameter(expectParam)) << expectParam.toString();
|
||||
|
||||
// get parameter
|
||||
Parameter getParam;
|
||||
Parameter::Id id;
|
||||
LoudnessEnhancer::Id leId;
|
||||
leId.set<LoudnessEnhancer::Id::commonTag>(tag);
|
||||
id.set<Parameter::Id::loudnessEnhancerTag>(leId);
|
||||
EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
|
||||
|
||||
EXPECT_EQ(expectParam, getParam) << "\nexpect:" << expectParam.toString()
|
||||
<< "\ngetParam:" << getParam.toString();
|
||||
binder_exception_t isGainValid(int gainMb) {
|
||||
LoudnessEnhancer le;
|
||||
le.set<LoudnessEnhancer::gainMb>(gainMb);
|
||||
if (isParameterValid<LoudnessEnhancer, Range::loudnessEnhancer>(le, mDescriptor)) {
|
||||
return EX_NONE;
|
||||
} else {
|
||||
return EX_ILLEGAL_ARGUMENT;
|
||||
}
|
||||
}
|
||||
|
||||
void addGainMbParam(int gainMb) {
|
||||
LoudnessEnhancer le;
|
||||
le.set<LoudnessEnhancer::gainMb>(gainMb);
|
||||
mTags.push_back({LoudnessEnhancer::gainMb, le});
|
||||
void setParameters(int gain, binder_exception_t expected) {
|
||||
// set parameter
|
||||
auto param = createLoudnessParam(gain);
|
||||
EXPECT_STATUS(expected, mEffect->setParameter(param)) << param.toString();
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::pair<LoudnessEnhancer::Tag, LoudnessEnhancer>> mTags;
|
||||
void CleanUp() { mTags.clear(); }
|
||||
void validateParameters(int gain) {
|
||||
// get parameter
|
||||
LoudnessEnhancer::Id leId;
|
||||
Parameter getParam;
|
||||
Parameter::Id id;
|
||||
|
||||
LoudnessEnhancer::Tag tag(LoudnessEnhancer::gainMb);
|
||||
leId.set<LoudnessEnhancer::Id::commonTag>(tag);
|
||||
id.set<Parameter::Id::loudnessEnhancerTag>(leId);
|
||||
EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
|
||||
auto expectedParam = createLoudnessParam(gain);
|
||||
EXPECT_EQ(expectedParam, getParam) << "\nexpectedParam:" << expectedParam.toString()
|
||||
<< "\ngetParam:" << getParam.toString();
|
||||
}
|
||||
|
||||
static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
|
||||
IEffect::OpenEffectReturn mOpenEffectReturn;
|
||||
std::shared_ptr<IFactory> mFactory;
|
||||
std::shared_ptr<IEffect> mEffect;
|
||||
Descriptor mDescriptor;
|
||||
};
|
||||
|
||||
/**
|
||||
* Here we focus on specific parameter checking, general IEffect interfaces testing performed in
|
||||
* VtsAudioEffectTargetTest.
|
||||
*/
|
||||
enum ParamName { PARAM_INSTANCE_NAME, PARAM_GAIN_MB };
|
||||
using LoudnessEnhancerParamTestParam =
|
||||
std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>;
|
||||
|
||||
class LoudnessEnhancerParamTest : public ::testing::TestWithParam<LoudnessEnhancerParamTestParam>,
|
||||
public LoudnessEnhancerEffectHelper {
|
||||
public:
|
||||
LoudnessEnhancerParamTest() : mParamGainMb(std::get<PARAM_GAIN_MB>(GetParam())) {
|
||||
std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
|
||||
}
|
||||
|
||||
void SetUp() override { SetUpLoudnessEnhancer(); }
|
||||
void TearDown() override { TearDownLoudnessEnhancer(); }
|
||||
int mParamGainMb = 0;
|
||||
};
|
||||
|
||||
TEST_P(LoudnessEnhancerParamTest, SetAndGetGainMb) {
|
||||
EXPECT_NO_FATAL_FAILURE(addGainMbParam(mParamGainMb));
|
||||
SetAndGetParameters();
|
||||
binder_exception_t expected = isGainValid(mParamGainMb);
|
||||
setParameters(mParamGainMb, expected);
|
||||
if (expected == EX_NONE) {
|
||||
validateParameters(mParamGainMb);
|
||||
}
|
||||
}
|
||||
|
||||
using LoudnessEnhancerDataTestParam = std::pair<std::shared_ptr<IFactory>, Descriptor>;
|
||||
|
||||
class LoudnessEnhancerDataTest : public ::testing::TestWithParam<LoudnessEnhancerDataTestParam>,
|
||||
public LoudnessEnhancerEffectHelper {
|
||||
public:
|
||||
LoudnessEnhancerDataTest() {
|
||||
std::tie(mFactory, mDescriptor) = GetParam();
|
||||
generateInputBuffer();
|
||||
mOutputBuffer.resize(kBufferSize);
|
||||
}
|
||||
|
||||
void SetUp() override {
|
||||
SetUpLoudnessEnhancer();
|
||||
|
||||
// Creating AidlMessageQueues
|
||||
mStatusMQ = std::make_unique<EffectHelper::StatusMQ>(mOpenEffectReturn.statusMQ);
|
||||
mInputMQ = std::make_unique<EffectHelper::DataMQ>(mOpenEffectReturn.inputDataMQ);
|
||||
mOutputMQ = std::make_unique<EffectHelper::DataMQ>(mOpenEffectReturn.outputDataMQ);
|
||||
}
|
||||
|
||||
void TearDown() override { TearDownLoudnessEnhancer(); }
|
||||
|
||||
// Fill inputBuffer with random values between -kMaxAudioSample to kMaxAudioSample
|
||||
void generateInputBuffer() {
|
||||
for (size_t i = 0; i < kBufferSize; i++) {
|
||||
mInputBuffer.push_back(((static_cast<float>(std::rand()) / RAND_MAX) * 2 - 1) *
|
||||
kMaxAudioSample);
|
||||
}
|
||||
}
|
||||
|
||||
// Add gains to the mInputBuffer and store processed output to mOutputBuffer
|
||||
void processAndWriteToOutput() {
|
||||
// Check AidlMessageQueues are not null
|
||||
ASSERT_TRUE(mStatusMQ->isValid());
|
||||
ASSERT_TRUE(mInputMQ->isValid());
|
||||
ASSERT_TRUE(mOutputMQ->isValid());
|
||||
|
||||
// Enabling the process
|
||||
ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
|
||||
ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
|
||||
|
||||
// Write from buffer to message queues and calling process
|
||||
EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(mStatusMQ, mInputMQ, mInputBuffer));
|
||||
|
||||
// Read the updated message queues into buffer
|
||||
EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(mStatusMQ, 1, mOutputMQ,
|
||||
mOutputBuffer.size(), mOutputBuffer));
|
||||
|
||||
// Disable the process
|
||||
ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
|
||||
}
|
||||
|
||||
void assertGreaterGain(const std::vector<float>& first, const std::vector<float>& second) {
|
||||
for (size_t i = 0; i < first.size(); i++) {
|
||||
if (first[i] != 0) {
|
||||
ASSERT_GT(abs(first[i]), abs(second[i]));
|
||||
|
||||
} else {
|
||||
ASSERT_EQ(first[i], second[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void assertSequentialGains(const std::vector<int>& gainValues, bool isIncreasing) {
|
||||
std::vector<float> baseOutput(kBufferSize);
|
||||
|
||||
// Process a reference output buffer with 0 gain which gives compressed input values
|
||||
binder_exception_t expected;
|
||||
expected = isGainValid(kZeroGain);
|
||||
ASSERT_EQ(expected, EX_NONE);
|
||||
setParameters(kZeroGain, expected);
|
||||
ASSERT_NO_FATAL_FAILURE(processAndWriteToOutput());
|
||||
baseOutput = mOutputBuffer;
|
||||
|
||||
// Compare the outputs for increasing gain
|
||||
for (int gain : gainValues) {
|
||||
// Setting the parameters
|
||||
binder_exception_t expected = isGainValid(gain);
|
||||
if (expected != EX_NONE) {
|
||||
GTEST_SKIP() << "Gains not supported.";
|
||||
}
|
||||
setParameters(gain, expected);
|
||||
ASSERT_NO_FATAL_FAILURE(processAndWriteToOutput());
|
||||
|
||||
// Compare the mOutputBuffer values with baseOutput and update it
|
||||
if (isIncreasing) {
|
||||
ASSERT_NO_FATAL_FAILURE(assertGreaterGain(mOutputBuffer, baseOutput));
|
||||
} else {
|
||||
ASSERT_NO_FATAL_FAILURE(assertGreaterGain(baseOutput, mOutputBuffer));
|
||||
}
|
||||
|
||||
baseOutput = mOutputBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<StatusMQ> mStatusMQ;
|
||||
std::unique_ptr<DataMQ> mInputMQ;
|
||||
std::unique_ptr<DataMQ> mOutputMQ;
|
||||
|
||||
std::vector<float> mInputBuffer;
|
||||
std::vector<float> mOutputBuffer;
|
||||
static constexpr float kBufferSize = 128;
|
||||
};
|
||||
|
||||
TEST_P(LoudnessEnhancerDataTest, IncreasingGains) {
|
||||
static const std::vector<int> kIncreasingGains = {50, 100};
|
||||
|
||||
assertSequentialGains(kIncreasingGains, true /*isIncreasing*/);
|
||||
}
|
||||
|
||||
TEST_P(LoudnessEnhancerDataTest, DecreasingGains) {
|
||||
static const std::vector<int> kDecreasingGains = {-50, -100};
|
||||
|
||||
assertSequentialGains(kDecreasingGains, false /*isIncreasing*/);
|
||||
}
|
||||
|
||||
TEST_P(LoudnessEnhancerDataTest, MinimumGain) {
|
||||
// Setting the parameters
|
||||
binder_exception_t expected = isGainValid(kMinGain);
|
||||
if (expected != EX_NONE) {
|
||||
GTEST_SKIP() << "Minimum integer value not supported";
|
||||
}
|
||||
setParameters(kMinGain, expected);
|
||||
ASSERT_NO_FATAL_FAILURE(processAndWriteToOutput());
|
||||
|
||||
// Validate that mOutputBuffer has 0 values for INT_MIN gain
|
||||
for (size_t i = 0; i < mOutputBuffer.size(); i++) {
|
||||
ASSERT_FLOAT_EQ(mOutputBuffer[i], 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(LoudnessEnhancerDataTest, MaximumGain) {
|
||||
// Setting the parameters
|
||||
binder_exception_t expected = isGainValid(kMaxGain);
|
||||
if (expected != EX_NONE) {
|
||||
GTEST_SKIP() << "Maximum integer value not supported";
|
||||
}
|
||||
setParameters(kMaxGain, expected);
|
||||
ASSERT_NO_FATAL_FAILURE(processAndWriteToOutput());
|
||||
|
||||
// Validate that mOutputBuffer reaches to kMaxAudioSample for INT_MAX gain
|
||||
for (size_t i = 0; i < mOutputBuffer.size(); i++) {
|
||||
if (mInputBuffer[i] != 0) {
|
||||
EXPECT_NEAR(kMaxAudioSample, abs(mOutputBuffer[i]), kAbsError);
|
||||
} else {
|
||||
ASSERT_EQ(mOutputBuffer[i], mInputBuffer[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
|
@ -140,6 +311,20 @@ INSTANTIATE_TEST_SUITE_P(
|
|||
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(LoudnessEnhancerParamTest);
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
LoudnessEnhancerTest, LoudnessEnhancerDataTest,
|
||||
testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
|
||||
IFactory::descriptor, getEffectTypeUuidLoudnessEnhancer())),
|
||||
[](const testing::TestParamInfo<LoudnessEnhancerDataTest::ParamType>& 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(LoudnessEnhancerDataTest);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
::testing::UnitTest::GetInstance()->listeners().Append(new TestExecutionTracer());
|
||||
|
|
Loading…
Reference in a new issue