-----------------------------------------------------------------------------
-- |
-- Module      :  DSP.Multirate.Halfband
-- Copyright   :  (c) Matthew Donadio 2003
-- License     :  GPL
--
-- Maintainer  :  m.p.donadio@ieee.org
-- Stability   :  experimental
-- Portability :  portable
--
-- Halfband interpolators and decimators
--
-- Reference: C&R
--
-----------------------------------------------------------------------------

module DSP.Multirate.Halfband (hb_interp, hb_decim) where

import Data.Array

import DSP.Basic (delay, uninterleave, interleave)
import DSP.Filter.FIR.FIR

mkhalfband :: Num a => Array Int a -> Array Int a
mkhalfband :: forall a. Num a => Array Int a -> Array Int a
mkhalfband Array Int a
h = forall i e. Ix i => (i, i) -> [e] -> Array i e
listArray (Int
0,Int
m forall a. Integral a => a -> a -> a
`div` Int
2) [ Array Int a
hforall i e. Ix i => Array i e -> i -> e
!Int
n | Int
n <- [Int
0,Int
2..Int
m] ]
    where m :: Int
m = forall a b. (a, b) -> b
snd forall a b. (a -> b) -> a -> b
$ forall i e. Array i e -> (i, i)
bounds Array Int a
h

-- | Halfband interpolator

hb_interp :: (Num a, Eq a) => Array Int a -- ^ h[n]
	  -> [a] -- ^ x[n]
	  -> [a] -- ^ y[n]

hb_interp :: forall a. (Num a, Eq a) => Array Int a -> [a] -> [a]
hb_interp Array Int a
h [a]
x = forall a. [a] -> [a] -> [a]
interleave [a]
y1 [a]
y2
    where ([a]
x1,[a]
x2) = forall a. [a] -> ([a], [a])
uninterleave [a]
x
	  y1 :: [a]
y1 = forall a. (Num a, Eq a) => Array Int a -> [a] -> [a]
fir (forall a. Num a => Array Int a -> Array Int a
mkhalfband Array Int a
h) [a]
x1
	  y2 :: [a]
y2 = forall a b. (a -> b) -> [a] -> [b]
map (Array Int a
hforall i e. Ix i => Array i e -> i -> e
!Int
m2 forall a. Num a => a -> a -> a
*) forall a b. (a -> b) -> a -> b
$ forall a. Num a => Int -> [a] -> [a]
delay Int
m2 forall a b. (a -> b) -> a -> b
$ [a]
x2
	  m2 :: Int
m2 = (forall a b. (a, b) -> b
snd forall a b. (a -> b) -> a -> b
$ forall i e. Array i e -> (i, i)
bounds Array Int a
h) forall a. Integral a => a -> a -> a
`div` Int
2

-- | Halfband decimator

hb_decim :: (Num a, Eq a) => Array Int a -- ^ h[n]
	 -> [a] -- ^ x[n]
	 -> [a] -- ^ y[n]

hb_decim :: forall a. (Num a, Eq a) => Array Int a -> [a] -> [a]
hb_decim Array Int a
h [a]
x = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall a. Num a => a -> a -> a
(+) [a]
y1 [a]
y2
    where ([a]
x1,[a]
x2) = forall a. [a] -> ([a], [a])
uninterleave [a]
x
	  y1 :: [a]
y1 = forall a. (Num a, Eq a) => Array Int a -> [a] -> [a]
fir (forall a. Num a => Array Int a -> Array Int a
mkhalfband Array Int a
h) [a]
x1
	  y2 :: [a]
y2 = forall a b. (a -> b) -> [a] -> [b]
map (Array Int a
hforall i e. Ix i => Array i e -> i -> e
!Int
m2 forall a. Num a => a -> a -> a
*) forall a b. (a -> b) -> a -> b
$ forall a. Num a => Int -> [a] -> [a]
delay Int
m2 forall a b. (a -> b) -> a -> b
$ [a]
x2
	  m2 :: Int
m2 = (forall a b. (a, b) -> b
snd forall a b. (a -> b) -> a -> b
$ forall i e. Array i e -> (i, i)
bounds Array Int a
h) forall a. Integral a => a -> a -> a
`div` Int
2