sdr-0.1.0.2: hs_sources/SDR/Demod.hs
{-# LANGUAGE FlexibleContexts #-}
{-| FM demodulation pipes -}
module SDR.Demod (
fmDemodStr,
fmDemodVec,
fmDemod
) where
import Data.Complex
import Data.Vector.Generic as VG
import Data.Vector.Fusion.Stream
import SDR.VectorUtils
import Pipes
-- | FM demodulate a stream of complex samples
{-# INLINE fmDemodStr #-}
fmDemodStr :: (RealFloat a)
=> Complex a -- ^ The starting sample - i.e. the last sample in the last buffer
-> Stream (Complex a) -- ^ The input stream
-> Stream a -- ^ The output stream
fmDemodStr = mapAccumMV func
where
{-# INLINE func #-}
func last sample = return (sample, phase (sample * conjugate last))
-- | FM demodulate a vector of complex samples
{-# INLINE fmDemodVec #-}
fmDemodVec :: (RealFloat a, Vector v (Complex a), Vector v a)
=> Complex a -- ^ The starting sample - i.e. the last sample in the last buffer
-> v (Complex a) -- ^ The input Vector
-> v a -- ^ The output Vector
fmDemodVec init = unstream . fmDemodStr init . stream
-- | Pipe that performs FM demodulation
{-# INLINE fmDemod #-}
fmDemod :: (RealFloat a, Vector v (Complex a), Vector v a) => Pipe (v (Complex a)) (v a) IO ()
fmDemod = func 0
where
func lastSample = do
dat <- await
yield $ fmDemodVec lastSample dat
func $ VG.unsafeIndex dat (VG.length dat - 1)