mirror of
https://github.com/AndroidAudioMods/ViPERFX_RE.git
synced 2024-12-22 22:47:25 +08:00
Update
This commit is contained in:
parent
9d54379bd8
commit
39aef22062
@ -1,7 +1,5 @@
|
||||
#include <cstring>
|
||||
#include <cerrno>
|
||||
#include <ctime>
|
||||
|
||||
#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<ViperContext *>(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<ViperContext *>(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<effect_param_t *>(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<effect_param_t *>(pCmdData);
|
||||
auto *pReplyParam = reinterpret_cast<effect_param_t *>(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<ViperContext *>(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<effect_handle_t>(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<ViperContext *>(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;
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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<ViPERBass::ProcessMode>(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<ViPERClarity::ClarityMode>(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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -1,53 +1,64 @@
|
||||
#include "Biquad.h"
|
||||
#include <cmath>
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user