module Sound.Sox.Information (
T(Cons),
simple,
format,
sampleRate,
numberOfChannels,
length,
bitsPerSample,
get,
exampleMulti,
exampleSingle,
) where
import qualified Control.Monad.Trans.Reader as MR
import Control.Applicative (Applicative, pure, liftA3, (<*>), )
import Data.String.HT (trim, )
import Text.Read.HT (maybeRead, )
import qualified System.Process as Proc
import qualified System.IO as IO
import Control.Exception (bracket, )
import Prelude hiding (length, )
newtype T a =
Cons (MR.ReaderT FilePath IO a)
instance Functor T where
{-# INLINE fmap #-}
fmap :: forall a b. (a -> b) -> T a -> T b
fmap a -> b
f (Cons ReaderT String IO a
m) = forall a. ReaderT String IO a -> T a
Cons (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f ReaderT String IO a
m)
instance Applicative T where
{-# INLINE pure #-}
{-# INLINE (<*>) #-}
pure :: forall a. a -> T a
pure = forall a. ReaderT String IO a -> T a
Cons forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a. Applicative f => a -> f a
pure
(Cons ReaderT String IO (a -> b)
f) <*> :: forall a b. T (a -> b) -> T a -> T b
<*> (Cons ReaderT String IO a
x) = forall a. ReaderT String IO a -> T a
Cons (ReaderT String IO (a -> b)
f forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ReaderT String IO a
x)
simple :: Read a => (String -> Maybe a) -> String -> T a
simple :: forall a. Read a => (String -> Maybe a) -> String -> T a
simple String -> Maybe a
rd String
option =
forall a. ReaderT String IO a -> T a
Cons forall a b. (a -> b) -> a -> b
$ forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
MR.ReaderT forall a b. (a -> b) -> a -> b
$ \String
fileName ->
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket
(String
-> [String]
-> Maybe String
-> Maybe [(String, String)]
-> IO (Handle, Handle, Handle, ProcessHandle)
Proc.runInteractiveProcess String
"soxi"
(String
option forall a. a -> [a] -> [a]
: String
fileName forall a. a -> [a] -> [a]
: [])
forall a. Maybe a
Nothing forall a. Maybe a
Nothing)
(\(Handle
input,Handle
output,Handle
err,ProcessHandle
proc) ->
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Handle -> IO ()
IO.hClose [Handle
input, Handle
output, Handle
err] forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
ProcessHandle -> IO ()
Proc.terminateProcess ProcessHandle
proc)
(\(Handle
_,Handle
output,Handle
_,ProcessHandle
_) ->
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(forall a. IOError -> IO a
ioError (String -> IOError
userError String
"soxi returned rubbish"))
forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
.
String -> Maybe a
rd forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
Handle -> IO String
IO.hGetContents Handle
output)
format :: T String
format :: T String
format = forall a. Read a => (String -> Maybe a) -> String -> T a
simple forall a. a -> Maybe a
Just String
"-t"
simpleRead :: String -> T Int
simpleRead :: String -> T Int
simpleRead = forall a. Read a => (String -> Maybe a) -> String -> T a
simple (forall a. Read a => String -> Maybe a
maybeRead forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
trim)
sampleRate :: T Int
sampleRate :: T Int
sampleRate = String -> T Int
simpleRead String
"-r"
numberOfChannels :: T Int
numberOfChannels :: T Int
numberOfChannels = String -> T Int
simpleRead String
"-c"
length :: T Int
length :: T Int
length = String -> T Int
simpleRead String
"-s"
bitsPerSample :: T Int
bitsPerSample :: T Int
bitsPerSample = String -> T Int
simpleRead String
"-b"
get :: T a -> FilePath -> IO a
get :: forall a. T a -> String -> IO a
get (Cons ReaderT String IO a
act) = forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
MR.runReaderT ReaderT String IO a
act
exampleMulti :: IO (String, Int, Int)
exampleMulti :: IO (String, Int, Int)
exampleMulti =
forall a. T a -> String -> IO a
get (forall (f :: * -> *) a b c d.
Applicative f =>
(a -> b -> c -> d) -> f a -> f b -> f c -> f d
liftA3 (,,) T String
format T Int
sampleRate T Int
bitsPerSample) String
"test.aiff"
exampleSingle :: IO Int
exampleSingle :: IO Int
exampleSingle =
forall a. T a -> String -> IO a
get T Int
sampleRate String
"test.aiff"