Rename filter flags: --highpass to --lowcut, --lowpass to --highcut; clarify docs and usage

This commit is contained in:
Bastian Bührig
2025-07-11 10:21:49 +02:00
parent a113550aee
commit 0cb60d884c
5 changed files with 124 additions and 1 deletions

View File

@@ -341,3 +341,87 @@ func FadeOutLinear(data []float64, fadeSamples int) []float64 {
}
return out
}
// ApplyLowpassButterworth applies a 2nd-order Butterworth low-pass filter to the data.
// cutoffHz: cutoff frequency in Hz, sampleRate: sample rate in Hz.
func ApplyLowpassButterworth(data []float64, sampleRate int, cutoffHz float64) []float64 {
if cutoffHz <= 0 || cutoffHz >= float64(sampleRate)/2 {
return data
}
// Biquad coefficients
w0 := 2 * math.Pi * cutoffHz / float64(sampleRate)
cosw0 := math.Cos(w0)
sinw0 := math.Sin(w0)
Q := 1.0 / math.Sqrt(2) // Butterworth Q
alpha := sinw0 / (2 * Q)
b0 := (1 - cosw0) / 2
b1 := 1 - cosw0
b2 := (1 - cosw0) / 2
a0 := 1 + alpha
a1 := -2 * cosw0
a2 := 1 - alpha
// Normalize
b0 /= a0
b1 /= a0
b2 /= a0
a1 /= a0
a2 /= a0
// Apply filter (Direct Form I)
out := make([]float64, len(data))
var x1, x2, y1, y2 float64
for i := 0; i < len(data); i++ {
x0 := data[i]
y0 := b0*x0 + b1*x1 + b2*x2 - a1*y1 - a2*y2
out[i] = y0
x2 = x1
x1 = x0
y2 = y1
y1 = y0
}
return out
}
// ApplyHighpassButterworth applies a 2nd-order Butterworth high-pass filter to the data.
// cutoffHz: cutoff frequency in Hz, sampleRate: sample rate in Hz.
func ApplyHighpassButterworth(data []float64, sampleRate int, cutoffHz float64) []float64 {
if cutoffHz <= 0 || cutoffHz >= float64(sampleRate)/2 {
return data
}
// Biquad coefficients
w0 := 2 * math.Pi * cutoffHz / float64(sampleRate)
cosw0 := math.Cos(w0)
sinw0 := math.Sin(w0)
Q := 1.0 / math.Sqrt(2) // Butterworth Q
alpha := sinw0 / (2 * Q)
b0 := (1 + cosw0) / 2
b1 := -(1 + cosw0)
b2 := (1 + cosw0) / 2
a0 := 1 + alpha
a1 := -2 * cosw0
a2 := 1 - alpha
// Normalize
b0 /= a0
b1 /= a0
b2 /= a0
a1 /= a0
a2 /= a0
// Apply filter (Direct Form I)
out := make([]float64, len(data))
var x1, x2, y1, y2 float64
for i := 0; i < len(data); i++ {
x0 := data[i]
y0 := b0*x0 + b1*x1 + b2*x2 - a1*y1 - a2*y2
out[i] = y0
x2 = x1
x1 = x0
y2 = y1
y1 = y0
}
return out
}