{-# 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 ()) -> IOFunc a -> Handle -> (IOCArray Index a) -> Count -> IO Count hIO checkBounds ioFunc (Handle info handle) buffer count = do size <- liftM rangeSize $ getBounds buffer checkBounds size (channels info) count result <- withIOCArray buffer $ \ptr -> liftM fromIntegral $ ioFunc handle ptr (cIntConv 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 instance MBuffer IOCArray Double IO where hGetSamples = hIO checkSampleBounds sf_read_double hGetFrames = hIO checkFrameBounds sf_read_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 instance MBuffer IOCArray Float IO where hGetSamples = hIO checkSampleBounds sf_read_float hGetFrames = hIO checkFrameBounds sf_read_float hPutSamples = hIO checkSampleBounds sf_write_float hPutFrames = hIO checkFrameBounds sf_write_float -- EOF