func NewLowPassBiQuadFilter(sampleRate, cutoffFreq, q float64) *BiQuadFilter {
	w0 := 2 * math.Pi * cutoffFreq / sampleRate
	sinW0 := math.Sin(w0)
	cosW0 := math.Cos(w0)
	alpha := sinW0 / (2 * q)
	return &BiQuadFilter{
		B0: (1 - cosW0) / 2,
		B1: 1 - cosW0,
		B2: (1 - cosW0) / 2,
		A0: 1 + alpha,
		A1: -2 * cosW0,
		A2: 1 - alpha,
	}
}
H(s) = 1 / (s^2 + s/Q + 1)
package dsp
import "math"
type BiQuadFilter struct {
	B0, B1, B2      float64
	A0, A1, A2      float64
	prevIn, prevOut [2]float64
}
func (f *BiQuadFilter) Filter(input, output []float64) {
	b0a0 := f.B0 / f.A0
	b1a0 := f.B1 / f.A0
	b2a0 := f.B2 / f.A0
	a1a0 := f.A1 / f.A0
	a2a0 := f.A2 / f.A0
	for i, s := range input {
		newSample := b0a0*s + b1a0*f.prevIn[0] + b2a0*f.prevIn[1] - a1a0*f.prevOut[0] - a2a0*f.prevOut[1]
		f.prevOut[1] = f.prevOut[0]
		f.prevOut[0] = newSample
		f.prevIn[1] = f.prevIn[0]
		f.prevIn[0] = s
		output[i] = newSample
	}
}
func (f *BiQuadFilter) FilterF32(input, output []float32) {
	b0a0 := f.B0 / f.A0
	b1a0 := f.B1 / f.A0
	b2a0 := f.B2 / f.A0
	a1a0 := f.A1 / f.A0
	a2a0 := f.A2 / f.A0
	for i, s := range input {
		newSample := b0a0*float64(s) + b1a0*f.prevIn[0] + b2a0*f.prevIn[1] - a1a0*f.prevOut[0] - a2a0*f.prevOut[1]
		f.prevOut[1] = f.prevOut[0]
		f.prevOut[0] = newSample
		f.prevIn[1] = f.prevIn[0]
		f.prevIn[0] = float64(s)
		output[i] = float32(newSample)
	}
}