{-# LANGUAGE NoImplicitPrelude #-}
module Synthesizer.Plain.Filter.Recursive.Test where

import qualified Synthesizer.Plain.Oscillator as Osci
import qualified Synthesizer.Plain.Filter.Recursive.SecondOrder as Filt2
import qualified Synthesizer.Plain.Filter.Recursive.Butterworth as Butter
import qualified Synthesizer.Plain.Filter.Recursive.Chebyshev   as Cheby
import qualified Synthesizer.Plain.Filter.Recursive.Moog        as Moog
import qualified Synthesizer.Plain.Filter.Recursive.Universal   as Uni
import qualified Synthesizer.Plain.Filter.Recursive.FirstOrderComplex as C1
import qualified Synthesizer.Basic.Wave as Wave

import Synthesizer.Plain.Filter.Recursive (Pole(..))

import Number.Complex ((+:), real, imag, )
import qualified Number.Complex as Complex

import qualified Algebra.Transcendental      as Trans
import qualified Algebra.Ring                as Ring

import NumericPrelude.Numeric
import NumericPrelude.Base


sampleRate :: Ring.C a => a
--sampleRate = 44100
sampleRate :: forall a. C a => a
sampleRate = a
22050
--sampleRate = 11025


chirp :: Double -> [Double]
chirp :: Double -> [Double]
chirp Double
len = Double -> [Double] -> [Double]
forall a. (C a, C a) => a -> T a -> T a
Osci.freqModSine Double
0 ((Double -> Double) -> Double -> [Double]
forall a. (a -> a) -> a -> [a]
iterate (Double -> Double -> Double
forall a. C a => a -> a -> a
+Double
0.5Double -> Double -> Double
forall a. C a => a -> a -> a
/Double
len) Double
0)

filter2ndOrderTest :: [Double]
filter2ndOrderTest :: [Double]
filter2ndOrderTest =
   Int -> [Double] -> [Double]
forall a. Int -> [a] -> [a]
take Int
10
      (T (Parameter Double) -> [Double] -> [Double]
forall a v. (C a, C a v) => T (Parameter a) -> T v -> T v
Filt2.run
          (Parameter Double -> T (Parameter Double)
forall a. a -> [a]
repeat (Double -> Double -> Double -> Double -> Double -> Parameter Double
forall a. a -> a -> a -> a -> a -> Parameter a
Filt2.Parameter Double
1 Double
0 Double
0 Double
0 (Double
1::Double)))
          (Double
1 Double -> [Double] -> [Double]
forall a. a -> [a] -> [a]
: Double -> [Double]
forall a. a -> [a]
repeat Double
0))


butterworthLowpassTest0 :: [Double]
butterworthLowpassTest0 :: [Double]
butterworthLowpassTest0 =
   Int -> [Double] -> [Double]
forall a. Int -> [a] -> [a]
take Int
30 (Int -> [Double] -> [Double] -> [Double] -> [Double]
forall a v. (C a, C a v) => Int -> T a -> T a -> T v -> T v
Butter.lowpassPole Int
2 (Double -> [Double]
forall a. a -> [a]
repeat Double
0.2) (Double -> [Double]
forall a. a -> [a]
repeat (Double
0.1::Double)) (Double -> [Double]
forall a. a -> [a]
repeat Double
1))

butterworthLowpassTest1 :: Double
butterworthLowpassTest1 :: Double
butterworthLowpassTest1 =
   [Double] -> Double
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum (Int -> [Double] -> [Double]
forall a. Int -> [a] -> [a]
take Int
300 (Int -> [Double] -> [Double]
forall a. Int -> [a] -> [a]
drop Int
500
         (Int -> [Double] -> [Double] -> [Double] -> [Double]
forall a v. (C a, C a v) => Int -> T a -> T a -> T v -> T v
Butter.lowpassPole Int
6 (Double -> [Double]
forall a. a -> [a]
repeat Double
0.1) (Double -> [Double]
forall a. a -> [a]
repeat (Double
0.05::Double))
               ((Double -> Double) -> [Double] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map Double -> Double
forall a. C a => a -> a
sin ((Double -> Double) -> Double -> [Double]
forall a. (a -> a) -> a -> [a]
iterate (Double -> Double -> Double
forall a. C a => a -> a -> a
+Double
2Double -> Double -> Double
forall a. C a => a -> a -> a
*Double
forall a. C a => a
piDouble -> Double -> Double
forall a. C a => a -> a -> a
*Double
0.05) Double
0)))))

butterworthLowpassTest2 :: [Double]
butterworthLowpassTest2 :: [Double]
butterworthLowpassTest2 =
   let len :: Double
len = Double
1Double -> Double -> Double
forall a. C a => a -> a -> a
*Double
forall a. C a => a
sampleRate
   in  Int -> [Double] -> [Double]
forall a. Int -> [a] -> [a]
take (Double -> Int
forall b. C b => Double -> b
forall a b. (C a, C b) => a -> b
round Double
len) (Int -> [Double] -> [Double] -> [Double] -> [Double]
forall a v. (C a, C a v) => Int -> T a -> T a -> T v -> T v
Butter.lowpassPole Int
20 (Double -> [Double]
forall a. a -> [a]
repeat Double
0.3) (Double -> [Double]
forall a. a -> [a]
repeat (Double
0.2::Double)) (Double -> [Double]
chirp Double
len))

chebyParameterA, chebyParameterB :: (Trans.C a) =>
   a -> Complex.T a -> a -> Filt2.Parameter a
chebyParameterA :: forall a. C a => a -> T a -> a -> Parameter a
chebyParameterA a
vol T a
z a
freq =
   let re :: a
re      = T a -> a
forall a. T a -> a
real T a
z
       im :: a
im      = T a -> a
forall a. T a -> a
imag T a
z
       phi :: a
phi     = a
forall a. C a => a
pia -> a -> a
forall a. C a => a -> a -> a
*a
freq
       sinphi :: a
sinphi  = a -> a
forall a. C a => a -> a
sin a
phi
       cosphi :: a
cosphi  = a -> a
forall a. C a => a -> a
cos a
phi
       cpims :: a
cpims   = a
cosphi a -> a -> a
forall a. C a => a -> a -> a
+ a
ima -> a -> a
forall a. C a => a -> a -> a
*a
sinphi
       cmims :: a
cmims   = a
cosphi a -> a -> a
forall a. C a => a -> a -> a
- a
ima -> a -> a
forall a. C a => a -> a -> a
*a
sinphi
       resin2 :: a
resin2  = (a
rea -> a -> a
forall a. C a => a -> a -> a
*a
sinphi)a -> Integer -> a
forall a. C a => a -> Integer -> a
^Integer
2
       denom :: a
denom   = - a
cmimsa -> Integer -> a
forall a. C a => a -> Integer -> a
^Integer
2 a -> a -> a
forall a. C a => a -> a -> a
- a
resin2
       c0 :: a
c0      = a
vol a -> a -> a
forall a. C a => a -> a -> a
* a
sinphia -> Integer -> a
forall a. C a => a -> Integer -> a
^Integer
2 a -> a -> a
forall a. C a => a -> a -> a
/ a
denom
   in  a -> a -> a -> a -> a -> Parameter a
forall a. a -> a -> a -> a -> a -> Parameter a
Filt2.Parameter
          a
c0 (a
2a -> a -> a
forall a. C a => a -> a -> a
*a
c0) a
c0
          (-a
2a -> a -> a
forall a. C a => a -> a -> a
*(a
cpimsa -> a -> a
forall a. C a => a -> a -> a
*a
cmims a -> a -> a
forall a. C a => a -> a -> a
- a
resin2)a -> a -> a
forall a. C a => a -> a -> a
/a
denom) ((a
cpimsa -> Integer -> a
forall a. C a => a -> Integer -> a
^Integer
2 a -> a -> a
forall a. C a => a -> a -> a
+ a
resin2)a -> a -> a
forall a. C a => a -> a -> a
/a
denom)

chebyParameterB :: forall a. C a => a -> T a -> a -> Parameter a
chebyParameterB a
a0 T a
z a
freq =
   let re :: a
re      = T a -> a
forall a. T a -> a
real T a
z
       im :: a
im      = T a -> a
forall a. T a -> a
imag T a
z
       phi :: a
phi     = a
forall a. C a => a
pia -> a -> a
forall a. C a => a -> a -> a
*a
freq
       sinphi :: a
sinphi  = a -> a
forall a. C a => a -> a
sin a
phi
       cosphi :: a
cosphi  = a -> a
forall a. C a => a -> a
cos a
phi
       spimc :: a
spimc   = a
sinphi a -> a -> a
forall a. C a => a -> a -> a
+ a
ima -> a -> a
forall a. C a => a -> a -> a
*a
cosphi
       smimc :: a
smimc   = a
sinphi a -> a -> a
forall a. C a => a -> a -> a
- a
ima -> a -> a
forall a. C a => a -> a -> a
*a
cosphi
       recos2 :: a
recos2  = (a
rea -> a -> a
forall a. C a => a -> a -> a
*a
cosphi)a -> Integer -> a
forall a. C a => a -> Integer -> a
^Integer
2
       denom :: a
denom   = a
smimca -> Integer -> a
forall a. C a => a -> Integer -> a
^Integer
2 a -> a -> a
forall a. C a => a -> a -> a
+ a
recos2
       c0 :: a
c0      = (a
sinphia -> Integer -> a
forall a. C a => a -> Integer -> a
^Integer
2 a -> a -> a
forall a. C a => a -> a -> a
+ a
a0a -> Integer -> a
forall a. C a => a -> Integer -> a
^Integer
2a -> a -> a
forall a. C a => a -> a -> a
*a
cosphia -> Integer -> a
forall a. C a => a -> Integer -> a
^Integer
2) a -> a -> a
forall a. C a => a -> a -> a
/ a
denom
       c1 :: a
c1      = (a
sinphia -> Integer -> a
forall a. C a => a -> Integer -> a
^Integer
2 a -> a -> a
forall a. C a => a -> a -> a
- a
a0a -> Integer -> a
forall a. C a => a -> Integer -> a
^Integer
2a -> a -> a
forall a. C a => a -> a -> a
*a
cosphia -> Integer -> a
forall a. C a => a -> Integer -> a
^Integer
2) a -> a -> a
forall a. C a => a -> a -> a
/ a
denom
   in  a -> a -> a -> a -> a -> Parameter a
forall a. a -> a -> a -> a -> a -> Parameter a
Filt2.Parameter
          a
c0 (a
2a -> a -> a
forall a. C a => a -> a -> a
*a
c1) a
c0
          (-a
2a -> a -> a
forall a. C a => a -> a -> a
*(a
spimca -> a -> a
forall a. C a => a -> a -> a
*a
smimc a -> a -> a
forall a. C a => a -> a -> a
- a
recos2)a -> a -> a
forall a. C a => a -> a -> a
/a
denom) (-(a
spimca -> Integer -> a
forall a. C a => a -> Integer -> a
^Integer
2 a -> a -> a
forall a. C a => a -> a -> a
+ a
recos2)a -> a -> a
forall a. C a => a -> a -> a
/a
denom)

-- cf. makeZero
chebyshevALowpassTest0 :: Filt2.Parameter Double
chebyshevALowpassTest0 :: Parameter Double
chebyshevALowpassTest0 =
   let beta :: Double
beta = Double -> Double
forall a. C a => a -> a
asinh Double
1 Double -> Double -> Double
forall a. C a => a -> a -> a
/ Double
4
   in  Double -> T Double -> Double -> Parameter Double
forall a. C a => a -> T a -> a -> Parameter a
chebyParameterA Double
1 (Double
12Double -> Double -> Double
forall a. C a => a -> a -> a
/Double
13 Double -> Double -> Double
forall a. C a => a -> a -> a
* Double -> Double
forall a. C a => a -> a
cosh Double
beta Double -> Double -> T Double
forall a. a -> a -> T a
+: (-Double
5Double -> Double -> Double
forall a. C a => a -> a -> a
/Double
13 Double -> Double -> Double
forall a. C a => a -> a -> a
* Double -> Double
forall a. C a => a -> a
sinh Double
beta)) Double
0.1

chebyshevBLowpassTest0 :: Filt2.Parameter Double
chebyshevBLowpassTest0 :: Parameter Double
chebyshevBLowpassTest0 =
   let beta :: Double
beta = Double -> Double
forall a. C a => a -> a
asinh Double
1 Double -> Double -> Double
forall a. C a => a -> a -> a
/ Double
4
   in  Double -> T Double -> Double -> Parameter Double
forall a. C a => a -> T a -> a -> Parameter a
chebyParameterB (Double
12Double -> Double -> Double
forall a. C a => a -> a -> a
/Double
13) (Double
12Double -> Double -> Double
forall a. C a => a -> a -> a
/Double
13 Double -> Double -> Double
forall a. C a => a -> a -> a
* Double -> Double
forall a. C a => a -> a
cosh Double
beta Double -> Double -> T Double
forall a. a -> a -> T a
+: (-Double
5Double -> Double -> Double
forall a. C a => a -> a -> a
/Double
13 Double -> Double -> Double
forall a. C a => a -> a -> a
* Double -> Double
forall a. C a => a -> a
sinh Double
beta)) Double
0.1

chebyshevLowpassTest1 :: [Double]
chebyshevLowpassTest1 :: [Double]
chebyshevLowpassTest1 =
   let len :: Double
len = Double
1Double -> Double -> Double
forall a. C a => a -> a -> a
*Double
forall a. C a => a
sampleRate
   in  Int -> [Double] -> [Double]
forall a. Int -> [a] -> [a]
take (Double -> Int
forall b. C b => Double -> b
forall a b. (C a, C b) => a -> b
round Double
len) (T (Parameter Double) -> [Double] -> [Double]
forall a v. (C a, C a v) => T (Parameter a) -> T v -> T v
Filt2.run (Parameter Double -> T (Parameter Double)
forall a. a -> [a]
repeat Parameter Double
chebyshevALowpassTest0) (Double -> [Double]
chirp Double
len))

chebyshevALowpassTest2 :: [Double]
chebyshevALowpassTest2 :: [Double]
chebyshevALowpassTest2 =
   let len :: Double
len = Double
1Double -> Double -> Double
forall a. C a => a -> a -> a
*Double
forall a. C a => a
sampleRate
   in  Int -> [Double] -> [Double]
forall a. Int -> [a] -> [a]
take (Double -> Int
forall b. C b => Double -> b
forall a b. (C a, C b) => a -> b
round Double
len) ([Double] -> [Double]) -> [Double] -> [Double]
forall a b. (a -> b) -> a -> b
$
       Int -> [Double] -> [Double] -> [Double] -> [Double]
forall a v. (C a, C a v) => Int -> T a -> T a -> T v -> T v
Cheby.lowpassAPole Int
10 (Double -> [Double]
forall a. a -> [a]
repeat Double
0.25) (Double -> [Double]
forall a. a -> [a]
repeat (Double
0.3::Double)) (Double -> [Double]
chirp Double
len)

chebyshevBLowpassTest2 :: [Double]
chebyshevBLowpassTest2 :: [Double]
chebyshevBLowpassTest2 =
   let len :: Double
len = Double
1Double -> Double -> Double
forall a. C a => a -> a -> a
*Double
forall a. C a => a
sampleRate
   in  Int -> [Double] -> [Double]
forall a. Int -> [a] -> [a]
take (Double -> Int
forall b. C b => Double -> b
forall a b. (C a, C b) => a -> b
round Double
len) ([Double] -> [Double]) -> [Double] -> [Double]
forall a b. (a -> b) -> a -> b
$
       Int -> [Double] -> [Double] -> [Double] -> [Double]
forall a v. (C a, C a v) => Int -> T a -> T a -> T v -> T v
Cheby.lowpassBPole Int
10 (Double -> [Double]
forall a. a -> [a]
repeat Double
0.25) (Double -> [Double]
forall a. a -> [a]
repeat (Double
0.1::Double)) (Double -> [Double]
chirp Double
len)



moogLowpassTest :: [Double]
moogLowpassTest :: [Double]
moogLowpassTest =
   Int -> T (Parameter Double) -> [Double] -> [Double]
forall a v. (C a, C a v) => Int -> T (Parameter a) -> T v -> T v
Moog.lowpass Int
10
      (Parameter Double -> T (Parameter Double)
forall a. a -> [a]
repeat (Int -> Pole Double -> Parameter Double
forall a. C a => Int -> Pole a -> Parameter a
Moog.parameter Int
10 (Double -> Double -> Pole Double
forall a. a -> a -> Pole a
Pole Double
10 (Double
0.05::Double))))
      (Double
1Double -> [Double] -> [Double]
forall a. a -> [a] -> [a]
:Double -> [Double]
forall a. a -> [a]
repeat Double
0)

universalTest :: [Uni.Result Double]
universalTest :: [Result Double]
universalTest =
   let len :: Double
len = Double
1Double -> Double -> Double
forall a. C a => a -> a -> a
*Double
forall a. C a => a
sampleRate
   in  Int -> [Result Double] -> [Result Double]
forall a. Int -> [a] -> [a]
take (Double -> Int
forall b. C b => Double -> b
forall a b. (C a, C b) => a -> b
round Double
len) ([Result Double] -> [Result Double])
-> [Result Double] -> [Result Double]
forall a b. (a -> b) -> a -> b
$
       T (Parameter Double) -> [Double] -> [Result Double]
forall a v. (C a, C a v) => T (Parameter a) -> T v -> T (Result v)
Uni.run
          (Parameter Double -> T (Parameter Double)
forall a. a -> [a]
repeat (Pole Double -> Parameter Double
forall a. C a => Pole a -> Parameter a
Uni.parameter (Double -> Double -> Pole Double
forall a. a -> a -> Pole a
Pole Double
5 (Double
0.1::Double))))
          (Double -> [Double]
chirp Double
len)


complexRealTest :: [Complex.T Double]
complexRealTest :: [T Double]
complexRealTest =
   let len :: Double
len = Double
1Double -> Double -> Double
forall a. C a => a -> a -> a
*Double
forall a. C a => a
sampleRate
   in  Int -> [T Double] -> [T Double]
forall a. Int -> [a] -> [a]
take (Double -> Int
forall b. C b => Double -> b
forall a b. (C a, C b) => a -> b
round Double
len) ([T Double] -> [T Double]) -> [T Double] -> [T Double]
forall a b. (a -> b) -> a -> b
$
       T (Parameter Double) -> [Double] -> [T Double]
forall a v. (C a, C a v) => T (Parameter a) -> T v -> T (Result v)
C1.run
          (Parameter Double -> T (Parameter Double)
forall a. a -> [a]
repeat (Double -> Pole Double -> Parameter Double
forall a. C a => a -> Pole a -> Parameter a
C1.parameterFromPeakWidth Double
0.025 (Double -> Double -> Pole Double
forall a. a -> a -> Pole a
Pole Double
5 (Double
0.1::Double))))
          (Double -> [Double]
chirp Double
len)

chirpComplex :: Double -> [Complex.T Double]
chirpComplex :: Double -> [T Double]
chirpComplex Double
len =
   T Double (T Double) -> Double -> [Double] -> [T Double]
forall a b. C a => T a b -> a -> T a -> T b
Osci.freqMod T Double (T Double)
forall a. C a => T a (T a)
Wave.helix Double
0 ((Double -> Double) -> Double -> [Double]
forall a. (a -> a) -> a -> [a]
iterate (Double -> Double -> Double
forall a. C a => a -> a -> a
+Double
0.5Double -> Double -> Double
forall a. C a => a -> a -> a
/Double
len) Double
0)

complexTest :: [Complex.T Double]
complexTest :: [T Double]
complexTest =
   let len :: Double
len = Double
1Double -> Double -> Double
forall a. C a => a -> a -> a
*Double
forall a. C a => a
sampleRate
   in  Int -> [T Double] -> [T Double]
forall a. Int -> [a] -> [a]
take (Double -> Int
forall b. C b => Double -> b
forall a b. (C a, C b) => a -> b
round Double
len) ([T Double] -> [T Double]) -> [T Double] -> [T Double]
forall a b. (a -> b) -> a -> b
$
       (T (T Double) -> T Double) -> [T (T Double)] -> [T Double]
forall a b. (a -> b) -> [a] -> [b]
map
          (\T (T Double)
x -> T (T Double) -> T Double
forall a. T a -> a
Complex.real T (T Double)
x T Double -> T Double -> T Double
forall a. C a => a -> a -> a
+ T Double -> T Double
forall a. C a => T a -> T a
Complex.quarterLeft (T (T Double) -> T Double
forall a. T a -> a
Complex.imag T (T Double)
x)) ([T (T Double)] -> [T Double]) -> [T (T Double)] -> [T Double]
forall a b. (a -> b) -> a -> b
$
       T (Parameter Double) -> [T Double] -> [T (T Double)]
forall a v. (C a, C a v) => T (Parameter a) -> T v -> T (Result v)
C1.run
          (Parameter Double -> T (Parameter Double)
forall a. a -> [a]
repeat (Double -> Pole Double -> Parameter Double
forall a. C a => a -> Pole a -> Parameter a
C1.parameterFromPeakWidth Double
0.025 (Double -> Double -> Pole Double
forall a. a -> a -> Pole a
Pole Double
5 (Double
0.1::Double))))
          (Double -> [T Double]
chirpComplex Double
len)