{-# 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 = forall a. (C a, C a) => a -> T a -> T a
Osci.freqModSine Double
0 (forall a. (a -> a) -> a -> [a]
iterate (forall a. C a => a -> a -> a
+Double
0.5forall a. C a => a -> a -> a
/Double
len) Double
0)

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


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

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

butterworthLowpassTest2 :: [Double]
butterworthLowpassTest2 :: [Double]
butterworthLowpassTest2 =
   let len :: Double
len = Double
1forall a. C a => a -> a -> a
*forall a. C a => a
sampleRate
   in  forall a. Int -> [a] -> [a]
take (forall a b. (C a, C b) => a -> b
round Double
len) (forall a v. (C a, C a v) => Int -> T a -> T a -> T v -> T v
Butter.lowpassPole Int
20 (forall a. a -> [a]
repeat Double
0.3) (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      = forall a. T a -> a
real T a
z
       im :: a
im      = forall a. T a -> a
imag T a
z
       phi :: a
phi     = forall a. C a => a
piforall a. C a => a -> a -> a
*a
freq
       sinphi :: a
sinphi  = forall a. C a => a -> a
sin a
phi
       cosphi :: a
cosphi  = forall a. C a => a -> a
cos a
phi
       cpims :: a
cpims   = a
cosphi forall a. C a => a -> a -> a
+ a
imforall a. C a => a -> a -> a
*a
sinphi
       cmims :: a
cmims   = a
cosphi forall a. C a => a -> a -> a
- a
imforall a. C a => a -> a -> a
*a
sinphi
       resin2 :: a
resin2  = (a
reforall a. C a => a -> a -> a
*a
sinphi)forall a. C a => a -> Integer -> a
^Integer
2
       denom :: a
denom   = - a
cmimsforall a. C a => a -> Integer -> a
^Integer
2 forall a. C a => a -> a -> a
- a
resin2
       c0 :: a
c0      = a
vol forall a. C a => a -> a -> a
* a
sinphiforall a. C a => a -> Integer -> a
^Integer
2 forall a. C a => a -> a -> a
/ a
denom
   in  forall a. a -> a -> a -> a -> a -> Parameter a
Filt2.Parameter
          a
c0 (a
2forall a. C a => a -> a -> a
*a
c0) a
c0
          (-a
2forall a. C a => a -> a -> a
*(a
cpimsforall a. C a => a -> a -> a
*a
cmims forall a. C a => a -> a -> a
- a
resin2)forall a. C a => a -> a -> a
/a
denom) ((a
cpimsforall a. C a => a -> Integer -> a
^Integer
2 forall a. C a => a -> a -> a
+ a
resin2)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      = forall a. T a -> a
real T a
z
       im :: a
im      = forall a. T a -> a
imag T a
z
       phi :: a
phi     = forall a. C a => a
piforall a. C a => a -> a -> a
*a
freq
       sinphi :: a
sinphi  = forall a. C a => a -> a
sin a
phi
       cosphi :: a
cosphi  = forall a. C a => a -> a
cos a
phi
       spimc :: a
spimc   = a
sinphi forall a. C a => a -> a -> a
+ a
imforall a. C a => a -> a -> a
*a
cosphi
       smimc :: a
smimc   = a
sinphi forall a. C a => a -> a -> a
- a
imforall a. C a => a -> a -> a
*a
cosphi
       recos2 :: a
recos2  = (a
reforall a. C a => a -> a -> a
*a
cosphi)forall a. C a => a -> Integer -> a
^Integer
2
       denom :: a
denom   = a
smimcforall a. C a => a -> Integer -> a
^Integer
2 forall a. C a => a -> a -> a
+ a
recos2
       c0 :: a
c0      = (a
sinphiforall a. C a => a -> Integer -> a
^Integer
2 forall a. C a => a -> a -> a
+ a
a0forall a. C a => a -> Integer -> a
^Integer
2forall a. C a => a -> a -> a
*a
cosphiforall a. C a => a -> Integer -> a
^Integer
2) forall a. C a => a -> a -> a
/ a
denom
       c1 :: a
c1      = (a
sinphiforall a. C a => a -> Integer -> a
^Integer
2 forall a. C a => a -> a -> a
- a
a0forall a. C a => a -> Integer -> a
^Integer
2forall a. C a => a -> a -> a
*a
cosphiforall a. C a => a -> Integer -> a
^Integer
2) forall a. C a => a -> a -> a
/ a
denom
   in  forall a. a -> a -> a -> a -> a -> Parameter a
Filt2.Parameter
          a
c0 (a
2forall a. C a => a -> a -> a
*a
c1) a
c0
          (-a
2forall a. C a => a -> a -> a
*(a
spimcforall a. C a => a -> a -> a
*a
smimc forall a. C a => a -> a -> a
- a
recos2)forall a. C a => a -> a -> a
/a
denom) (-(a
spimcforall a. C a => a -> Integer -> a
^Integer
2 forall a. C a => a -> a -> a
+ a
recos2)forall a. C a => a -> a -> a
/a
denom)

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

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

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

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

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



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

universalTest :: [Uni.Result Double]
universalTest :: [Result Double]
universalTest =
   let len :: Double
len = Double
1forall a. C a => a -> a -> a
*forall a. C a => a
sampleRate
   in  forall a. Int -> [a] -> [a]
take (forall a b. (C a, C b) => a -> b
round Double
len) forall a b. (a -> b) -> a -> b
$
       forall a v. (C a, C a v) => T (Parameter a) -> T v -> T (Result v)
Uni.run
          (forall a. a -> [a]
repeat (forall a. C a => Pole a -> Parameter a
Uni.parameter (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
1forall a. C a => a -> a -> a
*forall a. C a => a
sampleRate
   in  forall a. Int -> [a] -> [a]
take (forall a b. (C a, C b) => a -> b
round Double
len) forall a b. (a -> b) -> a -> b
$
       forall a v. (C a, C a v) => T (Parameter a) -> T v -> T (Result v)
C1.run
          (forall a. a -> [a]
repeat (forall a. C a => a -> Pole a -> Parameter a
C1.parameterFromPeakWidth Double
0.025 (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 =
   forall a b. C a => T a b -> a -> T a -> T b
Osci.freqMod forall a. C a => T a (T a)
Wave.helix Double
0 (forall a. (a -> a) -> a -> [a]
iterate (forall a. C a => a -> a -> a
+Double
0.5forall a. C a => a -> a -> a
/Double
len) Double
0)

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