bindings-portaudio 0.2.1 → 0.3
raw patch · 6 files changed
+62/−33 lines, 6 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- System.PortAudio: Closed :: Closed
- System.PortAudio: data Closed
- System.PortAudio: instance Foreign.Storable.Storable System.PortAudio.Closed
+ System.PortAudio: data Stream
+ System.PortAudio: instance GHC.Classes.Eq System.PortAudio.Status
+ System.PortAudio: instance GHC.Classes.Ord System.PortAudio.Status
+ System.PortAudio: instance GHC.Show.Show System.PortAudio.Status
+ System.PortAudio: isStreamStopped :: Stream -> IO Bool
+ System.PortAudio: setStreamFinishedCallback :: Stream -> IO () -> IO ()
+ System.PortAudio: startStream :: Stream -> IO ()
+ System.PortAudio: stopStream :: Stream -> IO ()
+ System.PortAudio: withStartStream :: Stream -> IO r -> IO r
- Bindings.PortAudio: c'Pa_SetStreamFinishedCallback :: Ptr C'PaStream -> Ptr C'PaStreamFinishedCallback -> IO CInt
+ Bindings.PortAudio: c'Pa_SetStreamFinishedCallback :: Ptr C'PaStream -> C'PaStreamFinishedCallback -> IO CInt
- Bindings.PortAudio: p'Pa_SetStreamFinishedCallback :: FunPtr (Ptr C'PaStream -> Ptr C'PaStreamFinishedCallback -> IO CInt)
+ Bindings.PortAudio: p'Pa_SetStreamFinishedCallback :: FunPtr (Ptr C'PaStream -> C'PaStreamFinishedCallback -> IO CInt)
- System.PortAudio: noConnection :: Maybe (StreamParameters t Closed)
+ System.PortAudio: noConnection :: Maybe (StreamParameters t ())
- System.PortAudio: withStream :: (Storable i, Storable o) => Double -> Int -> Maybe (StreamParameters Input i) -> Maybe (StreamParameters Output o) -> StreamFlags -> (Status -> Vector i -> IOVector o -> IO StreamCallbackResult) -> IO r -> IO r
+ System.PortAudio: withStream :: (Storable i, Storable o) => Double -> Int -> Maybe (StreamParameters Input i) -> Maybe (StreamParameters Output o) -> StreamFlags -> (Status -> Vector i -> IOVector o -> IO StreamCallbackResult) -> (Stream -> IO r) -> IO r
Files
- Bindings/PortAudio.hsc +1/−1
- CHANGELOG.md +6/−0
- System/PortAudio.hs +27/−12
- bindings-portaudio.cabal +4/−5
- example/example-portaudio.cabal +1/−0
- example/sine.hs +23/−15
Bindings/PortAudio.hsc view
@@ -221,7 +221,7 @@ #ccall Pa_OpenStream , Ptr (Ptr <PaStream>) -> Ptr <struct PaStreamParameters> -> Ptr <struct PaStreamParameters> -> CDouble -> CULong -> CULong -> <PaStreamCallback> -> Ptr () -> IO CInt #ccall Pa_OpenDefaultStream , Ptr (Ptr <PaStream>) -> CInt -> CInt -> CULong -> CDouble -> CULong -> <PaStreamCallback> -> Ptr () -> IO CInt #ccall Pa_CloseStream , Ptr <PaStream> -> IO CInt-#ccall Pa_SetStreamFinishedCallback , Ptr <PaStream> -> Ptr <PaStreamFinishedCallback> -> IO CInt+#ccall Pa_SetStreamFinishedCallback , Ptr <PaStream> -> <PaStreamFinishedCallback> -> IO CInt #ccall Pa_StartStream , Ptr <PaStream> -> IO CInt #ccall Pa_StopStream , Ptr <PaStream> -> IO CInt #ccall Pa_AbortStream , Ptr <PaStream> -> IO CInt
CHANGELOG.md view
@@ -0,0 +1,6 @@+0.3+----++* `withStream` no longer starts a stream on its own+* Added `withStartStream` and `setStreamFinishedCallback`+* Removed `Closed` in favour of `()`
System/PortAudio.hs view
@@ -10,13 +10,18 @@ , Input , Output -- * Opening a stream+ , Stream , withStream , StreamCallbackResult(..)+ , startStream+ , stopStream+ , withStartStream+ , isStreamStopped+ , setStreamFinishedCallback -- * Stream parameters , StreamParameters , streamParameters , PortAudioSample- , Closed(..) , noConnection -- * Timestamps and status flags , Status(..)@@ -198,8 +203,10 @@ , inputOverflow :: !Bool , outputUnderflow :: !Bool , outputOverflow :: !Bool- , primingOutput :: !Bool }+ , primingOutput :: !Bool } deriving (Show, Eq, Ord) +newtype Stream = Stream { unStream :: Ptr C'PaStream }+ withStream :: (Storable i, Storable o) => Double -- ^ sampling rate -> Int -- ^ buffer size@@ -207,7 +214,7 @@ -> Maybe (StreamParameters Output o) -> StreamFlags -> (Status -> V.Vector i -> MV.IOVector o -> IO StreamCallbackResult) -- ^ callback- -> IO r+ -> (Stream -> IO r) -> IO r withStream rate buf paramI paramO (StreamFlags flags) f m = withMaybe paramI $ \pin -> withMaybe paramO $ \pout -> do@@ -222,19 +229,27 @@ cb nullPtr peek ps- alloca $ \ps -> bracket (opener ps) (wrap . c'Pa_CloseStream)- $ \s -> bracket_ (wrap $ c'Pa_StartStream s) (wrap $ c'Pa_StopStream s) m+ alloca $ \ps -> bracket (opener ps) (wrap . c'Pa_CloseStream) $ m . Stream -data Closed = Closed+startStream :: Stream -> IO ()+startStream = wrap . c'Pa_StartStream . unStream -instance Storable Closed where- sizeOf _ = 0- alignment _ = 1- peek _ = return Closed- poke _ _ = return ()+stopStream :: Stream -> IO ()+stopStream = wrap . c'Pa_StopStream . unStream +setStreamFinishedCallback :: Stream -> IO () -> IO ()+setStreamFinishedCallback (Stream s) m = do+ cb <- mk'PaStreamFinishedCallback (const m)+ wrap $ c'Pa_SetStreamFinishedCallback s cb++isStreamStopped :: Stream -> IO Bool+isStreamStopped = fmap (==1) . c'Pa_IsStreamStopped . unStream++withStartStream :: Stream -> IO r -> IO r+withStartStream s = bracket_ (startStream s) (stopStream s)+ -- | This is 'Nothing', but it explicitly specifies the stream type with zero-width unit type.-noConnection :: Maybe (StreamParameters t Closed)+noConnection :: Maybe (StreamParameters t ()) noConnection = Nothing callback :: (Storable a, Storable b) => (Status -> V.Vector a -> MV.IOVector b -> IO StreamCallbackResult) -> Ptr () -> Ptr () -> CULong -> Ptr C'PaStreamCallbackTimeInfo -> CULong -> z -> IO CUInt
bindings-portaudio.cabal view
@@ -1,8 +1,9 @@ cabal-version: 2.4 name: bindings-portaudio-version: 0.2.1+version: 0.3 category: Sound +copyright: Copyright (c) 2020 Fumiaki Kinoshita author: Fumiaki Kinoshita <fumiexcel@gmail.com> maintainer: Fumiaki Kinoshita <fumiexcel@gmail.com> @@ -53,15 +54,13 @@ default-language: Haskell2010 ghc-options: -Wall -O2- if impl(ghc >= 6.8)- ghc-options: -fwarn-tabs exposed-modules: Bindings.PortAudio System.PortAudio - build-tools:- hsc2hs+ build-tool-depends:+ hsc2hs:hsc2hs build-depends: base < 5, bindings-DSL ^>= 1.0, vector
example/example-portaudio.cabal view
@@ -23,6 +23,7 @@ , bindings-portaudio , vector >= 0.10 && < 0.13 , linear+ , optparse-applicative -- hs-source-dirs: ghc-options: -threaded -Wall -O2 default-language: Haskell2010
example/sine.hs view
@@ -1,11 +1,12 @@ {-# LANGUAGE ViewPatterns, LambdaCase #-}+{-# LANGUAGE ApplicativeDo #-} import System.PortAudio import Control.Concurrent+import Control.Monad import Linear (V2(..)) import qualified Data.Vector as V import qualified Data.Vector.Storable.Mutable as MV-import System.Environment-import System.Exit+import Options.Applicative period :: Int period = 128@@ -30,17 +31,24 @@ go i0 (i + 1) main :: IO ()-main = getArgs >>= \case- ((read -> rate) : (read -> buf) : _) -> withPortAudio $ do- (_, dev : _) <- getDevices- phase <- newMVar 0- let output = streamParameters dev 0- withStream rate buf noConnection output mempty (callback phase)- $ threadDelay $ 1000 * 1000- _ -> usageExit+main = join $ execParser (info app mempty) -usageExit :: IO ()-usageExit = do- pname <- getProgName- putStrLn $ "\nUsage: " ++ pname ++ " <sample rate> <buffer size>\n"- exitSuccess+app :: Parser (IO ())+app = do+ rate <- option auto $ long "rate" <> help "sampling rate" <> value 44100+ buf <- option auto $ long "buffer" <> help "number of samples for the buffer" <> value 1024+ device <- option auto $ long "device" <> help "device index" <> value (-1)+ helper+ pure $ withPortAudio $ do+ (_, devs) <- getDevices+ if device < 0+ then forM_ (zip [0 :: Int ..] devs) $ \(i, dev) ->+ putStrLn $ show i ++ ": " ++ deviceName dev+ else do+ let dev = devs !! device+ phase <- newMVar 0+ let output = streamParameters dev 0+ withStream rate buf noConnection output mempty (callback phase)+ $ \s -> do+ setStreamFinishedCallback s $ putStrLn "Done"+ withStartStream s $ threadDelay $ 1000 * 1000