soxlib 0.0.2.1 → 0.0.3
raw patch · 3 files changed
+71/−14 lines, 3 filesdep +bytestringdep ~transformers
Dependencies added: bytestring
Dependency ranges changed: transformers
Files
- soxlib.cabal +4/−3
- src/Sound/SoxLib.hs +62/−11
- src/Sound/SoxLib/FFI.hsc +5/−0
soxlib.cabal view
@@ -1,5 +1,5 @@ Name: soxlib-Version: 0.0.2.1+Version: 0.0.3 License: BSD3 License-File: LICENSE Author: Henning Thielemann <haskell@henning-thielemann.de>@@ -22,7 +22,7 @@ src/Sound/SoxLib/Template.h Source-Repository this- Tag: 0.0.2.1+ Tag: 0.0.3 Type: darcs Location: http://hub.darcs.net/thielema/soxlib/ @@ -38,10 +38,11 @@ Build-Depends: sample-frame >=0.0.1 && <0.1, storablevector >=0.2.10 && <0.3,+ bytestring >=0.9 && <0.11, explicit-exception >=0.1.3 && < 0.2, -- that's the way to get compatibility between GHC 6.10 and 6.12 extensible-exceptions >=0.1.1 && <0.2,- transformers >=0.2 && <0.5,+ transformers >=0.2 && <0.6, containers >=0.1 && <0.6, utility-ht >=0.0.5 && <0.1, base >=4 && <5
src/Sound/SoxLib.hs view
@@ -2,6 +2,7 @@ with, formatWith, openRead, withRead, readStorableVector, readStorableVectorLazy, openWrite, withWrite, writeStorableVector, writeStorableVectorLazy,+ storableVectorLazyFromByteString, close, seek, FFI.Mode(..), FFI.ReadMode, FFI.WriteMode, ReaderInfo(..), defaultReaderInfo,@@ -61,7 +62,8 @@ import qualified Foreign.Marshal.Utils as U import qualified Foreign.C.String as CStr import Foreign.Storable (Storable, peek, )-import Foreign.Ptr (Ptr, nullFunPtr, nullPtr, )+import Foreign.ForeignPtr (ForeignPtr, FinalizerPtr, newForeignPtr, withForeignPtr, )+import Foreign.Ptr (Ptr, nullFunPtr, nullPtr, castPtr, ) import Control.Exception (bracket_, bracket, ) import System.IO.Error (mkIOError, doesNotExistErrorType, )@@ -69,18 +71,26 @@ import qualified Data.StorableVector.Base as SVB import qualified Data.StorableVector.Lazy as SVL import qualified Data.StorableVector as SV+import qualified Data.ByteString as B import qualified Control.Monad.Trans.Cont as MC import qualified Control.Monad.Trans.Class as MT import Control.Functor.HT (void, ) import Control.Monad (when, ) -import System.IO.Unsafe (unsafeInterleaveIO, )+import qualified Data.Traversable as Trav+import Data.Maybe.HT (toMaybe, ) +import System.IO.Unsafe (unsafePerformIO, unsafeInterleaveIO, )+ import Data.Int (Int32, ) -{-# DEPRECATED with "I found no documentation for it and thus think that it is deprecated. Use formatWith instead." #-}+{-+DEPRECATED with+ "I found no documentation for it and thus think that it is deprecated. Use formatWith instead."+-}+-- ToDo: on the other hand, example5.c uses it, but not formatInit with :: IO a -> IO a with = bracket_ FFI.init FFI.quit @@ -197,6 +207,9 @@ {- | Multi-channel data is interleaved. @size@ must be divisible by the number of channels.++Caution:+Writing large chunks (e.g. more than 8192 samples) may crash the FLAC backend. -} writeStorableVector :: FFI.FormatPtr FFI.WriteMode -> SV.Vector Int32 -> IO ()@@ -208,6 +221,19 @@ ioError $ userError $ FFI.soxErrStr f +readChunks ::+ IO (SV.Vector Int32) -> Int ->+ IO [SV.Vector Int32] ->+ IO [SV.Vector Int32]+readChunks readChunk size go = do+ chunk <- readChunk+ if SV.length chunk >= size+ then fmap (chunk:) go+ else return $+ if SV.length chunk == 0+ then []+ else [chunk]+ {- | Read complete file lazily into chunky storable vector. The chunkSize must be divisible by the number of channels.@@ -216,14 +242,8 @@ FFI.FormatPtr FFI.ReadMode -> SVL.ChunkSize -> IO (SVL.Vector Int32) readStorableVectorLazy fmt (SVL.ChunkSize size) = let go =- unsafeInterleaveIO $ do- chunk <- readStorableVector fmt size- if SV.length chunk >= size- then fmap (chunk:) go- else return $- if SV.length chunk == 0- then []- else [chunk]+ unsafeInterleaveIO $+ readChunks (readStorableVector fmt size) size go in fmap SVL.fromChunks go {- |@@ -241,3 +261,34 @@ when (res /= 0) $ do f <- peek fmt ioError $ userError $ FFI.soxErrStr f+++maybeNewForeignPtr :: FinalizerPtr a -> Ptr a -> IO (Maybe (ForeignPtr a))+maybeNewForeignPtr finalizer ptr =+ Trav.sequence $ toMaybe (ptr/=nullPtr) $ newForeignPtr finalizer ptr++{- |+It reads lazily to lazy storable vector.+That is, the whole 'ByteString' is kept as long as we process the lazy storable vector.+-}+-- ToDo: return (Either String) containing error message from Format.soxErrStr+storableVectorLazyFromByteString ::+ ReaderInfo -> B.ByteString -> SVL.ChunkSize -> Maybe (SVL.Vector Int32)+storableVectorLazyFromByteString info bytes (SVL.ChunkSize size) =+ unsafePerformIO $+ flip MC.runContT return $ do+ si <- withMaybe U.with $ readerSignalInfo info+ enc <- withMaybe U.with $ readerEncodingInfo info+ cft <- withMaybe CStr.withCString $+ fmap FFI.unFileType $ readerFileType info+ (src, len) <- MC.ContT $ B.useAsCStringLen bytes+ MT.lift $ do+ maybeFmt <-+ maybeNewForeignPtr FFI.closeFun+ =<< FFI.openMemRead (castPtr src) (fromIntegral len) si enc cft+ Trav.for maybeFmt $ \fmtForeign -> do+ let readChunk =+ withForeignPtr fmtForeign $ \fmt ->+ readStorableVector fmt size+ let go = unsafeInterleaveIO $ readChunks readChunk size go+ fmap SVL.fromChunks go
src/Sound/SoxLib/FFI.hsc view
@@ -375,3 +375,8 @@ foreign import ccall unsafe "sox.h sox_seek" seek :: FormatPtr mode -> C.CSize -> Whence -> IO C.CInt+++-- Is it safe on every platform to pretend that (IO CInt) is (IO ()) ?+foreign import ccall unsafe "sox.h &sox_close"+ closeFun :: FunPtr (FormatPtr mode -> IO ())