mirror of
https://github.com/AndroidAudioMods/ViPERFX_RE.git
synced 2024-12-22 14:37:24 +08:00
SpeakerCorrection and Subwoofer
This commit is contained in:
parent
4fb9cee285
commit
7b60aaeecd
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
# User-specific stuff
|
# User-specific stuff
|
||||||
.idea/
|
.idea/
|
||||||
|
.cmake/
|
||||||
.ninja_deps
|
.ninja_deps
|
||||||
.ninja_log
|
.ninja_log
|
||||||
build.ninja
|
build.ninja
|
||||||
|
@ -23,6 +23,7 @@ set(FILES
|
|||||||
src/effects/Cure.cpp
|
src/effects/Cure.cpp
|
||||||
src/effects/DynamicSystem.cpp
|
src/effects/DynamicSystem.cpp
|
||||||
src/effects/Reverberation.cpp
|
src/effects/Reverberation.cpp
|
||||||
|
src/effects/SpeakerCorrection.cpp
|
||||||
src/effects/SpectrumExtend.cpp
|
src/effects/SpectrumExtend.cpp
|
||||||
src/effects/TubeSimulator.cpp
|
src/effects/TubeSimulator.cpp
|
||||||
|
|
||||||
@ -43,6 +44,7 @@ set(FILES
|
|||||||
src/utils/NoiseSharpening.cpp
|
src/utils/NoiseSharpening.cpp
|
||||||
src/utils/PassFilter.cpp
|
src/utils/PassFilter.cpp
|
||||||
src/utils/PolesFilter.cpp
|
src/utils/PolesFilter.cpp
|
||||||
|
src/utils/Subwoofer.cpp
|
||||||
src/utils/TimeConstDelay.cpp
|
src/utils/TimeConstDelay.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ To view the progress, see [Issue #2](https://github.com/AndroidAudioMods/ViPERFX
|
|||||||
|
|
||||||
# CLion
|
# CLion
|
||||||
|
|
||||||
|
Make sure to install `ninja`
|
||||||
In CLion, make sure to set the following custom arguments: `-DCMAKE_TOOLCHAIN_FILE=<NDKROOT>/build/cmake/android.toolchain.cmake -DANDROID_ABI=<ABI> -G Ninja`
|
In CLion, make sure to set the following custom arguments: `-DCMAKE_TOOLCHAIN_FILE=<NDKROOT>/build/cmake/android.toolchain.cmake -DANDROID_ABI=<ABI> -G Ninja`
|
||||||
Then you can build the project with `ninja` instead of `make`
|
Then you can build the project with `ninja` instead of `make`
|
||||||
|
|
||||||
|
47
src/effects/SpeakerCorrection.cpp
Normal file
47
src/effects/SpeakerCorrection.cpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
//
|
||||||
|
// Created by mart on 7/30/21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "SpeakerCorrection.h"
|
||||||
|
#include "../constants.h"
|
||||||
|
|
||||||
|
SpeakerCorrection::SpeakerCorrection() {
|
||||||
|
this->samplerate = DEFAULT_SAMPLERATE;
|
||||||
|
this->enabled = false;
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpeakerCorrection::Process(float *samples, uint32_t size) {
|
||||||
|
for (int i = 0; i < size * 2; i++) {
|
||||||
|
float sample = samples[i];
|
||||||
|
int index = i % 2;
|
||||||
|
sample = this->lowpass[index].ProcessSample(sample);
|
||||||
|
sample = this->highpass[index].ProcessSample(sample);
|
||||||
|
float tmp = sample / 2.f;
|
||||||
|
samples[i] = tmp + this->bandpass[index].ProcessSample(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpeakerCorrection::Reset() {
|
||||||
|
this->lowpass[0].Reset();
|
||||||
|
this->lowpass[1].Reset();
|
||||||
|
this->bandpass[0].Reset();
|
||||||
|
this->bandpass[1].Reset();
|
||||||
|
|
||||||
|
this->highpass[0].RefreshFilter(FilterType::HIGHPASS, 0.f, 80.f, (float)this->samplerate, 1.f, false);
|
||||||
|
this->highpass[1].RefreshFilter(FilterType::HIGHPASS, 0.f, 80.f, (float)this->samplerate, 1.f, false);
|
||||||
|
this->lowpass[0].SetLowPassParameter(13500.f, this->samplerate, 1.0);
|
||||||
|
this->lowpass[1].SetLowPassParameter(13500.f, this->samplerate, 1.0);
|
||||||
|
this->bandpass[0].SetBandPassParameter(420.f, this->samplerate, 3.88f);
|
||||||
|
this->bandpass[1].SetBandPassParameter(420.f, this->samplerate, 3.88f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpeakerCorrection::SetEnable(bool enabled) {
|
||||||
|
this->enabled = enabled;
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpeakerCorrection::SetSamplingRate(uint32_t samplerate) {
|
||||||
|
this->samplerate = samplerate;
|
||||||
|
Reset();
|
||||||
|
}
|
25
src/effects/SpeakerCorrection.h
Normal file
25
src/effects/SpeakerCorrection.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// Created by mart on 7/30/21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../utils/MultiBiquad.h"
|
||||||
|
#include "../utils/FixedBiquad.h"
|
||||||
|
|
||||||
|
class SpeakerCorrection {
|
||||||
|
public:
|
||||||
|
SpeakerCorrection();
|
||||||
|
|
||||||
|
void Process(float* samples, uint32_t size);
|
||||||
|
void Reset();
|
||||||
|
|
||||||
|
void SetEnable(bool enabled);
|
||||||
|
void SetSamplingRate(uint32_t samplerate);
|
||||||
|
|
||||||
|
uint32_t samplerate;
|
||||||
|
bool enabled;
|
||||||
|
MultiBiquad highpass[2];
|
||||||
|
FixedBiquad lowpass[2];
|
||||||
|
FixedBiquad bandpass[2];
|
||||||
|
};
|
40
src/utils/Subwoofer.cpp
Normal file
40
src/utils/Subwoofer.cpp
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
//
|
||||||
|
// Created by mart on 7/30/21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Subwoofer.h"
|
||||||
|
#include "../constants.h"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
Subwoofer::Subwoofer() {
|
||||||
|
float samplerate = (float)DEFAULT_SAMPLERATE;
|
||||||
|
this->peak[0].RefreshFilter(FilterType::PEAK, 0.f, 37.f, samplerate, 1.f, false);
|
||||||
|
this->peak[1].RefreshFilter(FilterType::PEAK, 0.f, 37.f, samplerate, 1.f, false);
|
||||||
|
this->peakLow[0].RefreshFilter(FilterType::PEAK, 0.f, 75.f, samplerate, 1.f, false);
|
||||||
|
this->peakLow[1].RefreshFilter(FilterType::PEAK, 0.f, 75.f, samplerate, 1.f, false);
|
||||||
|
this->lowpass[0].RefreshFilter(FilterType::LOWPASS, 0.f, 200.f, samplerate, 1.f, false);
|
||||||
|
this->lowpass[1].RefreshFilter(FilterType::LOWPASS, 0.f, 200.f, samplerate, 1.f, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Subwoofer::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->peak[index].ProcessSample(sample);
|
||||||
|
tmp = this->peakLow[index].ProcessSample(tmp);
|
||||||
|
tmp = this->lowpass[index].ProcessSample(tmp - sample);
|
||||||
|
samples[i] = (sample / 2.f) + (tmp * 0.6f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Subwoofer::SetBassGain(uint32_t samplerate, float gainDb) {
|
||||||
|
float gain = 20.f * log10f(gainDb);
|
||||||
|
float gainLower = 20.f * log10f(gainDb / 8.f);
|
||||||
|
|
||||||
|
this->peak[0].RefreshFilter(FilterType::PEAK, gain, 44.f, (float)samplerate, 0.75, true);
|
||||||
|
this->peak[1].RefreshFilter(FilterType::PEAK, gain, 44.f, (float)samplerate, 0.75, true);
|
||||||
|
this->peakLow[0].RefreshFilter(FilterType::PEAK, gainLower, 80.f, (float)samplerate, 0.2, true);
|
||||||
|
this->peakLow[1].RefreshFilter(FilterType::PEAK, gainLower, 80.f, (float)samplerate, 0.2, true);
|
||||||
|
this->lowpass[0].RefreshFilter(FilterType::LOWPASS, 0.f, 380.f, (float)samplerate, 0.6, false);
|
||||||
|
this->lowpass[1].RefreshFilter(FilterType::LOWPASS, 0.f, 380.f, (float)samplerate, 0.6, false);
|
||||||
|
}
|
24
src/utils/Subwoofer.h
Normal file
24
src/utils/Subwoofer.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
//
|
||||||
|
// Created by mart on 7/30/21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include "MultiBiquad.h"
|
||||||
|
|
||||||
|
class Subwoofer {
|
||||||
|
public:
|
||||||
|
Subwoofer();
|
||||||
|
|
||||||
|
void Process(float* samples, uint32_t size);
|
||||||
|
|
||||||
|
void SetBassGain(uint32_t samplerate, float gainDb);
|
||||||
|
|
||||||
|
MultiBiquad peak[2];
|
||||||
|
MultiBiquad peakLow[2];
|
||||||
|
MultiBiquad lowpass[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user