From 39aef2206287ee3a636449599b186ad42b9d063c Mon Sep 17 00:00:00 2001 From: Iscle Date: Tue, 11 Oct 2022 00:36:38 +0200 Subject: [PATCH] Update --- src/cpp/ViPER4Android.cpp | 287 +++++++++----------- src/cpp/ViPER4Android.h | 79 +----- src/cpp/viper/ViPER.cpp | 207 +++----------- src/cpp/viper/ViPER.h | 10 +- src/cpp/viper/effects/AnalogX.cpp | 37 ++- src/cpp/viper/effects/AnalogX.h | 3 +- src/cpp/viper/effects/IIRFilter.cpp | 10 +- src/cpp/viper/effects/SpeakerCorrection.cpp | 16 +- src/cpp/viper/effects/SpectrumExtend.cpp | 16 +- src/cpp/viper/effects/TubeSimulator.cpp | 15 +- src/cpp/viper/effects/TubeSimulator.h | 4 +- src/cpp/viper/effects/ViPERBass.cpp | 32 ++- src/cpp/viper/effects/ViPERBass.h | 4 +- src/cpp/viper/effects/ViPERClarity.cpp | 22 +- src/cpp/viper/effects/ViPERClarity.h | 2 + src/cpp/viper/utils/AdaptiveBuffer.cpp | 8 +- src/cpp/viper/utils/Biquad.cpp | 128 +++++---- src/cpp/viper/utils/Biquad.h | 10 +- src/cpp/viper/utils/FIR.cpp | 6 +- src/cpp/viper/utils/MinPhaseIIRCoeffs.cpp | 22 +- src/cpp/viper/utils/Polyphase.cpp | 18 +- 21 files changed, 407 insertions(+), 529 deletions(-) diff --git a/src/cpp/ViPER4Android.cpp b/src/cpp/ViPER4Android.cpp index 79fc06d..dc8aaeb 100644 --- a/src/cpp/ViPER4Android.cpp +++ b/src/cpp/ViPER4Android.cpp @@ -1,7 +1,5 @@ #include -#include #include - #include "viper/ViPER.h" #include "essential.h" #include "log.h" @@ -10,7 +8,6 @@ #define VIPER_EFFECT_NAME "ViPER4Android" static effect_descriptor_t viper_descriptor = { - // ee48cf24-9221-4095-2cb9-40faa133111b .type = EFFECT_UUID_INITIALIZER, // 41d3c987-e6cf-11e3-a88a-11aba5d5c51b // Original: {0x41d3c987, 0xe6cf, 0x11e3, 0xa88a, {0x11, 0xab, 0xa5, 0xd5, 0xc5, 0x1b}} @@ -28,18 +25,13 @@ extern "C" { struct ViperContext { const struct effect_interface_s *interface; // Should always be the first struct member effect_config_t config; + bool isConfigValid; ViPER *viper; }; static int32_t Viper_IProcess(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) { auto pContext = reinterpret_cast(self); - static uint32_t tmp = 0; - if (tmp % 50 == 0) { - VIPER_LOGD("Viper_IProcess called!"); - } - tmp++; - if (pContext == nullptr || inBuffer == nullptr || outBuffer == nullptr || inBuffer->raw == nullptr || outBuffer->raw == nullptr || @@ -55,12 +47,12 @@ static int32_t Viper_IProcess(effect_handle_t self, audio_buffer_t *inBuffer, au memcpy(outBufferPtr, inBufferPtr, outBuffer->frameCount * 2 * sizeof(float)); } - /*return */pContext->viper->processBuffer(outBufferPtr, outBuffer->frameCount); - return 0; // TODO: Return code from processBuffer() + pContext->viper->processBuffer(outBufferPtr, outBuffer->frameCount); + return 0; } -static int configure(ViperContext *pContext, effect_config_t *newConfig) { - VIPER_LOGI("Begin audio configure ..."); +static int handleSetConfig(ViperContext *pContext, effect_config_t *newConfig) { + VIPER_LOGI("Begin handleSetConfig ..."); VIPER_LOGI("Checking input and output configuration ..."); VIPER_LOGD("Input sampling rate: %d", newConfig->inputCfg.samplingRate); @@ -70,6 +62,8 @@ static int configure(ViperContext *pContext, effect_config_t *newConfig) { VIPER_LOGD("Output channels: %d", newConfig->outputCfg.channels); VIPER_LOGD("Output format: %d", newConfig->outputCfg.format); + pContext->isConfigValid = false; + if (newConfig->inputCfg.samplingRate != newConfig->outputCfg.samplingRate) { VIPER_LOGE("ViPER4Android disabled, reason [in.SR = %d, out.SR = %d]", newConfig->inputCfg.samplingRate, newConfig->outputCfg.samplingRate); @@ -109,19 +103,127 @@ static int configure(ViperContext *pContext, effect_config_t *newConfig) { VIPER_LOGI("Input and output configuration checked."); pContext->config = *newConfig; + pContext->viper->samplingRate = newConfig->inputCfg.samplingRate; + pContext->viper->ResetAllEffects(); + pContext->isConfigValid = true; - VIPER_LOGI("Audio configure finished"); + VIPER_LOGI("Audio handleSetConfig finished"); return 0; } +static int32_t handleSetParam(ViperContext *pContext, effect_param_t *pCmdParam, void *pReplyData) { + // The value offset of an effect parameter is computed by rounding up + // the parameter size to the next 32 bit alignment. + uint32_t vOffset = ((pCmdParam->psize + sizeof(int32_t) - 1) / sizeof(int32_t)) * sizeof(int32_t); + + *(int *) pReplyData = 0; + + int param = *(int *) (pCmdParam->data); + int *intValues = (int *) (pCmdParam->data + vOffset); + if (pCmdParam->vsize == sizeof(int)) { + pContext->viper->DispatchCommand(param, intValues[0], 0, 0, 0, 0, nullptr); + return 0; + } else if (pCmdParam->vsize == sizeof(int) * 2) { + pContext->viper->DispatchCommand(param, intValues[0], intValues[1], 0, 0, 0, nullptr); + return 0; + } else if (pCmdParam->vsize == sizeof(int) * 3) { + pContext->viper->DispatchCommand(param, intValues[0], intValues[1], intValues[2], 0, 0, nullptr); + return 0; + } else if (pCmdParam->vsize == sizeof(int) * 4) { + pContext->viper->DispatchCommand(param, intValues[0], intValues[1], intValues[2], intValues[3], 0, nullptr); + return 0; + } else if (pCmdParam->vsize == 256 || pCmdParam->vsize == 1024) { + uint32_t arrSize = *(uint32_t *) (pCmdParam->data + vOffset); + signed char *arr = (signed char *) (pCmdParam->data + vOffset + sizeof(uint32_t)); + pContext->viper->DispatchCommand(param, 0, 0, 0, 0, arrSize, arr); + return 0; + } else if (pCmdParam->vsize == 8192) { + int value1 = *(int *) (pCmdParam->data + vOffset); + uint32_t arrSize = *(uint32_t *) (pCmdParam->data + vOffset + sizeof(int)); + signed char *arr = (signed char *) (pCmdParam->data + vOffset + sizeof(int) + sizeof(uint32_t)); + pContext->viper->DispatchCommand(param, value1, 0, 0, 0, arrSize, arr); + return 0; + } + + return -EINVAL; +} + +static int32_t handleGetParam(ViperContext *pContext, effect_param_t *pCmdParam, effect_param_t *pReplyParam, uint32_t *pReplySize) { + // The value offset of an effect parameter is computed by rounding up + // the parameter size to the next 32 bit alignment. + uint32_t vOffset = ((pCmdParam->psize + sizeof(int32_t) - 1) / sizeof(int32_t)) * sizeof(int32_t); + + VIPER_LOGD("Viper_ICommand() EFFECT_CMD_GET_PARAM called with data = %d, psize = %d, vsize = %d", *(uint32_t *) pCmdParam->data, pCmdParam->psize, pCmdParam->vsize); + + memcpy(pReplyParam, pCmdParam, sizeof(effect_param_t) + pCmdParam->psize); + + switch (*(uint32_t *) pCmdParam->data) { + case PARAM_GET_DRIVER_VERSION: { + pReplyParam->status = 0; + pReplyParam->vsize = sizeof(uint32_t); + *(uint32_t *) (pReplyParam->data + vOffset) = 0x2050005; // As original, change as needed + *pReplySize = sizeof(effect_param_t) + pReplyParam->psize + vOffset + pReplyParam->vsize; + return 0; + } + case PARAM_GET_ENABLED: { + pReplyParam->status = 0; + pReplyParam->vsize = sizeof(int32_t); + *(int32_t *) (pReplyParam->data + vOffset) = pContext->viper->enabled; + *pReplySize = sizeof(effect_param_t) + pReplyParam->psize + vOffset + pReplyParam->vsize; + return 0; + } + case PARAM_GET_CONFIGURE: { + pReplyParam->status = 0; + pReplyParam->vsize = sizeof(int32_t); + *(int32_t *) (pReplyParam->data + vOffset) = pContext->isConfigValid; + *pReplySize = sizeof(effect_param_t) + pReplyParam->psize + vOffset + pReplyParam->vsize; + return 0; + } + case PARAM_GET_STREAMING: { // Is processing + struct timeval time{}; + gettimeofday(&time, nullptr); + + uint64_t currentMs = (time.tv_sec * 1000) + (time.tv_usec / 1000); + uint64_t lastProcessTime = pContext->viper->processTimeMs; + + uint64_t diff; + if (currentMs > lastProcessTime) { + diff = currentMs - lastProcessTime; + } else { + diff = lastProcessTime - currentMs; + } + + pReplyParam->status = 0; + pReplyParam->vsize = sizeof(int32_t); + *(int32_t *) (pReplyParam->data + vOffset) = diff > 5000 ? 0 : 1; + *pReplySize = sizeof(effect_param_t) + pReplyParam->psize + vOffset + pReplyParam->vsize; + return 0; + } + case PARAM_GET_SAMPLING_RATE: { + pReplyParam->status = 0; + pReplyParam->vsize = sizeof(uint32_t); + *(uint32_t *) (pReplyParam->data + vOffset) = pContext->viper->samplingRate; + *pReplySize = sizeof(effect_param_t) + pReplyParam->psize + vOffset + pReplyParam->vsize; + return 0; + } + case PARAM_GET_CONVOLUTION_KERNEL_ID: { + pReplyParam->status = 0; + pReplyParam->vsize = sizeof(uint32_t); + *(uint32_t *) (pReplyParam->data + vOffset) = pContext->viper->convolver->GetKernelID(); + *pReplySize = sizeof(effect_param_t) + pReplyParam->psize + vOffset + pReplyParam->vsize; + return 0; + } + } + 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 = reinterpret_cast(self); if (pContext == nullptr || pContext->viper == nullptr) { - VIPER_LOGE("Viper_ICommand: pContext or pContext->viper is null!"); return -EINVAL; } @@ -131,25 +233,16 @@ static int32_t Viper_ICommand(effect_handle_t self, *((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(); - } - } - + *(int *) pReplyData = handleSetConfig(pContext, (effect_config_t *) pCmdData); return 0; } case EFFECT_CMD_RESET: { pContext->viper->ResetAllEffects(); - break; + *((int *) pReplyData) = 0; + return 0; } case EFFECT_CMD_ENABLE: { - if (!pContext->viper->enabled) { - pContext->viper->ResetAllEffects(); - } + pContext->viper->ResetAllEffects(); pContext->viper->enabled = true; *((int *) pReplyData) = 0; return 0; @@ -160,108 +253,10 @@ static int32_t Viper_ICommand(effect_handle_t self, return 0; } case EFFECT_CMD_SET_PARAM: { - auto *pCmdParam = reinterpret_cast(pCmdData); - // The value offset of an effect parameter is computed by rounding up - // the parameter size to the next 32 bit alignment. - uint32_t vOffset = ((pCmdParam->psize + sizeof(int32_t) - 1) / sizeof(int32_t)) * sizeof(int32_t); - - int param = *(int *) (pCmdParam->data); - *(int *) pReplyData = 0; - - int *intValues = (int *) (pCmdParam->data + vOffset); - if (pCmdParam->vsize == sizeof(int)) { - pContext->viper->DispatchCommand(param, intValues[0], 0, 0, 0, 0, nullptr); - return 0; - } else if (pCmdParam->vsize == sizeof(int) * 2) { - pContext->viper->DispatchCommand(param, intValues[0], intValues[1], 0, 0, 0, nullptr); - return 0; - } else if (pCmdParam->vsize == sizeof(int) * 3) { - pContext->viper->DispatchCommand(param, intValues[0], intValues[1], intValues[2], 0, 0, nullptr); - return 0; - } else if (pCmdParam->vsize == sizeof(int) * 4) { - pContext->viper->DispatchCommand(param, intValues[0], intValues[1], intValues[2], intValues[3], 0, nullptr); - return 0; - } else if (pCmdParam->vsize == 256 || pCmdParam->vsize == 1024) { - uint32_t arrSize = *(uint32_t *) (pCmdParam->data + vOffset); - signed char *arr = (signed char *) (pCmdParam->data + vOffset + sizeof(uint32_t)); - pContext->viper->DispatchCommand(param, 0, 0, 0, 0, arrSize, arr); - return 0; - } else if (pCmdParam->vsize == 8192) { - int value1 = *(int *) (pCmdParam->data + vOffset); - uint32_t arrSize = *(uint32_t *) (pCmdParam->data + vOffset + sizeof(int)); - signed char *arr = (signed char *) (pCmdParam->data + vOffset + sizeof(int) + sizeof(uint32_t)); - pContext->viper->DispatchCommand(param, value1, 0, 0, 0, arrSize, arr); - return 0; - } + return handleSetParam(pContext, (effect_param_t *) pCmdData, pReplyData); } case EFFECT_CMD_GET_PARAM: { - auto *pCmdParam = reinterpret_cast(pCmdData); - auto *pReplyParam = reinterpret_cast(pReplyData); - // The value offset of an effect parameter is computed by rounding up - // the parameter size to the next 32 bit alignment. - uint32_t vOffset = ((pCmdParam->psize + sizeof(int32_t) - 1) / sizeof(int32_t)) * sizeof(int32_t); - - VIPER_LOGD("Viper_ICommand() EFFECT_CMD_GET_PARAM called with data = %d, psize = %d, vsize = %d", *(uint32_t *) pCmdParam->data, pCmdParam->psize, pCmdParam->vsize); - - //memcpy(pReplyParam, pCmdParam, sizeof(effect_param_t) + pCmdParam->psize); - - switch (*(uint32_t *) pCmdParam->data) { - case PARAM_GET_DRIVER_VERSION: { - pReplyParam->status = 0; - pReplyParam->vsize = sizeof(uint32_t); - *(uint32_t *) (pReplyParam->data + vOffset) = 0x2050005; // As original, change as needed - *replySize = sizeof(effect_param_t) + pReplyParam->psize + vOffset + pReplyParam->vsize; - return 0; - } - case PARAM_GET_ENABLED: { - pReplyParam->status = 0; - pReplyParam->vsize = sizeof(int32_t); - *(int32_t *) (pReplyParam->data + vOffset) = pContext->viper->enabled; - *replySize = sizeof(effect_param_t) + pReplyParam->psize + vOffset + pReplyParam->vsize; - return 0; - } - case PARAM_GET_CONFIGURE: { - pReplyParam->status = 0; - pReplyParam->vsize = sizeof(int32_t); - *(int32_t *) (pReplyParam->data + vOffset) = 1; // TODO? - *replySize = sizeof(effect_param_t) + pReplyParam->psize + vOffset + pReplyParam->vsize; - return 0; - } - case PARAM_GET_STREAMING: { // Is processing - struct timeval time{}; - gettimeofday(&time, nullptr); - - uint64_t currentMs = (time.tv_sec * 1000) + (time.tv_usec / 1000); - uint64_t lastProcessTime = pContext->viper->process_time_ms; - - uint64_t diff; - if (currentMs > lastProcessTime) { - diff = currentMs - lastProcessTime; - } else { - diff = lastProcessTime - currentMs; - } - - pReplyParam->status = 0; - pReplyParam->vsize = sizeof(int32_t); - *(int32_t *) (pReplyParam->data + vOffset) = diff > 5000 ? 0 : 1; - *replySize = sizeof(effect_param_t) + pReplyParam->psize + vOffset + pReplyParam->vsize; - return 0; - } - case PARAM_GET_SAMPLINGRATE: { - pReplyParam->status = 0; - pReplyParam->vsize = sizeof(uint32_t); - *(uint32_t *) (pReplyParam->data + vOffset) = pContext->viper->samplingRate; - *replySize = sizeof(effect_param_t) + pReplyParam->psize + vOffset + pReplyParam->vsize; - return 0; - } - case PARAM_GET_CONVKNLID: { - pReplyParam->status = 0; - pReplyParam->vsize = sizeof(uint32_t); - *(uint32_t *) (pReplyParam->data + vOffset) = pContext->viper->convolver->GetKernelID(); - *replySize = sizeof(effect_param_t) + pReplyParam->psize + vOffset + pReplyParam->vsize; - return 0; - } - } + return handleGetParam(pContext, (effect_param_t *) pCmdData, (effect_param_t *) pReplyData, replySize); } case EFFECT_CMD_GET_CONFIG: { *(effect_config_t *) pReplyData = pContext->config; @@ -275,10 +270,7 @@ static int32_t Viper_ICommand(effect_handle_t self, static int32_t Viper_IGetDescriptor(effect_handle_t self, effect_descriptor_t *pDescriptor) { auto pContext = reinterpret_cast(self); - VIPER_LOGD("Viper_IGetDescriptor called"); - if (pContext == nullptr || pDescriptor == nullptr) { - VIPER_LOGE("Viper_IGetDescriptor: pContext or pDescriptor is null!"); return -EINVAL; } @@ -295,40 +287,21 @@ static const effect_interface_s viper_interface = { 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()"); - if (uuid == nullptr || pHandle == nullptr) { - VIPER_LOGE("Viper_Create: uuid or pHandle is null!"); return -EINVAL; } if (memcmp(uuid, &viper_descriptor.uuid, sizeof(effect_uuid_t)) != 0) { - VIPER_LOGE("Viper_Create: uuid is not viper_descriptor.uuid!"); return -EINVAL; } - VIPER_LOGI("Viper_Create: uuid matches, creating viper..."); - + VIPER_LOGD("Creating new ViPER instance"); auto *pContext = new ViperContext; Viper_Init(pContext); *pHandle = reinterpret_cast(pContext); @@ -339,15 +312,11 @@ Viper_Create(const effect_uuid_t *uuid, int32_t sessionId __unused, int32_t ioId static int32_t Viper_Release(effect_handle_t handle) { auto pContext = reinterpret_cast(handle); - VIPER_LOGI("Enter Viper_Release()"); - if (pContext == nullptr) { - VIPER_LOGE("Viper_Release: pContext is null!"); return -EINVAL; } - VIPER_LOGI("Viper_Release: deleting viper..."); - + VIPER_LOGD("Releasing ViPER instance"); delete pContext->viper; delete pContext; @@ -355,20 +324,14 @@ static int32_t Viper_Release(effect_handle_t handle) { } static int32_t Viper_GetDescriptor(const effect_uuid_t *uuid, effect_descriptor_t *pDescriptor) { - VIPER_LOGI("Enter Viper_GetDescriptor()"); - if (uuid == nullptr || pDescriptor == nullptr) { - VIPER_LOGE("Viper_GetDescriptor: uuid or pDescriptor is null!"); return -EINVAL; } if (memcmp(uuid, &viper_descriptor.uuid, sizeof(effect_uuid_t)) != 0) { - VIPER_LOGE("Viper_GetDescriptor: uuid is not viper_descriptor.uuid!"); return -EINVAL; } - VIPER_LOGI("Viper_GetDescriptor: uuid matches, returning descriptor..."); - *pDescriptor = viper_descriptor; return 0; diff --git a/src/cpp/ViPER4Android.h b/src/cpp/ViPER4Android.h index f374358..41a0942 100644 --- a/src/cpp/ViPER4Android.h +++ b/src/cpp/ViPER4Android.h @@ -4,35 +4,24 @@ // Updated parameters source: https://github.com/vipersaudio/viper4android_fx/blob/master/android_4.x/src/com/vipercn/viper4android_v2/service/ViPER4AndroidService.java extern "C" { -enum ParamsMode { - COMMAND_CODE_GET = 0x01, - COMMAND_CODE_SET, -}; +// Command code +#define COMMAND_CODE_GET 0x01 +#define COMMAND_CODE_SET 0x02 -enum ParamsGet { - PARAM_GET_DRIVER_VERSION = 0, - PARAM_GET_ENABLED, - PARAM_GET_CONFIGURE, - PARAM_GET_STREAMING, - PARAM_GET_SAMPLINGRATE, - PARAM_GET_CONVKNLID -}; +// Param get +#define PARAM_GET_DRIVER_VERSION 0 +#define PARAM_GET_ENABLED 1 +#define PARAM_GET_CONFIGURE 2 +#define PARAM_GET_STREAMING 3 +#define PARAM_GET_SAMPLING_RATE 4 +#define PARAM_GET_CONVOLUTION_KERNEL_ID 5 + +// Param set +#define PARAM_SET_UPDATE_STATUS 0x9002 +#define PARAM_SET_RESET_STATUS 0x9003 enum ParamsSet { - PARAM_SET_STATUS_BEGIN = 0x9000, - PARAM_SET_UNKNOWN, - PARAM_SET_UPDATE_STATUS, - PARAM_SET_RESET_STATUS, - PARAM_SET_DOPROCESS_STATUS, - PARAM_SET_FORCEENABLE_STATUS, - PARAM_SET_SELFDIAGNOSE_STATUS, - PARAM_SET_STATUS_END -}; - -enum ParamsConfigure { - PARAM_PROCESSUNIT_FX_BEGIN = 0x10000, - - PARAM_FX_TYPE_SWITCH, // 0x10001 + PARAM_FX_TYPE_SWITCH = 0x10001, // 0x10001 PARAM_HPFX_CONV_PROCESS_ENABLED, // 0x10002 PARAM_HPFX_CONV_UPDATEKERNEL, // 0x10003 /*****************************************/ @@ -87,26 +76,7 @@ enum ParamsConfigure { PARAM_HPFX_OUTPUT_VOLUME, // 0x10032 PARAM_HPFX_OUTPUT_PAN, // 0x10033 PARAM_HPFX_LIMITER_THRESHOLD, // 0x10034 - PARAM_SPKFX_CONV_PROCESS_ENABLED, // 0x10035 - PARAM_SPKFX_CONV_UPDATEKERNEL, // 0x10036 - PARAM_SPKFX_CONV_PREPAREBUFFER, // 0x10037 - PARAM_SPKFX_CONV_SETBUFFER, // 0x10038 - PARAM_SPKFX_CONV_COMMITBUFFER, // 0x10039 - PARAM_SPKFX_CONV_CROSSCHANNEL, // 0x1003A - PARAM_SPKFX_FIREQ_PROCESS_ENABLED, // 0x1003B - PARAM_SPKFX_FIREQ_BANDLEVEL, // 0x1003C - PARAM_SPKFX_REVB_PROCESS_ENABLED, // 0x1003D - PARAM_SPKFX_REVB_ROOMSIZE, // 0x1003E - PARAM_SPKFX_REVB_WIDTH, // 0x1003F - PARAM_SPKFX_REVB_DAMP, // 0x10040 - PARAM_SPKFX_REVB_WET, // 0x10041 - PARAM_SPKFX_REVB_DRY, // 0x10042 PARAM_SPKFX_AGC_PROCESS_ENABLED, // 0x10043 - PARAM_SPKFX_AGC_RATIO, // 0x10044 - PARAM_SPKFX_AGC_VOLUME, // 0x10045 - PARAM_SPKFX_AGC_MAXSCALER, // 0x10046 - PARAM_SPKFX_OUTPUT_VOLUME, // 0x10047 - PARAM_SPKFX_LIMITER_THRESHOLD, // 0x10048 PARAM_HPFX_FETCOMP_PROCESS_ENABLED, // 0x10049 PARAM_HPFX_FETCOMP_THRESHOLD, // 0x1004A PARAM_HPFX_FETCOMP_RATIO, // 0x1004B @@ -124,25 +94,6 @@ enum ParamsConfigure { PARAM_HPFX_FETCOMP_META_CREST, // 0x10057 PARAM_HPFX_FETCOMP_META_ADAPT, // 0x10058 PARAM_HPFX_FETCOMP_META_NOCLIP_ENABLED, // 0x10059 - PARAM_SPKFX_FETCOMP_PROCESS_ENABLED, // 0x1005A - PARAM_SPKFX_FETCOMP_THRESHOLD, // 0x1005B - PARAM_SPKFX_FETCOMP_RATIO, // 0x1005C - PARAM_SPKFX_FETCOMP_KNEEWIDTH, // 0x1005D - PARAM_SPKFX_FETCOMP_AUTOKNEE_ENABLED, // 0x1005E - PARAM_SPKFX_FETCOMP_GAIN, // 0x1005F - PARAM_SPKFX_FETCOMP_AUTOGAIN_ENABLED, // 0x10060 - PARAM_SPKFX_FETCOMP_ATTACK, // 0x10061 - PARAM_SPKFX_FETCOMP_AUTOATTACK_ENABLED, // 0x10062 - PARAM_SPKFX_FETCOMP_RELEASE, // 0x10063 - PARAM_SPKFX_FETCOMP_AUTORELEASE_ENABLED, // 0x10064 - PARAM_SPKFX_FETCOMP_META_KNEEMULTI, // 0x10065 - PARAM_SPKFX_FETCOMP_META_MAXATTACK, // 0x10066 - PARAM_SPKFX_FETCOMP_META_MAXRELEASE, // 0x10067 - PARAM_SPKFX_FETCOMP_META_CREST, // 0x10068 - PARAM_SPKFX_FETCOMP_META_ADAPT, // 0x10069 - PARAM_SPKFX_FETCOMP_META_NOCLIP_ENABLED, // 0x1006A - - PARAM_PROCESSUNIT_FX_END }; } diff --git a/src/cpp/viper/ViPER.cpp b/src/cpp/viper/ViPER.cpp index b8e645e..5816a3d 100644 --- a/src/cpp/viper/ViPER.cpp +++ b/src/cpp/viper/ViPER.cpp @@ -7,6 +7,8 @@ ViPER::ViPER() { VIPER_LOGI("Welcome to ViPER FX"); VIPER_LOGI("Current version is %s %s", VERSION_STRING, VERSION_CODENAME); + this->samplingRate = DEFAULT_SAMPLERATE; + this->adaptiveBuffer = new AdaptiveBuffer(2, 4096); this->waveBuffer = new WaveBuffer(2, 4096); @@ -81,11 +83,11 @@ ViPER::ViPER() { this->cure->Reset(); this->tubeSimulator = new TubeSimulator(); - this->tubeSimulator->enabled = false; //SetEnable(false); + this->tubeSimulator->SetEnable(false); this->tubeSimulator->Reset(); this->analogX = new AnalogX(); -// this->analogX->SetEnable(false); + this->analogX->SetEnable(false); this->analogX->SetSamplingRate(this->samplingRate); this->analogX->SetProcessingModel(0); this->analogX->Reset(); @@ -100,12 +102,12 @@ ViPER::ViPER() { softwareLimiter->ResetLimiter(); } - this->frame_scale = 1.0; - this->left_pan = 1.0; - this->process_time_ms = 0; - this->right_pan = 1.0; + this->frameScale = 1.0; + this->leftPan = 1.0; + this->rightPan = 1.0; + this->updateProcessTime = false; + this->processTimeMs = 0; this->enabled = false; - this->update_status = false; } ViPER::~ViPER() { @@ -144,10 +146,10 @@ void ViPER::processBuffer(float *buffer, uint32_t size) { return; } - if (this->update_status) { + if (this->updateProcessTime) { struct timeval time{}; gettimeofday(&time, nullptr); - this->process_time_ms = time.tv_sec * 1000 + time.tv_usec / 1000; + this->processTimeMs = time.tv_sec * 1000 + time.tv_usec / 1000; } uint32_t ret; @@ -155,6 +157,8 @@ void ViPER::processBuffer(float *buffer, uint32_t size) { uint32_t tmpBufSize; if (this->convolver->GetEnabled() || this->vhe->GetEnabled()) { + VIPER_LOGD("Convolver or VHE is enable, use wave buffer"); + if (!this->waveBuffer->PushSamples(buffer, size)) { this->waveBuffer->Reset(); return; @@ -178,6 +182,8 @@ void ViPER::processBuffer(float *buffer, uint32_t size) { tmpBuf = ptr; tmpBufSize = ret; } else { + VIPER_LOGD("Convolver and VHE are disabled, use adaptive buffer"); + if (this->adaptiveBuffer->PushFrames(buffer, size)) { this->adaptiveBuffer->SetBufferOffset(size); @@ -189,6 +195,7 @@ void ViPER::processBuffer(float *buffer, uint32_t size) { } } +// VIPER_LOGD("Process buffer size: %d", tmpBufSize); if (tmpBufSize != 0) { this->viperDdc->Process(tmpBuf, size); this->spectrumExtend->Process(tmpBuf, size); @@ -206,12 +213,12 @@ void ViPER::processBuffer(float *buffer, uint32_t size) { this->tubeSimulator->TubeProcess(tmpBuf, size); this->analogX->Process(tmpBuf, tmpBufSize); - if (this->frame_scale != 1.0) { - this->adaptiveBuffer->ScaleFrames(this->frame_scale); + if (this->frameScale != 1.0) { + this->adaptiveBuffer->ScaleFrames(this->frameScale); } - if (this->left_pan < 1.0 || this->right_pan < 1.0) { - this->adaptiveBuffer->PanFrames(this->left_pan, this->right_pan); + if (this->leftPan < 1.0 || this->rightPan < 1.0) { + this->adaptiveBuffer->PanFrames(this->leftPan, this->rightPan); } for (uint32_t i = 0; i < tmpBufSize * 2; i += 2) { @@ -235,41 +242,26 @@ void ViPER::processBuffer(float *buffer, uint32_t size) { void ViPER::DispatchCommand(int param, int val1, int val2, int val3, int val4, uint32_t arrSize, signed char *arr) { + VIPER_LOGD("Dispatch command: %d, %d, %d, %d, %d, %d, %p", param, val1, val2, val3, val4, arrSize, arr); switch (param) { - case PARAM_SET_UNKNOWN: { - break; - } case PARAM_SET_UPDATE_STATUS: { + this->updateProcessTime = val1 != 0; break; } case PARAM_SET_RESET_STATUS: { + this->ResetAllEffects(); break; } - case PARAM_SET_DOPROCESS_STATUS: { - break; - } - case PARAM_SET_FORCEENABLE_STATUS: { - break; - } - case PARAM_SET_SELFDIAGNOSE_STATUS: { - break; - } - case PARAM_FX_TYPE_SWITCH: { - // Unused - // TODO: Remove - break; - } // 0x10001 case PARAM_HPFX_CONV_PROCESS_ENABLED: { +// this->convolver->SetEnabled(val1 != 0); break; } // 0x10002 - case PARAM_HPFX_CONV_UPDATEKERNEL: { - break; - } // 0x10003 case PARAM_HPFX_CONV_PREPAREBUFFER: { this->convolver->PrepareKernelBuffer(val1, val2, val3); break; } // 0x10004 case PARAM_HPFX_CONV_SETBUFFER: { + this->convolver->SetKernelBuffer(val1, (float *) arr, arrSize); break; } // 0x10005 case PARAM_HPFX_CONV_COMMITBUFFER: { @@ -277,6 +269,7 @@ void ViPER::DispatchCommand(int param, int val1, int val2, int val3, int val4, u break; } // 0x10006 case PARAM_HPFX_CONV_CROSSCHANNEL: { + this->convolver->SetCrossChannel((float) val1 / 100.0f); break; } // 0x10007 case PARAM_HPFX_VHE_PROCESS_ENABLED: { @@ -333,6 +326,7 @@ void ViPER::DispatchCommand(int param, int val1, int val2, int val3, int val4, u break; } // 0x10014 case PARAM_HPFX_DIFFSURR_PROCESS_ENABLED: { + this->diffSurround->SetEnable(val1 != 0); break; } // 0x10015 case PARAM_HPFX_DIFFSURR_DELAYTIME: { @@ -340,9 +334,11 @@ void ViPER::DispatchCommand(int param, int val1, int val2, int val3, int val4, u break; } // 0x10016 case PARAM_HPFX_REVB_PROCESS_ENABLED: { + this->reverberation->SetEnable(val1 != 0); break; } // 0x10017 case PARAM_HPFX_REVB_ROOMSIZE: { + this->reverberation->SetRoomSize((float) val1 / 100.0f); break; } // 0x10018 case PARAM_HPFX_REVB_WIDTH: { @@ -350,12 +346,15 @@ void ViPER::DispatchCommand(int param, int val1, int val2, int val3, int val4, u break; } // 0x10019 case PARAM_HPFX_REVB_DAMP: { + this->reverberation->SetDamp((float) val1 / 100.0f); break; } // 0x1001A case PARAM_HPFX_REVB_WET: { + this->reverberation->SetWet((float) val1 / 100.0f); break; } // 0x1001B case PARAM_HPFX_REVB_DRY: { + this->reverberation->SetDry((float) val1 / 100.0f); break; } // 0x1001C case PARAM_HPFX_AGC_PROCESS_ENABLED: { @@ -395,11 +394,11 @@ void ViPER::DispatchCommand(int param, int val1, int val2, int val3, int val4, u break; } // 0x10025 case PARAM_HPFX_VIPERBASS_PROCESS_ENABLED: { -// this->viperBass->SetEnable(val1 != 0); + this->viperBass->SetEnable(val1 != 0); break; } // 0x10026 case PARAM_HPFX_VIPERBASS_MODE: { - this->viperBass->SetProcessMode(static_cast(val1)); + this->viperBass->SetProcessMode((ViPERBass::ProcessMode) val1); break; } // 0x10027 case PARAM_HPFX_VIPERBASS_SPEAKER: { @@ -411,11 +410,11 @@ void ViPER::DispatchCommand(int param, int val1, int val2, int val3, int val4, u break; } // 0x10029 case PARAM_HPFX_VIPERCLARITY_PROCESS_ENABLED: { - //this->viperClarity->SetEnable(val1 != 0); + this->viperClarity->SetEnable(val1 != 0); break; } // 0x1002A case PARAM_HPFX_VIPERCLARITY_MODE: { - this->viperClarity->SetProcessMode(static_cast(val1)); + this->viperClarity->SetProcessMode((ViPERClarity::ClarityMode) val1); break; } // 0x1002B case PARAM_HPFX_VIPERCLARITY_CLARITY: { @@ -441,11 +440,11 @@ void ViPER::DispatchCommand(int param, int val1, int val2, int val3, int val4, u break; } // 0x1002E case PARAM_HPFX_TUBE_PROCESS_ENABLED: { - // TODO: Enable + this->tubeSimulator->SetEnable(val1 != 0); break; } // 0x1002F case PARAM_HPFX_ANALOGX_PROCESS_ENABLED: { - // TODO: Enable + this->analogX->SetEnable(val1 != 0); break; } // 0x10030 case PARAM_HPFX_ANALOGX_MODE: { @@ -453,17 +452,17 @@ void ViPER::DispatchCommand(int param, int val1, int val2, int val3, int val4, u break; } // 0x10031 case PARAM_HPFX_OUTPUT_VOLUME: { - + this->frameScale = (float) val1 / 100.0f; break; } // 0x10032 case PARAM_HPFX_OUTPUT_PAN: { float tmp = (float) val1 / 100.0f; if (tmp < 0.0f) { - this->left_pan = 1.0f; - this->right_pan = 1.0f + tmp; + this->leftPan = 1.0f; + this->rightPan = 1.0f + tmp; } else { - this->left_pan = 1.0f - tmp; - this->right_pan = 1.0f; + this->leftPan = 1.0f - tmp; + this->rightPan = 1.0f; } break; } // 0x10033 @@ -472,77 +471,10 @@ void ViPER::DispatchCommand(int param, int val1, int val2, int val3, int val4, u this->softwareLimiters[1]->SetGate((float) val1 / 100.0f); break; } // 0x10034 - case PARAM_SPKFX_CONV_PROCESS_ENABLED: { - break; - } // 0x10035 - case PARAM_SPKFX_CONV_UPDATEKERNEL: { - break; - } // 0x10036 - case PARAM_SPKFX_CONV_PREPAREBUFFER: { - break; - } // 0x10037 - case PARAM_SPKFX_CONV_SETBUFFER: { - break; - } // 0x10038 - case PARAM_SPKFX_CONV_COMMITBUFFER: { - break; - } // 0x10039 - case PARAM_SPKFX_CONV_CROSSCHANNEL: { - this->convolver->SetCrossChannel((float) val1 / 100.0f); - break; - } // 0x1003A - case PARAM_SPKFX_FIREQ_PROCESS_ENABLED: { - break; - } // 0x1003B - case PARAM_SPKFX_FIREQ_BANDLEVEL: { - break; - } // 0x1003C - case PARAM_SPKFX_REVB_PROCESS_ENABLED: { - this->reverberation->SetEnable(val1 != 0); - break; - } // 0x1003D - case PARAM_SPKFX_REVB_ROOMSIZE: { - this->reverberation->SetRoomSize((float) val1 / 100.0f); - break; - } // 0x1003E - case PARAM_SPKFX_REVB_WIDTH: { - break; - } // 0x1003F - case PARAM_SPKFX_REVB_DAMP: { - this->reverberation->SetDamp((float) val1 / 100.0f); - break; - } // 0x10040 - case PARAM_SPKFX_REVB_WET: { - this->reverberation->SetWet((float) val1 / 100.0f); - break; - } // 0x10041 - case PARAM_SPKFX_REVB_DRY: { - this->reverberation->SetDry((float) val1 / 100.0f); - break; - } // 0x10042 case PARAM_SPKFX_AGC_PROCESS_ENABLED: { this->speakerCorrection->SetEnable(val1 != 0); break; } // 0x10043 - case PARAM_SPKFX_AGC_RATIO: { - break; - } // 0x10044 - case PARAM_SPKFX_AGC_VOLUME: { - this->playbackGain->SetVolume((float) val1 / 100.0f); - break; - } // 0x10045 - case PARAM_SPKFX_AGC_MAXSCALER: { - this->playbackGain->SetMaxGainFactor((float) val1 / 100.0f); - break; - } // 0x10046 - case PARAM_SPKFX_OUTPUT_VOLUME: { - this->frame_scale = (float) val1 / 100.0f; - break; - } // 0x10047 - case PARAM_SPKFX_LIMITER_THRESHOLD: { - this->frame_scale = (float) val1 / 100.0f; - break; - } // 0x10048 case PARAM_HPFX_FETCOMP_PROCESS_ENABLED: { break; } // 0x10049 @@ -598,59 +530,6 @@ void ViPER::DispatchCommand(int param, int val1, int val2, int val3, int val4, u this->fetCompressor->SetParameter(15, (float) val1 / 100.0f); break; } // 0x10059 - case PARAM_SPKFX_FETCOMP_PROCESS_ENABLED: { - break; - } // 0x1005A - case PARAM_SPKFX_FETCOMP_THRESHOLD: { - - break; - } // 0x1005B - case PARAM_SPKFX_FETCOMP_RATIO: { - break; - } // 0x1005C - case PARAM_SPKFX_FETCOMP_KNEEWIDTH: { - this->fetCompressor->SetParameter(2, (float) val1 / 100.0f); - break; - } // 0x1005D - case PARAM_SPKFX_FETCOMP_AUTOKNEE_ENABLED: { - break; - } // 0x1005E - case PARAM_SPKFX_FETCOMP_GAIN: { - break; - } // 0x1005F - case PARAM_SPKFX_FETCOMP_AUTOGAIN_ENABLED: { - break; - } // 0x10060 - case PARAM_SPKFX_FETCOMP_ATTACK: { - break; - } // 0x10061 - case PARAM_SPKFX_FETCOMP_AUTOATTACK_ENABLED: { - break; - } // 0x10062 - case PARAM_SPKFX_FETCOMP_RELEASE: { - break; - } // 0x10063 - case PARAM_SPKFX_FETCOMP_AUTORELEASE_ENABLED: { - break; - } // 0x10064 - case PARAM_SPKFX_FETCOMP_META_KNEEMULTI: { - break; - } // 0x10065 - case PARAM_SPKFX_FETCOMP_META_MAXATTACK: { - break; - } // 0x10066 - case PARAM_SPKFX_FETCOMP_META_MAXRELEASE: { - break; - } // 0x10067 - case PARAM_SPKFX_FETCOMP_META_CREST: { - break; - } // 0x10068 - case PARAM_SPKFX_FETCOMP_META_ADAPT: { - break; - } // 0x10069 - case PARAM_SPKFX_FETCOMP_META_NOCLIP_ENABLED: { - break; - } // 0x1006A } } diff --git a/src/cpp/viper/ViPER.h b/src/cpp/viper/ViPER.h index 009deaa..02bf432 100644 --- a/src/cpp/viper/ViPER.h +++ b/src/cpp/viper/ViPER.h @@ -33,8 +33,8 @@ public: void ResetAllEffects(); //private: - bool update_status; - uint64_t process_time_ms; + bool updateProcessTime; + uint64_t processTimeMs; bool enabled; uint32_t samplingRate; @@ -60,7 +60,7 @@ public: SpeakerCorrection *speakerCorrection; SoftwareLimiter *softwareLimiters[2]; - float frame_scale; - float left_pan; - float right_pan; + float frameScale; + float leftPan; + float rightPan; }; diff --git a/src/cpp/viper/effects/AnalogX.cpp b/src/cpp/viper/effects/AnalogX.cpp index 7102e7d..23c884e 100644 --- a/src/cpp/viper/effects/AnalogX.cpp +++ b/src/cpp/viper/effects/AnalogX.cpp @@ -18,27 +18,29 @@ static float ANALOGX_HARMONICS[10] = { AnalogX::AnalogX() { this->samplingRate = DEFAULT_SAMPLERATE; this->processingModel = 0; - this->enabled = false; + this->enable = false; Reset(); } void AnalogX::Process(float *samples, uint32_t size) { - for (int i = 0; i < size * 2; i++) { - float sample = samples[i]; - int channel = i % 2; + if (this->enable) { + for (int i = 0; i < size * 2; i++) { + float sample = samples[i]; + int channel = i % 2; - float tmp = this->highpass[channel].ProcessSample(sample); - tmp = this->harmonic[channel].Process(tmp); + float tmp = this->highpass[channel].ProcessSample(sample); + tmp = this->harmonic[channel].Process(tmp); - tmp = this->lowpass[channel].ProcessSample(sample + tmp * this->gain); - tmp = this->peak->ProcessSample(tmp * 0.8f); + tmp = this->lowpass[channel].ProcessSample(sample + tmp * this->gain); + tmp = this->peak->ProcessSample(tmp * 0.8f); - samples[i] = tmp; - } + samples[i] = tmp; + } - if (this->freqRange < this->samplingRate / 4) { - this->freqRange += size; - memset(samples, 0, size * 2 * sizeof(float)); + if (this->freqRange < this->samplingRate / 4) { + this->freqRange += size; + memset(samples, 0, size * 2 * sizeof(float)); + } } } @@ -90,6 +92,15 @@ void AnalogX::Reset() { this->freqRange = 0; } +void AnalogX::SetEnable(bool enable) { + if (this->enable != enable) { + if (!this->enable) { + Reset(); + } + this->enable = enable; + } +} + void AnalogX::SetProcessingModel(int processingModel) { if (this->processingModel != processingModel) { this->processingModel = processingModel; diff --git a/src/cpp/viper/effects/AnalogX.h b/src/cpp/viper/effects/AnalogX.h index caf9513..5afe2cd 100644 --- a/src/cpp/viper/effects/AnalogX.h +++ b/src/cpp/viper/effects/AnalogX.h @@ -10,6 +10,7 @@ public: void Process(float *samples, uint32_t size); void Reset(); + void SetEnable(bool enable); void SetProcessingModel(int processingModel); void SetSamplingRate(uint32_t samplingRate); @@ -23,7 +24,7 @@ private: uint32_t freqRange; int processingModel; uint32_t samplingRate; - bool enabled; + bool enable; }; diff --git a/src/cpp/viper/effects/IIRFilter.cpp b/src/cpp/viper/effects/IIRFilter.cpp index e1b7be3..b79fbaa 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->minPhaseIirCoeffs.UpdateCoeffs(bands, this->samplingRate); + this->minPhaseIirCoeffs.UpdateCoeffs(this->bands, this->samplingRate); } else { this->bands = 0; } @@ -17,7 +17,7 @@ IIRFilter::IIRFilter(uint32_t bands) { bandLevelWithQ = 0.636; } - this->Reset(); + Reset(); } void IIRFilter::Process(float *samples, uint32_t size) { @@ -54,14 +54,16 @@ void IIRFilter::Process(float *samples, uint32_t size) { } void IIRFilter::Reset() { - memset(this->buf,0,0x7c0); + memset(this->buf,0,sizeof(buf)); // size should be 0x7c0 this->unknown3 = 1; this->unknown2 = 2; this->unknown4 = 0; } void IIRFilter::SetBandLevel(uint32_t band, float level) { - this->bandLevelsWithQ[band] = (float) (pow(10.0, level / 20.0) * 0.636); + if (band > 30) return; + double bandLevel = pow(10.0, level / 20.0); + this->bandLevelsWithQ[band] = (float) (bandLevel * 0.636); } void IIRFilter::SetEnable(bool enable) { diff --git a/src/cpp/viper/effects/SpeakerCorrection.cpp b/src/cpp/viper/effects/SpeakerCorrection.cpp index e7a69c6..63a9a9c 100644 --- a/src/cpp/viper/effects/SpeakerCorrection.cpp +++ b/src/cpp/viper/effects/SpeakerCorrection.cpp @@ -8,13 +8,15 @@ SpeakerCorrection::SpeakerCorrection() { } void SpeakerCorrection::Process(float *samples, uint32_t size) { - for (int i = 0; i < size * 2; i++) { - float sample = samples[i]; - int index = i % 2; - sample = this->lowpass[index].ProcessSample(sample); - sample = this->highpass[index].ProcessSample(sample); - float tmp = sample / 2.f; - samples[i] = tmp + this->bandpass[index].ProcessSample(tmp); + if (this->enabled) { + for (int i = 0; i < size * 2; i++) { + float sample = samples[i]; + int index = i % 2; + sample = this->lowpass[index].ProcessSample(sample); + sample = this->highpass[index].ProcessSample(sample); + float tmp = sample / 2.f; + samples[i] = tmp + this->bandpass[index].ProcessSample(tmp); + } } } diff --git a/src/cpp/viper/effects/SpectrumExtend.cpp b/src/cpp/viper/effects/SpectrumExtend.cpp index b22d62c..4f40484 100644 --- a/src/cpp/viper/effects/SpectrumExtend.cpp +++ b/src/cpp/viper/effects/SpectrumExtend.cpp @@ -27,13 +27,15 @@ SpectrumExtend::~SpectrumExtend() { } void SpectrumExtend::Process(float *samples, uint32_t size) { - for (int i = 0; i < size * 2; i++) { - float sample = samples[i]; - int index = i % 2; - float tmp = this->highpass[index].ProcessSample(sample); - tmp = this->harmonics[index].Process(tmp); - tmp = this->lowpass[index].ProcessSample(tmp * this->exciter); - samples[i] = samples[i] + tmp; + if (this->enabled) { + for (int i = 0; i < size * 2; i++) { + float sample = samples[i]; + int index = i % 2; + float tmp = this->highpass[index].ProcessSample(sample); + tmp = this->harmonics[index].Process(tmp); + tmp = this->lowpass[index].ProcessSample(tmp * this->exciter); + samples[i] = samples[i] + tmp; + } } } diff --git a/src/cpp/viper/effects/TubeSimulator.cpp b/src/cpp/viper/effects/TubeSimulator.cpp index 686f1f0..7d46e80 100644 --- a/src/cpp/viper/effects/TubeSimulator.cpp +++ b/src/cpp/viper/effects/TubeSimulator.cpp @@ -3,17 +3,26 @@ TubeSimulator::TubeSimulator() { this->acc[0] = 0.f; this->acc[1] = 0.f; - this->enabled = false; + this->enable = false; } void TubeSimulator::Reset() { this->acc[0] = 0.f; this->acc[1] = 0.f; - this->enabled = false; + this->enable = false; +} + +void TubeSimulator::SetEnable(bool enable) { + if (this->enable != enable) { + if (!this->enable) { + Reset(); + } + this->enable = enable; + } } void TubeSimulator::TubeProcess(float *buffer, uint32_t size) { - if (this->enabled) { + if (this->enable) { for (int x = 0; x < size; x++) { this->acc[0] = (this->acc[0] + buffer[2 * x]) / 2.f; this->acc[1] = (this->acc[1] + buffer[2 * x + 1]) / 2.f; diff --git a/src/cpp/viper/effects/TubeSimulator.h b/src/cpp/viper/effects/TubeSimulator.h index 0c14c24..b7def43 100644 --- a/src/cpp/viper/effects/TubeSimulator.h +++ b/src/cpp/viper/effects/TubeSimulator.h @@ -8,9 +8,11 @@ public: ~TubeSimulator(); void Reset(); + void SetEnable(bool enable); void TubeProcess(float *buffer, uint32_t size); +private: float acc[2]; - bool enabled; + bool enable; }; diff --git a/src/cpp/viper/effects/ViPERBass.cpp b/src/cpp/viper/effects/ViPERBass.cpp index 925d64a..6dae9ae 100644 --- a/src/cpp/viper/effects/ViPERBass.cpp +++ b/src/cpp/viper/effects/ViPERBass.cpp @@ -2,9 +2,10 @@ #include "../constants.h" ViPERBass::ViPERBass() { + this->enable = false; this->samplingRate = DEFAULT_SAMPLERATE; this->speaker = 60; - this->invertedSamplingRate = 1.0 / DEFAULT_SAMPLERATE; + this->samplingRatePeriod = 1.0 / DEFAULT_SAMPLERATE; this->antiPop = 0.0; this->processMode = ProcessMode::NATURAL_BASS; this->bassFactor = 0.0; @@ -27,6 +28,10 @@ ViPERBass::~ViPERBass() { } void ViPERBass::Process(float *samples, uint32_t size) { + if (!this->enable) { + return; + } + if (size == 0) { return; } @@ -36,7 +41,7 @@ void ViPERBass::Process(float *samples, uint32_t size) { samples[i] *= this->antiPop; samples[i + 1] *= this->antiPop; - float x = this->antiPop + this->invertedSamplingRate; + float x = this->antiPop + this->samplingRatePeriod; if (x > 1.0) { x = 1.0; } @@ -48,14 +53,14 @@ void ViPERBass::Process(float *samples, uint32_t size) { case ProcessMode::NATURAL_BASS: { for (uint32_t i = 0; i < size * 2; i += 2) { double sample = ((double) samples[i] + (double) samples[i + 1]) / 2.0; - auto x = (float) this->biquad->ProcessSample(sample); + float x = (float) this->biquad->ProcessSample(sample) * this->bassFactor; samples[i] += x; samples[i + 1] += x; } break; } case ProcessMode::PURE_BASS_PLUS: { - if (this->waveBuffer->PushSamples(samples, size) != 0) { + if (this->waveBuffer->PushSamples(samples, size)) { float *buffer = this->waveBuffer->GetBuffer(); uint32_t bufferOffset = this->waveBuffer->GetBufferOffset(); @@ -90,8 +95,8 @@ void ViPERBass::Reset() { this->waveBuffer->PushZeros(this->polyphase->GetLatency()); this->subwoofer->SetBassGain(this->samplingRate, this->bassFactor * 2.5f); this->biquad->SetLowPassParameter((float) this->speaker, this->samplingRate, 0.53); + this->samplingRatePeriod = 1.0f / (float) this->samplingRate; this->antiPop = 0.0f; - this->invertedSamplingRate = 1.0f / (float) this->samplingRate; } void ViPERBass::SetBassFactor(float bassFactor) { @@ -101,6 +106,15 @@ void ViPERBass::SetBassFactor(float bassFactor) { } } +void ViPERBass::SetEnable(bool enable) { + if (this->enable != enable) { + if (!this->enable) { + Reset(); + } + this->enable = enable; + } +} + void ViPERBass::SetProcessMode(ProcessMode processMode) { if (this->processMode != processMode) { this->processMode = processMode; @@ -111,10 +125,10 @@ void ViPERBass::SetProcessMode(ProcessMode processMode) { void ViPERBass::SetSamplingRate(uint32_t samplingRate) { if (this->samplingRate != samplingRate) { this->samplingRate = samplingRate; - this->invertedSamplingRate = 1.0f / (float) samplingRate; - this->polyphase->SetSamplingRate(samplingRate); - this->biquad->SetLowPassParameter((float) this->speaker, samplingRate, 0.53); - this->subwoofer->SetBassGain(samplingRate, this->bassFactor * 2.5f); + this->samplingRatePeriod = 1.0f / (float) samplingRate; + this->polyphase->SetSamplingRate(this->samplingRate); + this->biquad->SetLowPassParameter((float) this->speaker, this->samplingRate, 0.53); + this->subwoofer->SetBassGain(this->samplingRate, this->bassFactor * 2.5f); } } diff --git a/src/cpp/viper/effects/ViPERBass.h b/src/cpp/viper/effects/ViPERBass.h index 377f3b0..c8245f2 100644 --- a/src/cpp/viper/effects/ViPERBass.h +++ b/src/cpp/viper/effects/ViPERBass.h @@ -20,6 +20,7 @@ public: void Process(float *samples, uint32_t size); void Reset(); void SetBassFactor(float bassFactor); + void SetEnable(bool enable); void SetProcessMode(ProcessMode processMode); void SetSamplingRate(uint32_t samplingRate); void SetSpeaker(uint32_t speaker); @@ -29,9 +30,10 @@ private: Biquad *biquad; Subwoofer *subwoofer; WaveBuffer *waveBuffer; + bool enable; ProcessMode processMode; uint32_t samplingRate; - float invertedSamplingRate; + float samplingRatePeriod; float antiPop; uint32_t speaker; float bassFactor; diff --git a/src/cpp/viper/effects/ViPERClarity.cpp b/src/cpp/viper/effects/ViPERClarity.cpp index 559bef0..c662860 100644 --- a/src/cpp/viper/effects/ViPERClarity.cpp +++ b/src/cpp/viper/effects/ViPERClarity.cpp @@ -8,13 +8,18 @@ ViPERClarity::ViPERClarity() { highShelf.SetSamplingRate(DEFAULT_SAMPLERATE); } + this->enable = false; this->processMode = ClarityMode::NATURAL; this->samplingRate = DEFAULT_SAMPLERATE; this->clarityGainPercent = 0.0; - this->Reset(); + Reset(); } void ViPERClarity::Process(float *samples, uint32_t size) { + if (!this->enable) { + return; + } + switch (this->processMode) { case ClarityMode::NATURAL: { this->noiseSharpening.Process(samples, size); @@ -50,7 +55,7 @@ void ViPERClarity::SetClarity(float gainPercent) { if (this->processMode != ClarityMode::OZONE) { this->SetClarityToFilter(); } else { - this->Reset(); + Reset(); } } @@ -61,16 +66,25 @@ void ViPERClarity::SetClarityToFilter() { this->hifi.SetClarity(this->clarityGainPercent + 1.0f); } +void ViPERClarity::SetEnable(bool enable) { + if (this->enable != enable) { + if (!this->enable) { + Reset(); + } + this->enable = enable; + } +} + void ViPERClarity::SetProcessMode(ClarityMode processMode) { if (this->processMode != processMode) { this->processMode = processMode; - this->Reset(); + Reset(); } } void ViPERClarity::SetSamplingRate(uint32_t samplingRate) { if (this->samplingRate != samplingRate) { this->samplingRate = samplingRate; - this->Reset(); + Reset(); } } diff --git a/src/cpp/viper/effects/ViPERClarity.h b/src/cpp/viper/effects/ViPERClarity.h index 8581224..d485139 100644 --- a/src/cpp/viper/effects/ViPERClarity.h +++ b/src/cpp/viper/effects/ViPERClarity.h @@ -19,6 +19,7 @@ public: void Reset(); void SetClarity(float gainPercent); void SetClarityToFilter(); + void SetEnable(bool enable); void SetProcessMode(ClarityMode processMode); void SetSamplingRate(uint32_t samplingRate); @@ -26,6 +27,7 @@ private: NoiseSharpening noiseSharpening; HighShelf highShelf[2]; HiFi hifi; + bool enable; ClarityMode processMode; uint32_t samplingRate; float clarityGainPercent; diff --git a/src/cpp/viper/utils/AdaptiveBuffer.cpp b/src/cpp/viper/utils/AdaptiveBuffer.cpp index 83fb1e7..d488211 100644 --- a/src/cpp/viper/utils/AdaptiveBuffer.cpp +++ b/src/cpp/viper/utils/AdaptiveBuffer.cpp @@ -38,7 +38,7 @@ uint32_t AdaptiveBuffer::GetChannels() const { void AdaptiveBuffer::PanFrames(float left, float right) { if (this->buffer != nullptr && this->channels == 2) { - for (int i = 0; i < this->offset * this->channels; i++) { + for (uint32_t i = 0; i < this->offset * this->channels; i++) { if (i % 2 == 0) { this->buffer[i] = this->buffer[i] * left; } else { @@ -57,7 +57,7 @@ int AdaptiveBuffer::PopFrames(float *frames, uint32_t length) { memcpy(frames, this->buffer, length * this->channels * sizeof(*frames)); this->offset = this->offset - length; if (this->offset != 0) { - memmove(this->buffer, &this->buffer[length * this->channels], this->offset * this->channels * sizeof(float)); + memmove(this->buffer, this->buffer + (length * this->channels), this->offset * this->channels * sizeof(float)); } } @@ -78,7 +78,7 @@ int AdaptiveBuffer::PushFrames(const float *frames, uint32_t length) { this->length = this->offset + length; } - memcpy(&this->buffer[this->offset * this->channels], frames, length * this->channels * sizeof(float)); + memcpy(this->buffer + (this->offset * this->channels), frames, length * this->channels * sizeof(float)); this->offset = this->offset + length; } @@ -98,7 +98,7 @@ int AdaptiveBuffer::PushZero(uint32_t length) { this->length = this->offset + length; } - memset(&this->buffer[this->offset * this->channels], 0, length * this->channels * sizeof(float)); + memset(this->buffer + (this->offset * this->channels), 0, length * this->channels * sizeof(float)); this->offset = this->offset + length; return 1; diff --git a/src/cpp/viper/utils/Biquad.cpp b/src/cpp/viper/utils/Biquad.cpp index d617451..cbbbb17 100644 --- a/src/cpp/viper/utils/Biquad.cpp +++ b/src/cpp/viper/utils/Biquad.cpp @@ -1,53 +1,64 @@ #include "Biquad.h" #include +// Some variable names RE'd with help from https://github.com/wooters/miniDSP/blob/master/biquad.c + Biquad::Biquad() { Reset(); SetCoeffs(1.0, 0.0, 0.0, 1.0, 0.0, 0.0); } double Biquad::ProcessSample(double sample) { - double out = sample * this->b0 + this->x_1 * this->b1 + this->x_2 * this->b2 + this->y_1 * this->a1 + - this->y_2 * this->a2; - this->y_2 = this->y_1; - this->y_1 = out; - this->x_2 = this->x_1; - this->x_1 = sample; + double out = + sample * this->b0 + + this->x1 * this->b1 + + this->x2 * this->b2 + + this->y1 * this->a1 + + this->y2 * this->a2; + + this->x2 = this->x1; + this->x1 = sample; + this->y2 = this->y1; + this->y1 = out; + return out; } void Biquad::Reset() { - this->a1 = 0; - this->a2 = 0; - this->b0 = 0; - this->b1 = 0; - this->b2 = 0; - this->x_1 = 0; - this->x_2 = 0; - this->y_1 = 0; - this->y_2 = 0; + this->a1 = 0.0; + this->a2 = 0.0; + this->b0 = 0.0; + this->b1 = 0.0; + this->b2 = 0.0; + this->x1 = 0.0; + this->x2 = 0.0; + this->y1 = 0.0; + this->y2 = 0.0; } void Biquad::SetBandPassParameter(float frequency, uint32_t samplingRate, float qFactor) { - double x = (2.0 * M_PI * (double) frequency) / (double) samplingRate; - double sinX = sin(x); - double cosX = cos(x); - double y = sinX / ((double) qFactor * 2.0); + double omega = (2.0 * M_PI * (double) frequency) / (double) samplingRate; + double sinOmega = sin(omega); + double cosOmega = cos(omega); - double a0 = 1.0 + y; - double a1 = -cosX * 2.0; - double a2 = 1.0 - y; - double b0 = sinX / 2.0; + double alpha = sinOmega / (2.0 * (double) qFactor); + + double a0 = 1.0 + alpha; + double a1 = -2.0 * cosOmega; + double a2 = 1.0 - alpha; + double b0 = sinOmega / 2.0; // Reference biquad implementation would use alpha here double b1 = 0.0; - double b2 = -sinX / 2.0; - this->SetCoeffs(a0, a1, a2, b0, b1, b2); + double b2 = -sinOmega / 2.0; // Reference biquad implementation would use -alpha here + + SetCoeffs(a0, a1, a2, b0, b1, b2); } void Biquad::SetCoeffs(double a0, double a1, double a2, double b0, double b1, double b2) { - this->x_2 = 0; - this->x_1 = 0; - this->y_2 = 0; - this->y_1 = 0; + this->x2 = 0.0; + this->x1 = 0.0; + this->y2 = 0.0; + this->y1 = 0.0; + this->a1 = -a1 / a0; this->a2 = -a2 / a0; this->b0 = b0 / a0; @@ -55,44 +66,47 @@ void Biquad::SetCoeffs(double a0, double a1, double a2, double b0, double b1, do this->b2 = b2 / a0; } +// TODO: Check void -Biquad::SetHighPassParameter(float frequency, uint32_t samplingRate, double param_4, float qFactor, double param_6) { - double x = (2.0 * M_PI * (double) frequency) / (double) samplingRate; - double sinX = sin(x); - double cosX = cos(x); +Biquad::SetHighPassParameter(float frequency, uint32_t samplingRate, double dbGain, float qFactor, double param_6) { + double omega = (2.0 * M_PI * (double) frequency) / (double) samplingRate; + double sinX = sin(omega); + double cosX = cos(omega); - double y = pow(10.0, param_4 / 40.0); - double sqrtY = sqrt(y); + double A = pow(10.0, dbGain / 40.0); + double sqrtY = sqrt(A); - double z = sinX / 2.0 * sqrt((1.0 / y + y) * (1.0 / (double) qFactor - 1.0) + 2.0); - double a = (y - 1.0) * cosX; - double b = (y + 1.0) + a; - double c = (y + 1.0) * cosX; - double d = (y + 1.0) - a; + double z = sinX / 2.0 * sqrt((1.0 / A + A) * (1.0 / (double) qFactor - 1.0) + 2.0); + double a = (A - 1.0) * cosX; + double b = (A + 1.0) + a; + double c = (A + 1.0) * cosX; + double d = (A + 1.0) - a; double e = pow(10.0, param_6 / 20.0); - double f = (y - 1.0) - c; + double f = (A - 1.0) - c; double a0 = d + (sqrtY * 2.0) * z; double a1 = f * 2.0; double a2 = d - (sqrtY * 2.0) * z; - double b0 = (b + (sqrtY * 2.0) * z) * y * e; - double b1 = y * -2.0 * ((y - 1.0) + c) * e; - double b2 = (b - (sqrtY * 2.0) * z) * y * e; - this->SetCoeffs(a0, a1, a2, b0, b1, b2); + double b0 = (b + (sqrtY * 2.0) * z) * A * e; + double b1 = A * -2.0 * ((A - 1.0) + c) * e; + double b2 = (b - (sqrtY * 2.0) * z) * A * e; + + SetCoeffs(a0, a1, a2, b0, b1, b2); } void Biquad::SetLowPassParameter(float frequency, uint32_t samplingRate, float qFactor) { - double x = (2.0 * M_PI * (double) frequency) / (double) samplingRate; - double sinX = sin(x); - double y = sinX / ((double) qFactor * 2.0); - double cosX = cos(x); - double z = 1.0 - cosX; + double omega = (2.0 * M_PI * (double) frequency) / (double) samplingRate; + double sinOmega = sin(omega); + double cosOmega = cos(omega); - double a0 = y + 1.0; - double a1 = -cosX * 2.0; - double a2 = 1.0 - y; - double b0 = z / 2.0; - double b1 = z; - double b2 = z / 2.0; - this->SetCoeffs(a0, a1, a2, b0, b1, b2); + double alpha = sinOmega / (2.0 * (double) qFactor); + + double a0 = 1.0 + alpha; + double a1 = -2.0 * cosOmega; + double a2 = 1.0 - alpha; + double b0 = (1.0 - cosOmega) / 2.0; + double b1 = 1.0 - cosOmega; + double b2 = (1.0 - cosOmega) / 2.0; + + SetCoeffs(a0, a1, a2, b0, b1, b2); } diff --git a/src/cpp/viper/utils/Biquad.h b/src/cpp/viper/utils/Biquad.h index 40f577b..2347ea1 100644 --- a/src/cpp/viper/utils/Biquad.h +++ b/src/cpp/viper/utils/Biquad.h @@ -10,14 +10,14 @@ public: void Reset(); void SetBandPassParameter(float frequency, uint32_t samplingRate, float qFactor); void SetCoeffs(double a0, double a1, double a2, double b0, double b1, double b2); - void SetHighPassParameter(float frequency, uint32_t samplingRate, double param_4, float qFactor, double param_6); + void SetHighPassParameter(float frequency, uint32_t samplingRate, double dbGain, float qFactor, double param_6); void SetLowPassParameter(float frequency, uint32_t samplingRate, float qFactor); private: - double x_1; - double x_2; - double y_1; - double y_2; + double x1; + double x2; + double y1; + double y2; double a1; double a2; double b0; diff --git a/src/cpp/viper/utils/FIR.cpp b/src/cpp/viper/utils/FIR.cpp index 5e8407a..081a080 100644 --- a/src/cpp/viper/utils/FIR.cpp +++ b/src/cpp/viper/utils/FIR.cpp @@ -28,10 +28,10 @@ void FIR::FilterSamplesInterleaved(float *samples, uint32_t size, uint32_t chann } if (this->blockLength > size) { - memset(&this->block[size], 0, (this->blockLength - size) * sizeof(float)); + memset(this->block + size, 0, (this->blockLength - size) * sizeof(float)); } - memcpy(&this->offsetBlock[this->coeffsSize - 1], this->block, this->blockLength * sizeof(float)); + memcpy(this->offsetBlock + this->coeffsSize - 1, this->block, this->blockLength * sizeof(float)); for (uint32_t i = 0; i < this->blockLength; i++) { float sample = 0.0f; @@ -46,7 +46,7 @@ void FIR::FilterSamplesInterleaved(float *samples, uint32_t size, uint32_t chann } if (this->coeffsSize > 1) { - memcpy(&this->offsetBlock[this->coeffsSize - 2], &this->block[this->blockLength - 1], this->blockLength - (this->coeffsSize - 1) * sizeof(float)); + memcpy(this->offsetBlock + this->coeffsSize - 2, this->block + this->blockLength - 1, this->blockLength - (this->coeffsSize - 1) * sizeof(float)); } } diff --git a/src/cpp/viper/utils/MinPhaseIIRCoeffs.cpp b/src/cpp/viper/utils/MinPhaseIIRCoeffs.cpp index 716d52e..88a46b6 100644 --- a/src/cpp/viper/utils/MinPhaseIIRCoeffs.cpp +++ b/src/cpp/viper/utils/MinPhaseIIRCoeffs.cpp @@ -131,7 +131,7 @@ float MinPhaseIIRCoeffs::GetIndexFrequency(uint32_t index) { } int MinPhaseIIRCoeffs::SolveRoot(double param_2, double param_3, double param_4, double *param_5) { - double x = (param_4 - pow(param_3, 2.0) / (param_2 * 4.0)) / param_2; + double x = (param_4 - pow(param_3, 2) / (param_2 * 4.0)) / param_2; double y = param_3 / (param_2 * 2.0); if (x >= 0.0) { @@ -151,7 +151,7 @@ int MinPhaseIIRCoeffs::SolveRoot(double param_2, double param_3, double param_4, } int MinPhaseIIRCoeffs::UpdateCoeffs(uint32_t bands, uint32_t samplingRate) { - if ((bands != 10 && bands != 15 && bands != 25 && bands != 31) || samplingRate != 44100) { + if ((bands != 10 && bands != 15 && bands != 25 && bands != 31) || samplingRate < 44100) { return 0; } @@ -159,7 +159,7 @@ int MinPhaseIIRCoeffs::UpdateCoeffs(uint32_t bands, uint32_t samplingRate) { this->samplingRate = samplingRate; delete[] this->coeffs; - this->coeffs = new float[bands * 4](); + this->coeffs = new float[bands * 4](); // TODO: Check this array size const float *coeffsArray; double tmp; @@ -186,7 +186,8 @@ int MinPhaseIIRCoeffs::UpdateCoeffs(uint32_t bands, uint32_t samplingRate) { for (uint32_t i = 0; i < bands; i++) { double ret1; double ret2; - this->Find_F1_F2(coeffsArray[i], tmp, &ret1, &ret2); + + Find_F1_F2(coeffsArray[i], tmp, &ret1, &ret2); double x = (2.0 * M_PI * (double) coeffsArray[i]) / (double) this->samplingRate; double y = (2.0 * M_PI * ret2) / (double) this->samplingRate; @@ -199,10 +200,17 @@ int MinPhaseIIRCoeffs::UpdateCoeffs(uint32_t bands, uint32_t samplingRate) { double b = pow(cosX, 2.0) / 2.0; double c = pow(sinY, 2.0); - if (this->SolveRoot(((b - a) + 0.5) - c, c + (((b + pow(cosY, 2.0)) - a) - 0.5), ((pow(cosX, 2.0) / 8.0 - cosX * cosY / 4.0) + 0.125) - c / 4.0, &ret1) == 0) { + // ((b - a) + 0.5) - c + double d = ((b - a) + 0.5) - c; + // c + (((b + pow(cosY, 2.0)) - a) - 0.5) + double e = c + (((b + pow(cosY, 2.0)) - a) - 0.5); + // ((pow(cosX, 2.0) / 8.0 - cosX * cosY / 4.0) + 0.125) - c / 4.0 + double f = ((pow(cosX, 2.0) * 0.125 - cosX * cosY * 0.25) + 0.125) - c * 0.25; + + if (SolveRoot(d, e, f, &ret1) == 0) { this->coeffs[4 * i] = (float) (ret1 * 2.0); - this->coeffs[4 * i + 1] = (float) (0.5 - ret1); - this->coeffs[4 * i + 2] = (float) ((ret1 + 0.5) * cosX); + this->coeffs[4 * i + 1] = (float) (((0.5 - ret1) * 0.5) * 2.0); + this->coeffs[4 * i + 2] = (float) (((ret1 + 0.5) * cosX) * 2.0); } } diff --git a/src/cpp/viper/utils/Polyphase.cpp b/src/cpp/viper/utils/Polyphase.cpp index 9cc75ef..73ff958 100644 --- a/src/cpp/viper/utils/Polyphase.cpp +++ b/src/cpp/viper/utils/Polyphase.cpp @@ -144,7 +144,7 @@ Polyphase::Polyphase(int unknown1) { if (unknown1 == 2) { this->fir1->LoadCoefficients(POLYPHASE_COEFFICIENTS_2, sizeof(POLYPHASE_COEFFICIENTS_2) / sizeof(float), 1008); this->fir2->LoadCoefficients(POLYPHASE_COEFFICIENTS_2, sizeof(POLYPHASE_COEFFICIENTS_2) / sizeof(float), 1008); - } else if (unknown1 > 2) { + } else { // if (unknown1 < 2) this->fir1->LoadCoefficients(POLYPHASE_COEFFICIENTS_OTHER, sizeof(POLYPHASE_COEFFICIENTS_OTHER) / sizeof(float), 1008); this->fir2->LoadCoefficients(POLYPHASE_COEFFICIENTS_OTHER, sizeof(POLYPHASE_COEFFICIENTS_OTHER) / sizeof(float), 1008); } @@ -163,21 +163,23 @@ uint32_t Polyphase::GetLatency() { } uint32_t Polyphase::Process(float *samples, uint32_t size) { - if (this->waveBuffer1->PushSamples(samples, size) != 0) { - uint32_t bufferOffset = this->waveBuffer1->GetBufferOffset(); - while (bufferOffset >= 1008) { + if (this->waveBuffer1->PushSamples(samples, size)) { + while (this->waveBuffer1->GetBufferOffset() >= 1008) { if (this->waveBuffer1->PopSamples(this->buffer, 1008, false) == 1008) { this->fir1->FilterSamplesInterleaved(this->buffer, 1008, 2); this->fir2->FilterSamplesInterleaved(this->buffer + 1, 1008, 2); this->waveBuffer2->PushSamples(this->buffer, 1008); } - bufferOffset = this->waveBuffer1->GetBufferOffset(); } - if (this->waveBuffer2->GetBufferOffset() >= size) { - this->waveBuffer2->PopSamples(samples, size, true); + + if (this->waveBuffer2->GetBufferOffset() < size) { + return 0; } + + this->waveBuffer2->PopSamples(samples, size, true); } - return 0; + + return size; } void Polyphase::Reset() {