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