packages feed

hsndfile 0.1.1 → 0.2.0

raw patch · 7 files changed

+137/−78 lines, 7 filesdep ~carrayPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: carray

API changes (from Hackage documentation)

+ Sound.File.Sndfile: Exception :: String -> Exception
+ Sound.File.Sndfile: MalformedFile :: String -> Exception
+ Sound.File.Sndfile: SystemError :: String -> Exception
+ Sound.File.Sndfile: UnrecognisedFormat :: String -> Exception
+ Sound.File.Sndfile: UnsupportedEncoding :: String -> Exception
+ Sound.File.Sndfile: hReadFrames :: (MBuffer a e m, Num e) => Handle -> Count -> m (Maybe (a Index e))
+ Sound.File.Sndfile: hReadSamples :: (MBuffer a e m, Num e) => Handle -> Count -> m (Maybe (a Index e))

Files

Sound/File/Sndfile.hs view
@@ -19,10 +19,12 @@     IOMode(..), openFile, getFileInfo, hFlush, hClose,     SeekMode(..), hSeek, hSeekRead, hSeekWrite,     -- *I\/O functions-    MBuffer(..), interact,+    MBuffer(..),+    hReadSamples, hReadFrames,+    interact,     --IBuffer(..),     -- *Exception handling-    Exception, errorString, catch,+    Exception(..), catch,     -- *Header string field access     StringType(..), getString, setString ) where@@ -31,6 +33,7 @@ import Sound.File.Sndfile.Buffer import Sound.File.Sndfile.Buffer.Storable () import Sound.File.Sndfile.Buffer.IOCArray ()+import Sound.File.Sndfile.Exception import Sound.File.Sndfile.Interface  -- EOF
Sound/File/Sndfile/Buffer.hs view
@@ -1,33 +1,53 @@+{-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE MultiParamTypeClasses #-}  module Sound.File.Sndfile.Buffer (     MBuffer(..),     checkSampleBounds, checkFrameBounds,-    interact+    hReadSamples, hReadFrames,+    interact,+    IOFunc,+    sf_read_double, sf_readf_double,+    sf_write_double, sf_writef_double,+    sf_read_float, sf_readf_float,+    sf_write_float, sf_writef_float ) where -import C2HS import Control.Monad (liftM, when) import Data.Array.Base (unsafeRead, unsafeWrite)-import Data.Array.MArray (Ix, MArray, getBounds)---import Data.Array.IArray (IArray)+import Data.Array.MArray (Ix, MArray, getBounds, newArray_) import Data.Ix (rangeSize)+import Foreign.Ptr (Ptr)+import Foreign.C.Types (CLLong) import Prelude hiding (interact)+import Sound.File.Sndfile.Exception (throw) import Sound.File.Sndfile.Interface  checkSampleBounds :: (Monad m) => Count -> Int -> Count -> m () checkSampleBounds size channels count-    | (count `mod` channels) /= 0 = throw (Exception ("invalid channel/count combination " ++ (show count)))-    | (count < 0) || (count > size) = throw (Exception "index out of bounds")+    | (count `mod` channels) /= 0   = throw 0 ("invalid channel/count combination " ++ (show count))+    | (count < 0) || (count > size) = throw 0 ("index out of bounds")     | otherwise = return ()  checkFrameBounds :: (Monad m) => Count -> Int -> Count -> m () checkFrameBounds size channels count-    | (size `mod` channels) /= 0 = throw (Exception "invalid buffer size")-    | (count < 0) || (count > (size `quot` channels)) = throw (Exception "index out of bounds")+    | (size `mod` channels) /= 0                      = throw 0 ("invalid buffer size")+    | (count < 0) || (count > (size `quot` channels)) = throw 0 ("index out of bounds")     | otherwise = return () +type IOFunc a = HandlePtr -> Ptr a -> CLLong -> IO CLLong++foreign import ccall unsafe "sf_read_double"   sf_read_double   :: IOFunc Double+foreign import ccall unsafe "sf_readf_double"  sf_readf_double  :: IOFunc Double+foreign import ccall unsafe "sf_write_double"  sf_write_double  :: IOFunc Double+foreign import ccall unsafe "sf_writef_double" sf_writef_double :: IOFunc Double++foreign import ccall unsafe "sf_read_float"   sf_read_float   :: IOFunc Float+foreign import ccall unsafe "sf_readf_float"  sf_readf_float  :: IOFunc Float+foreign import ccall unsafe "sf_write_float"  sf_write_float  :: IOFunc Float+foreign import ccall unsafe "sf_writef_float" sf_writef_float :: IOFunc Float+ -- |The class MBuffer is used for polymorphic I\/O on a 'Handle', and is -- parameterized on the mutable array type, the element type and the monad -- results are returned in.@@ -78,6 +98,40 @@     -- 'hPutFrames' returns the number of frames written (which should be the same     -- as the 'count' parameter).     hPutFrames  :: Handle -> a Index e -> Count -> m Count++-- TODO: Optimize unsafeWriteRange+unsafeWriteRange :: (MArray a e m) => a Int e -> (Int, Int) -> e -> m ()+unsafeWriteRange _ (i0, i) _ | i0 > i = return ()+unsafeWriteRange a (i0, i) e          = unsafeWrite a i0 e >> unsafeWriteRange a (i0+1,i) e++-- |Return an array with the requested number of items. The 'count' parameter+-- must be an integer product of the number of channels or an error will+-- occur.+hReadSamples :: (MBuffer a e m, Num e) => Handle -> Count -> m (Maybe (a Index e))+hReadSamples h n = do+    b  <- newArray_ (0, n-1)+    n' <- hGetSamples h b n+    if n' == 0+        then return Nothing+        else do+            when (n' < n) (unsafeWriteRange b (n',n-1) 0)+            return (Just b)++-- |Return an array with the requested number of frames of data.+-- The resulting array size is equal to the product of the number of frames+-- `n' and the number of channels in the soundfile.+hReadFrames :: (MBuffer a e m, Num e) => Handle -> Count -> m (Maybe (a Index e))+hReadFrames h n = do+    b  <- newArray_ (0, si)+    n' <- hGetFrames h b n+    if n' == 0+        then return Nothing+        else do+            when (n' < n) (unsafeWriteRange b (f2s n', si) 0)+            return (Just b)+    where+        f2s = (* channels (hInfo h))+        si  = (f2s n) - 1  modifyArray :: (MArray a e m, Ix i) => (e -> e) -> a i e -> Int -> Int -> m () modifyArray f a i n
Sound/File/Sndfile/Buffer/IOCArray.hs view
@@ -1,16 +1,12 @@-{-# LANGUAGE ForeignFunctionInterface #-} {-# OPTIONS_GHC -fglasgow-exts #-}  module Sound.File.Sndfile.Buffer.IOCArray where  import C2HS-import Control.Monad (liftM) import Data.Array.IOCArray import Sound.File.Sndfile.Buffer import Sound.File.Sndfile.Interface -type IOFunc a = HandlePtr -> Ptr a -> CLLong -> IO CLLong- {-# INLINE hIO #-} hIO :: (Storable a) =>            (Count -> Int -> Count -> IO ())@@ -18,30 +14,25 @@         -> Handle -> (IOCArray Index a) -> Count         -> IO Count hIO checkBounds ioFunc (Handle info handle) buffer count = do-    size <- liftM rangeSize $ getBounds buffer+    size <- rangeSize `fmap` getBounds buffer     checkBounds size (channels info) count     result <- withIOCArray buffer $-                \ptr -> liftM fromIntegral $ ioFunc handle ptr (cIntConv count)+                \ptr -> fromIntegral `fmap` ioFunc handle ptr (fromIntegral count)+                        :: IO Count     checkHandle handle     touchIOCArray buffer-    return $ cIntConv result--foreign import ccall unsafe "sf_read_double"  sf_read_double  :: IOFunc Double-foreign import ccall unsafe "sf_write_double" sf_write_double :: IOFunc Double+    return $ fromIntegral result  instance MBuffer IOCArray Double IO where     hGetSamples = hIO checkSampleBounds sf_read_double-    hGetFrames  = hIO checkFrameBounds  sf_read_double+    hGetFrames  = hIO checkFrameBounds  sf_readf_double     hPutSamples = hIO checkSampleBounds sf_write_double-    hPutFrames  = hIO checkFrameBounds  sf_write_double--foreign import ccall unsafe "sf_read_float"  sf_read_float  :: IOFunc Float-foreign import ccall unsafe "sf_write_float" sf_write_float :: IOFunc Float+    hPutFrames  = hIO checkFrameBounds  sf_writef_double  instance MBuffer IOCArray Float IO where     hGetSamples = hIO checkSampleBounds sf_read_float-    hGetFrames  = hIO checkFrameBounds  sf_read_float+    hGetFrames  = hIO checkFrameBounds  sf_readf_float     hPutSamples = hIO checkSampleBounds sf_write_float-    hPutFrames  = hIO checkFrameBounds  sf_write_float+    hPutFrames  = hIO checkFrameBounds  sf_writef_float  -- EOF
Sound/File/Sndfile/Buffer/Storable.hs view
@@ -1,16 +1,12 @@-{-# LANGUAGE ForeignFunctionInterface #-} {-# OPTIONS_GHC -fglasgow-exts #-}  module Sound.File.Sndfile.Buffer.Storable where  import C2HS-import Control.Monad (liftM) import Data.Array.Storable import Sound.File.Sndfile.Buffer import Sound.File.Sndfile.Interface -type IOFunc a = HandlePtr -> Ptr a -> CLLong -> IO CLLong- {-# INLINE hIO #-} hIO :: (Storable a) =>            (Count -> Int -> Count -> IO ())@@ -18,30 +14,25 @@         -> Handle -> (StorableArray Index a) -> Count         -> IO Count hIO checkBounds ioFunc (Handle info handle) buffer count = do-    size <- liftM rangeSize $ getBounds buffer+    size <- rangeSize `fmap` getBounds buffer     checkBounds size (channels info) count     result <- withStorableArray buffer $-                \ptr -> liftM fromIntegral $ ioFunc handle ptr (cIntConv count)+                \ptr -> fromIntegral `fmap` ioFunc handle ptr (cIntConv count)+                :: IO Count     checkHandle handle     touchStorableArray buffer     return $ cIntConv result -foreign import ccall unsafe "sf_read_double"  sf_read_double  :: IOFunc Double-foreign import ccall unsafe "sf_write_double" sf_write_double :: IOFunc Double- instance MBuffer StorableArray Double IO where     hGetSamples = hIO checkSampleBounds sf_read_double-    hGetFrames  = hIO checkFrameBounds  sf_read_double+    hGetFrames  = hIO checkFrameBounds  sf_readf_double     hPutSamples = hIO checkSampleBounds sf_write_double-    hPutFrames  = hIO checkFrameBounds  sf_write_double--foreign import ccall unsafe "sf_read_float"  sf_read_float  :: IOFunc Float-foreign import ccall unsafe "sf_write_float" sf_write_float :: IOFunc Float+    hPutFrames  = hIO checkFrameBounds  sf_writef_double  instance MBuffer StorableArray Float IO where     hGetSamples = hIO checkSampleBounds sf_read_float-    hGetFrames  = hIO checkFrameBounds  sf_read_float+    hGetFrames  = hIO checkFrameBounds  sf_readf_float     hPutSamples = hIO checkSampleBounds sf_write_float-    hPutFrames  = hIO checkFrameBounds  sf_write_float+    hPutFrames  = hIO checkFrameBounds  sf_writef_float  -- EOF
+ Sound/File/Sndfile/Exception.hs view
@@ -0,0 +1,37 @@+{-# OPTIONS_GHC -fglasgow-exts #-}++module Sound.File.Sndfile.Exception (+    Exception(..),+    catch, throw+) where++import Control.Exception (catchDyn, throwDyn)+import Data.Typeable (Typeable)+import Prelude hiding (catch)++-- |Values of type 'Exception' are thrown by the library when an error occurs.+--+-- Use 'catch' to catch only exceptions of this type.+data Exception =+    Exception           { errorString :: String }+  | UnrecognisedFormat  { errorString :: String }+  | SystemError         { errorString :: String }+  | MalformedFile       { errorString :: String }+  | UnsupportedEncoding { errorString :: String }+  deriving (Typeable, Show)++-- | Construct 'Exception' from error code and string.+fromErrorCode :: Int -> String -> Exception+fromErrorCode 1 = UnrecognisedFormat+fromErrorCode 2 = SystemError+fromErrorCode 3 = MalformedFile+fromErrorCode 4 = UnsupportedEncoding+fromErrorCode _ = Exception++-- |Catch values of type 'Exception'.+catch :: IO a -> (Exception -> IO a) -> IO a+catch = catchDyn++-- | Throw 'Exception' according to error code and string+throw :: Int -> String -> a+throw code str = throwDyn (fromErrorCode code str)
Sound/File/Sndfile/Interface.chs view
@@ -1,15 +1,11 @@ {-# LANGUAGE ForeignFunctionInterface #-}-{-# OPTIONS_GHC -fglasgow-exts #-}  module Sound.File.Sndfile.Interface where  import C2HS import Control.Monad (liftM, when)-import Control.Exception (catchDyn, throwDyn) import Data.Bits-import Data.Int (Int64)-import Data.Typeable (Typeable)-import Prelude hiding (catch)+import qualified Sound.File.Sndfile.Exception as E import System.IO.Unsafe (unsafePerformIO)  #include <sndfile.h>@@ -216,29 +212,11 @@ -- ==================================================================== -- Exceptions --- |Values of type 'Exception' are thrown by the library when an error occurs.------ Use 'catch' to catch only exceptions of this type.-data Exception = Exception String deriving (Typeable, Show)---- |Return the error string associated with the 'Exception'.-errorString :: Exception -> String-errorString (Exception s) = s---- |Catch values of type 'Exception'.-catch :: IO a -> (Exception -> IO a) -> IO a-catch = catchDyn--throw :: Exception -> a-throw = throwDyn--raiseError :: Handle -> IO ()-raiseError handle = liftM (throw . Exception) $ (peekCString $ {#call pure sf_strerror#} (hPtr handle))- checkHandle :: HandlePtr -> IO HandlePtr checkHandle handle = do     code <- liftM fromIntegral $ {#call unsafe sf_error#} handle-    when (code /= 0) $ raiseError (Handle defaultInfo handle)+    when (code /= 0) $+        peekCString ({#call pure sf_strerror#} handle) >>= E.throw code     return handle  -- ====================================================================
hsndfile.cabal view
@@ -1,6 +1,6 @@ Name:                   hsndfile-Version:                0.1.1-Category:		Sound+Version:                0.2.0+Category:               Sound License:                GPL License-File:           COPYING Copyright:              Stefan Kersten, 2007-2008@@ -14,14 +14,19 @@                         Libsndfile is a comprehensive C library for reading                         and writing a large number of soundfile formats:                         <http://www.mega-nerd.com/libsndfile/>.+						.+						Changelog and source tarballs can be found at+						<http://space.k-hornz.de/files/software/hsndfile> Tested-With:            GHC-Build-Type:		Simple-Build-Depends:          array, base, carray, haskell98+Build-Type:             Simple+Build-Depends:          array, base, carray >= 0.1.2, haskell98+Build-Tools:			c2hs >= 0.15 Exposed-Modules:        Sound.File.Sndfile-Other-Modules:          C2HS,-		        Sound.File.Sndfile.Buffer,-		        Sound.File.Sndfile.Buffer.IOCArray,-		        Sound.File.Sndfile.Buffer.Storable,-		        Sound.File.Sndfile.Interface-Ghc-Options:            -Wall+Other-Modules:          C2HS+                        Sound.File.Sndfile.Buffer+                        Sound.File.Sndfile.Buffer.IOCArray+                        Sound.File.Sndfile.Buffer.Storable+                        Sound.File.Sndfile.Exception+                        Sound.File.Sndfile.Interface+Ghc-Options:            -Wall -fno-warn-name-shadowing Extra-Libraries:        sndfile