mirror of
https://github.com/AndroidAudioMods/ViPERFX_RE.git
synced 2024-12-22 14:37:24 +08:00
harmonics, analogx and spectrumextend
This commit is contained in:
parent
46dac9bf20
commit
4fb9cee285
@ -19,9 +19,11 @@ set(FILES
|
||||
src/viper.cpp
|
||||
|
||||
# Effects
|
||||
src/effects/AnalogX.cpp
|
||||
src/effects/Cure.cpp
|
||||
src/effects/DynamicSystem.cpp
|
||||
src/effects/Reverberation.cpp
|
||||
src/effects/SpectrumExtend.cpp
|
||||
src/effects/TubeSimulator.cpp
|
||||
|
||||
# Utils
|
||||
@ -32,6 +34,7 @@ set(FILES
|
||||
src/utils/DepthSurround.cpp
|
||||
src/utils/DynamicBass.cpp
|
||||
src/utils/FixedBiquad.cpp
|
||||
src/utils/Harmonic.cpp
|
||||
src/utils/HighShelf.cpp
|
||||
src/utils/IIR_1st.cpp
|
||||
src/utils/IIR_NOrder_BW_BP.cpp
|
||||
|
90
src/effects/AnalogX.cpp
Normal file
90
src/effects/AnalogX.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
//
|
||||
// Created by mart on 7/30/21.
|
||||
//
|
||||
|
||||
#include <cstring>
|
||||
#include "AnalogX.h"
|
||||
#include "../constants.h"
|
||||
|
||||
static float ANALOGX_HARMONICS[10] = {
|
||||
0.01f,
|
||||
0.02f,
|
||||
0.0001f,
|
||||
0.001f,
|
||||
0.f,
|
||||
0.f,
|
||||
0.f,
|
||||
0.f,
|
||||
0.f,
|
||||
0.f
|
||||
};
|
||||
|
||||
AnalogX::AnalogX() {
|
||||
this->samplerate = DEFAULT_SAMPLERATE;
|
||||
this->processingModel = 0;
|
||||
this->enabled = false;
|
||||
Reset();
|
||||
}
|
||||
|
||||
void AnalogX::Process(float *samples, uint32_t size) {
|
||||
for (int i = 0; i < 2*size; i++) {
|
||||
float sample = samples[i];
|
||||
int index = i % 2;
|
||||
|
||||
float tmp = this->highpass[index].ProcessSample(sample);
|
||||
tmp = this->harmonics[index].Process(tmp);
|
||||
|
||||
tmp = this->lowpass[index].ProcessSample(sample + tmp * this->gain);
|
||||
tmp = this->peak->ProcessSample(tmp * 0.8f);
|
||||
|
||||
samples[i] = tmp;
|
||||
}
|
||||
|
||||
if (this->freqRange < this->samplerate / 4) {
|
||||
this->freqRange += size;
|
||||
memset(samples, 0, 2 * size * sizeof(float));
|
||||
}
|
||||
}
|
||||
|
||||
void AnalogX::Reset() {
|
||||
this->highpass[0].RefreshFilter(FilterType::HIGHPASS, 0.f, 240.f, (float)this->samplerate, 0.717, false);
|
||||
this->highpass[1].RefreshFilter(FilterType::HIGHPASS, 0.f, 240.f, (float)this->samplerate, 0.717, false);
|
||||
|
||||
this->peak[0].RefreshFilter(FilterType::PEAK, 0.58f, 633.f, (float)this->samplerate, 6.28, true);
|
||||
this->peak[1].RefreshFilter(FilterType::PEAK, 0.58f, 633.f, (float)this->samplerate, 6.28, true);
|
||||
|
||||
this->harmonics[0].Reset();
|
||||
this->harmonics[1].Reset();
|
||||
|
||||
if (this->processingModel == 0) {
|
||||
this->harmonics[0].SetHarmonics(ANALOGX_HARMONICS);
|
||||
this->harmonics[1].SetHarmonics(ANALOGX_HARMONICS);
|
||||
this->gain = 0.6f;
|
||||
this->lowpass[0].RefreshFilter(FilterType::LOWPASS, 0.0, 18233.f, (float)this->samplerate, 0.717f, false);
|
||||
this->lowpass[1].RefreshFilter(FilterType::LOWPASS, 0.0, 18233.f, (float)this->samplerate, 0.717f, false);
|
||||
} else if (this->processingModel == 1) {
|
||||
this->harmonics[0].SetHarmonics(ANALOGX_HARMONICS);
|
||||
this->harmonics[1].SetHarmonics(ANALOGX_HARMONICS);
|
||||
this->gain = 1.2f;
|
||||
this->lowpass[0].RefreshFilter(FilterType::LOWPASS, 0.0, 19650.f, (float)this->samplerate, 0.717f, false);
|
||||
this->lowpass[1].RefreshFilter(FilterType::LOWPASS, 0.0, 19650.f, (float)this->samplerate, 0.717f, false);
|
||||
} else if (this->processingModel == 2) {
|
||||
this->harmonics[0].SetHarmonics(ANALOGX_HARMONICS);
|
||||
this->harmonics[1].SetHarmonics(ANALOGX_HARMONICS);
|
||||
this->gain = 2.4f;
|
||||
this->lowpass[0].RefreshFilter(FilterType::LOWPASS, 0.0, 16307.f, (float)this->samplerate, 0.717f, false);
|
||||
this->lowpass[1].RefreshFilter(FilterType::LOWPASS, 0.0, 16307.f, (float)this->samplerate, 0.717f, false);
|
||||
}
|
||||
|
||||
this->freqRange = 0;
|
||||
}
|
||||
|
||||
void AnalogX::SetProcessingModel(int model) {
|
||||
this->processingModel = model;
|
||||
Reset();
|
||||
}
|
||||
|
||||
void AnalogX::SetSamplingRate(uint32_t samplerate) {
|
||||
this->samplerate = samplerate;
|
||||
Reset();
|
||||
}
|
33
src/effects/AnalogX.h
Normal file
33
src/effects/AnalogX.h
Normal file
@ -0,0 +1,33 @@
|
||||
//
|
||||
// Created by mart on 7/30/21.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "../utils/Harmonic.h"
|
||||
#include "../utils/MultiBiquad.h"
|
||||
|
||||
class AnalogX {
|
||||
public:
|
||||
AnalogX();
|
||||
|
||||
void Process(float* samples, uint32_t size);
|
||||
void Reset();
|
||||
|
||||
void SetProcessingModel(int model);
|
||||
void SetSamplingRate(uint32_t samplerate);
|
||||
|
||||
MultiBiquad highpass[2];
|
||||
Harmonic harmonics[2];
|
||||
MultiBiquad lowpass[2];
|
||||
MultiBiquad peak[2];
|
||||
|
||||
float gain;
|
||||
uint32_t freqRange;
|
||||
int processingModel;
|
||||
uint32_t samplerate;
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
|
80
src/effects/SpectrumExtend.cpp
Normal file
80
src/effects/SpectrumExtend.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
//
|
||||
// Created by mart on 7/30/21.
|
||||
//
|
||||
|
||||
#include "SpectrumExtend.h"
|
||||
#include "../constants.h"
|
||||
|
||||
static float SPECTRUM_HARMONICS[10] = {
|
||||
0.02f,
|
||||
0.f,
|
||||
0.02f,
|
||||
0.f,
|
||||
0.02f,
|
||||
0.f,
|
||||
0.02f,
|
||||
0.f,
|
||||
0.02f,
|
||||
0.f,
|
||||
};
|
||||
|
||||
SpectrumExtend::SpectrumExtend() {
|
||||
this->samplerate = DEFAULT_SAMPLERATE;
|
||||
this->referenceFreq = 7600;
|
||||
this->enabled = false;
|
||||
this->exciter = 0.f;
|
||||
Reset();
|
||||
}
|
||||
|
||||
SpectrumExtend::~SpectrumExtend() {
|
||||
// empty?
|
||||
}
|
||||
|
||||
void SpectrumExtend::Process(float *samples, uint32_t size) {
|
||||
for (int i = 0; i < size * 2; i++) {
|
||||
float sample = samples[i];
|
||||
int index = i % 2;
|
||||
float tmp = this->highpass[index].ProcessSample(sample);
|
||||
tmp = this->harmonics[index].Process(tmp);
|
||||
tmp = this->lowpass[index].ProcessSample(tmp * this->exciter);
|
||||
samples[i] = samples[i] + tmp;
|
||||
}
|
||||
}
|
||||
|
||||
void SpectrumExtend::Reset() {
|
||||
this->highpass[0].RefreshFilter(FilterType::HIGHPASS, 0.0, (float)this->referenceFreq, (float)this->samplerate, 0.717, false);
|
||||
this->highpass[1].RefreshFilter(FilterType::HIGHPASS, 0.0, (float)this->referenceFreq, (float)this->samplerate, 0.717, false);
|
||||
|
||||
this->lowpass[0].RefreshFilter(FilterType::LOWPASS, 0.0, (float)this->referenceFreq / 2.f - 2000.f, (float)this->referenceFreq, 0.717, false);
|
||||
this->lowpass[1].RefreshFilter(FilterType::LOWPASS, 0.0, (float)this->referenceFreq / 2.f - 2000.f, (float)this->referenceFreq, 0.717, false);
|
||||
|
||||
this->harmonics[0].Reset();
|
||||
this->harmonics[1].Reset();
|
||||
|
||||
this->harmonics[0].SetHarmonics(SPECTRUM_HARMONICS);
|
||||
this->harmonics[1].SetHarmonics(SPECTRUM_HARMONICS);
|
||||
}
|
||||
|
||||
void SpectrumExtend::SetEnable(bool enable) {
|
||||
this->enabled = enable;
|
||||
}
|
||||
|
||||
void SpectrumExtend::SetExciter(float value) {
|
||||
this->exciter = value;
|
||||
}
|
||||
|
||||
void SpectrumExtend::SetReferenceFrequency(uint32_t freq) {
|
||||
if (this->samplerate / 2 - 100 < freq) {
|
||||
freq = this->samplerate / 2 - 100;
|
||||
}
|
||||
this->referenceFreq = freq;
|
||||
Reset();
|
||||
}
|
||||
|
||||
void SpectrumExtend::SetSamplingRate(uint32_t samplerate) {
|
||||
this->samplerate = samplerate;
|
||||
if (this->samplerate / 2 - 100 < this->referenceFreq) {
|
||||
this->referenceFreq = this->samplerate / 2 - 100;
|
||||
}
|
||||
Reset();
|
||||
}
|
32
src/effects/SpectrumExtend.h
Normal file
32
src/effects/SpectrumExtend.h
Normal file
@ -0,0 +1,32 @@
|
||||
//
|
||||
// Created by mart on 7/30/21.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "../utils/Harmonic.h"
|
||||
#include "../utils/MultiBiquad.h"
|
||||
|
||||
class SpectrumExtend {
|
||||
public:
|
||||
SpectrumExtend();
|
||||
~SpectrumExtend();
|
||||
|
||||
void Process(float* samples, uint32_t size);
|
||||
void Reset();
|
||||
void SetEnable(bool enable);
|
||||
void SetExciter(float value);
|
||||
void SetReferenceFrequency(uint32_t freq);
|
||||
void SetSamplingRate(uint32_t samplerate);
|
||||
|
||||
MultiBiquad highpass[2];
|
||||
MultiBiquad lowpass[2];
|
||||
Harmonic harmonics[2];
|
||||
bool enabled;
|
||||
uint32_t samplerate;
|
||||
uint32_t referenceFreq;
|
||||
float exciter;
|
||||
};
|
||||
|
||||
|
65
src/utils/Harmonic.cpp
Normal file
65
src/utils/Harmonic.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
//
|
||||
// Created by mart on 7/30/21.
|
||||
//
|
||||
|
||||
#include "Harmonic.h"
|
||||
|
||||
static float HARMONIC_DEFAULT[10] = {
|
||||
1.f,
|
||||
0.f,
|
||||
0.f,
|
||||
0.f,
|
||||
0.f,
|
||||
0.f,
|
||||
0.f,
|
||||
0.f,
|
||||
0.f,
|
||||
0.f,
|
||||
};
|
||||
|
||||
Harmonic::Harmonic() {
|
||||
UpdateCoeffs(HARMONIC_DEFAULT);
|
||||
Reset();
|
||||
}
|
||||
|
||||
Harmonic::~Harmonic() {
|
||||
|
||||
}
|
||||
|
||||
float Harmonic::Process(float sample) {
|
||||
float prevLast = this->lastProcessed;
|
||||
this->lastProcessed = (
|
||||
sample * this->coeffs[0] +
|
||||
sample * this->coeffs[1] +
|
||||
sample * this->coeffs[2] +
|
||||
sample * this->coeffs[3] +
|
||||
sample * this->coeffs[4] +
|
||||
sample * this->coeffs[5] +
|
||||
sample * this->coeffs[6] +
|
||||
sample * this->coeffs[7] +
|
||||
sample * this->coeffs[8] +
|
||||
sample * this->coeffs[9] +
|
||||
sample * this->coeffs[10]
|
||||
);
|
||||
this->prevOut = this->lastProcessed + this->prevOut * 0.999f - prevLast;
|
||||
if (this->sampleCounter < this->buildup) {
|
||||
this->sampleCounter++;
|
||||
return 0;
|
||||
}
|
||||
return this->prevOut;
|
||||
}
|
||||
|
||||
void Harmonic::Reset() {
|
||||
this->lastProcessed = 0.f;
|
||||
this->prevOut = 0.f;
|
||||
this->sampleCounter = 0.f;
|
||||
}
|
||||
|
||||
void Harmonic::SetHarmonics(float *coeffs) {
|
||||
UpdateCoeffs(coeffs);
|
||||
Reset();
|
||||
}
|
||||
|
||||
void Harmonic::UpdateCoeffs(float *coeffs) {
|
||||
// TODO
|
||||
}
|
28
src/utils/Harmonic.h
Normal file
28
src/utils/Harmonic.h
Normal file
@ -0,0 +1,28 @@
|
||||
//
|
||||
// Created by mart on 7/30/21.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class Harmonic {
|
||||
public:
|
||||
Harmonic();
|
||||
~Harmonic();
|
||||
|
||||
float Process(float sample);
|
||||
|
||||
void Reset();
|
||||
void SetHarmonics(float* coeffs);
|
||||
void UpdateCoeffs(float* coeffs);
|
||||
|
||||
float coeffs[11];
|
||||
float lastProcessed;
|
||||
float prevOut;
|
||||
int buildup;
|
||||
int sampleCounter;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user