From 6d7fd4d9e61b68f7225d65776f04b55576a100e7 Mon Sep 17 00:00:00 2001 From: Iscle Date: Tue, 27 Sep 2022 03:48:49 +0200 Subject: [PATCH] Update --- CMakeLists.txt | 1 - src/cpp/ViPER4Android.cpp | 231 +++++++++++++++++++++-- src/cpp/ViPER4Android.h | 2 - src/cpp/viper/Effect.cpp | 112 ----------- src/cpp/viper/Effect.h | 28 --- src/cpp/viper/ViPER.cpp | 224 +++++----------------- src/cpp/viper/ViPER.h | 14 +- src/cpp/viper/effects/IIRFilter.cpp | 28 ++- src/cpp/viper/effects/IIRFilter.h | 6 +- src/cpp/viper/effects/SoftwareLimiter.h | 1 - src/cpp/viper/utils/Harmonic.cpp | 10 +- src/cpp/viper/utils/Harmonic.h | 10 +- src/cpp/viper/utils/Stereo3DSurround.cpp | 38 +++- src/cpp/viper/utils/Stereo3DSurround.h | 2 - src/include/essential.h | 2 + 15 files changed, 331 insertions(+), 378 deletions(-) delete mode 100644 src/cpp/viper/Effect.cpp delete mode 100644 src/cpp/viper/Effect.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 42e2842..d4e5e15 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,6 @@ include_directories(src/include) set(FILES # Main - src/cpp/viper/Effect.cpp src/cpp/viper/ViPER.cpp src/cpp/ViPER4Android.cpp diff --git a/src/cpp/ViPER4Android.cpp b/src/cpp/ViPER4Android.cpp index 45af8cd..88f5fdc 100644 --- a/src/cpp/ViPER4Android.cpp +++ b/src/cpp/ViPER4Android.cpp @@ -1,7 +1,9 @@ #include #include +#include #include "viper/ViPER.h" +#include "essential.h" #include "log.h" #include "viper/constants.h" @@ -22,35 +24,217 @@ static effect_descriptor_t viper_descriptor = { extern "C" { struct ViperContext { const struct effect_interface_s *interface; // Should always be the first struct member + effect_config_t config; ViPER *viper; }; static int32_t Viper_IProcess(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) { - auto pContext = (ViperContext *) self; + auto pContext = reinterpret_cast(self); - if (pContext == nullptr || pContext->viper == nullptr || inBuffer == nullptr || outBuffer == nullptr) { - VIPER_LOGE("Viper_IProcess: pContext, pContext->viper, inBuffer or outBuffer is null!"); + if (pContext == nullptr || + inBuffer == nullptr || outBuffer == nullptr || + inBuffer->raw == nullptr || outBuffer->raw == nullptr || + inBuffer->frameCount != outBuffer->frameCount || + inBuffer->frameCount == 0) { return -EINVAL; } - return pContext->viper->process(inBuffer, outBuffer); + float *inBufferPtr = inBuffer->f32; + float *outBufferPtr = outBuffer->f32; + + if (inBufferPtr != outBufferPtr) { + memcpy(outBufferPtr, inBufferPtr, outBuffer->frameCount * sizeof(float) * 2); + } + + /*return */pContext->viper->processBuffer(outBufferPtr, outBuffer->frameCount); + return 0; // TODO: Return code from processBuffer() +} + +static int configure(ViperContext *pContext, effect_config_t *newConfig) { + VIPER_LOGI("Begin audio configure ..."); + VIPER_LOGI("Checking input and output configuration ..."); + + if (newConfig->inputCfg.samplingRate != newConfig->outputCfg.samplingRate) { + VIPER_LOGE("ViPER4Android disabled, reason [in.SR = %d, out.SR = %d]", + newConfig->inputCfg.samplingRate, newConfig->outputCfg.samplingRate); + return -EINVAL; + } + + if (newConfig->inputCfg.samplingRate > 48000) { + VIPER_LOGE("ViPER4Android disabled, reason [SR out of range]"); + return -EINVAL; + } + + if (newConfig->inputCfg.channels != newConfig->outputCfg.channels) { + VIPER_LOGE("ViPER4Android disabled, reason [in.CH = %d, out.CH = %d]", + newConfig->inputCfg.channels, newConfig->outputCfg.channels); + return -EINVAL; + } + + if (newConfig->inputCfg.channels != AUDIO_CHANNEL_OUT_STEREO) { + VIPER_LOGE("ViPER4Android disabled, reason [CH != 2]"); + return -EINVAL; + } + + if (newConfig->inputCfg.format != AUDIO_FORMAT_PCM_FLOAT) { + VIPER_LOGE("ViPER4Android disabled, reason [in.FMT = %d]", newConfig->inputCfg.format); + VIPER_LOGE("We only accept f32 format"); + return -EINVAL; + } + + if (newConfig->outputCfg.format != AUDIO_FORMAT_PCM_FLOAT) { + VIPER_LOGE("ViPER4Android disabled, reason [out.FMT = %d]", newConfig->outputCfg.format); + VIPER_LOGE("We only accept f32 format"); + return -EINVAL; + } + + VIPER_LOGI("Input and output configuration checked."); + + pContext->config = *newConfig; + + VIPER_LOGI("Audio configure finished"); + + return 0; } static int32_t Viper_ICommand(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, uint32_t *replySize, void *pReplyData) { - auto pContext = (ViperContext *) self; + auto pContext = reinterpret_cast(self); if (pContext == nullptr || pContext->viper == nullptr) { VIPER_LOGE("Viper_ICommand: pContext or pContext->viper is null!"); return -EINVAL; } - return pContext->viper->command(cmdCode, cmdSize, pCmdData, replySize, pReplyData); + VIPER_LOGD("Viper_ICommand() called with cmdCode = %d", cmdCode); + switch (cmdCode) { + case EFFECT_CMD_INIT: + *((int *) pReplyData) = 0; + return 0; + case EFFECT_CMD_SET_CONFIG: { + auto currentSampleRate = pContext->viper->samplingRate; + + *(int *) pReplyData = configure(pContext, (effect_config_t *) pCmdData); + if (*(int *) pReplyData == 0) { + if (currentSampleRate != pContext->viper->samplingRate) { + pContext->viper->ResetAllEffects(); + } + } + + return 0; + } + case EFFECT_CMD_RESET: { + pContext->viper->ResetAllEffects(); + break; + } + case EFFECT_CMD_ENABLE: { + if (!pContext->viper->enabled) { + pContext->viper->ResetAllEffects(); + } + pContext->viper->enabled = true; + *((int *) pReplyData) = 0; + return 0; + } + case EFFECT_CMD_DISABLE: { + pContext->viper->enabled = false; + *((int *) pReplyData) = 0; + return 0; + } + case EFFECT_CMD_SET_PARAM: { + auto pCmdParam = (effect_param_t *) pCmdData; + + if (pCmdParam->psize != sizeof(int32_t)) { + *(int *) pReplyData = -EINVAL; + return 0; + } + + // TODO: implement + } + case EFFECT_CMD_GET_PARAM: { + auto *pCmdParam = (effect_param_t *) pCmdData; + auto *pReplyParam = (effect_param_t *) pReplyData; + + if (pCmdParam->psize != sizeof(int)) break; + + switch (*(int *) pCmdParam->data) { + case PARAM_GET_DRIVER_VERSION: { + pReplyParam->status = 0; + //pReplyParam->psize = sizeof(int32_t); // TODO + pReplyParam->vsize = sizeof(int32_t); + *(int32_t *) pReplyParam->data = 0x2050004; // As original, change as needed + *replySize = 0x14; // As original, TODO: calculate correctly + return 0; + } + case PARAM_GET_ENABLED: { + pReplyParam->status = 0; + //pReplyParam->psize = sizeof(int32_t); // TODO + pReplyParam->vsize = sizeof(int32_t); + *(int32_t *) pReplyParam->data = pContext->viper->enabled; + *replySize = 0x14; // As original, TODO: calculate correctly + return 0; + } + case PARAM_GET_CONFIGURE: { + pReplyParam->status = 0; + //pReplyParam->psize = sizeof(int32_t); // TODO + pReplyParam->vsize = sizeof(int32_t); + *(int32_t *) pReplyParam->data = 1; // TODO? + *replySize = 0x14; // As original, TODO: calculate correctly + return 0; + } + case PARAM_GET_DRVCANWORK: { + pReplyParam->status = 0; + //pReplyParam->psize = sizeof(int32_t); // TODO + pReplyParam->vsize = sizeof(int32_t); + *(int32_t *) pReplyParam->data = pContext->viper->init_ok; + *replySize = 0x14; // As original, TODO: calculate correctly + return 0; + } + case PARAM_GET_STREAMING: { + struct timeval time{}; + gettimeofday(&time, nullptr); + + // TODO: Do some calculations + + return 0; + } + case PARAM_GET_SAMPLINGRATE: { + pReplyParam->status = 0; + //pReplyParam->psize = sizeof(int32_t); // TODO + pReplyParam->vsize = sizeof(int32_t); + *(uint32_t *) pReplyParam->data = pContext->viper->samplingRate; + *replySize = 0x14; // As original, TODO: calculate correctly + return 0; + } + case PARAM_GET_CONVUSABLE: { + pReplyParam->status = 0; + //pReplyParam->psize = sizeof(int32_t); // TODO + pReplyParam->vsize = sizeof(int32_t); + *(int32_t *) pReplyParam->data = 1; // TODO: Figure out what is this + *replySize = 0x14; // As original, TODO: calculate correctly + return 0; + } + case PARAM_GET_CONVKNLID: { + pReplyParam->status = 0; + //pReplyParam->psize = sizeof(int32_t); // TODO + pReplyParam->vsize = sizeof(int32_t); + *(uint32_t *) pReplyParam->data = pContext->viper->convolver->GetKernelID(); + *replySize = 0x14; // As original, TODO: calculate correctly + return 0; + } + } + } + case EFFECT_CMD_GET_CONFIG: { + memcpy(pReplyData, &pContext->config, sizeof(effect_config_t)); + return 0; + } + } + + return -EINVAL; } static int32_t Viper_IGetDescriptor(effect_handle_t self, effect_descriptor_t *pDescriptor) { - auto *pContext = (ViperContext *) self; + auto pContext = reinterpret_cast(self); if (pContext == nullptr || pDescriptor == nullptr) { VIPER_LOGE("Viper_IGetDescriptor: pContext or pDescriptor is null!"); @@ -68,6 +252,26 @@ static const effect_interface_s viper_interface = { .get_descriptor = Viper_IGetDescriptor }; +static void Viper_Init(ViperContext *pContext) { + pContext->interface = &viper_interface; + + memset(&pContext->config, 0, sizeof(effect_config_t)); + + pContext->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ; + pContext->config.inputCfg.format = AUDIO_FORMAT_PCM_FLOAT; + pContext->config.inputCfg.samplingRate = DEFAULT_SAMPLERATE; + pContext->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; + pContext->config.inputCfg.mask = AUDIO_PORT_CONFIG_ALL; + + pContext->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE; + pContext->config.outputCfg.format = AUDIO_FORMAT_PCM_FLOAT; + pContext->config.outputCfg.samplingRate = DEFAULT_SAMPLERATE; + pContext->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; + pContext->config.outputCfg.mask = AUDIO_PORT_CONFIG_ALL; + + pContext->viper = new ViPER(); +} + static int32_t Viper_Create(const effect_uuid_t *uuid, int32_t sessionId __unused, int32_t ioId __unused, effect_handle_t *pHandle) { VIPER_LOGI("Enter Viper_Create()"); @@ -84,17 +288,15 @@ Viper_Create(const effect_uuid_t *uuid, int32_t sessionId __unused, int32_t ioId VIPER_LOGI("Viper_Create: uuid matches, creating viper..."); - auto *pContext = new ViperContext(); - pContext->interface = &viper_interface; - pContext->viper = new ViPER(); - + auto *pContext = new ViperContext; + Viper_Init(pContext); *pHandle = (effect_handle_t) pContext; return 0; } static int32_t Viper_Release(effect_handle_t handle) { - auto *pContext = (ViperContext *) handle; + auto pContext = reinterpret_cast(handle); VIPER_LOGI("Enter Viper_Release()"); @@ -105,10 +307,7 @@ static int32_t Viper_Release(effect_handle_t handle) { VIPER_LOGI("Viper_Release: deleting viper..."); - if (pContext->viper != nullptr) { - delete pContext->viper; - pContext->viper = nullptr; - } + delete pContext->viper; delete pContext; return 0; diff --git a/src/cpp/ViPER4Android.h b/src/cpp/ViPER4Android.h index bb0ad0c..ea35469 100644 --- a/src/cpp/ViPER4Android.h +++ b/src/cpp/ViPER4Android.h @@ -12,12 +12,10 @@ enum ParamsMode { enum ParamsGet { PARAM_GET_STATUS_BEGIN = 0x08000, PARAM_GET_DRIVER_VERSION, - PARAM_GET_NEONENABLED, PARAM_GET_ENABLED, PARAM_GET_CONFIGURE, PARAM_GET_DRVCANWORK, PARAM_GET_STREAMING, - PARAM_GET_EFFECT_TYPE, PARAM_GET_SAMPLINGRATE, PARAM_GET_CONVUSABLE, PARAM_GET_CONVKNLID, diff --git a/src/cpp/viper/Effect.cpp b/src/cpp/viper/Effect.cpp deleted file mode 100644 index fe4d8fc..0000000 --- a/src/cpp/viper/Effect.cpp +++ /dev/null @@ -1,112 +0,0 @@ -#include -#include "Effect.h" -#include "constants.h" - -Effect::Effect() { - this->enabled = false; - this->configureOk = false; - this->sampleRate = DEFAULT_SAMPLERATE; - - memset(&this->config, 0, sizeof(effect_config_t)); - - this->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ; - this->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT; // TODO: Try to use PCM_FLOAT instead - this->config.inputCfg.samplingRate = DEFAULT_SAMPLERATE; - this->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; - this->config.inputCfg.mask = AUDIO_PORT_CONFIG_ALL; - - this->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE; - this->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT; // TODO: Try to use PCM_FLOAT instead - this->config.outputCfg.samplingRate = DEFAULT_SAMPLERATE; - this->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; - this->config.outputCfg.mask = AUDIO_PORT_CONFIG_ALL; - - this->buffer = nullptr; - this->bufferSize = 0; - this->instance = nullptr; -} - -Effect::~Effect() { - delete this->buffer; -} - -int32_t Effect::process(audio_buffer_s *in, audio_buffer_s *out) { - // TODO - return -1; -} - -int32_t Effect::command(uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, uint32_t *replySize, void *pReplyData) { - switch (cmdCode) { - case EFFECT_CMD_INIT: - case EFFECT_CMD_SET_CONFIG: // receives effect_config_t - case EFFECT_CMD_SET_PARAM: - case EFFECT_CMD_SET_PARAM_COMMIT: - *((int *) pReplyData) = 0; - case EFFECT_CMD_RESET: - case EFFECT_CMD_SET_PARAM_DEFERRED: - break; - case EFFECT_CMD_SET_CONFIG_REVERSE: - *((int *) pReplyData) = -EINVAL; - default: - return -EINVAL; - case EFFECT_CMD_GET_CONFIG: - memcpy(pReplyData, &this->config, sizeof(effect_config_t)); - break; - } - return 0; -} - -int32_t Effect::configure(effect_config_t *newConfig) { - VIPER_LOGI("Begin audio configure ..."); - VIPER_LOGI("Checking input and output configuration ..."); - - if (newConfig->inputCfg.samplingRate != newConfig->outputCfg.samplingRate) { - VIPER_LOGE("ViPER4Android disabled, reason [in.SR = %d, out.SR = %d]", - newConfig->inputCfg.samplingRate, newConfig->outputCfg.samplingRate); - goto exit_error; - } - - if (newConfig->inputCfg.samplingRate > 48000) { - VIPER_LOGE("ViPER4Android disabled, reason [SR out of range]"); - goto exit_error; - } - - if (newConfig->inputCfg.channels != newConfig->outputCfg.channels) { - VIPER_LOGE("ViPER4Android disabled, reason [in.CH = %d, out.CH = %d]", - newConfig->inputCfg.channels, newConfig->outputCfg.channels); - goto exit_error; - } - - if (newConfig->inputCfg.channels != AUDIO_CHANNEL_OUT_STEREO) { - VIPER_LOGE("ViPER4Android disabled, reason [CH != 2]"); - goto exit_error; - } - - // TODO: Allow multiple formats by converting before/after processing - - if (newConfig->inputCfg.format != AUDIO_FORMAT_PCM_FLOAT) { - VIPER_LOGE("ViPER4Android disabled, reason [in.FMT = %d]", newConfig->inputCfg.format); - VIPER_LOGE("We only accept f32 format"); - goto exit_error; - } - - if (newConfig->outputCfg.format != AUDIO_FORMAT_PCM_FLOAT) { - VIPER_LOGE("ViPER4Android disabled, reason [out.FMT = %d]", newConfig->outputCfg.format); - VIPER_LOGE("We only accept f32 format"); - goto exit_error; - } - - VIPER_LOGI("Input and output configuration checked."); - - memcpy(&this->config, newConfig, sizeof(effect_config_t)); - this->configureOk = true; - - VIPER_LOGI("Audio configure finished"); - - return 0; - -exit_error: - this->configureOk = false; - return -EINVAL; -} - diff --git a/src/cpp/viper/Effect.h b/src/cpp/viper/Effect.h deleted file mode 100644 index 742ff54..0000000 --- a/src/cpp/viper/Effect.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include -#include "essential.h" - -class Effect { -public: - Effect(); - - ~Effect(); - - virtual int32_t command(uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, uint32_t *replySize, void *pReplyData); - - int32_t process(audio_buffer_s *in, audio_buffer_s *out); - - int32_t configure(effect_config_t *config); - - bool enabled; - bool configureOk; - uint32_t sampleRate; - effect_config_t config; - // Misc data here? - - // TODO: Figure out what buffer is used for - float *buffer; - uint32_t bufferSize; - void *instance; // type: ViPER -}; diff --git a/src/cpp/viper/ViPER.cpp b/src/cpp/viper/ViPER.cpp index 8bc5dc8..df1df13 100644 --- a/src/cpp/viper/ViPER.cpp +++ b/src/cpp/viper/ViPER.cpp @@ -1,6 +1,5 @@ #include "ViPER.h" #include -#include "Effect.h" #include "constants.h" ViPER::ViPER() { @@ -12,72 +11,72 @@ ViPER::ViPER() { this->convolver = new Convolver(); this->convolver->SetEnable(false); - this->convolver->SetSamplingRate(this->sampleRate); + this->convolver->SetSamplingRate(this->samplingRate); this->convolver->Reset(); this->vhe = new VHE(); this->vhe->SetEnable(false); - this->vhe->SetSamplingRate(this->sampleRate); + this->vhe->SetSamplingRate(this->samplingRate); this->vhe->Reset(); this->viperDdc = new ViPERDDC(); this->viperDdc->SetEnable(false); - this->viperDdc->SetSamplingRate(this->sampleRate); + this->viperDdc->SetSamplingRate(this->samplingRate); this->viperDdc->Reset(); this->spectrumExtend = new SpectrumExtend(); this->spectrumExtend->SetEnable(false); - this->spectrumExtend->SetSamplingRate(this->sampleRate); + this->spectrumExtend->SetSamplingRate(this->samplingRate); this->spectrumExtend->SetReferenceFrequency(7600); this->spectrumExtend->SetExciter(0); this->spectrumExtend->Reset(); - this->iirFilter = new IIRFilter(); + this->iirFilter = new IIRFilter(10); this->iirFilter->SetEnable(false); - this->iirFilter->SetSamplingRate(this->sampleRate); + this->iirFilter->SetSamplingRate(this->samplingRate); this->iirFilter->Reset(); this->colorfulMusic = new ColorfulMusic(); this->colorfulMusic->SetEnable(false); - this->colorfulMusic->SetSamplingRate(this->sampleRate); + this->colorfulMusic->SetSamplingRate(this->samplingRate); this->colorfulMusic->Reset(); this->reverberation = new Reverberation(); this->reverberation->SetEnable(false); - this->reverberation->SetSamplingRate(this->sampleRate); + this->reverberation->SetSamplingRate(this->samplingRate); this->reverberation->Reset(); this->playbackGain = new PlaybackGain(); this->playbackGain->SetEnable(false); - this->playbackGain->SetSamplingRate(this->sampleRate); + this->playbackGain->SetSamplingRate(this->samplingRate); this->playbackGain->Reset(); this->fetCompressor = new FETCompressor(); this->fetCompressor->SetParameter(0, 0.0); - this->fetCompressor->SetSamplingRate(this->sampleRate); + this->fetCompressor->SetSamplingRate(this->samplingRate); this->fetCompressor->Reset(); this->dynamicSystem = new DynamicSystem(); this->dynamicSystem->SetEnable(false); - this->dynamicSystem->SetSamplingRate(this->sampleRate); + this->dynamicSystem->SetSamplingRate(this->samplingRate); this->dynamicSystem->Reset(); this->viperBass = new ViPERBass(); - this->viperBass->SetSamplingRate(this->sampleRate); + this->viperBass->SetSamplingRate(this->samplingRate); this->viperBass->Reset(); this->viperClarity = new ViPERClarity(); - this->viperClarity->SetSamplingRate(this->sampleRate); + this->viperClarity->SetSamplingRate(this->samplingRate); this->viperClarity->Reset(); this->diffSurround = new DiffSurround(); this->diffSurround->SetEnable(false); - this->diffSurround->SetSamplingRate(this->sampleRate); + this->diffSurround->SetSamplingRate(this->samplingRate); this->diffSurround->Reset(); this->cure = new Cure(); this->cure->SetEnable(false); - this->cure->SetSamplingRate(this->sampleRate); + this->cure->SetSamplingRate(this->samplingRate); this->cure->Reset(); this->tubeSimulator = new TubeSimulator(); @@ -86,13 +85,13 @@ ViPER::ViPER() { this->analogX = new AnalogX(); // this->analogX->SetEnable(false); - this->analogX->SetSamplingRate(this->sampleRate); + this->analogX->SetSamplingRate(this->samplingRate); this->analogX->SetProcessingModel(0); this->analogX->Reset(); this->speakerCorrection = new SpeakerCorrection(); this->speakerCorrection->SetEnable(false); - this->speakerCorrection->SetSamplingRate(this->sampleRate); + this->speakerCorrection->SetSamplingRate(this->samplingRate); this->speakerCorrection->Reset(); for (auto &softwareLimiter: this->softwareLimiters) { @@ -136,143 +135,10 @@ ViPER::~ViPER() { } } -int32_t -ViPER::command(uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, uint32_t *replySize, void *pReplyData) { - switch (cmdCode) { - case EFFECT_CMD_ENABLE: { - if (!this->enabled) { - ResetAllEffects(); - break; - } - return 0; - } - case EFFECT_CMD_RESET: { - ResetAllEffects(); - break; - } - case EFFECT_CMD_SET_CONFIG: { - if (cmdSize != 64 || *replySize != 4) { - return -EINVAL; - } - - auto currentSampleRate = this->sampleRate; - - *(int32_t *) pReplyData = this->configure((effect_config_t *) pCmdData); - if (*(int32_t *) pReplyData == 0) { - if (currentSampleRate != this->sampleRate) { - ResetAllEffects(); - } - } - - return 0; - } - case EFFECT_CMD_SET_PARAM: { - auto pCmdParam = (effect_param_t *) pCmdData; - - if (pCmdParam->psize != sizeof(int32_t)) { - *(int32_t *) pReplyData = -EINVAL; - return 0; - } - - // TODO: implement - } - case EFFECT_CMD_GET_PARAM: { - auto *pCmdParam = (effect_param_t *) pCmdData; - auto *pReplyParam = (effect_param_t *) pReplyData; - - if (pCmdParam->psize != sizeof(int32_t)) break; - - switch (*(int *) pCmdParam->data) { - case PARAM_GET_DRIVER_VERSION: { - pReplyParam->status = 0; - //pReplyParam->psize = sizeof(int32_t); // TODO - pReplyParam->vsize = sizeof(int32_t); - *(int32_t *) pReplyParam->data = 0x2050004; // As original, change as needed - *replySize = 0x14; // As original, TODO: calculate correctly - return 0; - } - case PARAM_GET_NEONENABLED: { - pReplyParam->status = 0; - //pReplyParam->psize = sizeof(int32_t); // TODO - pReplyParam->vsize = sizeof(int32_t); - *(int32_t *) pReplyParam->data = 1; // TODO: check if neon is enabled - *replySize = 0x14; // As original, TODO: calculate correctly - return 0; - } - case PARAM_GET_ENABLED: { - pReplyParam->status = 0; - //pReplyParam->psize = sizeof(int32_t); // TODO - pReplyParam->vsize = sizeof(int32_t); - *(int32_t *) pReplyParam->data = this->enabled; - *replySize = 0x14; // As original, TODO: calculate correctly - return 0; - } - case PARAM_GET_CONFIGURE: { - pReplyParam->status = 0; - //pReplyParam->psize = sizeof(int32_t); // TODO - pReplyParam->vsize = sizeof(int32_t); - *(int32_t *) pReplyParam->data = this->configureOk; - *replySize = 0x14; // As original, TODO: calculate correctly - return 0; - } - case PARAM_GET_DRVCANWORK: { - pReplyParam->status = 0; - //pReplyParam->psize = sizeof(int32_t); // TODO - pReplyParam->vsize = sizeof(int32_t); - *(int32_t *) pReplyParam->data = this->init_ok; - *replySize = 0x14; // As original, TODO: calculate correctly - return 0; - } - case PARAM_GET_STREAMING: { - struct timeval time{}; - gettimeofday(&time, nullptr); - - // TODO: Do some calculations - - return 0; - } - case PARAM_GET_EFFECT_TYPE: { - pReplyParam->status = 0; - //pReplyParam->psize = sizeof(int32_t); // TODO - pReplyParam->vsize = sizeof(int32_t); - *(int32_t *) pReplyParam->data = 1; //this->mode; TODO: This driver is not using any effect type, it's completely controlled by the frontend - *replySize = 0x14; // As original, TODO: calculate correctly - return 0; - } - case PARAM_GET_SAMPLINGRATE: { - pReplyParam->status = 0; - //pReplyParam->psize = sizeof(int32_t); // TODO - pReplyParam->vsize = sizeof(int32_t); - *(uint32_t *) pReplyParam->data = this->sampleRate; - *replySize = 0x14; // As original, TODO: calculate correctly - return 0; - } - case PARAM_GET_CONVUSABLE: { - pReplyParam->status = 0; - //pReplyParam->psize = sizeof(int32_t); // TODO - pReplyParam->vsize = sizeof(int32_t); - *(int32_t *) pReplyParam->data = 1; // TODO: Figure out what is this - *replySize = 0x14; // As original, TODO: calculate correctly - return 0; - } - case PARAM_GET_CONVKNLID: { - pReplyParam->status = 0; - //pReplyParam->psize = sizeof(int32_t); // TODO - pReplyParam->vsize = sizeof(int32_t); - *(uint32_t *) pReplyParam->data = this->convolver->GetKernelID(); - *replySize = 0x14; // As original, TODO: calculate correctly - return 0; - } - } - } - } - - return this->Effect::command(cmdCode, cmdSize, pCmdData, replySize, pReplyData); -} - -void ViPER::processBuffer(float *buffer, int frameSize) { +// TODO: Return int +void ViPER::processBuffer(float *buffer, uint32_t size) { if (!this->enabled) return; - if (frameSize < 1) return; + if (size == 0) return; if (!this->init_ok) return; if (this->update_status) { @@ -284,18 +150,18 @@ void ViPER::processBuffer(float *buffer, int frameSize) { uint32_t ret; // if convolver is enabled - ret = this->waveBuffer->PushSamples(buffer, frameSize); + ret = this->waveBuffer->PushSamples(buffer, size); if (ret == 0) { this->waveBuffer->Reset(); return; } auto pWaveBuffer = this->waveBuffer->GetBuffer(); - this->convolver->Process(pWaveBuffer, pWaveBuffer, frameSize); - this->vhe->Process(pWaveBuffer, pWaveBuffer, frameSize); - this->waveBuffer->SetBufferOffset(frameSize); + this->convolver->Process(pWaveBuffer, pWaveBuffer, size); + this->vhe->Process(pWaveBuffer, pWaveBuffer, size); + this->waveBuffer->SetBufferOffset(size); - ret = this->adaptiveBuffer->PushZero(frameSize); + ret = this->adaptiveBuffer->PushZero(size); if (ret == 0) { this->waveBuffer->Reset(); this->adaptiveBuffer->FlushBuffer(); @@ -303,13 +169,13 @@ void ViPER::processBuffer(float *buffer, int frameSize) { } auto pAdaptiveBuffer = this->adaptiveBuffer->GetBufferPointer(); - ret = this->waveBuffer->PopSamples((float *) pAdaptiveBuffer, frameSize, true); + ret = this->waveBuffer->PopSamples((float *) pAdaptiveBuffer, size, true); this->adaptiveBuffer->SetBufferOffset(ret); pAdaptiveBuffer = this->adaptiveBuffer->GetBufferPointer(); if (ret != 0) { - this->viperDdc->Process(pAdaptiveBuffer, frameSize); - this->spectrumExtend->Process(pAdaptiveBuffer, frameSize); + this->viperDdc->Process(pAdaptiveBuffer, size); + this->spectrumExtend->Process(pAdaptiveBuffer, size); this->iirFilter->Process(pAdaptiveBuffer, ret); this->colorfulMusic->Process(pAdaptiveBuffer, ret); this->diffSurround->Process(pAdaptiveBuffer, ret); @@ -321,7 +187,7 @@ void ViPER::processBuffer(float *buffer, int frameSize) { this->viperBass->Process(pAdaptiveBuffer, ret); this->viperClarity->Process(pAdaptiveBuffer, ret); this->cure->Process(pAdaptiveBuffer, ret); - this->tubeSimulator->TubeProcess(pAdaptiveBuffer, frameSize); + this->tubeSimulator->TubeProcess(pAdaptiveBuffer, size); this->analogX->Process(pAdaptiveBuffer, ret); } @@ -351,70 +217,70 @@ void ViPER::ResetAllEffects() { this->waveBuffer->Reset(); } if (this->convolver != nullptr) { - this->convolver->SetSamplingRate(this->sampleRate); + this->convolver->SetSamplingRate(this->samplingRate); this->convolver->Reset(); } if (this->vhe != nullptr) { - this->vhe->SetSamplingRate(this->sampleRate); + this->vhe->SetSamplingRate(this->samplingRate); this->vhe->Reset(); } if (this->viperDdc != nullptr) { - this->viperDdc->SetSamplingRate(this->sampleRate); + this->viperDdc->SetSamplingRate(this->samplingRate); this->viperDdc->Reset(); } if (this->spectrumExtend != nullptr) { - this->spectrumExtend->SetSamplingRate(this->sampleRate); + this->spectrumExtend->SetSamplingRate(this->samplingRate); this->spectrumExtend->Reset(); } if (this->iirFilter != nullptr) { - this->iirFilter->SetSamplingRate(this->sampleRate); + this->iirFilter->SetSamplingRate(this->samplingRate); this->iirFilter->Reset(); } if (this->colorfulMusic != nullptr) { - this->colorfulMusic->SetSamplingRate(this->sampleRate); + this->colorfulMusic->SetSamplingRate(this->samplingRate); this->colorfulMusic->Reset(); } if (this->reverberation != nullptr) { - this->reverberation->SetSamplingRate(this->sampleRate); + this->reverberation->SetSamplingRate(this->samplingRate); this->reverberation->Reset(); } if (this->playbackGain != nullptr) { - this->playbackGain->SetSamplingRate(this->sampleRate); + this->playbackGain->SetSamplingRate(this->samplingRate); this->playbackGain->Reset(); } if (this->fetCompressor != nullptr) { - this->fetCompressor->SetSamplingRate(this->sampleRate); + this->fetCompressor->SetSamplingRate(this->samplingRate); this->fetCompressor->Reset(); } if (this->dynamicSystem != nullptr) { - this->dynamicSystem->SetSamplingRate(this->sampleRate); + this->dynamicSystem->SetSamplingRate(this->samplingRate); this->dynamicSystem->Reset(); } if (this->viperBass != nullptr) { - this->viperBass->SetSamplingRate(this->sampleRate); + this->viperBass->SetSamplingRate(this->samplingRate); this->viperBass->Reset(); } if (this->viperClarity != nullptr) { - this->viperClarity->SetSamplingRate(this->sampleRate); + this->viperClarity->SetSamplingRate(this->samplingRate); this->viperClarity->Reset(); } if (this->diffSurround != nullptr) { - this->diffSurround->SetSamplingRate(this->sampleRate); + this->diffSurround->SetSamplingRate(this->samplingRate); this->diffSurround->Reset(); } if (this->cure != nullptr) { - this->cure->SetSamplingRate(this->sampleRate); + this->cure->SetSamplingRate(this->samplingRate); this->cure->Reset(); } if (this->tubeSimulator != nullptr) { this->tubeSimulator->Reset(); } if (this->analogX != nullptr) { - this->analogX->SetSamplingRate(this->sampleRate); + this->analogX->SetSamplingRate(this->samplingRate); this->analogX->Reset(); } if (this->speakerCorrection != nullptr) { - this->speakerCorrection->SetSamplingRate(this->sampleRate); + this->speakerCorrection->SetSamplingRate(this->samplingRate); this->speakerCorrection->Reset(); } for (auto &softwareLimiter: softwareLimiters) { diff --git a/src/cpp/viper/ViPER.h b/src/cpp/viper/ViPER.h index aaf0822..fb6e5f8 100644 --- a/src/cpp/viper/ViPER.h +++ b/src/cpp/viper/ViPER.h @@ -1,6 +1,5 @@ #pragma once -#include "Effect.h" #include "utils/WaveBuffer.h" #include "effects/SpectrumExtend.h" #include "effects/Reverberation.h" @@ -23,29 +22,22 @@ #include "effects/PlaybackGain.h" #include "../ViPER4Android.h" -class ViPER : public Effect { +class ViPER { public: ViPER(); - ~ViPER(); - int32_t command(uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, uint32_t *replySize, void *pReplyData) override; - - void processBuffer(float *buffer, int frameSize); - + void processBuffer(float *buffer, uint32_t size); // TODO: Parameter types/names void DispatchCommand(int param_1, int param_2, int param_3, int param_4, int param_5, int param_6, int param_7); - void ResetAllEffects(); bool update_status; - // Something or padding of 3 bytes uint64_t process_time_ms; bool init_ok; bool enabled; bool force_enabled; - // Something or padding of 1 byte - // FxMode mode; + uint32_t samplingRate; // Effects AdaptiveBuffer *adaptiveBuffer; diff --git a/src/cpp/viper/effects/IIRFilter.cpp b/src/cpp/viper/effects/IIRFilter.cpp index b4bb5b9..9056fd8 100644 --- a/src/cpp/viper/effects/IIRFilter.cpp +++ b/src/cpp/viper/effects/IIRFilter.cpp @@ -8,7 +8,7 @@ IIRFilter::IIRFilter(uint32_t bands) { this->samplingRate = DEFAULT_SAMPLERATE; if (bands == 10 || bands == 15 || bands == 25 || bands == 31) { this->bands = bands; - this->coeffs.UpdateCoeffs(bands,this->samplingRate); + this->minPhaseIirCoeffs.UpdateCoeffs(bands, this->samplingRate); } else { this->bands = 0; } @@ -25,14 +25,32 @@ IIRFilter::~IIRFilter() { } void IIRFilter::Process(float *samples, uint32_t size) { + if (!this->enable) return; + float *coeffs = this->minPhaseIirCoeffs.GetCoefficients(); + if (coeffs == nullptr || size == 0) return; + + for (uint32_t i = 0; i < size; i++) { + for (uint32_t j = 0; j < 2; j++) { + float tmp = 0.0; + for (uint32_t k = 0; k < this->bands * 16; k++) { + samples[2 * i + j]; + } + + samples[2 * i + j] = tmp; + } + + this->unknown2 = (this->unknown2 + 1) % 3; + this->unknown3 = (this->unknown3 + 1) % 3; + this->unknown4 = (this->unknown4 + 1) % 3; + } } void IIRFilter::Reset() { memset(this->buf,0,0x7c0); -// this->unknown3 = 1; -// this->unknown2 = 2; -// this->unknown4 = 0; + this->unknown3 = 1; + this->unknown2 = 2; + this->unknown4 = 0; } void IIRFilter::SetBandLevel(uint32_t band, float level) { @@ -49,7 +67,7 @@ void IIRFilter::SetEnable(bool enable) { void IIRFilter::SetSamplingRate(uint32_t samplingRate) { this->samplingRate = samplingRate; if (this->bands != 0) { - this->coeffs->UpdateCoeffs(bands, samplingRate); + this->minPhaseIirCoeffs.UpdateCoeffs(bands, samplingRate); } this->Reset(); } diff --git a/src/cpp/viper/effects/IIRFilter.h b/src/cpp/viper/effects/IIRFilter.h index f9a1dab..329ab02 100644 --- a/src/cpp/viper/effects/IIRFilter.h +++ b/src/cpp/viper/effects/IIRFilter.h @@ -18,9 +18,11 @@ private: uint32_t bands; uint32_t samplingRate; bool enable; - MinPhaseIIRCoeffs coeffs; + MinPhaseIIRCoeffs minPhaseIirCoeffs; float buf[496]; - // 3 unknown + uint32_t unknown2; + uint32_t unknown3; + uint32_t unknown4; float bandLevelsWithQ[31]; }; diff --git a/src/cpp/viper/effects/SoftwareLimiter.h b/src/cpp/viper/effects/SoftwareLimiter.h index 60b7e7f..9835e5d 100644 --- a/src/cpp/viper/effects/SoftwareLimiter.h +++ b/src/cpp/viper/effects/SoftwareLimiter.h @@ -5,7 +5,6 @@ class SoftwareLimiter { public: SoftwareLimiter(); - ~SoftwareLimiter(); void Process(float *samples, uint32_t size); void ResetLimiter(); diff --git a/src/cpp/viper/utils/Harmonic.cpp b/src/cpp/viper/utils/Harmonic.cpp index 57d4ffa..591e23f 100644 --- a/src/cpp/viper/utils/Harmonic.cpp +++ b/src/cpp/viper/utils/Harmonic.cpp @@ -40,18 +40,18 @@ float Harmonic::Process(float sample) { sample * this->coeffs[9] + sample * this->coeffs[10] ); - this->prevOut = this->lastProcessed + this->prevOut * 0.999f - prevLast; + this->prevOut = (this->lastProcessed + this->prevOut * 0.999f) - prevLast; if (this->sampleCounter < this->buildup) { this->sampleCounter++; - return 0; + return 0.0; } return this->prevOut; } void Harmonic::Reset() { - this->lastProcessed = 0.f; - this->prevOut = 0.f; - this->sampleCounter = 0.f; + this->lastProcessed = 0.0; + this->prevOut = 0.0; + this->sampleCounter = 0; } void Harmonic::SetHarmonics(float *coefficients) { diff --git a/src/cpp/viper/utils/Harmonic.h b/src/cpp/viper/utils/Harmonic.h index 012076f..bf10a33 100644 --- a/src/cpp/viper/utils/Harmonic.h +++ b/src/cpp/viper/utils/Harmonic.h @@ -1,27 +1,23 @@ #pragma once - #include class Harmonic { public: Harmonic(); - ~Harmonic(); float Process(float sample); - void Reset(); - void SetHarmonics(float *coeffs); - void UpdateCoeffs(float *coeffs); +private: float coeffs[11]; float lastProcessed; float prevOut; - int buildup; - int sampleCounter; + uint32_t buildup; + uint32_t sampleCounter; }; diff --git a/src/cpp/viper/utils/Stereo3DSurround.cpp b/src/cpp/viper/utils/Stereo3DSurround.cpp index f71df3d..a93c953 100644 --- a/src/cpp/viper/utils/Stereo3DSurround.cpp +++ b/src/cpp/viper/utils/Stereo3DSurround.cpp @@ -3,22 +3,47 @@ Stereo3DSurround::Stereo3DSurround() { this->middleImage = 1.0; this->stereoWiden = 0.0; - this->unknown1 = 1.0; - this->unknown2 = 0.5; this->coeffLeft = 0.5; this->coeffRight = 0.5; } void Stereo3DSurround::Process(float *samples, uint32_t size) { - if (size >= 2) { + if (size == 0) return; + uint32_t pairs = size / 2; + uint32_t remainder = size % 2; + + if (pairs > 0) { + for (uint32_t i = 0; i < pairs; i++) { + float a = this->coeffLeft * (samples[4 * i] + samples[4 * i + 1]); + float b = this->coeffRight * (samples[4 * i + 1] - samples[4 * i]); + float c = this->coeffLeft * (samples[4 * i + 2] + samples[4 * i + 3]); + float d = this->coeffRight * (samples[4 * i + 3] - samples[4 * i + 2]); + + samples[4 * i] = a - b; + samples[4 * i + 1] = a + b; + samples[4 * i + 2] = c - d; + samples[4 * i + 3] = c + d; + } + } + + if (remainder > 0) { + for (uint32_t i = pairs; i < pairs + remainder; i++) { + float a = samples[2 * i]; + float b = samples[2 * i + 1]; + float c = this->coeffLeft * (a + b); + float d = this->coeffRight * (b - a); + + samples[2 * i] = c - d; + samples[2 * i + 1] = c + d; + } } } inline void Stereo3DSurround::ConfigureVariables() { - this->unknown1 = this->stereoWiden + 1.0f; + float tmp = this->stereoWiden + 1.0f; - float x = this->unknown1 + 1.0f; + float x = tmp + 1.0f; float y; if (x < 2.0) { y = 0.5; @@ -26,9 +51,8 @@ inline void Stereo3DSurround::ConfigureVariables() { y = 1.0f / x; } - this->unknown2 = y; this->coeffLeft = this->middleImage * y; - this->coeffRight = this->unknown1 * y; + this->coeffRight = tmp * y; } void Stereo3DSurround::SetMiddleImage(float middleImage) { diff --git a/src/cpp/viper/utils/Stereo3DSurround.h b/src/cpp/viper/utils/Stereo3DSurround.h index e252900..cd32643 100644 --- a/src/cpp/viper/utils/Stereo3DSurround.h +++ b/src/cpp/viper/utils/Stereo3DSurround.h @@ -15,8 +15,6 @@ private: float stereoWiden; float middleImage; - float unknown1; - float unknown2; float coeffLeft; float coeffRight; }; diff --git a/src/include/essential.h b/src/include/essential.h index 242d2f3..8e43b81 100644 --- a/src/include/essential.h +++ b/src/include/essential.h @@ -1,3 +1,5 @@ +#pragma once + // Source: https://android.googlesource.com/platform/system/media/+/master/audio/include/system typedef struct effect_uuid_s