-- | A small utility module that sends an audio stream via /stdout/ to a @sox@ -- system command that plays the audio. module Data.MediaBus.Conduit.Audio.Raw.DebugSink ( debugAudioPlaybackSink ) where import Control.Lens import Control.Monad.IO.Class import qualified Data.ByteString as B import Data.Conduit import Data.Default import Data.MediaBus.Media.Media import Data.MediaBus.Media.Audio import Data.MediaBus.Media.Audio.Raw import Data.MediaBus.Media.Buffer import Data.MediaBus.Media.Channels import Data.MediaBus.Media.Stream import Data.MediaBus.Conduit.Stream import Data.MediaBus.Basics.Ticks import Data.Proxy import Data.Streaming.Process (Inherited(..), streamingProcess, waitForStreamingProcess) import System.IO (Handle, hClose) import System.Process (shell) import Text.Printf -- | A 'Sink' that launches a shell command that starts @sox@ such that it reads -- raw audio data from @STDIN@ and plays it via the systems sound card. debugAudioPlaybackSink :: forall m i s t p c r ch pcm. ( Default i , MonadIO m , KnownRate r , KnownChannelLayout ch , IsPcmValue (Pcm ch pcm) , HasMediaL' c (Audio r ch (Raw pcm)) , HasMediaBuffer' (Audio r ch (Raw pcm)) ) => Sink (Stream i s t p c) m () debugAudioPlaybackSink = toFramesC .| do let cp = shell (printf "play -r %d -b 16 -c1 -e signed-integer -t raw -" (rateVal (Proxy :: Proxy r))) (!(sinH :: Handle), Inherited, Inherited, cph) <- streamingProcess cp awaitForever (mapMOf_ (framePayload . media' . mediaBuffer') (pcmToByteString sinH)) liftIO (hClose sinH) _ <- waitForStreamingProcess cph return () where pcmToByteString !h !d = liftIO (B.hPut h (mediaBufferToByteString d))