-- | Filter coefficient calculations.
module Sound.SC3.Common.Math.Filter where

-- | Butterworth low pass or high pass SOS filter coefficients, (a0,a1,a2,b0,b1).
bw_lpf_or_hpf_coef :: Floating n => Bool -> n -> n -> (n,n,n,n,n)
bw_lpf_or_hpf_coef :: Bool -> n -> n -> (n, n, n, n, n)
bw_lpf_or_hpf_coef Bool
is_hpf n
sample_rate n
f =
    let f' :: n
f' = n
f n -> n -> n
forall a. Num a => a -> a -> a
* n
forall a. Floating a => a
pi n -> n -> n
forall a. Fractional a => a -> a -> a
/ n
sample_rate
        c :: n
c = if Bool
is_hpf then n -> n
forall a. Floating a => a -> a
tan n
f' else n
1.0 n -> n -> n
forall a. Fractional a => a -> a -> a
/ n -> n
forall a. Floating a => a -> a
tan n
f'
        c2 :: n
c2 = n
c n -> n -> n
forall a. Num a => a -> a -> a
* n
c
        s2c :: n
s2c = n -> n
forall a. Floating a => a -> a
sqrt n
2.0 n -> n -> n
forall a. Num a => a -> a -> a
* n
c
        a0 :: n
a0 = n
1.0 n -> n -> n
forall a. Fractional a => a -> a -> a
/ (n
1.0 n -> n -> n
forall a. Num a => a -> a -> a
+ n
s2c n -> n -> n
forall a. Num a => a -> a -> a
+ n
c2)
        a1 :: n
a1 = if Bool
is_hpf then -n
2.0 n -> n -> n
forall a. Num a => a -> a -> a
* n
a0 else n
2.0 n -> n -> n
forall a. Num a => a -> a -> a
* n
a0
        a2 :: n
a2 = n
a0
        b1 :: n
b1 = if Bool
is_hpf then n
2.0 n -> n -> n
forall a. Num a => a -> a -> a
* (n
c2 n -> n -> n
forall a. Num a => a -> a -> a
- n
1.0) n -> n -> n
forall a. Num a => a -> a -> a
* n
a0 else n
2.0 n -> n -> n
forall a. Num a => a -> a -> a
* (n
1.0 n -> n -> n
forall a. Num a => a -> a -> a
- n
c2) n -> n -> n
forall a. Num a => a -> a -> a
* n
a0
        b2 :: n
b2 = (n
1.0 n -> n -> n
forall a. Num a => a -> a -> a
- n
s2c n -> n -> n
forall a. Num a => a -> a -> a
+ n
c2) n -> n -> n
forall a. Num a => a -> a -> a
* n
a0
    in (n
a0,n
a1,n
a2,n
b1,n
b2)

-- | rlpf coefficients, (a0,b1,b2).
rlpf_coef :: Floating n => (n -> n -> n) -> (n,n,n) -> (n,n,n)
rlpf_coef :: (n -> n -> n) -> (n, n, n) -> (n, n, n)
rlpf_coef n -> n -> n
max_f (n
radians_per_sample,n
f,n
rq) =
    let qr :: n
qr = n -> n -> n
max_f n
0.001 n
rq
        pf :: n
pf = n
f n -> n -> n
forall a. Num a => a -> a -> a
* n
radians_per_sample
        d :: n
d = n -> n
forall a. Floating a => a -> a
tan (n
pf n -> n -> n
forall a. Num a => a -> a -> a
* n
qr n -> n -> n
forall a. Num a => a -> a -> a
* n
0.5)
        c :: n
c = (n
1.0 n -> n -> n
forall a. Num a => a -> a -> a
- n
d) n -> n -> n
forall a. Fractional a => a -> a -> a
/ (n
1.0 n -> n -> n
forall a. Num a => a -> a -> a
+ n
d)
        b1 :: n
b1 = (n
1.0 n -> n -> n
forall a. Num a => a -> a -> a
+ n
c) n -> n -> n
forall a. Num a => a -> a -> a
* n -> n
forall a. Floating a => a -> a
cos n
pf
        b2 :: n
b2 = n -> n
forall a. Num a => a -> a
negate n
c
        a0 :: n
a0 = (n
1.0 n -> n -> n
forall a. Num a => a -> a -> a
+ n
c n -> n -> n
forall a. Num a => a -> a -> a
- n
b1) n -> n -> n
forall a. Num a => a -> a -> a
* n
0.25
    in (n
a0,n
b1,n
b2)

-- | resonz coefficients, (a0,b1,b2).
resonz_coef :: Floating n => (n,n,n) -> (n,n,n)
resonz_coef :: (n, n, n) -> (n, n, n)
resonz_coef (n
radians_per_sample,n
f,n
rq) =
    let ff :: n
ff = n
f n -> n -> n
forall a. Num a => a -> a -> a
* n
radians_per_sample
        b :: n
b = n
ff n -> n -> n
forall a. Num a => a -> a -> a
* n
rq
        r :: n
r = n
1.0 n -> n -> n
forall a. Num a => a -> a -> a
- n
b n -> n -> n
forall a. Num a => a -> a -> a
* n
0.5
        two_r :: n
two_r = n
2.0 n -> n -> n
forall a. Num a => a -> a -> a
* n
r
        r2 :: n
r2 = n
r n -> n -> n
forall a. Num a => a -> a -> a
* n
r
        ct :: n
ct = (n
two_r n -> n -> n
forall a. Num a => a -> a -> a
* n -> n
forall a. Floating a => a -> a
cos n
ff) n -> n -> n
forall a. Fractional a => a -> a -> a
/ (n
1.0 n -> n -> n
forall a. Num a => a -> a -> a
+ n
r2)
        b1 :: n
b1 = n
two_r n -> n -> n
forall a. Num a => a -> a -> a
* n
ct
        b2 :: n
b2 = n -> n
forall a. Num a => a -> a
negate n
r2
        a0 :: n
a0 = (n
1.0 n -> n -> n
forall a. Num a => a -> a -> a
- n
r2) n -> n -> n
forall a. Num a => a -> a -> a
* n
0.5
    in (n
a0,n
b1,n
b2)