conduit-audio-sndfile 0.1 → 0.1.1
raw patch · 2 files changed
+41/−15 lines, 2 files
Files
conduit-audio-sndfile.cabal view
@@ -1,5 +1,5 @@ name: conduit-audio-sndfile-version: 0.1+version: 0.1.1 author: Michael Tolly maintainer: miketolly@gmail.com license: LGPL@@ -18,9 +18,9 @@ exposed-modules: Data.Conduit.Audio.Sndfile build-depends:- base >= 4.6 && < 4.8+ base >= 4.6 && < 4.9 , conduit- , conduit-audio >= 0.1 && < 0.2+ , conduit-audio >= 0.1 && < 0.3 , hsndfile , hsndfile-vector , resourcet
src/Data/Conduit/Audio/Sndfile.hs view
@@ -1,6 +1,6 @@ module Data.Conduit.Audio.Sndfile-( sourceSnd, sourceSndFrom-, sinkSnd+( sourceSnd, sourceSndFrom, sourceSndWithHandle+, sinkSnd, sinkSndWithHandle ) where import Data.Conduit.Audio@@ -9,6 +9,7 @@ import qualified Sound.File.Sndfile as Snd import qualified Sound.File.Sndfile.Buffer.Vector as SndBuf import Control.Monad.IO.Class+import Control.Monad.Trans.Class (lift) import Control.Monad (void) import Control.Monad.Fix (fix) import Control.Monad.Trans.Resource (MonadResource)@@ -20,6 +21,7 @@ -> IO (AudioSource m a) sourceSnd = sourceSndFrom $ Frames 0 +-- | Lets you specify a position to start from in the file. sourceSndFrom :: (MonadResource m, Snd.Sample a) => Duration@@ -30,6 +32,17 @@ info <- Snd.getFileInfo fp sourceSndFrom (Frames $ secondsToFrames secs $ fromIntegral $ Snd.samplerate info) fp sourceSndFrom (Frames fms) fp = do+ src <- sourceSndWithHandle fp $ \h -> liftIO $ void $ Snd.hSeek h Snd.AbsoluteSeek fms+ return src{ frames = frames src - fms }++-- | Lets you perform arbitrary setup on the @libsndfile@ handle before decoding.+sourceSndWithHandle+ :: (MonadResource m, Snd.Sample a)+ => FilePath+ -> (Snd.Handle -> m ())+ -- ^ Perform any setup necessary with the @libsndfile@ handle+ -> IO (AudioSource m a)+sourceSndWithHandle fp setup = do -- TODO: allow user to supply Snd.Format for raw files? info <- Snd.getFileInfo fp let r = fromIntegral $ Snd.samplerate info@@ -38,21 +51,34 @@ (Snd.openFile fp Snd.ReadMode Snd.defaultInfo) Snd.hClose $ \h -> do- liftIO $ void $ Snd.hSeek h Snd.AbsoluteSeek fms+ lift $ setup h fix $ \loop -> liftIO (Snd.hGetBuffer h chunkSize) >>= \mx -> case mx of Nothing -> return () Just buf -> do C.yield $ SndBuf.fromBuffer buf loop- return $ AudioSource src r c $ Snd.frames info - fms+ return $ AudioSource src r c $ Snd.frames info -- | Uses @libsndfile@ to write an audio stream to a file. sinkSnd :: (MonadResource m, Snd.Sample a) => FilePath -> Snd.Format -> AudioSource m a -> m ()-sinkSnd fp fmt (AudioSource s r c _) = s C.$$ C.bracketP- (Snd.openFile fp Snd.WriteMode $ Snd.defaultInfo- { Snd.format = fmt- , Snd.samplerate = round r- , Snd.channels = c- })- Snd.hClose- (\h -> CL.mapM_ $ liftIO . void . Snd.hPutBuffer h . SndBuf.toBuffer)+sinkSnd fp fmt = sinkSndWithHandle fp fmt $ \_ -> return ()++-- | Lets you perform arbitrary setup on the @libsndfile@ handle before encoding.+sinkSndWithHandle+ :: (MonadResource m, Snd.Sample a)+ => FilePath+ -> Snd.Format+ -> (Snd.Handle -> m ())+ -> AudioSource m a+ -> m ()+sinkSndWithHandle fp fmt setup (AudioSource s r c _) = s C.$$ do+ C.bracketP+ (Snd.openFile fp Snd.WriteMode $ Snd.defaultInfo+ { Snd.format = fmt+ , Snd.samplerate = round r+ , Snd.channels = c+ })+ Snd.hClose+ $ \h -> do+ lift $ setup h+ CL.mapM_ $ liftIO . void . Snd.hPutBuffer h . SndBuf.toBuffer