mirror of
https://github.com/AndroidAudioMods/ViPERFX_RE.git
synced 2025-06-08 02:29:40 +08:00
hifi and clarity
This commit is contained in:
parent
aa87dba34f
commit
779c172aa8
@ -27,6 +27,7 @@ set(FILES
|
|||||||
src/effects/SpeakerCorrection.cpp
|
src/effects/SpeakerCorrection.cpp
|
||||||
src/effects/SpectrumExtend.cpp
|
src/effects/SpectrumExtend.cpp
|
||||||
src/effects/TubeSimulator.cpp
|
src/effects/TubeSimulator.cpp
|
||||||
|
src/effects/ViPERClarity.cpp
|
||||||
|
|
||||||
# Utils
|
# Utils
|
||||||
src/utils/CAllpassFilter.cpp
|
src/utils/CAllpassFilter.cpp
|
||||||
@ -37,6 +38,7 @@ set(FILES
|
|||||||
src/utils/DynamicBass.cpp
|
src/utils/DynamicBass.cpp
|
||||||
src/utils/FixedBiquad.cpp
|
src/utils/FixedBiquad.cpp
|
||||||
src/utils/Harmonic.cpp
|
src/utils/Harmonic.cpp
|
||||||
|
src/utils/HiFi.cpp
|
||||||
src/utils/HighShelf.cpp
|
src/utils/HighShelf.cpp
|
||||||
src/utils/IIR_1st.cpp
|
src/utils/IIR_1st.cpp
|
||||||
src/utils/IIR_NOrder_BW_BP.cpp
|
src/utils/IIR_NOrder_BW_BP.cpp
|
||||||
|
81
src/effects/ViPERClarity.cpp
Normal file
81
src/effects/ViPERClarity.cpp
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
//
|
||||||
|
// Created by mart on 7/31/21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "ViPERClarity.h"
|
||||||
|
#include "../constants.h"
|
||||||
|
|
||||||
|
ViPERClarity::ViPERClarity() {
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
this->hiShelf[i].SetFrequency(12000.f);
|
||||||
|
this->hiShelf[i].SetQuality(100.f);
|
||||||
|
this->hiShelf[i].SetGain(1.f);
|
||||||
|
this->hiShelf[i].SetSamplingRate(DEFAULT_SAMPLERATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->enabled = false;
|
||||||
|
this->processMode = 0;
|
||||||
|
this->clarityGainPercent = 0.f;
|
||||||
|
this->samplerate = DEFAULT_SAMPLERATE;
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViPERClarity::Process(float *samples, uint32_t size) {
|
||||||
|
if (this->enabled) {
|
||||||
|
if (this->processMode == 0) {
|
||||||
|
this->sharp.Process(samples, size);
|
||||||
|
} else if (this->processMode == 1) {
|
||||||
|
for (int i = 0; i < size * 2; i++) {
|
||||||
|
samples[i] = this->hiShelf[i % 2].Process(samples[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this->hifi.Process(samples, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViPERClarity::Reset() {
|
||||||
|
this->sharp.SetSamplingRate(this->samplerate);
|
||||||
|
this->sharp.Reset();
|
||||||
|
SetClarityToFilter();
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
this->hiShelf[i].SetFrequency(8250.f);
|
||||||
|
this->hiShelf[i].SetQuality(100.f);
|
||||||
|
this->hiShelf[i].SetSamplingRate(DEFAULT_SAMPLERATE);
|
||||||
|
}
|
||||||
|
this->hifi.SetSamplingRate(this->samplerate);
|
||||||
|
this->hifi.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViPERClarity::SetClarity(float gainPercent) {
|
||||||
|
this->clarityGainPercent = gainPercent;
|
||||||
|
if (this->processMode != 1) {
|
||||||
|
SetClarityToFilter();
|
||||||
|
} else {
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViPERClarity::SetClarityToFilter() {
|
||||||
|
this->sharp.SetGain(this->clarityGainPercent);
|
||||||
|
this->hiShelf[0].SetGain(this->clarityGainPercent + 1.f);
|
||||||
|
this->hiShelf[1].SetGain(this->clarityGainPercent + 1.f);
|
||||||
|
this->hifi.SetClarity(this->clarityGainPercent + 1.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViPERClarity::SetEnable(bool enabled) {
|
||||||
|
this->enabled = enabled;
|
||||||
|
if (this->enabled) {
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViPERClarity::SetProcessMode(int mode) {
|
||||||
|
this->processMode = mode;
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViPERClarity::SetSamplingRate(uint32_t samplerate) {
|
||||||
|
this->samplerate = samplerate;
|
||||||
|
Reset();
|
||||||
|
}
|
34
src/effects/ViPERClarity.h
Normal file
34
src/effects/ViPERClarity.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
//
|
||||||
|
// Created by mart on 7/31/21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
#include "../utils/NoiseSharpening.h"
|
||||||
|
#include "../utils/HiFi.h"
|
||||||
|
#include "../utils/HighShelf.h"
|
||||||
|
|
||||||
|
class ViPERClarity {
|
||||||
|
public:
|
||||||
|
ViPERClarity();
|
||||||
|
|
||||||
|
void Process(float* samples, uint32_t size);
|
||||||
|
void Reset();
|
||||||
|
|
||||||
|
void SetClarity(float gainPercent);
|
||||||
|
void SetClarityToFilter();
|
||||||
|
void SetEnable(bool enabled);
|
||||||
|
void SetProcessMode(int mode);
|
||||||
|
void SetSamplingRate(uint32_t samplerate);
|
||||||
|
|
||||||
|
NoiseSharpening sharp;
|
||||||
|
HighShelf hiShelf[2];
|
||||||
|
HiFi hifi;
|
||||||
|
bool enabled;
|
||||||
|
int processMode;
|
||||||
|
uint32_t samplerate;
|
||||||
|
float clarityGainPercent;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
82
src/utils/HiFi.cpp
Normal file
82
src/utils/HiFi.cpp
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
//
|
||||||
|
// Created by mart on 7/31/21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "HiFi.h"
|
||||||
|
#include "../constants.h"
|
||||||
|
|
||||||
|
HiFi::HiFi() {
|
||||||
|
this->gain = 1.f;
|
||||||
|
this->samplerate = DEFAULT_SAMPLERATE;
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
this->buffers[i] = new WaveBuffer_I32(2, 0x800);
|
||||||
|
this->filters[i].lowpass = new IIR_NOrder_BW_LH(1);
|
||||||
|
this->filters[i].highpass = new IIR_NOrder_BW_LH(3);
|
||||||
|
this->filters[i].bandpass = new IIR_NOrder_BW_BP(3);
|
||||||
|
}
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
HiFi::~HiFi() {
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
delete this->buffers[i];
|
||||||
|
delete this->filters[i].lowpass;
|
||||||
|
delete this->filters[i].highpass;
|
||||||
|
delete this->filters[i].bandpass;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HiFi::Process(float *samples, uint32_t size) {
|
||||||
|
if (size > 0) {
|
||||||
|
float* bpBuf = this->buffers[0]->PushZerosGetBuffer(size);
|
||||||
|
float* lpBuf = this->buffers[1]->PushZerosGetBuffer(size);
|
||||||
|
if (bpBuf == nullptr || lpBuf == nullptr) {
|
||||||
|
Reset();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < size*2; i++) {
|
||||||
|
int index = i % 2;
|
||||||
|
float out1 = do_filter_lh(this->filters[index].lowpass, samples[i]);
|
||||||
|
float out2 = do_filter_lh(this->filters[index].highpass, samples[i]);
|
||||||
|
float out3 = do_filter_bp(this->filters[index].bandpass, samples[i]);
|
||||||
|
samples[i] = out2;
|
||||||
|
lpBuf[i] = out1;
|
||||||
|
bpBuf[i] = out3;
|
||||||
|
}
|
||||||
|
float* bpOut = this->buffers[0]->GetCurrentBufferI32Ptr();
|
||||||
|
float* lpOut = this->buffers[1]->GetCurrentBufferI32Ptr();
|
||||||
|
for (int i = 0; i < size * 2; i++) {
|
||||||
|
float hp = samples[i] * this->gain * 1.2f;
|
||||||
|
float bp = bpOut[i] * this->gain;
|
||||||
|
samples[i] = hp + bp + lpOut[i];
|
||||||
|
}
|
||||||
|
this->buffers[0]->PopSamples(size, false);
|
||||||
|
this->buffers[1]->PopSamples(size, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HiFi::Reset() {
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
this->filters[i].lowpass->setLPF(120.0, this->samplerate);
|
||||||
|
this->filters[i].lowpass->Mute();
|
||||||
|
this->filters[i].highpass->setHPF(1200.0, this->samplerate);
|
||||||
|
this->filters[i].highpass->Mute();
|
||||||
|
this->filters[i].bandpass->setBPF(120.f, 1200.f, this->samplerate);
|
||||||
|
this->filters[i].bandpass->Mute();
|
||||||
|
}
|
||||||
|
this->buffers[0]->Reset();
|
||||||
|
this->buffers[0]->PushZeros(this->samplerate/400);
|
||||||
|
this->buffers[1]->Reset();
|
||||||
|
this->buffers[1]->PushZeros(this->samplerate/200);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void HiFi::SetClarity(float value) {
|
||||||
|
this->gain = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HiFi::SetSamplingRate(uint32_t samplerate) {
|
||||||
|
this->samplerate = samplerate;
|
||||||
|
Reset();
|
||||||
|
}
|
33
src/utils/HiFi.h
Normal file
33
src/utils/HiFi.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
//
|
||||||
|
// Created by mart on 7/31/21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
#include "IIR_NOrder_BW_LH.h"
|
||||||
|
#include "WaveBuffer_I32.h"
|
||||||
|
#include "IIR_NOrder_BW_BP.h"
|
||||||
|
|
||||||
|
class HiFi {
|
||||||
|
public:
|
||||||
|
HiFi();
|
||||||
|
~HiFi();
|
||||||
|
|
||||||
|
void Process(float* samples, uint32_t size);
|
||||||
|
void Reset();
|
||||||
|
|
||||||
|
void SetClarity(float value);
|
||||||
|
void SetSamplingRate(uint32_t samplerate);
|
||||||
|
|
||||||
|
WaveBuffer_I32* buffers[2];
|
||||||
|
struct {
|
||||||
|
IIR_NOrder_BW_LH* lowpass;
|
||||||
|
IIR_NOrder_BW_LH* highpass;
|
||||||
|
IIR_NOrder_BW_BP* bandpass;
|
||||||
|
} filters[2];
|
||||||
|
float gain;
|
||||||
|
uint32_t samplerate;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
@ -30,3 +30,10 @@ public:
|
|||||||
float b0, b1, a1;
|
float b0, b1, a1;
|
||||||
float prevSample;
|
float prevSample;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline float do_filter(IIR_1st* filter, float sample) {
|
||||||
|
float hist = sample * filter->b1;
|
||||||
|
sample = filter->prevSample + sample * filter->b0;
|
||||||
|
filter->prevSample = sample * filter->a1 + hist;
|
||||||
|
return sample;
|
||||||
|
}
|
@ -19,3 +19,20 @@ public:
|
|||||||
uint32_t order;
|
uint32_t order;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline float do_filter_bplp(IIR_NOrder_BW_BP* filt, float sample) {
|
||||||
|
for (int idx = 0; idx < filt->order; idx++) {
|
||||||
|
sample = do_filter(&filt->lowpass[idx], sample);
|
||||||
|
}
|
||||||
|
return sample;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float do_filter_bphp(IIR_NOrder_BW_BP* filt, float sample) {
|
||||||
|
for (int idx = 0; idx < filt->order; idx++) {
|
||||||
|
sample = do_filter(&filt->highpass[idx], sample);
|
||||||
|
}
|
||||||
|
return sample;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float do_filter_bp(IIR_NOrder_BW_BP* filt, float sample) {
|
||||||
|
return do_filter_bphp(filt, do_filter_bplp(filt, sample));
|
||||||
|
}
|
||||||
|
@ -18,3 +18,10 @@ public:
|
|||||||
IIR_1st* filters;
|
IIR_1st* filters;
|
||||||
uint32_t order;
|
uint32_t order;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline float do_filter_lh(IIR_NOrder_BW_LH* filt, float sample) {
|
||||||
|
for (int idx = 0; idx < filt->order; idx++) {
|
||||||
|
sample = do_filter(&filt->filters[idx], sample);
|
||||||
|
}
|
||||||
|
return sample;
|
||||||
|
}
|
||||||
|
@ -40,23 +40,15 @@ void PassFilter::Reset() {
|
|||||||
this->filters[3]->Mute();
|
this->filters[3]->Mute();
|
||||||
}
|
}
|
||||||
|
|
||||||
#define do_filter(filt, sample) \
|
|
||||||
for (int idx = 0; idx < (filt)->order; idx++) {\
|
|
||||||
IIR_1st filter = this->filters[2]->filters[idx];\
|
|
||||||
float hist = (sample) * filter.b1;\
|
|
||||||
left = filter.prevSample + (sample) * filter.b0;\
|
|
||||||
filter.prevSample = (sample) * filter.a1 + hist;\
|
|
||||||
}
|
|
||||||
|
|
||||||
void PassFilter::ProcessFrames(float *buffer, uint32_t size) {
|
void PassFilter::ProcessFrames(float *buffer, uint32_t size) {
|
||||||
for (int x = 0; x < size; x++) {
|
for (int x = 0; x < size; x++) {
|
||||||
float left = buffer[2*x];
|
float left = buffer[2*x];
|
||||||
float right = buffer[2*x+1];
|
float right = buffer[2*x+1];
|
||||||
|
|
||||||
do_filter(this->filters[2], left)
|
left = do_filter_lh(this->filters[2], left);
|
||||||
do_filter(this->filters[0], left)
|
left = do_filter_lh(this->filters[0], left);
|
||||||
do_filter(this->filters[3], right)
|
right = do_filter_lh(this->filters[3], right);
|
||||||
do_filter(this->filters[1], right)
|
right = do_filter_lh(this->filters[1], right);
|
||||||
|
|
||||||
buffer[2*x] = left;
|
buffer[2*x] = left;
|
||||||
buffer[2*x+1] = right;
|
buffer[2*x+1] = right;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user