2022-08-30 00:39:15 +02:00
|
|
|
#include "ViPERBass.h"
|
2022-09-19 02:36:53 +02:00
|
|
|
#include "../constants.h"
|
2022-09-06 17:57:23 +02:00
|
|
|
|
|
|
|
ViPERBass::ViPERBass() {
|
2022-09-19 02:36:53 +02:00
|
|
|
this->samplingRate = DEFAULT_SAMPLERATE;
|
|
|
|
this->speaker = 60;
|
|
|
|
this->invertedSamplingRate = 1.0f / DEFAULT_SAMPLERATE;
|
2022-09-19 02:43:27 +02:00
|
|
|
this->antiPop = 0.0;
|
2022-09-19 02:36:53 +02:00
|
|
|
this->processMode = NATURAL_BASS;
|
|
|
|
this->bassFactor = 0.0f;
|
|
|
|
this->polyphase = new Polyphase(2);
|
|
|
|
this->biquad = new Biquad();
|
|
|
|
this->subwoofer = new Subwoofer();
|
|
|
|
this->waveBuffer = new WaveBuffer(1, 0x1000);
|
|
|
|
|
|
|
|
this->biquad->Reset();
|
|
|
|
this->biquad->SetLowPassParameter(this->speaker, this->samplingRate, 0.53);
|
|
|
|
this->subwoofer->SetBassGain(this->samplingRate, 0.0);
|
|
|
|
this->Reset();
|
2022-09-06 17:57:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
ViPERBass::~ViPERBass() {
|
2022-09-19 02:36:53 +02:00
|
|
|
delete this->polyphase;
|
|
|
|
this->polyphase = nullptr;
|
|
|
|
|
|
|
|
delete this->biquad;
|
|
|
|
this->biquad = nullptr;
|
|
|
|
|
|
|
|
delete this->subwoofer;
|
|
|
|
this->subwoofer = nullptr;
|
2022-09-06 17:57:23 +02:00
|
|
|
|
2022-09-19 02:36:53 +02:00
|
|
|
delete this->waveBuffer;
|
|
|
|
this->waveBuffer = nullptr;
|
2022-09-06 17:57:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void ViPERBass::Process(float *samples, uint32_t size) {
|
2022-09-19 02:36:53 +02:00
|
|
|
if (size == 0) {
|
|
|
|
return;
|
|
|
|
}
|
2022-09-06 17:57:23 +02:00
|
|
|
|
2022-09-19 02:43:27 +02:00
|
|
|
if (this->antiPop < 1.0) {
|
2022-09-19 02:36:53 +02:00
|
|
|
for (uint32_t i = 0; i < size * 2; i += 2) {
|
2022-09-19 02:43:27 +02:00
|
|
|
samples[i] *= this->antiPop;
|
|
|
|
samples[i + 1] *= this->antiPop;
|
2022-09-19 02:36:53 +02:00
|
|
|
|
2022-09-19 02:43:27 +02:00
|
|
|
float x = this->antiPop + this->invertedSamplingRate;
|
2022-09-19 02:36:53 +02:00
|
|
|
if (x > 1.0) {
|
|
|
|
x = 1.0;
|
|
|
|
}
|
2022-09-19 02:43:27 +02:00
|
|
|
this->antiPop = x;
|
2022-09-19 02:36:53 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (this->processMode) {
|
|
|
|
case NATURAL_BASS: {
|
|
|
|
for (uint32_t i = 0; i < size * 2; i += 2) {
|
|
|
|
double sample = ((double) samples[i] + (double) samples[i + 1]) / 2.0;
|
|
|
|
auto x = (float) this->biquad->ProcessSample(sample);
|
|
|
|
samples[i] += x;
|
|
|
|
samples[i + 1] += x;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case PURE_BASS_PLUS: {
|
|
|
|
if (this->waveBuffer->PushSamples(samples, size) != 0) {
|
|
|
|
float *buffer = this->waveBuffer->GetBuffer();
|
|
|
|
uint32_t bufferOffset = this->waveBuffer->GetBufferOffset();
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < size * 2; i += 2) {
|
|
|
|
double sample = ((double) samples[i] + (double) samples[i + 1]) / 2.0;
|
|
|
|
auto x = (float) this->biquad->ProcessSample(sample);
|
|
|
|
buffer[bufferOffset - size + i / 2] = x;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this->polyphase->Process(samples, size) == size) {
|
|
|
|
for (uint32_t i = 0; i < size; i++) {
|
|
|
|
samples[i] += buffer[i] * this->bassFactor;
|
|
|
|
samples[i + 1] += buffer[i] * this->bassFactor;
|
|
|
|
}
|
|
|
|
this->waveBuffer->PopSamples(size, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case SUBWOOFER: {
|
|
|
|
this->subwoofer->Process(samples, size);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2022-09-06 17:57:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void ViPERBass::Reset() {
|
2022-09-16 03:16:58 +02:00
|
|
|
this->polyphase->SetSamplingRate(this->samplingRate);
|
|
|
|
this->polyphase->Reset();
|
|
|
|
this->waveBuffer->Reset();
|
|
|
|
this->waveBuffer->PushZeros(this->polyphase->GetLatency());
|
|
|
|
this->subwoofer->SetBassGain(this->samplingRate, this->bassFactor * 2.5f);
|
2022-09-19 02:36:53 +02:00
|
|
|
this->biquad->SetLowPassParameter(this->speaker, this->samplingRate, 0.53);
|
2022-09-19 02:43:27 +02:00
|
|
|
this->antiPop = 0.0f;
|
2022-09-19 02:36:53 +02:00
|
|
|
this->invertedSamplingRate = 1.0f / (float) this->samplingRate;
|
2022-09-06 17:57:23 +02:00
|
|
|
}
|
|
|
|
|
2022-09-16 03:16:58 +02:00
|
|
|
void ViPERBass::SetBassFactor(float bassFactor) {
|
2022-09-19 02:36:53 +02:00
|
|
|
if (this->bassFactor != bassFactor) {
|
|
|
|
this->bassFactor = bassFactor;
|
|
|
|
this->subwoofer->SetBassGain(this->samplingRate, this->bassFactor * 2.5f);
|
2022-09-16 03:16:58 +02:00
|
|
|
}
|
2022-09-06 17:57:23 +02:00
|
|
|
}
|
|
|
|
|
2022-09-19 02:36:53 +02:00
|
|
|
void ViPERBass::SetProcessMode(ProcessMode processMode) {
|
2022-09-19 02:37:58 +02:00
|
|
|
if (this->processMode != processMode) {
|
2022-09-19 02:36:53 +02:00
|
|
|
this->processMode = processMode;
|
|
|
|
this->Reset();
|
|
|
|
}
|
2022-09-06 17:57:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void ViPERBass::SetSamplingRate(uint32_t samplingRate) {
|
2022-09-19 02:36:53 +02:00
|
|
|
if (this->samplingRate != samplingRate) {
|
|
|
|
this->samplingRate = samplingRate;
|
|
|
|
this->invertedSamplingRate = 1.0f / (float) samplingRate;
|
|
|
|
this->polyphase->SetSamplingRate(samplingRate);
|
|
|
|
this->biquad->SetLowPassParameter(this->speaker, samplingRate, 0.53);
|
|
|
|
this->subwoofer->SetBassGain(samplingRate, this->bassFactor * 2.5);
|
|
|
|
}
|
2022-09-06 17:57:23 +02:00
|
|
|
}
|
|
|
|
|
2022-09-19 02:36:53 +02:00
|
|
|
void ViPERBass::SetSpeaker(uint32_t speaker) {
|
2022-09-16 03:16:58 +02:00
|
|
|
if (this->speaker != speaker) {
|
|
|
|
this->speaker = speaker;
|
2022-09-19 02:36:53 +02:00
|
|
|
this->biquad->SetLowPassParameter(this->speaker, this->samplingRate, 0.53);
|
2022-09-16 03:16:58 +02:00
|
|
|
}
|
2022-09-06 17:57:23 +02:00
|
|
|
}
|