mirror of
https://github.com/AndroidAudioMods/ViPERFX_RE.git
synced 2025-06-22 16:22:24 +08:00
Update
This commit is contained in:
@ -5,7 +5,7 @@
|
||||
|
||||
ViPER::ViPER() {
|
||||
VIPER_LOGI("Welcome to ViPER FX");
|
||||
VIPER_LOGI("Current version is %s %s", VERSION_STRING, VERSION_CODENAME);
|
||||
VIPER_LOGI("Current version is %s (%d)", VERSION_NAME, VERSION_CODE);
|
||||
|
||||
this->samplingRate = VIPER_DEFAULT_SAMPLING_RATE;
|
||||
|
||||
|
@ -8,9 +8,5 @@
|
||||
|
||||
#include "../log.h" // TODO: Remove this dependency
|
||||
|
||||
#define STR_HELPER(x) #x
|
||||
#define STR(x) STR_HELPER(x)
|
||||
#define VERSION_STRING "v" STR(VERSION_MAJOR) "." STR(VERSION_MINOR)
|
||||
|
||||
#define VIPER_DEFAULT_SAMPLING_RATE 44100
|
||||
#define VIPER_AUTHORS "viper.WYF, Martmists, Iscle"
|
@ -1,5 +1,7 @@
|
||||
#include "Cure.h"
|
||||
|
||||
// Iscle: Verified with the latest version at 13/12/2022
|
||||
|
||||
Cure::Cure() {
|
||||
this->enabled = false;
|
||||
Reset();
|
||||
@ -17,15 +19,16 @@ float Cure::GetLevelDelay() {
|
||||
return this->crossfeed.GetLevelDelay();
|
||||
}
|
||||
|
||||
// TODO: Fix with crossfeed
|
||||
struct Crossfeed::Preset Cure::GetPreset() {
|
||||
return this->crossfeed.GetPreset();
|
||||
}
|
||||
|
||||
void Cure::Process(float *buffer, uint32_t size) {
|
||||
if (this->enabled) {
|
||||
this->crossfeed.ProcessFrames(buffer, size);
|
||||
this->passFilter.ProcessFrames(buffer, size);
|
||||
}
|
||||
if (!this->enabled) return;
|
||||
|
||||
this->crossfeed.ProcessFrames(buffer, size);
|
||||
this->passFilter.ProcessFrames(buffer, size);
|
||||
}
|
||||
|
||||
void Cure::Reset() {
|
||||
@ -39,10 +42,10 @@ void Cure::SetCutoff(uint16_t cutoff) {
|
||||
|
||||
void Cure::SetEnable(bool enabled) {
|
||||
if (this->enabled != enabled) {
|
||||
this->enabled = enabled;
|
||||
if (enabled) {
|
||||
Reset();
|
||||
}
|
||||
this->enabled = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include "../utils/Crossfeed.h"
|
||||
#include "../utils/PassFilter.h"
|
||||
|
||||
// Iscle: Verified with the latest version at 13/12/2022
|
||||
|
||||
class Cure {
|
||||
public:
|
||||
Cure();
|
||||
@ -11,7 +13,7 @@ public:
|
||||
uint16_t GetCutoff();
|
||||
float GetFeedback();
|
||||
float GetLevelDelay();
|
||||
struct Crossfeed::Preset GetPreset();
|
||||
struct Crossfeed::Preset GetPreset(); // TODO: Fix with crossfeed
|
||||
void Process(float *buffer, uint32_t size);
|
||||
void Reset();
|
||||
void SetCutoff(uint16_t cutoff);
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include "IIRFilter.h"
|
||||
#include "../constants.h"
|
||||
|
||||
// Iscle: Verified with latest version at 13/12/2022
|
||||
// Iscle: Verified with the latest version at 13/12/2022
|
||||
|
||||
IIRFilter::IIRFilter(uint32_t bands) {
|
||||
this->enable = false;
|
||||
@ -75,10 +75,10 @@ void IIRFilter::SetBandLevel(uint32_t band, float level) {
|
||||
|
||||
void IIRFilter::SetEnable(bool enable) {
|
||||
if (this->enable != enable) {
|
||||
this->enable = enable;
|
||||
if (enable) {
|
||||
Reset();
|
||||
}
|
||||
this->enable = enable;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <cstdint>
|
||||
#include "../utils/MinPhaseIIRCoeffs.h"
|
||||
|
||||
// Iscle: Verified with latest version at 13/12/2022
|
||||
// Iscle: Verified with the latest version at 13/12/2022
|
||||
|
||||
class IIRFilter {
|
||||
public:
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include "SpeakerCorrection.h"
|
||||
#include "../constants.h"
|
||||
|
||||
// Iscle: Verified with the latest version at 13/12/2022
|
||||
|
||||
SpeakerCorrection::SpeakerCorrection() {
|
||||
this->samplingRate = VIPER_DEFAULT_SAMPLING_RATE;
|
||||
this->enable = false;
|
||||
@ -43,7 +45,7 @@ void SpeakerCorrection::Reset() {
|
||||
|
||||
void SpeakerCorrection::SetEnable(bool enable) {
|
||||
if (this->enable != enable) {
|
||||
if (!this->enable) {
|
||||
if (enable) {
|
||||
Reset();
|
||||
}
|
||||
this->enable = enable;
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include "../utils/MultiBiquad.h"
|
||||
#include "../utils/Biquad.h"
|
||||
|
||||
// Iscle: Verified with the latest version at 13/12/2022
|
||||
|
||||
class SpeakerCorrection {
|
||||
public:
|
||||
SpeakerCorrection();
|
||||
|
@ -1,14 +1,16 @@
|
||||
#include "TubeSimulator.h"
|
||||
|
||||
// Iscle: Verified with the latest version at 13/12/2022
|
||||
|
||||
TubeSimulator::TubeSimulator() {
|
||||
this->acc[0] = 0.f;
|
||||
this->acc[1] = 0.f;
|
||||
this->acc[0] = 0.0;
|
||||
this->acc[1] = 0.0;
|
||||
this->enable = false;
|
||||
}
|
||||
|
||||
void TubeSimulator::Reset() {
|
||||
this->acc[0] = 0.f;
|
||||
this->acc[1] = 0.f;
|
||||
this->acc[0] = 0.0;
|
||||
this->acc[1] = 0.0;
|
||||
this->enable = false;
|
||||
}
|
||||
|
||||
@ -22,16 +24,12 @@ void TubeSimulator::SetEnable(bool enable) {
|
||||
}
|
||||
|
||||
void TubeSimulator::TubeProcess(float *buffer, uint32_t size) {
|
||||
if (this->enable) {
|
||||
for (uint32_t x = 0; x < size; x++) {
|
||||
this->acc[0] = (this->acc[0] + buffer[2 * x]) / 2.f;
|
||||
this->acc[1] = (this->acc[1] + buffer[2 * x + 1]) / 2.f;
|
||||
buffer[2 * x] = this->acc[0];
|
||||
buffer[2 * x + 1] = this->acc[1];
|
||||
}
|
||||
if (!this->enable) return;
|
||||
|
||||
for (uint32_t i = 0; i < size; i += 2) {
|
||||
this->acc[0] = (this->acc[0] + buffer[i * 2]) / 2.0;
|
||||
this->acc[1] = (this->acc[1] + buffer[i * 2 + 1]) / 2.0;
|
||||
buffer[i * 2] = (float) this->acc[0];
|
||||
buffer[i * 2 + 1] = (float) this->acc[1];
|
||||
}
|
||||
}
|
||||
|
||||
TubeSimulator::~TubeSimulator() {
|
||||
|
||||
}
|
||||
|
@ -2,17 +2,18 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
// Iscle: Verified with the latest version at 13/12/2022
|
||||
|
||||
class TubeSimulator {
|
||||
public:
|
||||
TubeSimulator();
|
||||
~TubeSimulator();
|
||||
|
||||
void Reset();
|
||||
void SetEnable(bool enable);
|
||||
void TubeProcess(float *buffer, uint32_t size);
|
||||
|
||||
private:
|
||||
float acc[2];
|
||||
double acc[2];
|
||||
bool enable;
|
||||
};
|
||||
|
||||
|
@ -1,23 +1,25 @@
|
||||
#include "ViPERBass.h"
|
||||
#include "../constants.h"
|
||||
|
||||
// Iscle: Verified with the latest version at 13/12/2022
|
||||
|
||||
ViPERBass::ViPERBass() {
|
||||
this->enable = false;
|
||||
this->samplingRate = VIPER_DEFAULT_SAMPLING_RATE;
|
||||
this->speaker = 60;
|
||||
this->samplingRatePeriod = 1.0 / VIPER_DEFAULT_SAMPLING_RATE;
|
||||
this->antiPop = 0.0;
|
||||
this->enable = false;
|
||||
this->processMode = ProcessMode::NATURAL_BASS;
|
||||
this->antiPop = 0.0;
|
||||
this->bassFactor = 0.0;
|
||||
this->samplingRate = VIPER_DEFAULT_SAMPLING_RATE;
|
||||
this->samplingRatePeriod = 1.0 / VIPER_DEFAULT_SAMPLING_RATE;
|
||||
this->polyphase = new Polyphase(2);
|
||||
this->biquad = new Biquad();
|
||||
this->subwoofer = new Subwoofer();
|
||||
this->waveBuffer = new WaveBuffer(1, 0x1000);
|
||||
this->waveBuffer = new WaveBuffer(1, 4096);
|
||||
|
||||
this->biquad->Reset();
|
||||
this->biquad->SetLowPassParameter((float) this->speaker, this->samplingRate, 0.53);
|
||||
this->subwoofer->SetBassGain(this->samplingRate, 0.0);
|
||||
this->Reset();
|
||||
Reset();
|
||||
}
|
||||
|
||||
ViPERBass::~ViPERBass() {
|
||||
@ -28,23 +30,17 @@ ViPERBass::~ViPERBass() {
|
||||
}
|
||||
|
||||
void ViPERBass::Process(float *samples, uint32_t size) {
|
||||
if (!this->enable) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
return;
|
||||
}
|
||||
if (!this->enable) return;
|
||||
if (size == 0) return;
|
||||
|
||||
// Iscle: TODO: Maybe we could attenuate the effect instead of the entire sample
|
||||
if (this->antiPop < 1.0) {
|
||||
for (uint32_t i = 0; i < size * 2; i += 2) {
|
||||
samples[i] *= this->antiPop;
|
||||
samples[i + 1] *= this->antiPop;
|
||||
|
||||
float x = this->antiPop + this->samplingRatePeriod;
|
||||
if (x > 1.0) {
|
||||
x = 1.0;
|
||||
}
|
||||
if (x > 1.0) x = 1.0;
|
||||
this->antiPop = x;
|
||||
}
|
||||
}
|
||||
@ -108,9 +104,7 @@ void ViPERBass::SetBassFactor(float bassFactor) {
|
||||
|
||||
void ViPERBass::SetEnable(bool enable) {
|
||||
if (this->enable != enable) {
|
||||
if (!this->enable) {
|
||||
Reset();
|
||||
}
|
||||
if (enable) Reset();
|
||||
this->enable = enable;
|
||||
}
|
||||
}
|
||||
@ -118,7 +112,7 @@ void ViPERBass::SetEnable(bool enable) {
|
||||
void ViPERBass::SetProcessMode(ProcessMode processMode) {
|
||||
if (this->processMode != processMode) {
|
||||
this->processMode = processMode;
|
||||
this->Reset();
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include "../utils/WaveBuffer.h"
|
||||
#include "../utils/Polyphase.h"
|
||||
|
||||
// Iscle: Verified with the latest version at 13/12/2022
|
||||
|
||||
class ViPERBass {
|
||||
public:
|
||||
enum ProcessMode {
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include "ViPERClarity.h"
|
||||
#include "../constants.h"
|
||||
|
||||
// Iscle: Verified with the latest version at 13/12/2022
|
||||
|
||||
ViPERClarity::ViPERClarity() {
|
||||
for (auto &highShelf : this->highShelf) {
|
||||
highShelf.SetFrequency(12000.0);
|
||||
@ -10,15 +12,13 @@ ViPERClarity::ViPERClarity() {
|
||||
|
||||
this->enable = false;
|
||||
this->processMode = ClarityMode::NATURAL;
|
||||
this->samplingRate = VIPER_DEFAULT_SAMPLING_RATE;
|
||||
this->clarityGainPercent = 0.0;
|
||||
this->samplingRate = VIPER_DEFAULT_SAMPLING_RATE;
|
||||
Reset();
|
||||
}
|
||||
|
||||
void ViPERClarity::Process(float *samples, uint32_t size) {
|
||||
if (!this->enable) {
|
||||
return;
|
||||
}
|
||||
if (!this->enable) return;
|
||||
|
||||
switch (this->processMode) {
|
||||
case ClarityMode::NATURAL: {
|
||||
@ -26,8 +26,9 @@ void ViPERClarity::Process(float *samples, uint32_t size) {
|
||||
break;
|
||||
}
|
||||
case ClarityMode::OZONE: {
|
||||
for (uint32_t i = 0; i < size * 2; i++) {
|
||||
samples[i] = (float) this->highShelf[i % 2].Process(samples[i]);
|
||||
for (uint32_t i = 0; i < size * 2; i += 2) {
|
||||
samples[i] = (float) this->highShelf[0].Process(samples[i]);
|
||||
samples[i + 1] = (float) this->highShelf[1].Process(samples[i + 1]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -41,7 +42,7 @@ void ViPERClarity::Process(float *samples, uint32_t size) {
|
||||
void ViPERClarity::Reset() {
|
||||
this->noiseSharpening.SetSamplingRate(this->samplingRate);
|
||||
this->noiseSharpening.Reset();
|
||||
this->SetClarityToFilter();
|
||||
SetClarityToFilter();
|
||||
for (auto &highShelf : this->highShelf) {
|
||||
highShelf.SetFrequency(8250.0);
|
||||
highShelf.SetSamplingRate(this->samplingRate);
|
||||
@ -52,10 +53,10 @@ void ViPERClarity::Reset() {
|
||||
|
||||
void ViPERClarity::SetClarity(float gainPercent) {
|
||||
this->clarityGainPercent = gainPercent;
|
||||
if (this->processMode != ClarityMode::OZONE) {
|
||||
this->SetClarityToFilter();
|
||||
} else {
|
||||
if (this->processMode == ClarityMode::OZONE) {
|
||||
Reset();
|
||||
} else {
|
||||
SetClarityToFilter();
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,7 +69,7 @@ void ViPERClarity::SetClarityToFilter() {
|
||||
|
||||
void ViPERClarity::SetEnable(bool enable) {
|
||||
if (this->enable != enable) {
|
||||
if (!this->enable) {
|
||||
if (enable) {
|
||||
Reset();
|
||||
}
|
||||
this->enable = enable;
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include "../utils/HiFi.h"
|
||||
#include "../utils/HighShelf.h"
|
||||
|
||||
// Iscle: Verified with the latest version at 13/12/2022
|
||||
|
||||
class ViPERClarity {
|
||||
public:
|
||||
enum ClarityMode {
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "Biquad.h"
|
||||
#include <cmath>
|
||||
|
||||
// Iscle: Verified with the latest version at 13/12/2022
|
||||
// Some variable names RE'd with help from https://github.com/wooters/miniDSP/blob/master/biquad.c
|
||||
|
||||
Biquad::Biquad() {
|
||||
@ -41,14 +42,14 @@ void Biquad::SetBandPassParameter(float frequency, uint32_t samplingRate, float
|
||||
double sinOmega = sin(omega);
|
||||
double cosOmega = cos(omega);
|
||||
|
||||
double alpha = sinOmega / (2.0 * (double) qFactor);
|
||||
double alpha = sinOmega / ((double) qFactor + (double) qFactor);
|
||||
|
||||
double a0 = 1.0 + alpha;
|
||||
double a1 = -2.0 * cosOmega;
|
||||
double a0 = alpha + 1.0;
|
||||
double a1 = cosOmega * -2.0;
|
||||
double a2 = 1.0 - alpha;
|
||||
double b0 = sinOmega / 2.0; // Reference biquad implementation would use alpha here
|
||||
double b1 = 0.0;
|
||||
double b2 = -sinOmega / 2.0; // Reference biquad implementation would use -alpha here
|
||||
double b2 = -(sinOmega / 2.0); // Reference biquad implementation would use -alpha here
|
||||
|
||||
SetCoeffs(a0, a1, a2, b0, b1, b2);
|
||||
}
|
||||
@ -59,37 +60,30 @@ void Biquad::SetCoeffs(double a0, double a1, double a2, double b0, double b1, do
|
||||
this->y2 = 0.0;
|
||||
this->y1 = 0.0;
|
||||
|
||||
this->a1 = -a1 / a0;
|
||||
this->a2 = -a2 / a0;
|
||||
this->a1 = -(a1 / a0);
|
||||
this->a2 = -(a2 / a0);
|
||||
this->b0 = b0 / a0;
|
||||
this->b1 = b1 / a0;
|
||||
this->b2 = b2 / a0;
|
||||
}
|
||||
|
||||
// TODO: Check
|
||||
void
|
||||
Biquad::SetHighPassParameter(float frequency, uint32_t samplingRate, double dbGain, float qFactor, double param_6) {
|
||||
double omega = (2.0 * M_PI * (double) frequency) / (double) samplingRate;
|
||||
double sinX = sin(omega);
|
||||
double cosX = cos(omega);
|
||||
double sinOmega = sin(omega);
|
||||
double cosOmega = cos(omega);
|
||||
|
||||
double A = pow(10.0, dbGain / 40.0);
|
||||
double sqrtY = sqrt(A);
|
||||
double sqrtA = sqrt(A);
|
||||
|
||||
double z = sinX / 2.0 * sqrt((1.0 / A + A) * (1.0 / (double) qFactor - 1.0) + 2.0);
|
||||
double a = (A - 1.0) * cosX;
|
||||
double b = (A + 1.0) + a;
|
||||
double c = (A + 1.0) * cosX;
|
||||
double d = (A + 1.0) - a;
|
||||
double e = pow(10.0, param_6 / 20.0);
|
||||
double f = (A - 1.0) - c;
|
||||
double z = sinOmega / 2.0 * sqrt((1.0 / A + A) * (1.0 / (double) qFactor - 1.0) + 2.0);
|
||||
|
||||
double a0 = d + (sqrtY * 2.0) * z;
|
||||
double a1 = f * 2.0;
|
||||
double a2 = d - (sqrtY * 2.0) * z;
|
||||
double b0 = (b + (sqrtY * 2.0) * z) * A * e;
|
||||
double b1 = A * -2.0 * ((A - 1.0) + c) * e;
|
||||
double b2 = (b - (sqrtY * 2.0) * z) * A * e;
|
||||
double a0 = (A + 1.0) - (A - 1.0) * cosOmega + (sqrtA * 2.0) * z;
|
||||
double a1 = ((A - 1.0) - (A + 1.0) * cosOmega) * 2.0;
|
||||
double a2 = (A + 1.0) - (A - 1.0) * cosOmega - (sqrtA * 2.0) * z;
|
||||
double b0 = ((A + 1.0) + (A - 1.0) * cosOmega + (sqrtA * 2.0) * z) * A * omega;
|
||||
double b1 = A * -2.0 * ((A - 1.0) + (A + 1.0) * cosOmega) * omega;
|
||||
double b2 = ((A + 1.0) + (A - 1.0) * cosOmega - (sqrtA * 2.0) * z) * A * omega;
|
||||
|
||||
SetCoeffs(a0, a1, a2, b0, b1, b2);
|
||||
}
|
||||
@ -99,10 +93,10 @@ void Biquad::SetLowPassParameter(float frequency, uint32_t samplingRate, float q
|
||||
double sinOmega = sin(omega);
|
||||
double cosOmega = cos(omega);
|
||||
|
||||
double alpha = sinOmega / (2.0 * (double) qFactor);
|
||||
double alpha = sinOmega / ((double) qFactor + (double) qFactor);
|
||||
|
||||
double a0 = 1.0 + alpha;
|
||||
double a1 = -2.0 * cosOmega;
|
||||
double a0 = alpha + 1.0;
|
||||
double a1 = cosOmega * -2.0;
|
||||
double a2 = 1.0 - alpha;
|
||||
double b0 = (1.0 - cosOmega) / 2.0;
|
||||
double b1 = 1.0 - cosOmega;
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
// Iscle: Verified with the latest version at 13/12/2022
|
||||
|
||||
class Biquad {
|
||||
public:
|
||||
Biquad();
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include "../constants.h"
|
||||
#include <cmath>
|
||||
|
||||
// Iscle: Verified with latest version at 13/12/2022
|
||||
// Iscle: Verified with the latest version at 13/12/2022
|
||||
|
||||
static const float MIN_PHASE_IIR_COEFFS_FREQ_10BANDS[] = {
|
||||
31.0,
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
// Iscle: Verified with latest version at 13/12/2022
|
||||
// Iscle: Verified with the latest version at 13/12/2022
|
||||
|
||||
class MinPhaseIIRCoeffs {
|
||||
public:
|
||||
|
@ -49,11 +49,11 @@ MultiBiquad::RefreshFilter(FilterType type, float gainAmp, float frequency, uint
|
||||
if (type == FilterType::LOW_SHELF || type == FilterType::HIGH_SHELF) {
|
||||
y = sinOmega / 2.0 * sqrt((1.0 / gain + gain) * (1.0 / (double) qFactor - 1.0) + 2.0);
|
||||
z = sqrt(gain) * 2.0 * y;
|
||||
} else if (!param_7) {
|
||||
y = sinOmega / ((double) qFactor * 2.0);
|
||||
} else if (param_7) {
|
||||
y = sinh(((double) qFactor * log(2.0) * omega / 2.0) / sinOmega) * sinOmega;
|
||||
z = -1.0; // Unused in this case
|
||||
} else {
|
||||
y = sinh(((double) qFactor * log(2.0) * omega / 2.0) / sinOmega) * sinOmega;
|
||||
y = sinOmega / ((double) qFactor + (double) qFactor);
|
||||
z = -1.0; // Unused in this case
|
||||
}
|
||||
|
||||
@ -143,13 +143,13 @@ MultiBiquad::RefreshFilter(FilterType type, float gainAmp, float frequency, uint
|
||||
}
|
||||
}
|
||||
|
||||
this->x2 = 0.0;
|
||||
this->x1 = 0.0;
|
||||
this->y2 = 0.0;
|
||||
this->x2 = 0.0;
|
||||
this->y1 = 0.0;
|
||||
this->y2 = 0.0;
|
||||
|
||||
this->a1 = -a1 / a0;
|
||||
this->a2 = -a2 / a0;
|
||||
this->a1 = -(a1 / a0);
|
||||
this->a2 = -(a2 / a0);
|
||||
this->b0 = b0 / a0;
|
||||
this->b1 = b1 / a0;
|
||||
this->b2 = b2 / a0;
|
||||
|
Reference in New Issue
Block a user