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/SpectrumExtend.cpp
|
||||
src/effects/TubeSimulator.cpp
|
||||
src/effects/ViPERClarity.cpp
|
||||
|
||||
# Utils
|
||||
src/utils/CAllpassFilter.cpp
|
||||
@ -37,6 +38,7 @@ set(FILES
|
||||
src/utils/DynamicBass.cpp
|
||||
src/utils/FixedBiquad.cpp
|
||||
src/utils/Harmonic.cpp
|
||||
src/utils/HiFi.cpp
|
||||
src/utils/HighShelf.cpp
|
||||
src/utils/IIR_1st.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 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;
|
||||
};
|
||||
|
||||
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;
|
||||
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();
|
||||
}
|
||||
|
||||
#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) {
|
||||
for (int x = 0; x < size; x++) {
|
||||
float left = buffer[2*x];
|
||||
float right = buffer[2*x+1];
|
||||
|
||||
do_filter(this->filters[2], left)
|
||||
do_filter(this->filters[0], left)
|
||||
do_filter(this->filters[3], right)
|
||||
do_filter(this->filters[1], right)
|
||||
left = do_filter_lh(this->filters[2], left);
|
||||
left = do_filter_lh(this->filters[0], left);
|
||||
right = do_filter_lh(this->filters[3], right);
|
||||
right = do_filter_lh(this->filters[1], right);
|
||||
|
||||
buffer[2*x] = left;
|
||||
buffer[2*x+1] = right;
|
||||
|
Loading…
x
Reference in New Issue
Block a user