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