module Sound.Sox.Read ( Handle, open, close, -- withFile, withHandle1, withHandle2, ) where import qualified Sound.Sox.Frame as Frame -- import Sound.Sox.System (catchCtrlC, ) import qualified Sound.Sox.Option.Format as Option import qualified Sound.Sox.Private.Option as OptPriv import qualified Sound.Sox.Private.Arguments as Args import Data.Monoid (mconcat, ) import qualified System.Process as Proc import qualified System.IO as IO -- import Control.Exception (bracket, ) import System.Exit (ExitCode, ) data Handle signal = Handle { pipeInput, pipeOutput, pipeError :: IO.Handle, processId :: Proc.ProcessHandle } {- withFile :: (Frame.C y) => (IO.Handle -> IO (sig y)) {- ^ Reader routine - e.g. 'Sound.Sox.Signal.List.put' or 'Data.StorableVector.hPut' -} -> Option.T -> FilePath -> IO ExitCode withFile = undefined -} {- | Unfortunately we cannot retrieve the sample rate using @sox@. However there is @soxi@ for this purpose, which we may support in future. > :load Sound.Sox.Read Sound.Sox.Signal.List > :module + Control.Exception > bracket (open Option.none "test.aiff") close $ \h -> withHandle2 Sound.Sox.Signal.List.getContents h >>= \x -> print (Control.Monad.Exception.Asynchronous.result x :: [Data.Int.Int16]) -} open :: (Frame.C y) => Option.T -> FilePath -> IO (Handle (sig y)) open opts = openAux undefined opts Option.none openAux :: (Frame.C y) => y -> Option.T -> Option.T -> FilePath -> IO (Handle (sig y)) openAux frame srcOpts dstOpts fileName = fmap (\(input,output,err,proc) -> Handle input output err proc) (Proc.runInteractiveProcess "sox" (Args.decons $ mconcat $ OptPriv.toArguments srcOpts : Args.fileName fileName : OptPriv.toArguments (mconcat $ dstOpts : Option.numberOfChannels (Frame.numberOfChannels frame) : Option.format (Frame.format frame) : []) : Args.pipe : []) Nothing Nothing) close :: Handle signal -> IO ExitCode close h = mapM_ IO.hClose [pipeInput h, pipeOutput h, pipeError h] >> Proc.waitForProcess (processId h) withHandle1 :: (IO.Handle -> m signal) -> (Handle signal -> m signal) withHandle1 act h = act (pipeOutput h) withHandle2 :: (IO.Handle -> m (f signal)) -> (Handle signal -> m (f signal)) withHandle2 act h = act (pipeOutput h)