sox 0.2.2.1 → 0.2.2.2
raw patch · 2 files changed
+101/−5 lines, 2 filesdep ~unix
Dependency ranges changed: unix
Files
- sox.cabal +6/−5
- src/Sound/Sox/Private/Information.hs +95/−0
sox.cabal view
@@ -1,5 +1,5 @@ Name: sox-Version: 0.2.2.1+Version: 0.2.2.2 License: GPL License-File: LICENSE Author: Henning Thielemann <haskell@henning-thielemann.de>@@ -22,7 +22,8 @@ There is some ancient code, which allows interactive playback using the shell-pipe package on GHC-6.2, where no runInteractiveProcess was available.-Tested-With: GHC==6.8.2, GHC==6.10.4, GHC==6.12.1, GHC==7.0.4, GHC==7.2.1+Tested-With: GHC==6.8.2, GHC==6.10.4, GHC==6.12.1+Tested-With: GHC==7.0.4, GHC==7.2.1, GHC==7.4.2, GHC==7.6.1 Cabal-Version: >=1.6 Build-Type: Simple Extra-Source-Files:@@ -40,7 +41,7 @@ default: False Source-Repository this- Tag: 0.2.2+ Tag: 0.2.2.2 Type: darcs Location: http://code.haskell.org/~thielema/sox/ @@ -71,7 +72,7 @@ Hs-Source-Dirs: windows/src Else Hs-Source-Dirs: unix/src- Build-Depends: unix >=2.3 && <2.6+ Build-Depends: unix >=2.3 && <2.7 GHC-Options: -Wall @@ -90,5 +91,5 @@ Sound.Sox.Private.Option Sound.Sox.Private.Arguments Sound.Sox.Private.Format--- Sound.Sox.Private.Information+ Sound.Sox.Private.Information Sound.Sox.System
+ src/Sound/Sox/Private/Information.hs view
@@ -0,0 +1,95 @@+{- |+This module calls the 'soxi' command+which is available since 'sox' version 14.++This module is very clever as it calls 'soxi' once+with one option per requested piece of information+and parses the results in a correctly typed tuple.+Unfortunately, 'soxi' does not work this way.+It accepts only one option per call.+-}+module Sound.Sox.Private.Information where++import Control.Monad.Trans.Writer (Writer, writer, runWriter, )+import Control.Monad.Trans.State (StateT(StateT), runStateT, )+import Control.Monad.Trans.Class (lift, )+import Control.Applicative (Applicative, pure, liftA3, (<*>), )+import Data.Functor.Compose (Compose(Compose), )+import Data.List.HT (viewL, )+import Text.Read.HT (maybeRead, )++import qualified System.Process as Proc+import qualified System.IO as IO+import Control.Exception (bracket, )+-- import System.IO.Error (ioError, userError, )+-- import System.Exit (ExitCode, )++import Prelude hiding (length, )+++{-+Cf. Synthesizer.Basic.Interpolation.PrefixReader.+-}+newtype T a =+ Cons (Compose (Writer [String]) (StateT [String] Maybe) a)++instance Functor T where+ {-# INLINE fmap #-}+ fmap f (Cons m) = Cons (fmap f m)++instance Applicative T where+ {-# INLINE pure #-}+ {-# INLINE (<*>) #-}+ pure = Cons . pure+ (Cons f) <*> (Cons x) = Cons (f <*> x)+++simple :: Read a => (String -> Maybe a) -> String -> T a+simple rd option =+ Cons $ Compose $ writer+ (lift . rd =<< StateT viewL, [option])++format :: T String+format = simple Just "-t"++sampleRate :: T Int+sampleRate = simple maybeRead "-r"++numberOfChannels :: T Int+numberOfChannels = simple maybeRead "-c"++length :: T Int+length = simple maybeRead "-s"++bitsPerSample :: T Int+bitsPerSample = simple maybeRead "-b"++++get :: T a -> FilePath -> IO a+get (Cons (Compose w)) fileName =+ let (parser, opts) = runWriter w+ in bracket+ (Proc.runInteractiveProcess "soxi"+ (opts ++ fileName : [])+ Nothing Nothing)+ (\(input,output,err,proc) ->+ mapM_ IO.hClose [input, output, err] >>+ Proc.terminateProcess proc)+ (\(_,output,_,_) ->+ maybe+ (ioError (userError "soxi returned rubbish"))+ (\(x,str) ->+ if null str+ then return x+ else ioError (userError "soxi returned more lines than expected")) .+ runStateT parser . lines =<<+ IO.hGetContents output)++exampleMulti :: IO (String, Int, Int)+exampleMulti =+ get (liftA3 (,,) format sampleRate bitsPerSample) "test.aiff"++exampleSingle :: IO Int+exampleSingle =+ get sampleRate "test.aiff"