From 8107aee217899f6bb5d91ad5c64eb75ff58ab2dc Mon Sep 17 00:00:00 2001 From: Iscle Date: Thu, 14 Mar 2024 14:11:11 +0100 Subject: [PATCH] Improved interface Not all effects are implemented. Untested. --- src/ViPER4Android.cpp | 4 +- src/ViPER4Android.h | 129 ++----- src/ViperContext.cpp | 368 ++++++++++++++++-- src/viper/ViPER.cpp | 586 +++++++++++++---------------- src/viper/ViPER.h | 22 +- src/viper/constants.h | 24 +- src/viper/effects/AnalogX.cpp | 20 +- src/viper/effects/ViPERBass.h | 8 +- src/viper/effects/ViPERClarity.h | 4 +- src/viper/utils/AdaptiveBuffer.cpp | 12 +- src/viper/utils/AdaptiveBuffer.h | 3 +- 11 files changed, 681 insertions(+), 499 deletions(-) diff --git a/src/ViPER4Android.cpp b/src/ViPER4Android.cpp index 76f38c7..10217e7 100644 --- a/src/ViPER4Android.cpp +++ b/src/ViPER4Android.cpp @@ -31,11 +31,11 @@ static int32_t viperInterfaceProcess(effect_handle_t self, audio_buffer_t *inBuf static int32_t viperInterfaceCommand(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, - uint32_t *replySize, void *pReplyData) { + uint32_t *pReplySize, void *pReplyData) { auto viperHandle = reinterpret_cast(self); if (viperHandle == nullptr) return -EINVAL; - return viperHandle->context->handleCommand(cmdCode, cmdSize, pCmdData, replySize, pReplyData); + return viperHandle->context->handleCommand(cmdCode, cmdSize, pCmdData, pReplySize, pReplyData); } static int32_t viperInterfaceGetDescriptor(effect_handle_t self, effect_descriptor_t *pDescriptor) { diff --git a/src/ViPER4Android.h b/src/ViPER4Android.h index e5c54f3..439b349 100644 --- a/src/ViPER4Android.h +++ b/src/ViPER4Android.h @@ -3,11 +3,6 @@ // Source: https://github.com/vipersaudio/viperfx_core_binary/blob/master/viperfx_intf.h // Updated parameters source: https://github.com/vipersaudio/viper4android_fx/blob/master/android_4.x/src/com/vipercn/viper4android_v2/service/ViPER4AndroidService.java -extern "C" { -// Command code -#define COMMAND_CODE_GET 0x01 -#define COMMAND_CODE_SET 0x02 - typedef enum { PARAM_GET_ENABLED = 0, PARAM_GET_FRAME_COUNT, @@ -17,94 +12,36 @@ typedef enum { PARAM_GET_ARCHITECTURE, } param_get_t; -// Param set -#define PARAM_SET_UPDATE_STATUS 0x9002 -#define PARAM_SET_RESET_STATUS 0x9003 - -#define PARAM_CONVOLUTION_ENABLE 65538 -#define PARAM_CONVOLUTION_PREPARE_BUFFER 65540 -#define PARAM_CONVOLUTION_SET_BUFFER 65541 -#define PARAM_CONVOLUTION_COMMIT_BUFFER 65542 -#define PARAM_CONVOLUTION_CROSS_CHANNEL 65543 - -#define PARAM_HEADPHONE_SURROUND_ENABLE 65544 -#define PARAM_HEADPHONE_SURROUND_STRENGTH 65545 - -#define PARAM_DDC_ENABLE 65546 -#define PARAM_DDC_COEFFICIENTS 65547 - -#define PARAM_SPECTRUM_EXTENSION_ENABLE 65548 -#define PARAM_SPECTRUM_EXTENSION_BARK 65549 // Bark is a scale like dB -#define PARAM_SPECTRUM_EXTENSION_BARK_RECONSTRUCT 65550 - -#define PARAM_FIR_EQUALIZER_ENABLE 65551 -#define PARAM_FIR_EQUALIZER_BAND_LEVEL 65552 - -#define PARAM_FIELD_SURROUND_ENABLE 65553 -#define PARAM_FIELD_SURROUND_WIDENING 65554 -#define PARAM_FIELD_SURROUND_MID_IMAGE 65555 -#define PARAM_FIELD_SURROUND_DEPTH 65556 - -#define PARAM_DIFFERENTIAL_SURROUND_ENABLE 65557 -#define PARAM_DIFFERENTIAL_SURROUND_DELAY 65558 - -#define PARAM_REVERBERATION_ENABLE 0x10017 -#define PARAM_REVERBERATION_ROOM_SIZE 0x10018 -#define PARAM_REVERBERATION_ROOM_WIDTH 0x10019 -#define PARAM_REVERBERATION_ROOM_DAMPENING 0x1001A -#define PARAM_REVERBERATION_ROOM_WET_SIGNAL 0x1001B -#define PARAM_REVERBERATION_ROOM_DRY_SIGNAL 0x1001C - -#define PARAM_AUTOMATIC_GAIN_CONTROL_ENABLE 65565 -#define PARAM_AUTOMATIC_GAIN_CONTROL_RATIO 65566 -#define PARAM_AUTOMATIC_GAIN_CONTROL_VOLUME 65567 -#define PARAM_AUTOMATIC_GAIN_CONTROL_MAX_SCALER 65568 - -#define PARAM_DYNAMIC_SYSTEM_ENABLE 65569 -#define PARAM_DYNAMIC_SYSTEM_X_COEFFICIENTS 65570 -#define PARAM_DYNAMIC_SYSTEM_Y_COEFFICIENTS 65571 -#define PARAM_DYNAMIC_SYSTEM_SIDE_GAIN 65572 -#define PARAM_DYNAMIC_SYSTEM_STRENGTH 65573 - -#define PARAM_FIDELITY_BASS_ENABLE 65574 -#define PARAM_FIDELITY_BASS_MODE 65575 -#define PARAM_FIDELITY_BASS_FREQUENCY 65576 -#define PARAM_FIDELITY_BASS_GAIN 65577 - -#define PARAM_FIDELITY_CLARITY_ENABLE 65578 -#define PARAM_FIDELITY_CLARITY_MODE 65579 -#define PARAM_FIDELITY_CLARITY_GAIN 65580 - -#define PARAM_CURE_CROSS_FEED_ENABLED 65581 -#define PARAM_CURE_CROSS_FEED_STRENGTH 65582 - -#define PARAM_TUBE_SIMULATOR_ENABLED 65583 - -#define PARAM_ANALOGX_ENABLE 65584 -#define PARAM_ANALOGX_MODE 65585 - -#define PARAM_GATE_OUTPUT_VOLUME 65586 -#define PARAM_GATE_CHANNEL_PAN 65587 -#define PARAM_GATE_LIMIT 65588 - -#define PARAM_SPEAKER_OPTIMIZATION 65603 - -#define PARAM_FET_COMPRESSOR_ENABLE 65610 -#define PARAM_FET_COMPRESSOR_THRESHOLD 65611 -#define PARAM_FET_COMPRESSOR_RATIO 65612 -#define PARAM_FET_COMPRESSOR_KNEE 65613 -#define PARAM_FET_COMPRESSOR_AUTO_KNEE 65614 -#define PARAM_FET_COMPRESSOR_GAIN 65615 -#define PARAM_FET_COMPRESSOR_AUTO_GAIN 65616 -#define PARAM_FET_COMPRESSOR_ATTACK 65617 -#define PARAM_FET_COMPRESSOR_AUTO_ATTACK 65618 -#define PARAM_FET_COMPRESSOR_RELEASE 65619 -#define PARAM_FET_COMPRESSOR_AUTO_RELEASE 65620 -#define PARAM_FET_COMPRESSOR_KNEE_MULTI 65621 -#define PARAM_FET_COMPRESSOR_MAX_ATTACK 65622 -#define PARAM_FET_COMPRESSOR_MAX_RELEASE 65623 -#define PARAM_FET_COMPRESSOR_CREST 65624 -#define PARAM_FET_COMPRESSOR_ADAPT 65625 -#define PARAM_FET_COMPRESSOR_NO_CLIP 65626 - -} +typedef enum { + PARAM_SET_RESET = 0, + PARAM_SET_DDC_ENABLE, + PARAM_SET_DDC_COEFFICIENTS, + PARAM_SET_VIPER_BASS_ENABLE, + PARAM_SET_VIPER_BASS_MODE, + PARAM_SET_VIPER_BASS_FREQUENCY, + PARAM_SET_VIPER_BASS_GAIN, + PARAM_SET_VIPER_CLARITY_ENABLE, + PARAM_SET_VIPER_CLARITY_MODE, + PARAM_SET_VIPER_CLARITY_GAIN, + PARAM_SET_OUTPUT_GAIN, + PARAM_SET_THRESHOLD_LIMIT, + PARAM_SET_SPEAKER_OPTIMIZATION_ENABLE, + PARAM_SET_ANALOGX_ENABLE, + PARAM_SET_ANALOGX_LEVEL, + PARAM_SET_TUBE_SIMULATOR_ENABLE, + PARAM_SET_CURE_ENABLE, + PARAM_SET_CURE_LEVEL, + PARAM_SET_REVERBERATION_ENABLE, + PARAM_SET_REVERBERATION_ROOM_SIZE, + PARAM_SET_REVERBERATION_SOUND_FIELD, + PARAM_SET_REVERBERATION_DAMPING, + PARAM_SET_REVERBERATION_WET_SIGNAL, + PARAM_SET_REVERBERATION_DRY_SIGNAL, + PARAM_SET_DIFFERENTIAL_SURROUND_ENABLE, + PARAM_SET_DIFFERENTIAL_SURROUND_DELAY, + PARAM_SET_FIELD_SURROUND_ENABLE, + PARAM_SET_FIELD_SURROUND_DEPTH, + PARAM_SET_FIELD_SURROUND_MID_IMAGE, + PARAM_SET_IIR_EQUALIZER_ENABLE, + PARAM_SET_IIR_EQUALIZER_BAND_LEVEL, +} param_set_t; diff --git a/src/ViperContext.cpp b/src/ViperContext.cpp index d9e64da..be1c6b6 100644 --- a/src/ViperContext.cpp +++ b/src/ViperContext.cpp @@ -10,7 +10,7 @@ ViperContext::ViperContext() : config({}), - disableReason(DisableReason::NONE), + disableReason(DisableReason::UNKNOWN), buffer(std::vector()), bufferFrameCount(0), enabled(false) { @@ -125,8 +125,8 @@ void ViperContext::handleSetConfig(effect_config_t *newConfig) { bufferFrameCount = config.inputCfg.buffer.frameCount; // ViPER - viper.samplingRate = config.inputCfg.samplingRate; - viper.resetAllEffects(); + viper.setSamplingRate(config.inputCfg.samplingRate); + viper.reset(); } int32_t ViperContext::handleSetParam(effect_param_t *pCmdParam, void *pReplyData) { @@ -134,42 +134,332 @@ int32_t ViperContext::handleSetParam(effect_param_t *pCmdParam, void *pReplyData // 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; + if (pCmdParam->psize != sizeof(uint32_t)) { + VIPER_LOGE("handleSetParam() EFFECT_CMD_SET_PARAM called with invalid psize = %d, expected psize = %zu", pCmdParam->vsize, sizeof(uint32_t)); + return -EINVAL; + } - int param = *(int *) (pCmdParam->data); - int *intValues = (int *) (pCmdParam->data + vOffset); - switch (pCmdParam->vsize) { - case sizeof(int): { - viper.DispatchCommand(param, intValues[0], 0, 0, 0, 0, nullptr); + *(int32_t *) pReplyData = 0; + + uint32_t key = *(uint32_t *) (pCmdParam->data); + switch (key) { + case PARAM_SET_RESET: { + viper.reset(); return 0; } - case sizeof(int) * 2: { - viper.DispatchCommand(param, intValues[0], intValues[1], 0, 0, 0, nullptr); + case PARAM_SET_DDC_ENABLE: { + return 0; } - case sizeof(int) * 3: { - viper.DispatchCommand(param, intValues[0], intValues[1], intValues[2], 0, 0, nullptr); + case PARAM_SET_DDC_COEFFICIENTS: { + return 0; } - case sizeof(int) * 4: { - viper.DispatchCommand(param, intValues[0], intValues[1], intValues[2], intValues[3], 0, nullptr); + case PARAM_SET_VIPER_BASS_ENABLE: { + if (pCmdParam->vsize != sizeof(uint8_t)) { + VIPER_LOGE("handleSetParam() PARAM_SET_VIPER_BASS_ENABLE called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint8_t)); + return -EINVAL; + } + bool enable = *(uint8_t *) (pCmdParam->data + vOffset) != 0; + viper.viperBass.SetEnable(enable); return 0; } - case 256: - case 1024: { - uint32_t arrSize = *(uint32_t *) (pCmdParam->data + vOffset); - signed char *arr = (signed char *) (pCmdParam->data + vOffset + sizeof(uint32_t)); - viper.DispatchCommand(param, 0, 0, 0, 0, arrSize, arr); + case PARAM_SET_VIPER_BASS_MODE: { + if (pCmdParam->vsize != sizeof(uint8_t)) { + VIPER_LOGE("handleSetParam() PARAM_SET_VIPER_BASS_MODE called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint8_t)); + return -EINVAL; + } + uint8_t mode = *(uint8_t *) (pCmdParam->data + vOffset); + if (mode > 2) { + VIPER_LOGE("handleSetParam() PARAM_SET_VIPER_BASS_MODE called with invalid mode = %d, expected mode = 0, 1 or 2", mode); + *(int32_t *) pReplyData = -EINVAL; + return 0; + } + + viper.viperBass.SetProcessMode(static_cast(mode)); return 0; } - case 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)); - viper.DispatchCommand(param, value1, 0, 0, 0, arrSize, arr); + case PARAM_SET_VIPER_BASS_FREQUENCY: { + if (pCmdParam->vsize != sizeof(uint8_t)) { + VIPER_LOGE("handleSetParam() PARAM_SET_VIPER_BASS_FREQUENCY called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint8_t)); + return -EINVAL; + } + uint8_t frequency = *(uint8_t *) (pCmdParam->data + vOffset); + viper.viperBass.SetSpeaker(frequency); + return 0; + } + case PARAM_SET_VIPER_BASS_GAIN: { + if (pCmdParam->vsize != sizeof(uint16_t)) { + VIPER_LOGE("handleSetParam() PARAM_SET_VIPER_BASS_GAIN called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint16_t)); + return -EINVAL; + } + uint16_t gain = *(uint16_t *) (pCmdParam->data + vOffset); + viper.viperBass.SetBassFactor(static_cast(gain) / 100.0f); + return 0; + } + case PARAM_SET_VIPER_CLARITY_ENABLE: { + if (pCmdParam->vsize != sizeof(uint8_t)) { + VIPER_LOGE("handleSetParam() PARAM_SET_VIPER_CLARITY_ENABLE called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint8_t)); + return -EINVAL; + } + bool enable = *(uint8_t *) (pCmdParam->data + vOffset) != 0; + viper.viperClarity.SetEnable(enable); + return 0; + } + case PARAM_SET_VIPER_CLARITY_MODE: { + if (pCmdParam->vsize != sizeof(uint8_t)) { + VIPER_LOGE("handleSetParam() PARAM_SET_VIPER_CLARITY_MODE called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint8_t)); + return -EINVAL; + } + uint8_t mode = *(uint8_t *) (pCmdParam->data + vOffset); + if (mode > 2) { + VIPER_LOGE("handleSetParam() PARAM_SET_VIPER_CLARITY_MODE called with invalid mode = %d, expected mode = 0, 1 or 2", mode); + *(int32_t *) pReplyData = -EINVAL; + return 0; + } + + viper.viperClarity.SetProcessMode(static_cast(mode)); + return 0; + } + case PARAM_SET_VIPER_CLARITY_GAIN: { + if (pCmdParam->vsize != sizeof(uint16_t)) { + VIPER_LOGE("handleSetParam() PARAM_SET_VIPER_CLARITY_GAIN called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint16_t)); + return -EINVAL; + } + uint16_t gain = *(uint16_t *) (pCmdParam->data + vOffset); + viper.viperClarity.SetClarity(static_cast(gain) / 100.0f); + return 0; + } + case PARAM_SET_OUTPUT_GAIN: { + // 0 - 255 + if (pCmdParam->vsize != sizeof(uint8_t) * 2) { + VIPER_LOGE("handleSetParam() PARAM_SET_OUTPUT_GAIN called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint8_t) * 2); + return -EINVAL; + } + uint8_t gainL = *(uint8_t *) (pCmdParam->data + vOffset); + uint8_t gainR = *(uint8_t *) (pCmdParam->data + vOffset + sizeof(uint8_t)); + viper.setGain(static_cast(gainL) / 100.0f, static_cast(gainR) / 100.0f); + return 0; + } + case PARAM_SET_THRESHOLD_LIMIT: { + // 0 - 100 (TODO: Check range) + if (pCmdParam->vsize != sizeof(uint8_t)) { + VIPER_LOGE("handleSetParam() PARAM_SET_THRESHOLD_LIMIT called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint8_t)); + return -EINVAL; + } + uint8_t limit = *(uint8_t *) (pCmdParam->data + vOffset); + viper.setThresholdLimit(static_cast(limit) / 100.0f); + return 0; + } + case PARAM_SET_SPEAKER_OPTIMIZATION_ENABLE: { + if (pCmdParam->vsize != sizeof(uint8_t)) { + VIPER_LOGE("handleSetParam() PARAM_SET_SPEAKER_OPTIMIZATION_ENABLE called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint8_t)); + return -EINVAL; + } + bool enable = *(uint8_t *) (pCmdParam->data + vOffset) != 0; + viper.speakerCorrection.SetEnable(enable); + return 0; + } + case PARAM_SET_ANALOGX_ENABLE: { + if (pCmdParam->vsize != sizeof(uint8_t)) { + VIPER_LOGE("handleSetParam() PARAM_SET_ANALOGX_ENABLE called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint8_t)); + return -EINVAL; + } + bool enable = *(uint8_t *) (pCmdParam->data + vOffset) != 0; + viper.analogX.SetEnable(enable); + return 0; + } + case PARAM_SET_ANALOGX_LEVEL: { + if (pCmdParam->vsize != sizeof(uint8_t)) { + VIPER_LOGE("handleSetParam() PARAM_SET_ANALOGX_LEVEL called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint8_t)); + return -EINVAL; + } + uint8_t level = *(uint8_t *) (pCmdParam->data + vOffset); + if (level > 2) { + VIPER_LOGE("handleSetParam() PARAM_SET_ANALOGX_LEVEL called with invalid level = %d, expected level = 0, 1 or 2", level); + *(int32_t *) pReplyData = -EINVAL; + return 0; + } + + viper.analogX.SetProcessingModel(level); + return 0; + } + case PARAM_SET_TUBE_SIMULATOR_ENABLE: { + if (pCmdParam->vsize != sizeof(uint8_t)) { + VIPER_LOGE("handleSetParam() PARAM_SET_TUBE_SIMULATOR_ENABLE called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint8_t)); + return -EINVAL; + } + bool enable = *(uint8_t *) (pCmdParam->data + vOffset) != 0; + viper.tubeSimulator.SetEnable(enable); + return 0; + } + case PARAM_SET_CURE_ENABLE: { + if (pCmdParam->vsize != sizeof(uint8_t)) { + VIPER_LOGE("handleSetParam() PARAM_SET_CURE_ENABLE called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint8_t)); + return -EINVAL; + } + bool enable = *(uint8_t *) (pCmdParam->data + vOffset) != 0; + viper.cure.SetEnable(enable); + return 0; + } + case PARAM_SET_CURE_LEVEL: { + if (pCmdParam->vsize != sizeof(uint8_t)) { + VIPER_LOGE("handleSetParam() PARAM_SET_CURE_LEVEL called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint8_t)); + return -EINVAL; + } + uint8_t level = *(uint8_t *) (pCmdParam->data + vOffset); + switch (level) { + case 0: { + struct Crossfeed::Preset preset = { + .cutoff = 650, + .feedback = 95, + }; + viper.cure.SetPreset(preset); + break; + } + case 1: { + struct Crossfeed::Preset preset = { + .cutoff = 700, + .feedback = 60, + }; + viper.cure.SetPreset(preset); + break; + } + case 2: { + struct Crossfeed::Preset preset = { + .cutoff = 700, + .feedback = 45, + }; + viper.cure.SetPreset(preset); + break; + } + default: + VIPER_LOGE("handleSetParam() PARAM_SET_CURE_LEVEL called with invalid level = %d, expected level = 0, 1 or 2", level); + *(int32_t *) pReplyData = -EINVAL; + break; + } + return 0; + } + case PARAM_SET_REVERBERATION_ENABLE: { + if (pCmdParam->vsize != sizeof(uint8_t)) { + VIPER_LOGE("handleSetParam() PARAM_SET_REVERBERATION_ENABLE called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint8_t)); + return -EINVAL; + } + bool enable = *(uint8_t *) (pCmdParam->data + vOffset) != 0; + viper.reverberation.SetEnable(enable); + return 0; + } + case PARAM_SET_REVERBERATION_ROOM_SIZE: { + if (pCmdParam->vsize != sizeof(uint8_t)) { + VIPER_LOGE("handleSetParam() PARAM_SET_REVERBERATION_ROOM_SIZE called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint8_t)); + return -EINVAL; + } + uint8_t roomSize = *(uint8_t *) (pCmdParam->data + vOffset); + viper.reverberation.SetRoomSize(static_cast(roomSize) / 100.0f); + return 0; + } + case PARAM_SET_REVERBERATION_SOUND_FIELD: { + if (pCmdParam->vsize != sizeof(uint8_t)) { + VIPER_LOGE("handleSetParam() PARAM_SET_REVERBERATION_SOUND_FIELD called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint8_t)); + return -EINVAL; + } + uint8_t soundField = *(uint8_t *) (pCmdParam->data + vOffset); + viper.reverberation.SetWidth(static_cast(soundField) / 100.0f); + return 0; + } + case PARAM_SET_REVERBERATION_DAMPING: { + if (pCmdParam->vsize != sizeof(uint8_t)) { + VIPER_LOGE("handleSetParam() PARAM_SET_REVERBERATION_DAMPING called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint8_t)); + return -EINVAL; + } + uint8_t damping = *(uint8_t *) (pCmdParam->data + vOffset); + viper.reverberation.SetDamp(static_cast(damping) / 100.0f); + return 0; + } + case PARAM_SET_REVERBERATION_WET_SIGNAL: { + if (pCmdParam->vsize != sizeof(uint8_t)) { + VIPER_LOGE("handleSetParam() PARAM_SET_REVERBERATION_WET_SIGNAL called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint8_t)); + return -EINVAL; + } + uint8_t wetSignal = *(uint8_t *) (pCmdParam->data + vOffset); + viper.reverberation.SetWet(static_cast(wetSignal) / 100.0f); + return 0; + } + case PARAM_SET_REVERBERATION_DRY_SIGNAL: { + if (pCmdParam->vsize != sizeof(uint8_t)) { + VIPER_LOGE("handleSetParam() PARAM_SET_REVERBERATION_DRY_SIGNAL called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint8_t)); + return -EINVAL; + } + uint8_t drySignal = *(uint8_t *) (pCmdParam->data + vOffset); + viper.reverberation.SetDry(static_cast(drySignal) / 100.0f); + return 0; + } + case PARAM_SET_DIFFERENTIAL_SURROUND_ENABLE: { + if (pCmdParam->vsize != sizeof(uint8_t)) { + VIPER_LOGE("handleSetParam() PARAM_SET_DIFFERENTIAL_SURROUND_ENABLE called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint8_t)); + return -EINVAL; + } + bool enable = *(uint8_t *) (pCmdParam->data + vOffset) != 0; + viper.diffSurround.SetEnable(enable); + return 0; + } + case PARAM_SET_DIFFERENTIAL_SURROUND_DELAY: { + if (pCmdParam->vsize != sizeof(uint16_t)) { + VIPER_LOGE("handleSetParam() PARAM_SET_DIFFERENTIAL_SURROUND_DELAY called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint16_t)); + return -EINVAL; + } + uint16_t delay = *(uint16_t *) (pCmdParam->data + vOffset); + viper.diffSurround.SetDelayTime(static_cast(delay) / 100.0f); + return 0; + } + case PARAM_SET_FIELD_SURROUND_ENABLE: { + if (pCmdParam->vsize != sizeof(uint8_t)) { + VIPER_LOGE("handleSetParam() PARAM_SET_FIELD_SURROUND_ENABLE called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint8_t)); + return -EINVAL; + } + bool enable = *(uint8_t *) (pCmdParam->data + vOffset) != 0; + viper.colorfulMusic.SetEnable(enable); + return 0; + } + case PARAM_SET_FIELD_SURROUND_DEPTH: { + if (pCmdParam->vsize != sizeof(uint16_t)) { + VIPER_LOGE("handleSetParam() PARAM_SET_FIELD_SURROUND_DEPTH called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint16_t)); + return -EINVAL; + } + uint16_t depth = *(uint16_t *) (pCmdParam->data + vOffset); + viper.colorfulMusic.SetDepthValue(depth); + return 0; + } + case PARAM_SET_FIELD_SURROUND_MID_IMAGE: { + if (pCmdParam->vsize != sizeof(uint8_t)) { + VIPER_LOGE("handleSetParam() PARAM_SET_FIELD_SURROUND_MID_IMAGE called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint8_t)); + return -EINVAL; + } + uint8_t midImage = *(uint8_t *) (pCmdParam->data + vOffset); + viper.colorfulMusic.SetMidImageValue(static_cast(midImage) / 100.0f); + return 0; + } + case PARAM_SET_IIR_EQUALIZER_ENABLE: { + if (pCmdParam->vsize != sizeof(uint8_t)) { + VIPER_LOGE("handleSetParam() PARAM_SET_IIR_EQUALIZER_ENABLE called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint8_t)); + return -EINVAL; + } + bool enable = *(uint8_t *) (pCmdParam->data + vOffset) != 0; + viper.iirFilter.SetEnable(enable); + return 0; + } + case PARAM_SET_IIR_EQUALIZER_BAND_LEVEL: { + if (pCmdParam->vsize != sizeof(uint8_t) + sizeof(int16_t)) { + VIPER_LOGE("handleSetParam() PARAM_SET_IIR_EQUALIZER_BAND_LEVEL called with invalid vsize = %d, expected vsize = %zu", pCmdParam->vsize, sizeof(uint8_t) + sizeof(int16_t)); + return -EINVAL; + } + uint8_t band = *(uint8_t *) (pCmdParam->data + vOffset); + int16_t level = *(int16_t *) (pCmdParam->data + vOffset + sizeof(uint8_t)); + viper.iirFilter.SetBandLevel(band, static_cast(level) / 100.0f); return 0; } default: { + VIPER_LOGE("handleSetParam() called with unknown key: %d", key); return -EINVAL; } } @@ -180,11 +470,15 @@ int32_t ViperContext::handleGetParam(effect_param_t *pCmdParam, effect_param_t * // 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("handleGetParam() EFFECT_CMD_GET_PARAM called with data = %d, psize = %d, vsize = %d", *(uint32_t *) pCmdParam->data, pCmdParam->psize, pCmdParam->vsize); + if (pCmdParam->psize != sizeof(uint32_t)) { + VIPER_LOGE("handleGetParam() EFFECT_CMD_GET_PARAM called with invalid psize = %d, expected psize = %zu", pCmdParam->vsize, sizeof(uint32_t)); + return -EINVAL; + } memcpy(pReplyParam, pCmdParam, sizeof(effect_param_t) + pCmdParam->psize); - switch (*(uint32_t *) pCmdParam->data) { + uint32_t key = *(uint32_t *) (pCmdParam->data); + switch (key) { case PARAM_GET_ENABLED: { pReplyParam->status = 0; pReplyParam->vsize = sizeof(uint8_t); @@ -195,7 +489,7 @@ int32_t ViperContext::handleGetParam(effect_param_t *pCmdParam, effect_param_t * case PARAM_GET_FRAME_COUNT: { pReplyParam->status = 0; pReplyParam->vsize = sizeof(uint64_t); - *(uint64_t *) (pReplyParam->data + vOffset) = viper.frameCount; + *(uint64_t *) (pReplyParam->data + vOffset) = viper.getFrameCount(); *pReplySize = sizeof(effect_param_t) + pReplyParam->psize + vOffset + pReplyParam->vsize; return 0; } @@ -236,13 +530,15 @@ int32_t ViperContext::handleGetParam(effect_param_t *pCmdParam, effect_param_t * case PARAM_GET_ARCHITECTURE: { pReplyParam->status = 0; pReplyParam->vsize = sizeof(uint8_t); - *(uint8_t *) (pReplyParam->data + vOffset) = VIPER_ARCHITECTURE; + *(uint8_t *) (pReplyParam->data + vOffset) = static_cast(VIPER_ARCHITECTURE); *pReplySize = sizeof(effect_param_t) + pReplyParam->psize + vOffset + pReplyParam->vsize; return 0; } + default: { + VIPER_LOGE("handleGetParam() called with unknown key: %d", key); + return -EINVAL; + } } - - return -EINVAL; } int32_t ViperContext::handleCommand(uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, uint32_t *pReplySize, void *pReplyData) { @@ -257,8 +553,8 @@ int32_t ViperContext::handleCommand(uint32_t cmdCode, uint32_t cmdSize, void *pC return 0; } case EFFECT_CMD_SET_CONFIG: { - if (cmdSize < sizeof(effect_config_t) || pCmdData == nullptr || replySize != sizeof(int32_t) || pReplyData == nullptr) { - VIPER_LOGE("EFFECT_CMD_SET_CONFIG called with invalid cmdSize = %d, pCmdData = %p, replySize = %d, pReplyData = %p, expected cmdSize = %zu, replySize = %zu", cmdSize, pCmdData, replySize, pReplyData, sizeof(effect_config_t), sizeof(int32_t)); + if (cmdSize != sizeof(effect_config_t) || pCmdData == nullptr || replySize != sizeof(int32_t) || pReplyData == nullptr) { + VIPER_LOGE("EFFECT_CMD_SET_CONFIG called with invalid cmdSize = %d, pCmdData = %p, replySize = %d, pReplyData = %p, expected cmdSize = %zu, expected replySize = %zu", cmdSize, pCmdData, replySize, pReplyData, sizeof(effect_config_t), sizeof(int32_t)); return -EINVAL; } handleSetConfig((effect_config_t *) pCmdData); @@ -270,7 +566,7 @@ int32_t ViperContext::handleCommand(uint32_t cmdCode, uint32_t cmdSize, void *pC VIPER_LOGE("EFFECT_CMD_RESET called with invalid replySize = %d, pReplyData = %p, expected replySize = %zu", replySize, pReplyData, sizeof(int32_t)); return -EINVAL; } - viper.resetAllEffects(); + viper.reset(); SET(int32_t, pReplyData, 0); return 0; } @@ -294,14 +590,14 @@ int32_t ViperContext::handleCommand(uint32_t cmdCode, uint32_t cmdSize, void *pC } case EFFECT_CMD_SET_PARAM: { if (cmdSize < sizeof(effect_param_t) || pCmdData == nullptr || replySize != sizeof(int32_t) || pReplyData == nullptr) { - VIPER_LOGE("EFFECT_CMD_SET_PARAM called with invalid cmdSize = %d, pCmdData = %p, replySize = %d, pReplyData = %p, expected cmdSize = %zu, replySize = %zu", cmdSize, pCmdData, replySize, pReplyData, sizeof(effect_param_t), sizeof(int32_t)); + VIPER_LOGE("EFFECT_CMD_SET_PARAM called with invalid cmdSize = %d, pCmdData = %p, replySize = %d, pReplyData = %p, expected cmdSize >= %zu, expected replySize >= %zu", cmdSize, pCmdData, replySize, pReplyData, sizeof(effect_param_t), sizeof(int32_t)); return -EINVAL; } return handleSetParam((effect_param_t *) pCmdData, pReplyData); } case EFFECT_CMD_GET_PARAM: { if (cmdSize < sizeof(effect_param_t) || pCmdData == nullptr || replySize < sizeof(effect_param_t) || pReplyData == nullptr) { - VIPER_LOGE("EFFECT_CMD_GET_PARAM called with invalid cmdSize = %d, pCmdData = %p, replySize = %d, pReplyData = %p, expected cmdSize = %zu, replySize = %zu", cmdSize, pCmdData, replySize, pReplyData, sizeof(effect_param_t), sizeof(effect_param_t)); + VIPER_LOGE("EFFECT_CMD_GET_PARAM called with invalid cmdSize = %d, pCmdData = %p, replySize = %d, pReplyData = %p, expected cmdSize >= %zu, expected replySize >= %zu", cmdSize, pCmdData, replySize, pReplyData, sizeof(effect_param_t), sizeof(effect_param_t)); return -EINVAL; } return handleGetParam((effect_param_t *) pCmdData, (effect_param_t *) pReplyData, pReplySize); diff --git a/src/viper/ViPER.cpp b/src/viper/ViPER.cpp index 90aaa80..1d0fdcc 100644 --- a/src/viper/ViPER.cpp +++ b/src/viper/ViPER.cpp @@ -8,7 +8,9 @@ ViPER::ViPER() : samplingRate(VIPER_DEFAULT_SAMPLING_RATE), adaptiveBuffer(AdaptiveBuffer(2, 4096)), waveBuffer(WaveBuffer(2, 4096)), - iirFilter(IIRFilter(10)) { + iirFilter(IIRFilter(10)), + gainL(1.0), + gainR(1.0) { VIPER_LOGI("Welcome to ViPER FX"); VIPER_LOGI("Current version is %d", VIPER_VERSION); @@ -82,11 +84,6 @@ ViPER::ViPER() : for (auto &softwareLimiter: this->softwareLimiters) { softwareLimiter.Reset(); } - - this->frameScale = 1.0; - this->leftPan = 1.0; - this->rightPan = 1.0; - this->frameCount = 0; } void ViPER::process(std::vector& buffer, uint32_t size) { @@ -153,12 +150,8 @@ void ViPER::process(std::vector& buffer, uint32_t size) { this->tubeSimulator.TubeProcess(tmpBuf, size); this->analogX.Process(tmpBuf, tmpBufSize); - if (this->frameScale != 1.0) { - this->adaptiveBuffer.ScaleFrames(this->frameScale); - } - - if (this->leftPan < 1.0 || this->rightPan < 1.0) { - this->adaptiveBuffer.PanFrames(this->leftPan, this->rightPan); + if (this->gainL != 1.0f || this->gainR != 1.0f) { + this->adaptiveBuffer.SetGain(this->gainL, this->gainR); } for (uint32_t i = 0; i < tmpBufSize * 2; i += 2) { @@ -180,310 +173,255 @@ void ViPER::process(std::vector& buffer, uint32_t size) { memset(buffer.data(), 0, (size - tmpBufSize) * sizeof(float)); } -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_RESET_STATUS: { - this->resetAllEffects(); - break; - } - case PARAM_CONVOLUTION_ENABLE: { +//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_RESET_STATUS: { +// this->reset(); +// break; +// } +// case PARAM_CONVOLUTION_ENABLE: { // this->convolver.SetEnabled(val1 != 0); - break; - } // 0x10002 - case PARAM_CONVOLUTION_PREPARE_BUFFER: { - break; - } // 0x10004 - case PARAM_CONVOLUTION_SET_BUFFER: { - break; - } // 0x10005 - case PARAM_CONVOLUTION_COMMIT_BUFFER: { - break; - } // 0x10006 - case PARAM_CONVOLUTION_CROSS_CHANNEL: { - this->convolver.SetCrossChannel((float) val1 / 100.0f); - break; - } // 0x10007 - case PARAM_HEADPHONE_SURROUND_ENABLE: { - this->vhe.SetEnable(val1 != 0); - break; - } // 0x10008 - case PARAM_HEADPHONE_SURROUND_STRENGTH: { - this->vhe.SetEffectLevel(val1); - break; - } // 0x10009 - case PARAM_DDC_ENABLE: { - this->viperDdc.SetEnable(val1 != 0); - break; - } // 0x1000A - case PARAM_DDC_COEFFICIENTS: { - this->viperDdc.SetCoeffs(arrSize, (float *) arr, (float *) (arr + arrSize * sizeof(float))); - break; - } // 0x1000B - case PARAM_SPECTRUM_EXTENSION_ENABLE: { - this->spectrumExtend.SetEnable(val1 != 0); - break; - } // 0x1000C - case PARAM_SPECTRUM_EXTENSION_BARK: { - this->spectrumExtend.SetReferenceFrequency(val1); - break; - } // 0x1000D - case PARAM_SPECTRUM_EXTENSION_BARK_RECONSTRUCT: { - this->spectrumExtend.SetExciter((float) val1 / 100.0f); - break; - } // 0x1000E - case PARAM_FIR_EQUALIZER_ENABLE: { - this->iirFilter.SetEnable(val1 != 0); - break; - } // 0x1000F - case PARAM_FIR_EQUALIZER_BAND_LEVEL: { - this->iirFilter.SetBandLevel((uint32_t) val1, (float) val2 / 100.0f); - break; - } // 0x10010 - case PARAM_FIELD_SURROUND_ENABLE: { - this->colorfulMusic.SetEnable(val1 != 0); - break; - } // 0x10011 - case PARAM_FIELD_SURROUND_WIDENING: { - this->colorfulMusic.SetWidenValue((float) val1 / 100.0f); - break; - } // 0x10012 - case PARAM_FIELD_SURROUND_MID_IMAGE: { - this->colorfulMusic.SetMidImageValue((float) val1 / 100.0f); - break; - } // 0x10013 - case PARAM_FIELD_SURROUND_DEPTH: { - this->colorfulMusic.SetDepthValue((short) val1); - break; - } // 0x10014 - case PARAM_DIFFERENTIAL_SURROUND_ENABLE: { - this->diffSurround.SetEnable(val1 != 0); - break; - } // 0x10015 - case PARAM_DIFFERENTIAL_SURROUND_DELAY: { - this->diffSurround.SetDelayTime((float) val1 / 100.0f); - break; - } // 0x10016 - case PARAM_REVERBERATION_ENABLE: { - this->reverberation.SetEnable(val1 != 0); - break; - } // 0x10017 - case PARAM_REVERBERATION_ROOM_SIZE: { - this->reverberation.SetRoomSize((float) val1 / 100.0f); - break; - } // 0x10018 - case PARAM_REVERBERATION_ROOM_WIDTH: { - this->reverberation.SetWidth((float) val1 / 100.0f); - break; - } // 0x10019 - case PARAM_REVERBERATION_ROOM_DAMPENING: { - this->reverberation.SetDamp((float) val1 / 100.0f); - break; - } // 0x1001A - case PARAM_REVERBERATION_ROOM_WET_SIGNAL: { - this->reverberation.SetWet((float) val1 / 100.0f); - break; - } // 0x1001B - case PARAM_REVERBERATION_ROOM_DRY_SIGNAL: { - this->reverberation.SetDry((float) val1 / 100.0f); - break; - } // 0x1001C - case PARAM_AUTOMATIC_GAIN_CONTROL_ENABLE: { - this->playbackGain.SetEnable(val1 != 0); - break; - } // 0x1001D - case PARAM_AUTOMATIC_GAIN_CONTROL_RATIO: { - this->playbackGain.SetRatio((float) val1 / 100.0f); - break; - } // 0x1001E - case PARAM_AUTOMATIC_GAIN_CONTROL_VOLUME: { - this->playbackGain.SetVolume((float) val1 / 100.0f); - break; - } // 0x1001F - case PARAM_AUTOMATIC_GAIN_CONTROL_MAX_SCALER: { - this->playbackGain.SetMaxGainFactor((float) val1 / 100.0f); - break; - } // 0x10020 - case PARAM_DYNAMIC_SYSTEM_ENABLE: { - this->dynamicSystem.SetEnable(val1 != 0); - break; - } // 0x10021 - case PARAM_DYNAMIC_SYSTEM_X_COEFFICIENTS: { - this->dynamicSystem.SetXCoeffs(val1, val2); - break; - } // 0x10022 - case PARAM_DYNAMIC_SYSTEM_Y_COEFFICIENTS: { - this->dynamicSystem.SetYCoeffs(val1, val2); - break; - } // 0x10023 - case PARAM_DYNAMIC_SYSTEM_SIDE_GAIN: { - this->dynamicSystem.SetSideGain((float) val1 / 100.0f, (float) val2 / 100.0f); - break; - } // 0x10024 - case PARAM_DYNAMIC_SYSTEM_STRENGTH: { - this->dynamicSystem.SetBassGain((float) val1 / 100.0f); - break; - } // 0x10025 - case PARAM_FIDELITY_BASS_ENABLE: { - this->viperBass.SetEnable(val1 != 0); - break; - } // 0x10026 - case PARAM_FIDELITY_BASS_MODE: { - this->viperBass.SetProcessMode((ViPERBass::ProcessMode) val1); - break; - } // 0x10027 - case PARAM_FIDELITY_BASS_FREQUENCY: { - this->viperBass.SetSpeaker((uint32_t) val1); - break; - } // 0x10028 - case PARAM_FIDELITY_BASS_GAIN: { - this->viperBass.SetBassFactor((float) val1 / 100.0f); - break; - } // 0x10029 - case PARAM_FIDELITY_CLARITY_ENABLE: { - this->viperClarity.SetEnable(val1 != 0); - break; - } // 0x1002A - case PARAM_FIDELITY_CLARITY_MODE: { - this->viperClarity.SetProcessMode((ViPERClarity::ClarityMode) val1); - break; - } // 0x1002B - case PARAM_FIDELITY_CLARITY_GAIN: { - this->viperClarity.SetClarity((float) val1 / 100.0f); - break; - } // 0x1002C - case PARAM_CURE_CROSS_FEED_ENABLED: { - this->cure.SetEnable(val1 != 0); - break; - } // 0x1002D - case PARAM_CURE_CROSS_FEED_STRENGTH: { - switch (val1) { - case 0: { - // Cure_R::SetPreset(pCVar17,0x5f028a); - struct Crossfeed::Preset preset = { - .cutoff = 650, - .feedback = 95, - }; - this->cure.SetPreset(preset); - break; - } - case 1: { - // Cure_R::SetPreset(pCVar17,0x3c02bc); - struct Crossfeed::Preset preset = { - .cutoff = 700, - .feedback = 60, - }; - this->cure.SetPreset(preset); - break; - } - case 2: { - // Cure_R::SetPreset(pCVar17,0x2d02bc); - struct Crossfeed::Preset preset = { - .cutoff = 700, - .feedback = 45, - }; - this->cure.SetPreset(preset); - break; - } - } - break; - } // 0x1002E - case PARAM_TUBE_SIMULATOR_ENABLED: { - this->tubeSimulator.SetEnable(val1 != 0); - break; - } // 0x1002F - case PARAM_ANALOGX_ENABLE: { - this->analogX.SetEnable(val1 != 0); - break; - } // 0x10030 - case PARAM_ANALOGX_MODE: { - this->analogX.SetProcessingModel(val1); - break; - } // 0x10031 - case PARAM_GATE_OUTPUT_VOLUME: { - this->frameScale = (float) val1 / 100.0f; - break; - } // 0x10032 - case PARAM_GATE_CHANNEL_PAN: { - float tmp = (float) val1 / 100.0f; - if (tmp < 0.0f) { - this->leftPan = 1.0f; - this->rightPan = 1.0f + tmp; - } else { - this->leftPan = 1.0f - tmp; - this->rightPan = 1.0f; - } - break; - } // 0x10033 - case PARAM_GATE_LIMIT: { - this->softwareLimiters[0].SetGate((float) val1 / 100.0f); - this->softwareLimiters[1].SetGate((float) val1 / 100.0f); - break; - } // 0x10034 - case PARAM_SPEAKER_OPTIMIZATION: { - this->speakerCorrection.SetEnable(val1 != 0); - break; - } // 0x10043 - case PARAM_FET_COMPRESSOR_ENABLE: { - break; - } // 0x10049 - case PARAM_FET_COMPRESSOR_THRESHOLD: { - break; - } // 0x1004A - case PARAM_FET_COMPRESSOR_RATIO: { - this->fetCompressor.SetParameter(FETCompressor::THRESHOLD, (float) val1 / 100.0f); - break; - } // 0x1004B - case PARAM_FET_COMPRESSOR_KNEE: { - break; - } // 0x1004C - case PARAM_FET_COMPRESSOR_AUTO_KNEE: { - break; - } // 0x1004D - case PARAM_FET_COMPRESSOR_GAIN: { - break; - } // 0x1004E - case PARAM_FET_COMPRESSOR_AUTO_GAIN: { - this->fetCompressor.SetParameter(FETCompressor::GAIN, (float) val1 / 100.0f); - break; - } // 0x1004F - case PARAM_FET_COMPRESSOR_ATTACK: { - break; - } // 0x10050 - case PARAM_FET_COMPRESSOR_AUTO_ATTACK: { - break; - } // 0x10051 - case PARAM_FET_COMPRESSOR_RELEASE: { - break; - } // 0x10052 - case PARAM_FET_COMPRESSOR_AUTO_RELEASE: { - break; - } // 0x10053 - case PARAM_FET_COMPRESSOR_KNEE_MULTI: { - break; - } // 0x10054 - case PARAM_FET_COMPRESSOR_MAX_ATTACK: { - break; - } // 0x10055 - case PARAM_FET_COMPRESSOR_MAX_RELEASE: { - this->fetCompressor.SetParameter(FETCompressor::MAX_ATTACK, (float) val1 / 100.0f); - break; - } // 0x10056 - case PARAM_FET_COMPRESSOR_CREST: { - break; - } // 0x10057 - case PARAM_FET_COMPRESSOR_ADAPT: { - break; - } // 0x10058 - case PARAM_FET_COMPRESSOR_NO_CLIP: { - this->fetCompressor.SetParameter(FETCompressor::ADAPT, (float) val1 / 100.0f); - break; - } // 0x10059 - } -} +// break; +// } // 0x10002 +// case PARAM_CONVOLUTION_PREPARE_BUFFER: { +// break; +// } // 0x10004 +// case PARAM_CONVOLUTION_SET_BUFFER: { +// break; +// } // 0x10005 +// case PARAM_CONVOLUTION_COMMIT_BUFFER: { +// break; +// } // 0x10006 +// case PARAM_CONVOLUTION_CROSS_CHANNEL: { +// this->convolver.SetCrossChannel((float) val1 / 100.0f); +// break; +// } // 0x10007 +// case PARAM_HEADPHONE_SURROUND_ENABLE: { +// this->vhe.SetEnable(val1 != 0); +// break; +// } // 0x10008 +// case PARAM_HEADPHONE_SURROUND_STRENGTH: { +// this->vhe.SetEffectLevel(val1); +// break; +// } // 0x10009 +// case PARAM_DDC_ENABLE: { +// this->viperDdc.SetEnable(val1 != 0); +// break; +// } // 0x1000A +// case PARAM_DDC_COEFFICIENTS: { +// this->viperDdc.SetCoeffs(arrSize, (float *) arr, (float *) (arr + arrSize * sizeof(float))); +// break; +// } // 0x1000B +// case PARAM_SPECTRUM_EXTENSION_ENABLE: { +// this->spectrumExtend.SetEnable(val1 != 0); +// break; +// } // 0x1000C +// case PARAM_SPECTRUM_EXTENSION_BARK: { +// this->spectrumExtend.SetReferenceFrequency(val1); +// break; +// } // 0x1000D +// case PARAM_SPECTRUM_EXTENSION_BARK_RECONSTRUCT: { +// this->spectrumExtend.SetExciter((float) val1 / 100.0f); +// break; +// } // 0x1000E +// case PARAM_FIR_EQUALIZER_ENABLE: { +// this->iirFilter.SetEnable(val1 != 0); +// break; +// } // 0x1000F +// case PARAM_FIR_EQUALIZER_BAND_LEVEL: { +// this->iirFilter.SetBandLevel((uint32_t) val1, (float) val2 / 100.0f); +// break; +// } // 0x10010 +// case PARAM_FIELD_SURROUND_ENABLE: { +// this->colorfulMusic.SetEnable(val1 != 0); +// break; +// } // 0x10011 +// case PARAM_FIELD_SURROUND_WIDENING: { +// this->colorfulMusic.SetWidenValue((float) val1 / 100.0f); +// break; +// } // 0x10012 +// case PARAM_FIELD_SURROUND_MID_IMAGE: { +// this->colorfulMusic.SetMidImageValue((float) val1 / 100.0f); +// break; +// } // 0x10013 +// case PARAM_FIELD_SURROUND_DEPTH: { +// this->colorfulMusic.SetDepthValue((short) val1); +// break; +// } // 0x10014 +// case PARAM_DIFFERENTIAL_SURROUND_ENABLE: { +// this->diffSurround.SetEnable(val1 != 0); +// break; +// } // 0x10015 +// case PARAM_DIFFERENTIAL_SURROUND_DELAY: { +// this->diffSurround.SetDelayTime((float) val1 / 100.0f); +// break; +// } // 0x10016 +// case PARAM_REVERBERATION_ENABLE: { +// this->reverberation.SetEnable(val1 != 0); +// break; +// } // 0x10017 +// case PARAM_REVERBERATION_ROOM_SIZE: { +// this->reverberation.SetRoomSize((float) val1 / 100.0f); +// break; +// } // 0x10018 +// case PARAM_REVERBERATION_ROOM_WIDTH: { +// this->reverberation.SetWidth((float) val1 / 100.0f); +// break; +// } // 0x10019 +// case PARAM_REVERBERATION_ROOM_DAMPENING: { +// this->reverberation.SetDamp((float) val1 / 100.0f); +// break; +// } // 0x1001A +// case PARAM_REVERBERATION_ROOM_WET_SIGNAL: { +// this->reverberation.SetWet((float) val1 / 100.0f); +// break; +// } // 0x1001B +// case PARAM_REVERBERATION_ROOM_DRY_SIGNAL: { +// this->reverberation.SetDry((float) val1 / 100.0f); +// break; +// } // 0x1001C +// case PARAM_AUTOMATIC_GAIN_CONTROL_ENABLE: { +// this->playbackGain.SetEnable(val1 != 0); +// break; +// } // 0x1001D +// case PARAM_AUTOMATIC_GAIN_CONTROL_RATIO: { +// this->playbackGain.SetRatio((float) val1 / 100.0f); +// break; +// } // 0x1001E +// case PARAM_AUTOMATIC_GAIN_CONTROL_VOLUME: { +// this->playbackGain.SetVolume((float) val1 / 100.0f); +// break; +// } // 0x1001F +// case PARAM_AUTOMATIC_GAIN_CONTROL_MAX_SCALER: { +// this->playbackGain.SetMaxGainFactor((float) val1 / 100.0f); +// break; +// } // 0x10020 +// case PARAM_DYNAMIC_SYSTEM_ENABLE: { +// this->dynamicSystem.SetEnable(val1 != 0); +// break; +// } // 0x10021 +// case PARAM_DYNAMIC_SYSTEM_X_COEFFICIENTS: { +// this->dynamicSystem.SetXCoeffs(val1, val2); +// break; +// } // 0x10022 +// case PARAM_DYNAMIC_SYSTEM_Y_COEFFICIENTS: { +// this->dynamicSystem.SetYCoeffs(val1, val2); +// break; +// } // 0x10023 +// case PARAM_DYNAMIC_SYSTEM_SIDE_GAIN: { +// this->dynamicSystem.SetSideGain((float) val1 / 100.0f, (float) val2 / 100.0f); +// break; +// } // 0x10024 +// case PARAM_DYNAMIC_SYSTEM_STRENGTH: { +// this->dynamicSystem.SetBassGain((float) val1 / 100.0f); +// break; +// } // 0x10025 +// case PARAM_FIDELITY_BASS_ENABLE: { +// this->viperBass.SetEnable(val1 != 0); +// break; +// } // 0x10026 +// case PARAM_FIDELITY_BASS_MODE: { +// this->viperBass.SetProcessMode((ViPERBass::ProcessMode) val1); +// break; +// } // 0x10027 +// case PARAM_FIDELITY_BASS_FREQUENCY: { +// this->viperBass.SetSpeaker((uint32_t) val1); +// break; +// } // 0x10028 +// case PARAM_FIDELITY_BASS_GAIN: { +// this->viperBass.SetBassFactor((float) val1 / 100.0f); +// break; +// } // 0x10029 +// case PARAM_FIDELITY_CLARITY_ENABLE: { +// this->viperClarity.SetEnable(val1 != 0); +// break; +// } // 0x1002A +// case PARAM_FIDELITY_CLARITY_MODE: { +// this->viperClarity.SetProcessMode((ViPERClarity::ClarityMode) val1); +// break; +// } // 0x1002B +// case PARAM_FIDELITY_CLARITY_GAIN: { +// this->viperClarity.SetClarity((float) val1 / 100.0f); +// break; +// } // 0x1002C +// case PARAM_CURE_CROSS_FEED_ENABLED: { +// this->cure.SetEnable(val1 != 0); +// break; +// } // 0x1002D +// case PARAM_CURE_CROSS_FEED_STRENGTH: { +// switch (val1) { +// case 0: { +// // Cure_R::SetPreset(pCVar17,0x5f028a); +// struct Crossfeed::Preset preset = { +// .cutoff = 650, +// .feedback = 95, +// }; +// this->cure.SetPreset(preset); +// break; +// } +// case 1: { +// // Cure_R::SetPreset(pCVar17,0x3c02bc); +// struct Crossfeed::Preset preset = { +// .cutoff = 700, +// .feedback = 60, +// }; +// this->cure.SetPreset(preset); +// break; +// } +// case 2: { +// // Cure_R::SetPreset(pCVar17,0x2d02bc); +// struct Crossfeed::Preset preset = { +// .cutoff = 700, +// .feedback = 45, +// }; +// this->cure.SetPreset(preset); +// break; +// } +// } +// break; +// } // 0x1002E +// case PARAM_TUBE_SIMULATOR_ENABLED: { +// this->tubeSimulator.SetEnable(val1 != 0); +// break; +// } // 0x1002F +// case PARAM_ANALOGX_ENABLE: { +// this->analogX.SetEnable(val1 != 0); +// break; +// } // 0x10030 +// case PARAM_ANALOGX_MODE: { +// this->analogX.SetProcessingModel(val1); +// break; +// } // 0x10031 +// case PARAM_GATE_OUTPUT_VOLUME: { +// this->frameScale = (float) val1 / 100.0f; +// break; +// } // 0x10032 +// case PARAM_GATE_CHANNEL_PAN: { +// float tmp = (float) val1 / 100.0f; +// if (tmp < 0.0f) { +// this->leftPan = 1.0f; +// this->rightPan = 1.0f + tmp; +// } else { +// this->leftPan = 1.0f - tmp; +// this->rightPan = 1.0f; +// } +// break; +// } // 0x10033 +// case PARAM_GATE_LIMIT: { +// this->softwareLimiters[0].SetGate((float) val1 / 100.0f); +// this->softwareLimiters[1].SetGate((float) val1 / 100.0f); +// break; +// } // 0x10034 +// case PARAM_SPEAKER_OPTIMIZATION: { +// this->speakerCorrection.SetEnable(val1 != 0); +// break; +// } // 0x10043 +// } +//} -void ViPER::resetAllEffects() { +void ViPER::reset() { this->adaptiveBuffer.FlushBuffer(); this->waveBuffer.Reset(); @@ -541,3 +479,23 @@ void ViPER::resetAllEffects() { softwareLimiter.Reset(); } } + +void ViPER::setSamplingRate(uint32_t samplingRate) { + this->samplingRate = samplingRate; + // TODO: Set sampling rate to all other effects +} + +uint64_t ViPER::getFrameCount() { + return this->frameCount; +} + +void ViPER::setGain(float gainL, float gainR) { + this->gainL = gainL; + this->gainR = gainR; +} + +void ViPER::setThresholdLimit(float thresholdLimit) { + for (auto &softwareLimiter: softwareLimiters) { + softwareLimiter.SetGate(thresholdLimit); + } +} diff --git a/src/viper/ViPER.h b/src/viper/ViPER.h index 7fb6cdd..72b6336 100644 --- a/src/viper/ViPER.h +++ b/src/viper/ViPER.h @@ -28,13 +28,11 @@ public: ViPER(); void process(std::vector& buffer, uint32_t size); - // TODO: Parameter types/names - void DispatchCommand(int param, int val1, int val2, int val3, int val4, uint32_t arrSize, signed char *arr); - void resetAllEffects(); - -//private: - uint64_t frameCount; - uint32_t samplingRate; + void reset(); + uint64_t getFrameCount(); + void setSamplingRate(uint32_t samplingRate); + void setGain(float gainL, float gainR); + void setThresholdLimit(float thresholdLimit); // Effects AdaptiveBuffer adaptiveBuffer; @@ -56,9 +54,11 @@ public: TubeSimulator tubeSimulator; AnalogX analogX; SpeakerCorrection speakerCorrection; - std::array softwareLimiters; - float frameScale; - float leftPan; - float rightPan; +private: + std::array softwareLimiters; + uint64_t frameCount; + uint32_t samplingRate; + float gainL; + float gainR; }; diff --git a/src/viper/constants.h b/src/viper/constants.h index 58a2309..2b451d8 100644 --- a/src/viper/constants.h +++ b/src/viper/constants.h @@ -8,25 +8,25 @@ #include "../log.h" // TODO: Remove this dependency -typedef enum { - ARCH_UNKNOWN = 0, - ARCH_ARM, - ARCH_ARM64, - ARCH_X86, - ARCH_X86_64, -} arch_t; +enum class Architecture : uint8_t { + UNKNOWN = 0, + ARM, + ARM64, + X86, + X86_64, +}; #if defined(__arm__) -#define VIPER_ARCHITECTURE ARCH_ARM +#define VIPER_ARCHITECTURE Architecture::ARM #elif defined(__aarch64__) -#define VIPER_ARCHITECTURE ARCH_ARM64 +#define VIPER_ARCHITECTURE Architecture::ARM64 #elif defined(__i386__) -#define VIPER_ARCHITECTURE ARCH_X86 +#define VIPER_ARCHITECTURE Architecture::X86 #elif defined(__x86_64__) -#define VIPER_ARCHITECTURE ARCH_X86_64 +#define VIPER_ARCHITECTURE Architecture::X86_64 #else #warning "Unknown architecture" -#define VIPER_ARCHITECTURE ARCH_UNKNOWN +#define VIPER_ARCHITECTURE Architecture::UNKNOWN /* * Note from the developer: * diff --git a/src/viper/effects/AnalogX.cpp b/src/viper/effects/AnalogX.cpp index 0b57efa..c2cb822 100644 --- a/src/viper/effects/AnalogX.cpp +++ b/src/viper/effects/AnalogX.cpp @@ -3,16 +3,16 @@ #include "../constants.h" static const float ANALOGX_HARMONICS[] = { - 0.01, - 0.02, - 0.0001, - 0.001, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 + 0.01f, + 0.02f, + 0.0001f, + 0.001f, + 0.0f, + 0.0f, + 0.0f, + 0.0f, + 0.0f, + 0.0f, }; AnalogX::AnalogX() { diff --git a/src/viper/effects/ViPERBass.h b/src/viper/effects/ViPERBass.h index 734e926..9e3668d 100644 --- a/src/viper/effects/ViPERBass.h +++ b/src/viper/effects/ViPERBass.h @@ -10,10 +10,10 @@ class ViPERBass { public: - enum ProcessMode { + enum class ProcessMode : uint8_t { NATURAL_BASS = 0, - PURE_BASS_PLUS = 1, - SUBWOOFER = 2, + PURE_BASS_PLUS, + SUBWOOFER, }; ViPERBass(); @@ -39,5 +39,3 @@ private: uint32_t speaker; float bassFactor; }; - - diff --git a/src/viper/effects/ViPERClarity.h b/src/viper/effects/ViPERClarity.h index 89b613c..c52dfb2 100644 --- a/src/viper/effects/ViPERClarity.h +++ b/src/viper/effects/ViPERClarity.h @@ -9,8 +9,8 @@ class ViPERClarity { public: - enum ClarityMode { - NATURAL, + enum class ClarityMode : uint8_t { + NATURAL = 0, OZONE, XHIFI }; diff --git a/src/viper/utils/AdaptiveBuffer.cpp b/src/viper/utils/AdaptiveBuffer.cpp index c84c7cd..fac8c93 100644 --- a/src/viper/utils/AdaptiveBuffer.cpp +++ b/src/viper/utils/AdaptiveBuffer.cpp @@ -28,8 +28,8 @@ uint32_t AdaptiveBuffer::GetChannels() const { return this->channels; } -void AdaptiveBuffer::PanFrames(float left, float right) { - if (this->channels == 2) { +void AdaptiveBuffer::SetGain(float left, float right) { + //if (this->channels == 2) { for (uint32_t i = 0; i < this->offset * this->channels; i++) { if (i % 2 == 0) { this->buffer[i] = this->buffer[i] * left; @@ -37,7 +37,7 @@ void AdaptiveBuffer::PanFrames(float left, float right) { this->buffer[i] = this->buffer[i] * right; } } - } + //} } int AdaptiveBuffer::PopFrames(float *frames, uint32_t length) { @@ -82,12 +82,6 @@ int AdaptiveBuffer::PushZero(uint32_t length) { return 1; } -void AdaptiveBuffer::ScaleFrames(float scale) { - for (uint32_t i = 0; i < this->offset * this->channels; i++) { - this->buffer[i] = this->buffer[i] * scale; - } -} - void AdaptiveBuffer::SetBufferOffset(uint32_t offset) { this->offset = offset; } diff --git a/src/viper/utils/AdaptiveBuffer.h b/src/viper/utils/AdaptiveBuffer.h index 54f5ed3..256c748 100644 --- a/src/viper/utils/AdaptiveBuffer.h +++ b/src/viper/utils/AdaptiveBuffer.h @@ -12,11 +12,10 @@ public: uint32_t GetBufferOffset() const; float *GetBuffer(); uint32_t GetChannels() const; - void PanFrames(float left, float right); + void SetGain(float left, float right); int PopFrames(float *frames, uint32_t length); int PushFrames(const float *frames, uint32_t length); int PushZero(uint32_t length); - void ScaleFrames(float scale); void SetBufferOffset(uint32_t offset); private: