2021-07-30 16:54:59 +02:00
|
|
|
#include "AnalogX.h"
|
2022-08-30 00:39:15 +02:00
|
|
|
#include <cstring>
|
2021-07-30 16:54:59 +02:00
|
|
|
#include "../constants.h"
|
|
|
|
|
2022-10-16 16:54:32 +02:00
|
|
|
static const float ANALOGX_HARMONICS[] = {
|
2022-10-15 03:40:21 +02:00
|
|
|
0.01,
|
|
|
|
0.02,
|
|
|
|
0.0001,
|
|
|
|
0.001,
|
|
|
|
0.0,
|
|
|
|
0.0,
|
|
|
|
0.0,
|
|
|
|
0.0,
|
|
|
|
0.0,
|
|
|
|
0.0
|
2021-07-30 16:54:59 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
AnalogX::AnalogX() {
|
2022-10-13 03:01:20 +02:00
|
|
|
this->samplingRate = VIPER_DEFAULT_SAMPLING_RATE;
|
2021-07-30 16:54:59 +02:00
|
|
|
this->processingModel = 0;
|
2022-10-11 00:36:38 +02:00
|
|
|
this->enable = false;
|
2023-05-15 02:15:46 +02:00
|
|
|
this->gain = 0.0;
|
|
|
|
this->freqRange = 0;
|
2021-07-30 16:54:59 +02:00
|
|
|
Reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
void AnalogX::Process(float *samples, uint32_t size) {
|
2022-10-11 00:36:38 +02:00
|
|
|
if (this->enable) {
|
2022-10-15 03:40:21 +02:00
|
|
|
for (uint32_t i = 0; i < size * 2; i += 2) {
|
|
|
|
double inL = samples[i];
|
|
|
|
double outL = this->highPass[0].ProcessSample(inL);
|
|
|
|
outL = this->harmonic[0].Process(outL);
|
|
|
|
outL = this->lowPass[0].ProcessSample(inL + outL * this->gain);
|
|
|
|
outL = this->peak[0].ProcessSample(outL * 0.8);
|
|
|
|
samples[i] = (float) outL;
|
|
|
|
|
|
|
|
double inR = samples[i + 1];
|
|
|
|
double outR = this->highPass[1].ProcessSample(inR);
|
|
|
|
outR = this->harmonic[1].Process(outR);
|
|
|
|
outR = this->lowPass[1].ProcessSample(inR + outR * this->gain);
|
|
|
|
outR = this->peak[1].ProcessSample(outR * 0.8);
|
|
|
|
samples[i + 1] = (float) outR;
|
2022-10-11 00:36:38 +02:00
|
|
|
}
|
2021-07-30 16:54:59 +02:00
|
|
|
|
2022-10-11 00:36:38 +02:00
|
|
|
if (this->freqRange < this->samplingRate / 4) {
|
|
|
|
this->freqRange += size;
|
|
|
|
memset(samples, 0, size * 2 * sizeof(float));
|
|
|
|
}
|
2021-07-30 16:54:59 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void AnalogX::Reset() {
|
2022-10-15 03:40:21 +02:00
|
|
|
this->highPass[0].RefreshFilter(MultiBiquad::FilterType::HIGH_PASS, 0.0, 240.0, this->samplingRate, 0.717, false);
|
|
|
|
this->highPass[1].RefreshFilter(MultiBiquad::FilterType::HIGH_PASS, 0.0, 240.0, this->samplingRate, 0.717, false);
|
2021-07-30 16:54:59 +02:00
|
|
|
|
2022-10-15 03:40:21 +02:00
|
|
|
this->peak[0].RefreshFilter(MultiBiquad::FilterType::PEAK, 0.58, 633.0, this->samplingRate, 6.28, true);
|
|
|
|
this->peak[1].RefreshFilter(MultiBiquad::FilterType::PEAK, 0.58, 633.0, this->samplingRate, 6.28, true);
|
2021-07-30 16:54:59 +02:00
|
|
|
|
2022-10-15 03:40:21 +02:00
|
|
|
this->harmonic[0].Reset();
|
|
|
|
this->harmonic[1].Reset();
|
2021-07-30 16:54:59 +02:00
|
|
|
|
2022-10-15 03:40:21 +02:00
|
|
|
switch (this->processingModel) {
|
|
|
|
case 0: {
|
|
|
|
this->harmonic[0].SetHarmonics(ANALOGX_HARMONICS);
|
|
|
|
this->harmonic[1].SetHarmonics(ANALOGX_HARMONICS);
|
2022-09-13 02:16:31 +02:00
|
|
|
|
2022-10-15 03:40:21 +02:00
|
|
|
this->gain = 0.6;
|
2022-09-13 02:16:31 +02:00
|
|
|
|
2022-10-15 03:40:21 +02:00
|
|
|
this->lowPass[0].RefreshFilter(MultiBiquad::FilterType::LOW_PASS, 0.0, 19650.0, this->samplingRate, 0.717, false);
|
|
|
|
this->lowPass[1].RefreshFilter(MultiBiquad::FilterType::LOW_PASS, 0.0, 19650.0, this->samplingRate, 0.717, false);
|
|
|
|
break;
|
2022-09-13 02:16:31 +02:00
|
|
|
}
|
2022-10-15 03:40:21 +02:00
|
|
|
case 1: {
|
|
|
|
this->harmonic[0].SetHarmonics(ANALOGX_HARMONICS);
|
|
|
|
this->harmonic[1].SetHarmonics(ANALOGX_HARMONICS);
|
2022-09-13 02:16:31 +02:00
|
|
|
|
2022-10-15 03:40:21 +02:00
|
|
|
this->gain = 1.2;
|
2022-09-13 02:16:31 +02:00
|
|
|
|
2022-10-15 03:40:21 +02:00
|
|
|
this->lowPass[0].RefreshFilter(MultiBiquad::FilterType::LOW_PASS, 0.0, 18233.0, this->samplingRate, 0.717, false);
|
|
|
|
this->lowPass[1].RefreshFilter(MultiBiquad::FilterType::LOW_PASS, 0.0, 18233.0, this->samplingRate, 0.717, false);
|
|
|
|
break;
|
2022-09-13 02:16:31 +02:00
|
|
|
}
|
2022-10-15 03:40:21 +02:00
|
|
|
case 2: {
|
|
|
|
this->harmonic[0].SetHarmonics(ANALOGX_HARMONICS);
|
|
|
|
this->harmonic[1].SetHarmonics(ANALOGX_HARMONICS);
|
2022-09-13 02:16:31 +02:00
|
|
|
|
2022-10-15 03:40:21 +02:00
|
|
|
this->gain = 2.4;
|
2022-09-13 02:16:31 +02:00
|
|
|
|
2022-10-15 03:40:21 +02:00
|
|
|
this->lowPass[0].RefreshFilter(MultiBiquad::FilterType::LOW_PASS, 0.0, 16307.0, this->samplingRate, 0.717, false);
|
|
|
|
this->lowPass[1].RefreshFilter(MultiBiquad::FilterType::LOW_PASS, 0.0, 16307.0, this->samplingRate, 0.717, false);
|
|
|
|
break;
|
2022-09-13 02:16:31 +02:00
|
|
|
}
|
2021-07-30 16:54:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
this->freqRange = 0;
|
|
|
|
}
|
|
|
|
|
2022-10-11 00:36:38 +02:00
|
|
|
void AnalogX::SetEnable(bool enable) {
|
|
|
|
if (this->enable != enable) {
|
|
|
|
if (!this->enable) {
|
|
|
|
Reset();
|
|
|
|
}
|
|
|
|
this->enable = enable;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-13 02:16:31 +02:00
|
|
|
void AnalogX::SetProcessingModel(int processingModel) {
|
|
|
|
if (this->processingModel != processingModel) {
|
|
|
|
this->processingModel = processingModel;
|
|
|
|
Reset();
|
|
|
|
}
|
2021-07-30 16:54:59 +02:00
|
|
|
}
|
|
|
|
|
2022-09-13 02:16:31 +02:00
|
|
|
void AnalogX::SetSamplingRate(uint32_t samplingRate) {
|
|
|
|
if (this->samplingRate != samplingRate) {
|
|
|
|
this->samplingRate = samplingRate;
|
|
|
|
Reset();
|
|
|
|
}
|
2021-07-30 16:54:59 +02:00
|
|
|
}
|