54 for (size i = 0; i <
mConfig.numBands; ++i) {
58 FL_WARN(
"SpectralEqualizer: custom gains size mismatch (" <<
mConfig.customGains.size() <<
" != " <<
mConfig.numBands <<
"), using flat gains");
71 for (size i = 0; i <
mConfig.numBands; ++i) {
78 const float* curve =
nullptr;
84 }
else if (
mConfig.numBands == 32) {
89 FL_WARN(
"SpectralEqualizer: A-weighting not defined for " <<
mConfig.numBands <<
" bands, using flat gains");
95 for (size i = 0; i <
mConfig.numBands && i < curveSize; ++i) {
101 if (gains.size() !=
mConfig.numBands) {
102 FL_WARN(
"SpectralEqualizer: custom gains size mismatch (" << gains.size() <<
" != " <<
mConfig.numBands <<
")");
108 mConfig.customGains.reserve(gains.size());
109 for (size i = 0; i < gains.size(); ++i) {
110 mConfig.customGains.push_back(gains[i]);
119 if (inputBins.size() !=
mConfig.numBands) {
120 FL_WARN(
"SpectralEqualizer: input size mismatch (" << inputBins.size() <<
" != " <<
mConfig.numBands <<
")");
124 if (outputBins.size() <
mConfig.numBands) {
125 FL_WARN(
"SpectralEqualizer: output buffer too small (" << outputBins.size() <<
" < " <<
mConfig.numBands <<
")");
130 float inputPeak = 0.0f;
131 float outputPeak = 0.0f;
132 float inputSum = 0.0f;
133 float outputSum = 0.0f;
136 for (size i = 0; i <
mConfig.numBands; ++i) {
137 float inputValue = inputBins[i];
139 float outputValue = inputValue * gain;
142 if (
mConfig.enableCompression) {
146 outputBins[i] = outputValue;
149 if (inputValue > inputPeak) {
150 inputPeak = inputValue;
152 if (outputValue > outputPeak) {
153 outputPeak = outputValue;
155 inputSum += inputValue;
156 outputSum += outputValue;
160 float makeupGain = 1.0f;
165 for (size i = 0; i <
mConfig.numBands; ++i) {
166 outputBins[i] *= makeupGain;
170 outputPeak *= makeupGain;
171 outputSum *= makeupGain;
175 mStats.applicationsCount++;
176 mStats.lastInputPeak = inputPeak;
177 mStats.lastOutputPeak = outputPeak;
178 mStats.lastMakeupGain = makeupGain;
179 mStats.avgInputLevel = inputSum /
static_cast<float>(
mConfig.numBands);
180 mStats.avgOutputLevel = outputSum /
static_cast<float>(
mConfig.numBands);
185 float inputAvg = 0.0f;
186 float outputAvg = 0.0f;
188 for (size i = 0; i <
mConfig.numBands; ++i) {
189 inputAvg += inputBins[i];
190 outputAvg += outputBins[i];
193 inputAvg /=
static_cast<float>(
mConfig.numBands);
194 outputAvg /=
static_cast<float>(
mConfig.numBands);
197 if (outputAvg < 0.001f) {
203 float targetLevel = inputAvg *
mConfig.makeupGainTarget;
204 float makeupGain = targetLevel / outputAvg;
207 if (makeupGain < 0.1f) {
210 if (makeupGain > 10.0f) {
226 float compressed = excess /
mConfig.compressionRatio;
227 return mConfig.compressionThreshold + compressed;
static constexpr float A_WEIGHTING_16BAND[16]
A-weighting coefficients for 16-band frequency analysis These approximate the A-weighting curve acros...
float applyCompression(float value) const FL_NO_EXCEPT
Apply dynamic range compression per band.
void configure(const SpectralEqualizerConfig &config) FL_NO_EXCEPT
Configure the spectral equalizer This calculates per-band gain multipliers based on the selected curv...
~SpectralEqualizer() FL_NO_EXCEPT
void calculateFlatGains() FL_NO_EXCEPT
Calculate flat gains (all 1.0)
void calculateAWeightingGains() FL_NO_EXCEPT
Calculate A-weighting gains.
void resetStats() FL_NO_EXCEPT
Reset statistics.
void apply(span< const float > inputBins, span< float > outputBins) const FL_NO_EXCEPT
Apply equalization to frequency bins.
SpectralEqualizer() FL_NO_EXCEPT
float calculateMakeupGain(span< const float > inputBins, span< const float > outputBins) const FL_NO_EXCEPT
Calculate makeup gain to maintain target level.
void calculateGains() FL_NO_EXCEPT
Calculate gains based on current curve.
static constexpr float A_WEIGHTING_32BAND[32]
A-weighting coefficients for 32-band frequency analysis.
void setCustomGains(span< const float > gains) FL_NO_EXCEPT
Set custom per-band gains (switches to Custom curve)
SpectralEqualizerConfig mConfig
vector< float > mGains
Per-band gain multipliers.
Get statistics (for debugging/monitoring)
Configuration for spectral equalizer.
u8 u8 fract8 blur_amount FL_NO_EXCEPT
constexpr int type_rank< T >::value
Base definition for an LED controller.