content: {-| Pulse Audio Pipes sink -}
  module SDR.Pulse (
      pulseAudioSink,
      doPulse
      ) where
  
  import Foreign.ForeignPtr
  import Foreign.C.Types
  import Control.Concurrent
  import Data.ByteString.Internal
  import Data.Vector.Storable     as VS
  
  import Sound.Pulse.Simple
  import Pipes
  import Pipes.Concurrent
  
  -- | Returns a consumer that sends all incoming data to pulseaudio. Runs Pulse Audio output writing in a different thread. This is probably what you want as it does not block the entire pipline while the data is being played.
  pulseAudioSink :: IO (Consumer (VS.Vector Float) IO ())
  pulseAudioSink = do
      (output, input) <- spawn $ bounded 1
      doIt <- doPulse 
      forkOS $ runEffect $ fromInput input >-> doIt
      return $ toOutput output
  
  -- | Returns a consumer that sends all incoming data to pulseaudio.
  doPulse :: IO (Consumer (VS.Vector Float) IO ())
  doPulse = do
      s <- simpleNew Nothing "Haskell SDR" Play Nothing "Software Defined Radio library" (SampleSpec (F32 LittleEndian) 48000 1) Nothing Nothing
      return $ for cat $ \buf -> 
          lift $ do
              let (fp, offset, length) = VS.unsafeToForeignPtr buf
              simpleWriteRaw s (PS (castForeignPtr fp) (offset * 4) (length * 4))
  
  