diff --git a/src/audio.c b/src/audio.c index 33f3a99..f600b11 100644 --- a/src/audio.c +++ b/src/audio.c @@ -136,14 +136,23 @@ static void ApplyBandpassFilterFFT(float* samples, int numSamples, int sampleRat FFT(fftInput, fftOutput, fftSize, false); float freqPerBin = (float)sampleRate / fftSize; + + // Transition (skirt) width in Hz: ~20% of the passband, capped at 100 Hz, + // with a floor of 3 FFT bins so it stays smooth at coarse resolution. + // Previously the skirt was tied to bin width alone (freqPerBin * 10), so the + // FFT size — and thus the filter's sharpness — changed with the selection + // length: the same band sounded different depending on how much you boxed. + float bandwidthHz = freqHigh - freqLow; + float transitionHz = fmaxf(fminf(bandwidthHz * 0.2f, 100.0f), freqPerBin * 3.0f); + for (int bin = 0; bin < fftSize / 2 + 1; bin++) { float frequency = bin * freqPerBin; float attenuation = 1.0f; if (frequency < freqLow) { - float dist = (freqLow - frequency) / (freqPerBin * 10.0f); + float dist = (freqLow - frequency) / transitionHz; attenuation = 1.0f / (1.0f + dist * dist * dist); } else if (frequency > freqHigh) { - float dist = (frequency - freqHigh) / (freqPerBin * 10.0f); + float dist = (frequency - freqHigh) / transitionHz; attenuation = 1.0f / (1.0f + dist * dist * dist); } fftOutput[bin] *= attenuation;