module DSP.Window
(window, rectangular, bartlett, hanning, hamming, blackman,
kaiser, gen_hamming, parzen) where
import DSP.Basic ((^!))
import Data.Array
window :: Array Int Double
-> Array Int Double
-> Array Int Double
window w x = listArray (0,m) [ w!i * x!i | i <- [0..m] ]
where m = snd $ bounds w
rectangular :: Int
-> Array Int Double
rectangular m = listArray (0,m) $ repeat 1
bartlett :: Int
-> Array Int Double
bartlett = makeArray bartlett'
bartlett' :: Double -> Double -> Double
bartlett' m n =
if n <= m / 2
then 2 * n / m
else 2 - 2 * n / m
hanning :: Int
-> Array Int Double
hanning = makeArray hanning'
hanning' :: Double -> Double -> Double
hanning' m n = 0.5 - 0.5 * cos(2 * pi * n / m)
hamming :: Int
-> Array Int Double
hamming = makeArray hamming'
hamming' :: Double -> Double -> Double
hamming' m n = 0.54 - 0.46 * cos(2 * pi * n / m)
blackman :: Int
-> Array Int Double
blackman = makeArray blackman'
blackman' :: Double -> Double -> Double
blackman' m n =
0.42 - 0.5 * cos(2 * pi * n / m) +
0.08 * cos (4 * pi * n / m)
gen_hamming :: Double
-> Int
-> Array Int Double
gen_hamming = makeArray . gen_hamming'
gen_hamming' :: Double -> Double -> Double -> Double
gen_hamming' a m n = a - (1 - a) * cos(2 * pi * n / m)
kaiser :: Double
-> Int
-> Array Int Double
kaiser = makeArray . kaiser'
kaiser' :: Double -> Double -> Double -> Double
kaiser' b m n =
let a = m / 2
in i0 (b * sqrt (1 -((n-a)/a)^!2)) / i0 b
i0 :: Double -> Double
i0 x = i0' x 2 1
i0' :: Double -> Double -> Double -> Double
i0' x d ds | ds < 1.0e-30 = 1
| otherwise = ds * x^!2 / d^!2 + (i0' x (d+2) (ds * x^!2 / d^!2))
parzen :: Int
-> Array Int Double
parzen = makeArray parzen'
parzen' :: Double -> Double -> Double
parzen' m n =
if n <= m / 2
then 2 * (1-n/m) ^! 3 - (1-2*n/m) ^! 3
else 2 * (1-n/m) ^! 3
makeArray :: (Double -> Double -> Double) -> Int -> Array Int Double
makeArray win m =
let md = fromIntegral m
in listArray (0,m) $ map (win md . fromIntegral) [(0::Int) ..]