AIDL effect: Add Equalizer parameters implementation and vts
Bug: 238913361
Test: atest VtsHalAudioEffectTargetTest
atest VtsHalAudioEffectFactoryTargetTest
atest VtsHalEqualizerTargetTest
Change-Id: I94b2283ca2aa0e45715e1c9ac3ea6ad809ec2a2c
diff --git a/audio/aidl/default/equalizer/Equalizer.cpp b/audio/aidl/default/equalizer/Equalizer.cpp
index 2e4e538..43fa206 100644
--- a/audio/aidl/default/equalizer/Equalizer.cpp
+++ b/audio/aidl/default/equalizer/Equalizer.cpp
@@ -16,10 +16,12 @@
#define LOG_TAG "AHAL_EqualizerSw"
#include <Utils.h>
-#include <android-base/logging.h>
+#include <algorithm>
#include <unordered_set>
-#include "effect-impl/EffectUUID.h"
+#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+
#include "equalizer-impl/EqualizerSw.h"
using android::hardware::audio::common::getFrameSizeInBytes;
@@ -68,20 +70,26 @@
auto& output = common.output;
size_t inputFrameSize = getFrameSizeInBytes(input.base.format, input.base.channelMask);
size_t outputFrameSize = getFrameSizeInBytes(output.base.format, output.base.channelMask);
- if (!createFmq(1, input.frameCount * inputFrameSize, output.frameCount * outputFrameSize,
- _aidl_return)) {
+ mContext = std::make_shared<EqualizerSwContext>(1, input.frameCount * inputFrameSize,
+ output.frameCount * outputFrameSize);
+ if (!mContext) {
+ LOG(ERROR) << __func__ << " created EqualizerSwContext failed";
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_UNSUPPORTED_OPERATION,
"FailedToCreateFmq");
}
+ setContext(mContext);
// create the worker thread
- if (RetCode::SUCCESS != mWorker->create(LOG_TAG)) {
+ if (RetCode::SUCCESS != createThread(LOG_TAG)) {
LOG(ERROR) << __func__ << " created worker thread failed";
- destroyFmq();
+ mContext.reset();
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_UNSUPPORTED_OPERATION,
- "FailedToCreateFmq");
+ "FailedToCreateWorker");
}
+ _aidl_return->statusMQ = mContext->getStatusFmq()->dupeDesc();
+ _aidl_return->inputDataMQ = mContext->getInputDataFmq()->dupeDesc();
+ _aidl_return->outputDataMQ = mContext->getOutputDataFmq()->dupeDesc();
mState = State::IDLE;
return ndk::ScopedAStatus::ok();
}
@@ -98,8 +106,9 @@
// stop the worker thread
mState = State::INIT;
- mWorker->destroy();
- destroyFmq();
+ destroyThread();
+ mContext.reset();
+
LOG(DEBUG) << __func__;
return ndk::ScopedAStatus::ok();
}
@@ -121,19 +130,19 @@
case CommandId::START:
// start processing.
mState = State::PROCESSING;
- mWorker->start();
+ startThread();
LOG(DEBUG) << __func__ << " state: " << toString(mState);
return ndk::ScopedAStatus::ok();
case CommandId::STOP:
// stop processing.
mState = State::IDLE;
- mWorker->stop();
+ stopThread();
LOG(DEBUG) << __func__ << " state: " << toString(mState);
return ndk::ScopedAStatus::ok();
case CommandId::RESET:
// TODO: reset buffer status.
mState = State::IDLE;
- mWorker->stop();
+ stopThread();
LOG(DEBUG) << __func__ << " state: " << toString(mState);
return ndk::ScopedAStatus::ok();
default:
@@ -173,23 +182,27 @@
LOG(DEBUG) << __func__ << " get: " << _aidl_return->toString();
return ndk::ScopedAStatus::ok();
}
- case Parameter::Id::specificTag: {
- auto& id = in_paramId.get<Parameter::Id::specificTag>();
- if (id != Parameter::Specific::equalizer) {
- LOG(ERROR) << " unsupported parameter Id: " << in_paramId.toString();
- return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
- EX_ILLEGAL_ARGUMENT, "Parameter::IdNotSupported");
- }
+ case Parameter::Id::specificId: {
+ auto& id = in_paramId.get<Parameter::Id::specificId>();
Parameter::Specific specific;
- specific.set<Parameter::Specific::equalizer>(mEqualizerParam);
+ ndk::ScopedAStatus status = getSpecificParameter(id, &specific);
+ if (!status.isOk()) {
+ LOG(ERROR) << __func__
+ << " getSpecificParameter error: " << status.getDescription();
+ return status;
+ }
_aidl_return->set<Parameter::specific>(specific);
LOG(DEBUG) << __func__ << _aidl_return->toString();
return ndk::ScopedAStatus::ok();
}
- default:
- return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
- "Parameter::IdNotSupported");
+ case Parameter::Id::vendorTag: {
+ LOG(DEBUG) << __func__ << " noop for vendor tag now";
+ return ndk::ScopedAStatus::ok();
+ }
}
+ LOG(ERROR) << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "Parameter:IdNotSupported");
}
ndk::ScopedAStatus EqualizerSw::getState(State* _aidl_return) {
@@ -198,35 +211,12 @@
}
/// Private methods.
-bool EqualizerSw::createFmq(int statusDepth, int inBufferSize, int outBufferSize,
- OpenEffectReturn* ret) {
- mStatusMQ = std::make_unique<StatusMQ>(statusDepth, true /*configureEventFlagWord*/);
- mInputMQ = std::make_unique<DataMQ>(inBufferSize);
- mOutputMQ = std::make_unique<DataMQ>(outBufferSize);
-
- if (!mStatusMQ->isValid() || !mInputMQ->isValid() || !mOutputMQ->isValid()) {
- LOG(ERROR) << __func__ << " created invalid FMQ";
- return false;
- }
- ret->statusMQ = mStatusMQ->dupeDesc();
- ret->inputDataMQ = mInputMQ->dupeDesc();
- ret->outputDataMQ = mOutputMQ->dupeDesc();
- return true;
-}
-
-void EqualizerSw::destroyFmq() {
- mStatusMQ.reset(nullptr);
- mInputMQ.reset(nullptr);
- mOutputMQ.reset(nullptr);
-}
-
ndk::ScopedAStatus EqualizerSw::setCommonParameter(const Parameter::Common& common) {
mCommonParam = common;
LOG(DEBUG) << __func__ << " set: " << mCommonParam.toString();
return ndk::ScopedAStatus::ok();
}
-// TODO: implementation need change to save all parameters.
ndk::ScopedAStatus EqualizerSw::setSpecificParameter(const Parameter::Specific& specific) {
if (Parameter::Specific::equalizer != specific.getTag()) {
LOG(ERROR) << " unsupported effect: " << specific.toString();
@@ -234,9 +224,76 @@
"EffectNotSupported");
}
- mEqualizerParam = specific.get<Parameter::Specific::equalizer>();
- LOG(DEBUG) << __func__ << mEqualizerParam.toString();
- return ndk::ScopedAStatus::ok();
+ auto& eqParam = specific.get<Parameter::Specific::equalizer>();
+ auto tag = eqParam.getTag();
+ switch (tag) {
+ case Equalizer::bandLevels: {
+ auto& bandLevels = eqParam.get<Equalizer::bandLevels>();
+ const auto& [minItem, maxItem] = std::minmax_element(
+ bandLevels.begin(), bandLevels.end(),
+ [](const auto& a, const auto& b) { return a.index < b.index; });
+ if (bandLevels.size() >= NUM_OF_BANDS || minItem->index < 0 ||
+ maxItem->index >= NUM_OF_BANDS) {
+ LOG(ERROR) << " bandLevels " << bandLevels.size() << "minIndex " << minItem->index
+ << "maxIndex " << maxItem->index << " illegal ";
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "ExceedMaxBandNum");
+ }
+ mBandLevels = bandLevels;
+ return ndk::ScopedAStatus::ok();
+ }
+ case Equalizer::preset: {
+ int preset = eqParam.get<Equalizer::preset>();
+ if (preset < 0 || preset >= NUM_OF_PRESETS) {
+ LOG(ERROR) << " preset: " << preset << " invalid";
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "ExceedMaxBandNum");
+ }
+ mPreset = preset;
+ LOG(DEBUG) << __func__ << " preset set to " << mPreset;
+ return ndk::ScopedAStatus::ok();
+ }
+ case Equalizer::vendor: {
+ LOG(DEBUG) << __func__ << " noop for vendor tag now";
+ return ndk::ScopedAStatus::ok();
+ }
+ }
+
+ LOG(ERROR) << __func__ << " unsupported eq param tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "ParamNotSupported");
+}
+
+ndk::ScopedAStatus EqualizerSw::getSpecificParameter(Parameter::Specific::Id id,
+ Parameter::Specific* specific) {
+ Equalizer eqParam;
+ auto tag = id.getTag();
+ if (tag != Parameter::Specific::Id::equalizerTag) {
+ LOG(ERROR) << " invalid tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "UnsupportedTag");
+ }
+ auto eqTag = id.get<Parameter::Specific::Id::equalizerTag>();
+ switch (eqTag) {
+ case Equalizer::bandLevels: {
+ eqParam.set<Equalizer::bandLevels>(mBandLevels);
+ specific->set<Parameter::Specific::equalizer>(eqParam);
+ return ndk::ScopedAStatus::ok();
+ }
+ case Equalizer::preset: {
+ eqParam.set<Equalizer::preset>(mPreset);
+ LOG(DEBUG) << __func__ << " preset " << mPreset;
+ specific->set<Parameter::Specific::equalizer>(eqParam);
+ return ndk::ScopedAStatus::ok();
+ }
+ case Equalizer::vendor: {
+ LOG(DEBUG) << __func__ << " noop for vendor tag now";
+ return ndk::ScopedAStatus::ok();
+ }
+ }
+ LOG(ERROR) << __func__ << " unsupported eq param: " << toString(eqTag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "ParamNotSupported");
}
void EqualizerSw::cleanUp() {
@@ -248,9 +305,18 @@
}
}
-// Processing method running in worker thread.
-void EqualizerSwWorker::process() {
- // TODO: add EQ processing with FMQ, should wait until data available before data processing.
+IEffect::Status EqualizerSw::status(binder_status_t status, size_t consumed, size_t produced) {
+ IEffect::Status ret;
+ ret.status = status;
+ ret.fmqByteConsumed = consumed;
+ ret.fmqByteProduced = produced;
+ return ret;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status EqualizerSw::effectProcessImpl() {
+ // TODO: get data buffer and process.
+ return status(STATUS_OK, mContext->availableToRead(), mContext->availableToWrite());
}
} // namespace aidl::android::hardware::audio::effect