Build ViPER for all AIDL versions (V1, V2, V3)
Some checks failed
build / build (arm64-v8a) (push) Failing after 17s
build / build (armeabi-v7a) (push) Failing after 31s
build / build (x86) (push) Failing after 15s
build / build (x86_64) (push) Failing after 15s
build / package (push) Has been skipped

This commit is contained in:
Iscle 2025-04-28 00:29:21 +02:00
parent 95a3c3f7c2
commit ff8f29489c
10 changed files with 550 additions and 280 deletions

82
src/AidlUtils.h Normal file
View File

@ -0,0 +1,82 @@
#pragma once
#include <aidl/android/media/audio/common/AudioUuid.h>
#include <aidl/android/media/audio/common/PcmType.h>
using aidl::android::media::audio::common::AudioUuid;
using aidl::android::media::audio::common::PcmType;
inline AudioUuid stringToUuid(const char* str) {
AudioUuid uuid{};
uint32_t tmp[10];
if (!str || sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", tmp,
tmp + 1, tmp + 2, tmp + 3, tmp + 4, tmp + 5, tmp + 6,
tmp + 7, tmp + 8, tmp + 9) < 10) {
return uuid;
}
uuid.timeLow = (uint32_t)tmp[0];
uuid.timeMid = (uint16_t)tmp[1];
uuid.timeHiAndVersion = (uint16_t)tmp[2];
uuid.clockSeq = (uint16_t)tmp[3];
uuid.node.insert(uuid.node.end(), {(uint8_t)tmp[4], (uint8_t)tmp[5], (uint8_t)tmp[6],
(uint8_t)tmp[7], (uint8_t)tmp[8], (uint8_t)tmp[9]});
return uuid;
}
constexpr size_t getPcmSampleSizeInBytes(::aidl::android::media::audio::common::PcmType pcm) {
using ::aidl::android::media::audio::common::PcmType;
switch (pcm) {
case PcmType::UINT_8_BIT:
return 1;
case PcmType::INT_16_BIT:
return 2;
case PcmType::INT_32_BIT:
return 4;
case PcmType::FIXED_Q_8_24:
return 4;
case PcmType::FLOAT_32_BIT:
return 4;
case PcmType::INT_24_BIT:
return 3;
}
return 0;
}
constexpr size_t getChannelCount(
const ::aidl::android::media::audio::common::AudioChannelLayout& layout,
int32_t mask = std::numeric_limits<int32_t>::max()) {
using Tag = ::aidl::android::media::audio::common::AudioChannelLayout::Tag;
switch (layout.getTag()) {
case Tag::none:
return 0;
case Tag::invalid:
return 0;
case Tag::indexMask:
return __builtin_popcount(layout.get<Tag::indexMask>() & mask);
case Tag::layoutMask:
return __builtin_popcount(layout.get<Tag::layoutMask>() & mask);
case Tag::voiceMask:
return __builtin_popcount(layout.get<Tag::voiceMask>() & mask);
}
return 0;
}
constexpr size_t getFrameSizeInBytes(
const ::aidl::android::media::audio::common::AudioFormatDescription& format,
const ::aidl::android::media::audio::common::AudioChannelLayout& layout) {
if (format == ::aidl::android::media::audio::common::AudioFormatDescription{}) {
// Unspecified format.
return 0;
}
using ::aidl::android::media::audio::common::AudioFormatType;
if (format.type == AudioFormatType::PCM) {
return getPcmSampleSizeInBytes(format.pcm) * getChannelCount(layout);
} else if (format.type == AudioFormatType::NON_PCM) {
// For non-PCM formats always use the underlying PCM size. The default value for
// PCM is "UINT_8_BIT", thus non-encapsulated streams have the frame size of 1.
return getPcmSampleSizeInBytes(format.pcm);
}
// Something unexpected.
return 0;
}

View File

@ -1,45 +1,28 @@
#include "ViPER4Aidl.h" #define LOG_TAG "ViPER4AIDL"
#include <aidl/android/media/audio/common/PcmType.h>
#include <android-base/thread_annotations.h>
#include "ViPER4Aidl.h"
#include "AidlUtils.h"
#include <android-base/thread_annotations.h>
#include <aidl/android/hardware/audio/effect/DefaultExtension.h>
#include <system/audio_effect.h>
using aidl::android::hardware::audio::effect::kEventFlagDataMqUpdate;
using aidl::android::hardware::audio::effect::CommandId; using aidl::android::hardware::audio::effect::CommandId;
using aidl::android::hardware::audio::effect::DefaultExtension;
using aidl::android::hardware::audio::effect::Descriptor; using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::Flags; using aidl::android::hardware::audio::effect::Flags;
using aidl::android::hardware::audio::effect::IEffect; using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::Parameter; using aidl::android::hardware::audio::effect::Parameter;
using aidl::android::hardware::audio::effect::RetCode; using aidl::android::hardware::audio::effect::RetCode;
using aidl::android::hardware::audio::effect::State; using aidl::android::hardware::audio::effect::State;
using aidl::android::hardware::audio::effect::VendorExtension;
using aidl::android::media::audio::common::AudioUuid; using aidl::android::media::audio::common::AudioUuid;
using aidl::android::media::audio::common::PcmType; using aidl::android::media::audio::common::PcmType;
using android::hardware::EventFlag; using android::hardware::EventFlag;
/** static const AudioUuid kType = stringToUuid("b9bc100c-26cd-42e6-acb6-cad8c3f778de");
* EventFlag to indicate that the data FMQ is not Empty after a write. static const AudioUuid kUuid = stringToUuid("90380da3-8536-4744-a6a3-5731970e640f");
* TODO: b/277900230, Define in future AIDL version. static const Descriptor kDescriptor = {
*/
static constexpr uint32_t kEventFlagDataMqNotEmpty = 0x1 << 11;
inline AudioUuid stringToUuid(const char* str) {
AudioUuid uuid{};
uint32_t tmp[10];
if (!str || sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", tmp,
tmp + 1, tmp + 2, tmp + 3, tmp + 4, tmp + 5, tmp + 6,
tmp + 7, tmp + 8, tmp + 9) < 10) {
return uuid;
}
uuid.timeLow = (uint32_t)tmp[0];
uuid.timeMid = (uint16_t)tmp[1];
uuid.timeHiAndVersion = (uint16_t)tmp[2];
uuid.clockSeq = (uint16_t)tmp[3];
uuid.node.insert(uuid.node.end(), {(uint8_t)tmp[4], (uint8_t)tmp[5], (uint8_t)tmp[6],
(uint8_t)tmp[7], (uint8_t)tmp[8], (uint8_t)tmp[9]});
return uuid;
}
const AudioUuid kType = stringToUuid("b9bc100c-26cd-42e6-acb6-cad8c3f778de");
const AudioUuid kUuid = stringToUuid("90380da3-8536-4744-a6a3-5731970e640f");
const Descriptor kDescriptor = {
.common = { .common = {
.id = { .id = {
.type = kType, .type = kType,
@ -49,128 +32,51 @@ const Descriptor kDescriptor = {
.flags = { .flags = {
.type = Flags::Type::INSERT, .type = Flags::Type::INSERT,
.insert = Flags::Insert::LAST, .insert = Flags::Insert::LAST,
.volume = Flags::Volume::NONE
}, },
.name = "ViPER4Android", .name = "ViPER4Android",
.implementor = "Iscle", .implementor = "Iscle",
}, },
}; };
constexpr size_t getPcmSampleSizeInBytes(::aidl::android::media::audio::common::PcmType pcm) { ndk::ScopedAStatus ViPER4AIDL::open(const Parameter::Common &common,
using ::aidl::android::media::audio::common::PcmType;
switch (pcm) {
case PcmType::UINT_8_BIT:
return 1;
case PcmType::INT_16_BIT:
return 2;
case PcmType::INT_32_BIT:
return 4;
case PcmType::FIXED_Q_8_24:
return 4;
case PcmType::FLOAT_32_BIT:
return 4;
case PcmType::INT_24_BIT:
return 3;
}
return 0;
}
constexpr size_t getChannelCount(
const ::aidl::android::media::audio::common::AudioChannelLayout& layout,
int32_t mask = std::numeric_limits<int32_t>::max()) {
using Tag = ::aidl::android::media::audio::common::AudioChannelLayout::Tag;
switch (layout.getTag()) {
case Tag::none:
return 0;
case Tag::invalid:
return 0;
case Tag::indexMask:
return __builtin_popcount(layout.get<Tag::indexMask>() & mask);
case Tag::layoutMask:
return __builtin_popcount(layout.get<Tag::layoutMask>() & mask);
case Tag::voiceMask:
return __builtin_popcount(layout.get<Tag::voiceMask>() & mask);
}
return 0;
}
constexpr size_t getFrameSizeInBytes(
const ::aidl::android::media::audio::common::AudioFormatDescription& format,
const ::aidl::android::media::audio::common::AudioChannelLayout& layout) {
if (format == ::aidl::android::media::audio::common::AudioFormatDescription{}) {
// Unspecified format.
return 0;
}
using ::aidl::android::media::audio::common::AudioFormatType;
if (format.type == AudioFormatType::PCM) {
return getPcmSampleSizeInBytes(format.pcm) * getChannelCount(layout);
} else if (format.type == AudioFormatType::NON_PCM) {
// For non-PCM formats always use the underlying PCM size. The default value for
// PCM is "UINT_8_BIT", thus non-encapsulated streams have the frame size of 1.
return getPcmSampleSizeInBytes(format.pcm);
}
// Something unexpected.
return 0;
}
//int ViPER4AndroidAIDL::notifyEventFlag(uint32_t flag) {
// if (!mEventFlag) {
// ALOGE("notifyEventFlag: StatusEventFlag invalid");
// return -1;
// }
// if (const auto ret = mEventFlag->wake(flag); ret != ::android::OK) {
// ALOGE("notifyEventFlag: wake failure with ret %d", ret);
// return -1;
// }
// return 0;
//}
ndk::ScopedAStatus ViPER4AndroidAIDL::open(const Parameter::Common &common,
const std::optional<Parameter::Specific> &specific, const std::optional<Parameter::Specific> &specific,
IEffect::OpenEffectReturn *ret) { IEffect::OpenEffectReturn *ret) {
ALOGD("open called");
if (common.input.base.format.pcm != PcmType::FLOAT_32_BIT || if (common.input.base.format.pcm != PcmType::FLOAT_32_BIT ||
common.output.base.format.pcm != PcmType::FLOAT_32_BIT) { common.output.base.format.pcm != PcmType::FLOAT_32_BIT) {
ALOGE("open called with invalid PCM type"); ALOGE("open: unsupported PCM type (input: %d, output: %d)",
static_cast<int>(common.input.base.format.pcm),
static_cast<int>(common.output.base.format.pcm));
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
} }
std::lock_guard lg(mImplMutex); std::lock_guard lg(mImplMutex);
ALOGD("mImplMutex locked");
if (mState != State::INIT) { if (mState != State::INIT) {
ALOGD("open: already opened"); ALOGD("open: already opened");
return ndk::ScopedAStatus::ok(); return ndk::ScopedAStatus::ok();
} }
size_t mInputFrameSize = getFrameSizeInBytes( size_t inputFrameSize = getFrameSizeInBytes(
common.input.base.format, common.input.base.channelMask); common.input.base.format, common.input.base.channelMask);
size_t mOutputFrameSize = getFrameSizeInBytes( size_t outputFrameSize = getFrameSizeInBytes(
common.output.base.format, common.output.base.channelMask); common.output.base.format, common.output.base.channelMask);
size_t inBufferSizeInFloat = common.input.frameCount * mInputFrameSize / sizeof(float); /* EffectContext constructor start */
size_t outBufferSizeInFloat = common.output.frameCount * mOutputFrameSize / sizeof(float); mCommon = common;
size_t inBufferSizeInFloat = common.input.frameCount * inputFrameSize / sizeof(float);
size_t outBufferSizeInFloat = common.output.frameCount * outputFrameSize / sizeof(float);
ALOGD("open: inBufferSizeInFloat %zu, outBufferSizeInFloat %zu", inBufferSizeInFloat, ALOGD("open: inBufferSizeInFloat %zu, outBufferSizeInFloat %zu", inBufferSizeInFloat,
outBufferSizeInFloat); outBufferSizeInFloat);
// only status FMQ use the EventFlag // only status FMQ use the EventFlag
mStatusMQ = std::make_shared<StatusMQ>(1, true /*configureEventFlagWord*/); mStatusMQ = std::make_shared<StatusMQ>(1, true /* configureEventFlagWord */);
mInputMQ = std::make_shared<DataMQ>(inBufferSizeInFloat); mInputMQ = std::make_shared<DataMQ>(inBufferSizeInFloat);
mOutputMQ = std::make_shared<DataMQ>(outBufferSizeInFloat); mOutputMQ = std::make_shared<DataMQ>(outBufferSizeInFloat);
if (!mStatusMQ || !mInputMQ || !mOutputMQ) {
ALOGE("open: failed to create message queues");
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
}
ALOGD("message queues created");
ALOGD("open: mStatusMQ %p, mInputMQ %p, mOutputMQ %p", mStatusMQ.get(), mInputMQ.get(),
mOutputMQ.get());
if (!mStatusMQ->isValid() || !mInputMQ->isValid() || !mOutputMQ->isValid()) { if (!mStatusMQ->isValid() || !mInputMQ->isValid() || !mOutputMQ->isValid()) {
ALOGE("open: failed to create message queues"); ALOGE("open: invalid FMQ (status: %d, input: %d, output: %d)",
mStatusMQ->isValid(), mInputMQ->isValid(), mOutputMQ->isValid());
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
} }
@ -181,11 +87,8 @@ ndk::ScopedAStatus ViPER4AndroidAIDL::open(const Parameter::Common &common,
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
} }
ALOGD("open: event flag created");
mWorkBuffer.resize(std::max(inBufferSizeInFloat, outBufferSizeInFloat)); mWorkBuffer.resize(std::max(inBufferSizeInFloat, outBufferSizeInFloat));
/* EffectContext constructor end */
ALOGD("open: work buffer size %zu", mWorkBuffer.size());
if (specific.has_value()) { if (specific.has_value()) {
ALOGD("open: specific parameters provided, ignoring for now..."); ALOGD("open: specific parameters provided, ignoring for now...");
@ -193,143 +96,475 @@ ndk::ScopedAStatus ViPER4AndroidAIDL::open(const Parameter::Common &common,
mState = State::IDLE; mState = State::IDLE;
ALOGD("open: state set to IDLE"); dupeFmq(ret);
ret->statusMQ = mStatusMQ->dupeDesc();
ret->inputDataMQ = mInputMQ->dupeDesc();
ret->outputDataMQ = mOutputMQ->dupeDesc();
ALOGD("open: mq descriptors set");
if (createThread("ViPER4Android") != RetCode::SUCCESS) { if (createThread("ViPER4Android") != RetCode::SUCCESS) {
ALOGE("open: failed to create thread"); ALOGE("open: failed to create thread");
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
} }
ALOGD("open: thread created"); return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus ViPER4AIDL::close() {
{
std::lock_guard lg(mImplMutex);
if (mState == State::INIT) {
ALOGD("close: already closed");
return ndk::ScopedAStatus::ok();
}
if (mState == State::PROCESSING) {
ALOGE("close: cannot close while processing");
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
}
mState = State::INIT;
}
if (notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS) {
ALOGE("close: failed to notify not empty event flag");
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
}
if (destroyThread() != RetCode::SUCCESS) {
ALOGE("close: failed to destroy thread");
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
{
std::lock_guard lg(mImplMutex);
EventFlag::deleteEventFlag(&mEventFlag);
}
return ndk::ScopedAStatus::ok(); return ndk::ScopedAStatus::ok();
} }
ndk::ScopedAStatus ViPER4AndroidAIDL::close() { ndk::ScopedAStatus ViPER4AIDL::getDescriptor(Descriptor *descriptor) {
ALOGD("close called"); if (descriptor == nullptr) {
return ndk::ScopedAStatus::ok(); ALOGE("getDescriptor: descriptor is null");
} return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
ndk::ScopedAStatus
ViPER4AndroidAIDL::getDescriptor(Descriptor *descriptor) {
ALOGD("getDescriptor: returning descriptor");
*descriptor = kDescriptor; *descriptor = kDescriptor;
return ndk::ScopedAStatus::ok(); return ndk::ScopedAStatus::ok();
} }
ndk::ScopedAStatus ViPER4AndroidAIDL::command(CommandId id) { ndk::ScopedAStatus ViPER4AIDL::command(CommandId command) {
std::lock_guard lg(mImplMutex); std::lock_guard lg(mImplMutex);
if (mState == State::INIT) { if (mState == State::INIT) {
ALOGE("command: instance not open"); ALOGE("command: instance not open");
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
} }
switch (id) { switch (command) {
case CommandId::START: { case CommandId::START: {
ALOGD("command: START");
if (mState == State::PROCESSING) { if (mState == State::PROCESSING) {
ALOGD("command: already started");
return ndk::ScopedAStatus::ok(); return ndk::ScopedAStatus::ok();
} }
//RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed");
mState = State::PROCESSING; mState = State::PROCESSING;
// if (notifyEventFlag() != 0) { if (notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS) {
// ALOGE("id: failed to notify event flag"); ALOGE("command: failed to notify not empty event flag");
// return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
// } }
startThread(); startThread();
break; break;
} }
case CommandId::STOP: { case CommandId::STOP: {
ALOGD("command: STOP");
if (mState == State::IDLE) { if (mState == State::IDLE) {
ALOGD("command: already stopped");
return ndk::ScopedAStatus::ok(); return ndk::ScopedAStatus::ok();
} }
mState = State::IDLE; mState = State::IDLE;
if (notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS) {
ALOGE("command: failed to notify not empty event flag");
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
}
stopThread(); stopThread();
//RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed");
break; break;
} }
case CommandId::RESET: { case CommandId::RESET: {
ALOGD("command: RESET");
mState = State::IDLE; mState = State::IDLE;
if (notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS) {
ALOGE("command: failed to notify not empty event flag");
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
}
stopThread(); stopThread();
resetBuffer();
//RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed");
break; break;
} }
default: default:
ALOGE("command: unknown command %d", static_cast<int>(id)); ALOGE("command: unknown command %d", static_cast<uint32_t>(command));
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
} }
return ndk::ScopedAStatus::ok(); return ndk::ScopedAStatus::ok();
} }
ndk::ScopedAStatus ViPER4AndroidAIDL::getState(State *state) { ndk::ScopedAStatus ViPER4AIDL::getState(State *state) {
ALOGD("getState: returning state"); if (state == nullptr) {
ALOGE("getState: state is null");
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
*state = mState; *state = mState;
return ndk::ScopedAStatus::ok(); return ndk::ScopedAStatus::ok();
} }
ndk::ScopedAStatus ndk::ScopedAStatus
ViPER4AndroidAIDL::setParameter(const Parameter &parameter) { ViPER4AIDL::setParameter(const Parameter &parameter) {
ALOGD("setParameter called"); std::lock_guard lg(mImplMutex);
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
const auto &tag = parameter.getTag();
switch (tag) {
case Parameter::Tag::common: {
auto common = parameter.get<Parameter::Tag::common>();
if (common.input.base.format.pcm != PcmType::FLOAT_32_BIT ||
common.output.base.format.pcm != PcmType::FLOAT_32_BIT) {
ALOGE("setParameter: common: unsupported PCM type (input: %d, output: %d)",
static_cast<int>(common.input.base.format.pcm),
static_cast<int>(common.output.base.format.pcm));
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
#if VIPER_AIDL_VERSION >= 2
if (mWorkBuffer.size() != 0 && mInputMQ != nullptr && mOutputMQ != nullptr) {
size_t prevInputFrameSize = getFrameSizeInBytes(
mCommon.input.base.format, mCommon.input.base.channelMask);
size_t prevOutputFrameSize = getFrameSizeInBytes(
mCommon.output.base.format, mCommon.output.base.channelMask);
size_t inputFrameSize = getFrameSizeInBytes(
common.input.base.format, common.input.base.channelMask);
size_t outputFrameSize = getFrameSizeInBytes(
common.output.base.format, common.output.base.channelMask);
bool needUpdateMq = false;
if (inputFrameSize != prevInputFrameSize ||
mCommon.input.frameCount != common.input.frameCount) {
ALOGD("setParameter: common: reset input MQ");
mInputMQ.reset();
needUpdateMq = true;
}
if (outputFrameSize != prevOutputFrameSize ||
mCommon.output.frameCount != common.output.frameCount) {
ALOGD("setParameter: common: reset output MQ");
mOutputMQ.reset();
needUpdateMq = true;
}
ALOGD("setParameter: common: inBufferSizeInFloat %zu, outBufferSizeInFloat %zu, needUpdateMq %d",
(size_t) (common.input.frameCount * inputFrameSize / sizeof(float)),
(size_t) (common.output.frameCount * outputFrameSize / sizeof(float)),
needUpdateMq);
if (needUpdateMq && mEventFlag->wake(kEventFlagDataMqUpdate) != ::android::OK) {
ALOGE("setParameter: common: failed to wake event flag");
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
}
}
#endif
mCommon = common;
return ndk::ScopedAStatus::ok();
}
case Parameter::Tag::specific: {
auto specific = parameter.get<Parameter::Tag::specific>();
if (specific.getTag() != Parameter::Specific::Tag::vendorEffect) {
ALOGE("setParameter: specific: unsupported tag %d",
static_cast<int32_t>(specific.getTag()));
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
auto vendorEffect = specific.get<Parameter::Specific::Tag::vendorEffect>();
std::optional<DefaultExtension> defaultExtension;
if (vendorEffect.extension.getParcelable(&defaultExtension) != STATUS_OK || !defaultExtension.has_value()) {
ALOGE("setParameter: specific: failed to get default extension");
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
auto data = defaultExtension->bytes;
ALOGD("setParameter: specific: vendorEffect data size %zu", data.size());
int32_t ret = 0;
uint32_t retSize = sizeof(ret);
if (viperContext.handleCommand(
EFFECT_CMD_SET_PARAM,
data.size(),
data.data(),
&retSize,
&ret
) != 0) {
ALOGE("setParameter: specific: failed to handle command");
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
if (ret != 0) {
ALOGE("setParameter: specific: command failed with ret %d", ret);
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
return ndk::ScopedAStatus::ok();
}
default:
ALOGE("setParameter: unsupported parameter tag %d", static_cast<int32_t>(tag));
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
} }
ndk::ScopedAStatus ndk::ScopedAStatus
ViPER4AndroidAIDL::getParameter(const Parameter::Id &id, Parameter *param) { ViPER4AIDL::getParameter(const Parameter::Id &id, Parameter *param) {
ALOGD("getParameter called"); if (param == nullptr) {
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); ALOGE("getParameter: param is null");
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
std::lock_guard lg(mImplMutex);
const auto &tag = id.getTag();
switch (tag) {
case Parameter::Id::commonTag: {
auto commonTag = id.get<Parameter::Id::Tag::commonTag>();
if (commonTag != Parameter::Tag::common) {
ALOGE("getParameter: commonTag: unsupported tag %d",
static_cast<int32_t>(commonTag));
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
param->set<Parameter::Tag::common>(mCommon);
return ndk::ScopedAStatus::ok();
}
case Parameter::Id::vendorEffectTag: {
auto vendorEffectTag = id.get<Parameter::Id::Tag::vendorEffectTag>();
std::optional<DefaultExtension> cmdDefaultExtension;
if (vendorEffectTag.extension.getParcelable(&cmdDefaultExtension) != STATUS_OK || !cmdDefaultExtension.has_value()) {
ALOGE("getParameter: vendorEffectTag: failed to get default extension");
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
VendorExtension replyVendorExtension;
DefaultExtension replyDefaultExtension;
replyDefaultExtension.bytes.resize(sizeof(effect_param_t) + 2 * sizeof(int32_t));
auto cmdData = cmdDefaultExtension->bytes;
auto replyData = replyDefaultExtension.bytes;
uint32_t replySize = replyData.size();
if (viperContext.handleCommand(
EFFECT_CMD_GET_PARAM,
cmdData.size(),
cmdData.data(),
&replySize,
replyData.data()
) != 0) {
ALOGE("getParameter: vendorEffectTag: failed to handle command");
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
replyData.resize(replySize);
if (replyVendorExtension.extension.setParcelable(replyDefaultExtension) != STATUS_OK) {
ALOGE("getParameter: vendorEffectTag: failed to set default extension");
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
Parameter::Specific specific;
specific.set<Parameter::Specific::Tag::vendorEffect>(replyVendorExtension);
param->set<Parameter::Tag::specific>(specific);
return ndk::ScopedAStatus::ok();
}
default:
ALOGD("getParameter: unsupported parameter tag %d", static_cast<int32_t>(tag));
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
} }
#if VIPER_AIDL_VERSION >= 2 #if VIPER_AIDL_VERSION >= 2
ndk::ScopedAStatus ndk::ScopedAStatus ViPER4AIDL::reopen(IEffect::OpenEffectReturn *ret) {
ViPER4AndroidAIDL::reopen(IEffect::OpenEffectReturn *open_effect_return) {
std::lock_guard lg(mImplMutex); std::lock_guard lg(mImplMutex);
if (mState == State::INIT) { if (mState == State::INIT) {
ALOGE("reopen: already closed"); ALOGE("reopen: already closed");
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
} }
// TODO
ALOGD("reopen: reopening effect");
dupeFmqWithReopen(ret);
return ndk::ScopedAStatus::ok(); return ndk::ScopedAStatus::ok();
} }
#endif #endif
void ViPER4AndroidAIDL::process() { void ViPER4AIDL::process() {
ALOGD("process called"); /**
} * wait for the EventFlag without lock, it's ok because the mEventFlag pointer will not change
* in the life cycle of workerThread (threadLoop).
extern "C" binder_exception_t createEffect(const AudioUuid *audio_uuid, std::shared_ptr<IEffect> *instance) { */
if (audio_uuid == nullptr || instance == nullptr) { uint32_t efState = 0;
ALOGE("createEffect called with null arguments"); if (!mEventFlag || mEventFlag->wait(mDataMqNotEmptyEf, &efState, 0 /* no timeout */, true /* retry */) != ::android::OK || !(efState & mDataMqNotEmptyEf)) {
return EX_ILLEGAL_ARGUMENT; ALOGE("process: mEventFlag - %p, efState - %x", mEventFlag, efState);
return;
}
{
std::lock_guard lg(mImplMutex);
#if VIPER_AIDL_VERSION >= 3
if (mState != State::PROCESSING && mState != State::DRAINING) {
#else
if (mState != State::PROCESSING) {
#endif
ALOGD("process: skip process in state: %s", toString(mState).c_str());
return;
}
ALOGD("process: processing in state: %s, mInputMQ - %p, mOutputMQ - %p",
toString(mState).c_str(), mInputMQ.get(), mOutputMQ.get());
if (!mInputMQ || !mOutputMQ) {
ALOGE("process: mInputMQ or mOutputMQ is null");
return;
}
assert(mWorkBuffer.size() >= std::max(mInputMQ->availableToRead(), mOutputMQ->availableToWrite()));
auto processSamples = std::min(mInputMQ->availableToRead(), mOutputMQ->availableToWrite());
if (processSamples) {
auto buffer = static_cast<float*>(mWorkBuffer.data());
mInputMQ->read(buffer, processSamples);
IEffect::Status status = effectProcessImpl(buffer, buffer, processSamples);
mOutputMQ->write(buffer, status.fmqProduced);
mStatusMQ->writeBlocking(&status, 1);
}
} }
ALOGD("createEffect: creating effect instance");
*instance = ndk::SharedRefBase::make<ViPER4AndroidAIDL>();
return EX_NONE;
} }
extern "C" binder_exception_t destroyEffect(const std::shared_ptr<IEffect> &instance) { void ViPER4AIDL::dupeFmq(IEffect::OpenEffectReturn* ret) {
ALOGD("destroyEffect called"); ALOGD("dupeFmq: mStatusMQ - %p, mInputMQ - %p, mOutputMQ - %p",
return EX_ILLEGAL_STATE; mStatusMQ.get(), mInputMQ.get(), mOutputMQ.get());
if (ret && mStatusMQ && mInputMQ && mOutputMQ) {
ret->statusMQ = mStatusMQ->dupeDesc();
ret->inputDataMQ = mInputMQ->dupeDesc();
ret->outputDataMQ = mOutputMQ->dupeDesc();
}
}
void ViPER4AIDL::dupeFmqWithReopen(IEffect::OpenEffectReturn* ret) {
size_t inputFrameSize = getFrameSizeInBytes(
mCommon.input.base.format, mCommon.input.base.channelMask);
size_t outputFrameSize = getFrameSizeInBytes(
mCommon.output.base.format, mCommon.output.base.channelMask);
const size_t inBufferSizeInFloat = mCommon.input.frameCount * inputFrameSize / sizeof(float);
const size_t outBufferSizeInFloat = mCommon.output.frameCount * outputFrameSize / sizeof(float);
const size_t bufferSize = std::max(inBufferSizeInFloat, outBufferSizeInFloat);
if (!mInputMQ) {
mInputMQ = std::make_shared<DataMQ>(inBufferSizeInFloat);
}
if (!mOutputMQ) {
mOutputMQ = std::make_shared<DataMQ>(outBufferSizeInFloat);
}
if (mWorkBuffer.size() != bufferSize) {
mWorkBuffer.resize(bufferSize);
}
dupeFmq(ret);
}
RetCode ViPER4AIDL::notifyEventFlag(uint32_t flag) {
if (!mEventFlag) {
ALOGE("notifyEventFlag: StatusEventFlag invalid");
return RetCode::ERROR_EVENT_FLAG_ERROR;
}
if (const auto ret = mEventFlag->wake(flag); ret != ::android::OK) {
ALOGE("notifyEventFlag: wake failure with ret %d", ret);
return RetCode::ERROR_EVENT_FLAG_ERROR;
}
return RetCode::SUCCESS;
}
// reset buffer status by abandon input data in FMQ
void ViPER4AIDL::resetBuffer() {
if (mStatusMQ) {
std::vector<IEffect::Status> status(mStatusMQ->availableToRead());
}
if (mInputMQ) {
auto buffer = static_cast<float*>(mWorkBuffer.data());
mInputMQ->read(buffer, mInputMQ->availableToRead());
}
}
// A placeholder processing implementation to copy samples from input to output
IEffect::Status ViPER4AIDL::effectProcessImpl(float* in, float* out, int samples) {
viperContext.process(in, out, samples);
return {STATUS_OK, samples, samples};
} }
extern "C" binder_exception_t queryEffect(const AudioUuid *audio_uuid, Descriptor *descriptor) { extern "C" binder_exception_t queryEffect(const AudioUuid *audio_uuid, Descriptor *descriptor) {
if (audio_uuid == nullptr || descriptor == nullptr) { if (audio_uuid == nullptr || descriptor == nullptr) {
ALOGE("queryEffect called with null arguments"); ALOGE("queryEffect: audio_uuid or descriptor is null");
return EX_ILLEGAL_ARGUMENT; return EX_ILLEGAL_ARGUMENT;
} }
if (*audio_uuid != kUuid) { if (*audio_uuid != kUuid) {
ALOGE("queryEffect called with invalid uuid"); ALOGE("queryEffect: invalid uuid");
return EX_ILLEGAL_ARGUMENT; return EX_ILLEGAL_ARGUMENT;
} }
ALOGD("queryEffect: returning descriptor");
*descriptor = kDescriptor; *descriptor = kDescriptor;
return EX_NONE; return EX_NONE;
} }
extern "C" binder_exception_t createEffect(const AudioUuid *audio_uuid, std::shared_ptr<IEffect> *instanceSp) {
if (audio_uuid == nullptr || instanceSp == nullptr) {
ALOGE("createEffect: audio_uuid or instanceSp is null");
return EX_ILLEGAL_ARGUMENT;
}
*instanceSp = ndk::SharedRefBase::make<ViPER4AIDL>();
return EX_NONE;
}
extern "C" binder_exception_t destroyEffect(const std::shared_ptr<IEffect> &instanceSp) {
if (!instanceSp) {
ALOGE("destroyEffect: instanceSp is null");
return EX_ILLEGAL_ARGUMENT;
}
Descriptor desc;
ndk::ScopedAStatus status = instanceSp->getDescriptor(&desc);
if (!status.isOk()) {
ALOGE("destroyEffect: failed to get descriptor, status: %s", status.getDescription().c_str());
return EX_ILLEGAL_STATE;
}
State state;
status = instanceSp->getState(&state);
if (!status.isOk()) {
ALOGE("destroyEffect: failed to get state, status: %s", status.getDescription().c_str());
return EX_ILLEGAL_STATE;
}
#if VIPER_AIDL_VERSION >= 3
instanceSp->command(CommandId::RESET);
instanceSp->close();
#else
if (state != State::INIT) {
ALOGE("destroyEffect: can not destroy instance in state: %s", toString(state).c_str());
return EX_ILLEGAL_STATE;
}
#endif
return EX_NONE;
}

View File

@ -5,27 +5,36 @@
#include <aidl/android/hardware/audio/effect/BnEffect.h> #include <aidl/android/hardware/audio/effect/BnEffect.h>
#include <fmq/AidlMessageQueue.h> #include <fmq/AidlMessageQueue.h>
#include <effect-impl/EffectThread.h> #include <effect-impl/EffectThread.h>
#include "ViperContext.h"
using aidl::android::hardware::common::fmq::SynchronizedReadWrite; using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
#if VIPER_AIDL_VERSION >= 2
using aidl::android::hardware::audio::effect::kEventFlagDataMqNotEmpty;
#else
using aidl::android::hardware::audio::effect::kEventFlagNotEmpty;
#endif
using aidl::android::hardware::audio::effect::BnEffect; using aidl::android::hardware::audio::effect::BnEffect;
using aidl::android::hardware::audio::effect::CommandId; using aidl::android::hardware::audio::effect::CommandId;
using aidl::android::hardware::audio::effect::Descriptor; using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::EffectThread; using aidl::android::hardware::audio::effect::EffectThread;
using aidl::android::hardware::audio::effect::Parameter; using aidl::android::hardware::audio::effect::Parameter;
using aidl::android::hardware::audio::effect::RetCode;
using aidl::android::hardware::audio::effect::State; using aidl::android::hardware::audio::effect::State;
using android::hardware::EventFlag;
class ViPER4AndroidAIDL : public BnEffect, public EffectThread { class ViPER4AIDL : public BnEffect, public EffectThread {
public: public:
// BnEffect // BnEffect
ndk::ScopedAStatus open(const Parameter::Common &common, const std::optional<Parameter::Specific> &specific, IEffect::OpenEffectReturn *ret) override; ndk::ScopedAStatus open(const Parameter::Common &common, const std::optional<Parameter::Specific> &specific, IEffect::OpenEffectReturn *ret) override;
ndk::ScopedAStatus close() override; ndk::ScopedAStatus close() override;
ndk::ScopedAStatus getDescriptor(Descriptor *_aidl_return) override; ndk::ScopedAStatus getDescriptor(Descriptor *_aidl_return) override;
ndk::ScopedAStatus command(CommandId id) override; ndk::ScopedAStatus command(CommandId id) override;
ndk::ScopedAStatus getState(State *_aidl_return) override; ndk::ScopedAStatus getState(State *state) override;
ndk::ScopedAStatus setParameter(const Parameter &in_param) override; ndk::ScopedAStatus setParameter(const Parameter &in_param) override;
ndk::ScopedAStatus getParameter(const Parameter::Id &in_paramId, Parameter *_aidl_return) override; ndk::ScopedAStatus getParameter(const Parameter::Id &in_paramId, Parameter *param) override;
#if VIPER_AIDL_VERSION >= 2 #if VIPER_AIDL_VERSION >= 2
ndk::ScopedAStatus reopen(IEffect::OpenEffectReturn *_aidl_return) override; ndk::ScopedAStatus reopen(IEffect::OpenEffectReturn *ret) override;
#endif #endif
// EffectThread // EffectThread
@ -34,12 +43,28 @@ private:
typedef android::AidlMessageQueue<IEffect::Status, SynchronizedReadWrite> StatusMQ; typedef android::AidlMessageQueue<IEffect::Status, SynchronizedReadWrite> StatusMQ;
typedef android::AidlMessageQueue<float, SynchronizedReadWrite> DataMQ; typedef android::AidlMessageQueue<float, SynchronizedReadWrite> DataMQ;
void dupeFmq(IEffect::OpenEffectReturn* ret);
void dupeFmqWithReopen(IEffect::OpenEffectReturn* ret);
RetCode notifyEventFlag(uint32_t flag);
void resetBuffer();
IEffect::Status effectProcessImpl(float* in, float* out, int samples);
std::mutex mImplMutex; std::mutex mImplMutex;
State mState = State::INIT; State mState = State::INIT;
#if VIPER_AIDL_VERSION >= 2
static const int mDataMqNotEmptyEf = kEventFlagDataMqNotEmpty;
#else
static const int mDataMqNotEmptyEf = kEventFlagNotEmpty;
#endif
Parameter::Common mCommon;
std::shared_ptr<StatusMQ> mStatusMQ; std::shared_ptr<StatusMQ> mStatusMQ;
std::shared_ptr<DataMQ> mInputMQ; std::shared_ptr<DataMQ> mInputMQ;
std::shared_ptr<DataMQ> mOutputMQ; std::shared_ptr<DataMQ> mOutputMQ;
android::hardware::EventFlag *mEventFlag; EventFlag *mEventFlag;
std::vector<float> mWorkBuffer; std::vector<float> mWorkBuffer;
ViperContext viperContext;
}; };

View File

@ -2,7 +2,7 @@
#include <cstring> #include <cstring>
#include <cmath> #include <cmath>
#include "ViperContext.h" #include "ViperContext.h"
#include <log.h> #include <log/log.h>
#include <constants.h> #include <constants.h>
#define SET(type, ptr, value) (*(type *) (ptr) = (value)) #define SET(type, ptr, value) (*(type *) (ptr) = (value))
@ -840,7 +840,7 @@ int32_t ViperContext::process(audio_buffer_t *inBuffer, audio_buffer_t *outBuffe
return -EINVAL; return -EINVAL;
} }
viper.process(buffer, frameCount); viper.process(buffer.data(), frameCount);
const bool accumulate = config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE; const bool accumulate = config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE;
switch (config.outputCfg.format) { switch (config.outputCfg.format) {
@ -860,6 +860,14 @@ int32_t ViperContext::process(audio_buffer_t *inBuffer, audio_buffer_t *outBuffe
return 0; return 0;
} }
int32_t ViperContext::process(float *inBuffer, float *outBuffer, size_t count) {
memcpy(outBuffer, inBuffer, count * sizeof(float));
// The viper process function expects the count to be the number of
// stereo frames, not the number of samples. Thus, we divide by 2.
viper.process(outBuffer, count / 2);
return 0;
}
void ViperContext::setDisableReason(DisableReason reason) { void ViperContext::setDisableReason(DisableReason reason) {
this->disableReason = reason; this->disableReason = reason;
} }

View File

@ -21,6 +21,7 @@ public:
int32_t handleCommand(uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, uint32_t *replySize, void *pReplyData); int32_t handleCommand(uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, uint32_t *replySize, void *pReplyData);
int32_t process(audio_buffer_t *inBuffer, audio_buffer_t *outBuffer); int32_t process(audio_buffer_t *inBuffer, audio_buffer_t *outBuffer);
int32_t process(float *inBuffer, float *outBuffer, size_t count);
private: private:
effect_config_t config; effect_config_t config;

View File

@ -6,7 +6,7 @@
#include <cerrno> #include <cerrno>
#endif #endif
#include <log.h> // TODO: Remove this dependency #include <log/log.h> // TODO: Remove this dependency
enum class Architecture : uint8_t { enum class Architecture : uint8_t {
UNKNOWN = 0, UNKNOWN = 0,

View File

@ -1,81 +0,0 @@
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <android/log.h>
#ifndef LOG_TAG
#define LOG_TAG "ViPER4Android"
#endif
#ifndef LOG_NDEBUG
#ifdef NDEBUG
#define LOG_NDEBUG 1
#else
#define LOG_NDEBUG 0
#endif
#endif
/*
* Basic log message macros intended to emulate the behavior of log/log.h
* in system core. This should be dependent only on ndk exposed logging
* functionality.
*/
#ifndef ALOG
#define ALOG(priority, tag, ...) \
__android_log_print(ANDROID_##priority, tag, __VA_ARGS__)
#endif
#ifndef ALOGV
#if LOG_NDEBUG
#define ALOGV(...) ((void)0)
#else
#define ALOGV(...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
#endif
#endif
#ifndef ALOGD
#define ALOGD(...) ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__))
#endif
#ifndef ALOGI
#define ALOGI(...) ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__))
#endif
#ifndef ALOGW
#define ALOGW(...) ((void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__))
#endif
#ifndef ALOGE
#define ALOGE(...) ((void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__))
#endif
#ifndef ALOGF
#define ALOGF(...) ((void)ALOG(LOG_FATAL, LOG_TAG, __VA_ARGS__))
#endif
/*
* Log a fatal error if cond is true. The condition test is inverted from
* assert(3) semantics. The test and message are not stripped from release
* builds
*/
#ifndef ALOG_ALWAYS_FATAL_IF
#define ALOG_ALWAYS_FATAL_IF(cond, ...) \
if (cond) __android_log_assert(#cond, LOG_TAG, __VA_ARGS__)
#endif

View File

@ -1,7 +1,7 @@
#include "ViPER.h" #include "ViPER.h"
#include <cstring> #include <cstring>
#include <constants.h> #include <constants.h>
#include <log.h> #include <log/log.h>
ViPER::ViPER() : ViPER::ViPER() :
adaptiveBuffer(2, 4096), adaptiveBuffer(2, 4096),
@ -86,7 +86,7 @@ ViPER::ViPER() :
} }
} }
void ViPER::process(std::vector<float>& buffer, uint32_t size) { void ViPER::process(float *buffer, uint32_t size) {
this->frameCount += size; this->frameCount += size;
uint32_t ret; uint32_t ret;
@ -96,7 +96,7 @@ void ViPER::process(std::vector<float>& buffer, uint32_t size) {
if (this->convolver.GetEnabled() || this->vhe.GetEnabled()) { if (this->convolver.GetEnabled() || this->vhe.GetEnabled()) {
// ALOGD("Convolver or VHE is enable, use wave buffer"); // ALOGD("Convolver or VHE is enable, use wave buffer");
if (!this->waveBuffer.PushSamples(buffer.data(), size)) { if (!this->waveBuffer.PushSamples(buffer, size)) {
this->waveBuffer.Reset(); this->waveBuffer.Reset();
return; return;
} }
@ -121,7 +121,7 @@ void ViPER::process(std::vector<float>& buffer, uint32_t size) {
} else { } else {
// ALOGD("Convolver and VHE are disabled, use adaptive buffer"); // ALOGD("Convolver and VHE are disabled, use adaptive buffer");
if (this->adaptiveBuffer.PushFrames(buffer.data(), size)) { if (this->adaptiveBuffer.PushFrames(buffer, size)) {
this->adaptiveBuffer.SetBufferOffset(size); this->adaptiveBuffer.SetBufferOffset(size);
tmpBuf = this->adaptiveBuffer.GetBuffer(); tmpBuf = this->adaptiveBuffer.GetBuffer();
@ -159,7 +159,7 @@ void ViPER::process(std::vector<float>& buffer, uint32_t size) {
tmpBuf[i + 1] = this->softwareLimiters[1].Process(tmpBuf[i + 1]); tmpBuf[i + 1] = this->softwareLimiters[1].Process(tmpBuf[i + 1]);
} }
if (!this->adaptiveBuffer.PopFrames(buffer.data(), tmpBufSize)) { if (!this->adaptiveBuffer.PopFrames(buffer, tmpBufSize)) {
this->adaptiveBuffer.FlushBuffer(); this->adaptiveBuffer.FlushBuffer();
return; return;
} }
@ -169,8 +169,8 @@ void ViPER::process(std::vector<float>& buffer, uint32_t size) {
} }
} }
memmove(buffer.data() + (size - tmpBufSize) * 2, buffer.data(), tmpBufSize * sizeof(float)); memmove(buffer + (size - tmpBufSize) * 2, buffer, tmpBufSize * sizeof(float));
memset(buffer.data(), 0, (size - tmpBufSize) * sizeof(float)); memset(buffer, 0, (size - tmpBufSize) * sizeof(float));
} }
//void ViPER::DispatchCommand(int param, int val1, int val2, int val3, int val4, uint32_t arrSize, //void ViPER::DispatchCommand(int param, int val1, int val2, int val3, int val4, uint32_t arrSize,

View File

@ -27,7 +27,7 @@ class ViPER {
public: public:
ViPER(); ViPER();
void process(std::vector<float>& buffer, uint32_t size); void process(float *buffer, uint32_t size);
void reset(); void reset();
uint64_t getFrameCount(); uint64_t getFrameCount();
void setSamplingRate(uint32_t samplingRate); void setSamplingRate(uint32_t samplingRate);

View File

@ -1,5 +1,5 @@
#include "ViPERDDC.h" #include "ViPERDDC.h"
#include <log.h> #include <log/log.h>
#include <constants.h> #include <constants.h>
#include <cstring> #include <cstring>