packages feed

bindings-portaudio 0.2 → 0.2.1

raw patch · 5 files changed

+69/−70 lines, 5 filesdep ~bindings-DSLPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: bindings-DSL

API changes (from Hackage documentation)

- System.PortAudio: instance GHC.Exception.Exception System.PortAudio.Error
+ System.PortAudio: instance GHC.Base.Semigroup System.PortAudio.StreamCallbackResult
+ System.PortAudio: instance GHC.Base.Semigroup System.PortAudio.StreamFlags
+ System.PortAudio: instance GHC.Exception.Type.Exception System.PortAudio.Error
- Bindings.PortAudio: c'paAL :: (Num a) => a
+ Bindings.PortAudio: c'paAL :: Num a => a
- Bindings.PortAudio: c'paALSA :: (Num a) => a
+ Bindings.PortAudio: c'paALSA :: Num a => a
- Bindings.PortAudio: c'paASIO :: (Num a) => a
+ Bindings.PortAudio: c'paASIO :: Num a => a
- Bindings.PortAudio: c'paAbort :: (Num a) => a
+ Bindings.PortAudio: c'paAbort :: Num a => a
- Bindings.PortAudio: c'paAudioScienceHPI :: (Num a) => a
+ Bindings.PortAudio: c'paAudioScienceHPI :: Num a => a
- Bindings.PortAudio: c'paBadBufferPtr :: (Num a) => a
+ Bindings.PortAudio: c'paBadBufferPtr :: Num a => a
- Bindings.PortAudio: c'paBadIODeviceCombination :: (Num a) => a
+ Bindings.PortAudio: c'paBadIODeviceCombination :: Num a => a
- Bindings.PortAudio: c'paBadStreamPtr :: (Num a) => a
+ Bindings.PortAudio: c'paBadStreamPtr :: Num a => a
- Bindings.PortAudio: c'paBeOS :: (Num a) => a
+ Bindings.PortAudio: c'paBeOS :: Num a => a
- Bindings.PortAudio: c'paBufferTooBig :: (Num a) => a
+ Bindings.PortAudio: c'paBufferTooBig :: Num a => a
- Bindings.PortAudio: c'paBufferTooSmall :: (Num a) => a
+ Bindings.PortAudio: c'paBufferTooSmall :: Num a => a
- Bindings.PortAudio: c'paCanNotReadFromACallbackStream :: (Num a) => a
+ Bindings.PortAudio: c'paCanNotReadFromACallbackStream :: Num a => a
- Bindings.PortAudio: c'paCanNotReadFromAnOutputOnlyStream :: (Num a) => a
+ Bindings.PortAudio: c'paCanNotReadFromAnOutputOnlyStream :: Num a => a
- Bindings.PortAudio: c'paCanNotWriteToACallbackStream :: (Num a) => a
+ Bindings.PortAudio: c'paCanNotWriteToACallbackStream :: Num a => a
- Bindings.PortAudio: c'paCanNotWriteToAnInputOnlyStream :: (Num a) => a
+ Bindings.PortAudio: c'paCanNotWriteToAnInputOnlyStream :: Num a => a
- Bindings.PortAudio: c'paComplete :: (Num a) => a
+ Bindings.PortAudio: c'paComplete :: Num a => a
- Bindings.PortAudio: c'paContinue :: (Num a) => a
+ Bindings.PortAudio: c'paContinue :: Num a => a
- Bindings.PortAudio: c'paCoreAudio :: (Num a) => a
+ Bindings.PortAudio: c'paCoreAudio :: Num a => a
- Bindings.PortAudio: c'paDeviceUnavailable :: (Num a) => a
+ Bindings.PortAudio: c'paDeviceUnavailable :: Num a => a
- Bindings.PortAudio: c'paDirectSound :: (Num a) => a
+ Bindings.PortAudio: c'paDirectSound :: Num a => a
- Bindings.PortAudio: c'paHostApiNotFound :: (Num a) => a
+ Bindings.PortAudio: c'paHostApiNotFound :: Num a => a
- Bindings.PortAudio: c'paInDevelopment :: (Num a) => a
+ Bindings.PortAudio: c'paInDevelopment :: Num a => a
- Bindings.PortAudio: c'paIncompatibleHostApiSpecificStreamInfo :: (Num a) => a
+ Bindings.PortAudio: c'paIncompatibleHostApiSpecificStreamInfo :: Num a => a
- Bindings.PortAudio: c'paIncompatibleStreamHostApi :: (Num a) => a
+ Bindings.PortAudio: c'paIncompatibleStreamHostApi :: Num a => a
- Bindings.PortAudio: c'paInputOverflowed :: (Num a) => a
+ Bindings.PortAudio: c'paInputOverflowed :: Num a => a
- Bindings.PortAudio: c'paInsufficientMemory :: (Num a) => a
+ Bindings.PortAudio: c'paInsufficientMemory :: Num a => a
- Bindings.PortAudio: c'paInternalError :: (Num a) => a
+ Bindings.PortAudio: c'paInternalError :: Num a => a
- Bindings.PortAudio: c'paInvalidChannelCount :: (Num a) => a
+ Bindings.PortAudio: c'paInvalidChannelCount :: Num a => a
- Bindings.PortAudio: c'paInvalidDevice :: (Num a) => a
+ Bindings.PortAudio: c'paInvalidDevice :: Num a => a
- Bindings.PortAudio: c'paInvalidFlag :: (Num a) => a
+ Bindings.PortAudio: c'paInvalidFlag :: Num a => a
- Bindings.PortAudio: c'paInvalidHostApi :: (Num a) => a
+ Bindings.PortAudio: c'paInvalidHostApi :: Num a => a
- Bindings.PortAudio: c'paInvalidSampleRate :: (Num a) => a
+ Bindings.PortAudio: c'paInvalidSampleRate :: Num a => a
- Bindings.PortAudio: c'paJACK :: (Num a) => a
+ Bindings.PortAudio: c'paJACK :: Num a => a
- Bindings.PortAudio: c'paMME :: (Num a) => a
+ Bindings.PortAudio: c'paMME :: Num a => a
- Bindings.PortAudio: c'paNoError :: (Num a) => a
+ Bindings.PortAudio: c'paNoError :: Num a => a
- Bindings.PortAudio: c'paNotInitialized :: (Num a) => a
+ Bindings.PortAudio: c'paNotInitialized :: Num a => a
- Bindings.PortAudio: c'paNullCallback :: (Num a) => a
+ Bindings.PortAudio: c'paNullCallback :: Num a => a
- Bindings.PortAudio: c'paOSS :: (Num a) => a
+ Bindings.PortAudio: c'paOSS :: Num a => a
- Bindings.PortAudio: c'paOutputUnderflowed :: (Num a) => a
+ Bindings.PortAudio: c'paOutputUnderflowed :: Num a => a
- Bindings.PortAudio: c'paSampleFormatNotSupported :: (Num a) => a
+ Bindings.PortAudio: c'paSampleFormatNotSupported :: Num a => a
- Bindings.PortAudio: c'paSoundManager :: (Num a) => a
+ Bindings.PortAudio: c'paSoundManager :: Num a => a
- Bindings.PortAudio: c'paStreamIsNotStopped :: (Num a) => a
+ Bindings.PortAudio: c'paStreamIsNotStopped :: Num a => a
- Bindings.PortAudio: c'paStreamIsStopped :: (Num a) => a
+ Bindings.PortAudio: c'paStreamIsStopped :: Num a => a
- Bindings.PortAudio: c'paTimedOut :: (Num a) => a
+ Bindings.PortAudio: c'paTimedOut :: Num a => a
- Bindings.PortAudio: c'paUnanticipatedHostError :: (Num a) => a
+ Bindings.PortAudio: c'paUnanticipatedHostError :: Num a => a
- Bindings.PortAudio: c'paWASAPI :: (Num a) => a
+ Bindings.PortAudio: c'paWASAPI :: Num a => a
- Bindings.PortAudio: c'paWDMKS :: (Num a) => a
+ Bindings.PortAudio: c'paWDMKS :: Num a => a
- Bindings.PortAudio: mK'PaStreamCallback :: C'PaStreamCallback -> (Ptr () -> Ptr () -> CULong -> Ptr C'PaStreamCallbackTimeInfo -> C'PaStreamCallbackFlags -> Ptr () -> IO C'PaStreamCallbackResult)
+ Bindings.PortAudio: mK'PaStreamCallback :: C'PaStreamCallback -> Ptr () -> Ptr () -> CULong -> Ptr C'PaStreamCallbackTimeInfo -> C'PaStreamCallbackFlags -> Ptr () -> IO C'PaStreamCallbackResult
- Bindings.PortAudio: mK'PaStreamFinishedCallback :: C'PaStreamFinishedCallback -> (Ptr () -> IO ())
+ Bindings.PortAudio: mK'PaStreamFinishedCallback :: C'PaStreamFinishedCallback -> Ptr () -> IO ()
- Bindings.PortAudio: p'PaDeviceInfo'defaultHighInputLatency :: Ptr (C'PaDeviceInfo) -> Ptr (CDouble)
+ Bindings.PortAudio: p'PaDeviceInfo'defaultHighInputLatency :: Ptr C'PaDeviceInfo -> Ptr CDouble
- Bindings.PortAudio: p'PaDeviceInfo'defaultHighOutputLatency :: Ptr (C'PaDeviceInfo) -> Ptr (CDouble)
+ Bindings.PortAudio: p'PaDeviceInfo'defaultHighOutputLatency :: Ptr C'PaDeviceInfo -> Ptr CDouble
- Bindings.PortAudio: p'PaDeviceInfo'defaultLowInputLatency :: Ptr (C'PaDeviceInfo) -> Ptr (CDouble)
+ Bindings.PortAudio: p'PaDeviceInfo'defaultLowInputLatency :: Ptr C'PaDeviceInfo -> Ptr CDouble
- Bindings.PortAudio: p'PaDeviceInfo'defaultLowOutputLatency :: Ptr (C'PaDeviceInfo) -> Ptr (CDouble)
+ Bindings.PortAudio: p'PaDeviceInfo'defaultLowOutputLatency :: Ptr C'PaDeviceInfo -> Ptr CDouble
- Bindings.PortAudio: p'PaDeviceInfo'defaultSampleRate :: Ptr (C'PaDeviceInfo) -> Ptr (CDouble)
+ Bindings.PortAudio: p'PaDeviceInfo'defaultSampleRate :: Ptr C'PaDeviceInfo -> Ptr CDouble
- Bindings.PortAudio: p'PaDeviceInfo'hostApi :: Ptr (C'PaDeviceInfo) -> Ptr (CInt)
+ Bindings.PortAudio: p'PaDeviceInfo'hostApi :: Ptr C'PaDeviceInfo -> Ptr CInt
- Bindings.PortAudio: p'PaDeviceInfo'maxInputChannels :: Ptr (C'PaDeviceInfo) -> Ptr (CInt)
+ Bindings.PortAudio: p'PaDeviceInfo'maxInputChannels :: Ptr C'PaDeviceInfo -> Ptr CInt
- Bindings.PortAudio: p'PaDeviceInfo'maxOutputChannels :: Ptr (C'PaDeviceInfo) -> Ptr (CInt)
+ Bindings.PortAudio: p'PaDeviceInfo'maxOutputChannels :: Ptr C'PaDeviceInfo -> Ptr CInt
- Bindings.PortAudio: p'PaDeviceInfo'name :: Ptr (C'PaDeviceInfo) -> Ptr (CString)
+ Bindings.PortAudio: p'PaDeviceInfo'name :: Ptr C'PaDeviceInfo -> Ptr CString
- Bindings.PortAudio: p'PaDeviceInfo'structVersion :: Ptr (C'PaDeviceInfo) -> Ptr (CInt)
+ Bindings.PortAudio: p'PaDeviceInfo'structVersion :: Ptr C'PaDeviceInfo -> Ptr CInt
- Bindings.PortAudio: p'PaHostApiInfo'defaultInputDevice :: Ptr (C'PaHostApiInfo) -> Ptr (CInt)
+ Bindings.PortAudio: p'PaHostApiInfo'defaultInputDevice :: Ptr C'PaHostApiInfo -> Ptr CInt
- Bindings.PortAudio: p'PaHostApiInfo'defaultOutputDevice :: Ptr (C'PaHostApiInfo) -> Ptr (CInt)
+ Bindings.PortAudio: p'PaHostApiInfo'defaultOutputDevice :: Ptr C'PaHostApiInfo -> Ptr CInt
- Bindings.PortAudio: p'PaHostApiInfo'deviceCount :: Ptr (C'PaHostApiInfo) -> Ptr (CInt)
+ Bindings.PortAudio: p'PaHostApiInfo'deviceCount :: Ptr C'PaHostApiInfo -> Ptr CInt
- Bindings.PortAudio: p'PaHostApiInfo'name :: Ptr (C'PaHostApiInfo) -> Ptr (CString)
+ Bindings.PortAudio: p'PaHostApiInfo'name :: Ptr C'PaHostApiInfo -> Ptr CString
- Bindings.PortAudio: p'PaHostApiInfo'structVersion :: Ptr (C'PaHostApiInfo) -> Ptr (CInt)
+ Bindings.PortAudio: p'PaHostApiInfo'structVersion :: Ptr C'PaHostApiInfo -> Ptr CInt
- Bindings.PortAudio: p'PaHostApiInfo'type :: Ptr (C'PaHostApiInfo) -> Ptr (C'PaHostApiTypeId)
+ Bindings.PortAudio: p'PaHostApiInfo'type :: Ptr C'PaHostApiInfo -> Ptr C'PaHostApiTypeId
- Bindings.PortAudio: p'PaHostErrorInfo'errorCode :: Ptr (C'PaHostErrorInfo) -> Ptr (CLong)
+ Bindings.PortAudio: p'PaHostErrorInfo'errorCode :: Ptr C'PaHostErrorInfo -> Ptr CLong
- Bindings.PortAudio: p'PaHostErrorInfo'errorText :: Ptr (C'PaHostErrorInfo) -> Ptr (CString)
+ Bindings.PortAudio: p'PaHostErrorInfo'errorText :: Ptr C'PaHostErrorInfo -> Ptr CString
- Bindings.PortAudio: p'PaHostErrorInfo'hostApiType :: Ptr (C'PaHostErrorInfo) -> Ptr (C'PaHostApiTypeId)
+ Bindings.PortAudio: p'PaHostErrorInfo'hostApiType :: Ptr C'PaHostErrorInfo -> Ptr C'PaHostApiTypeId
- Bindings.PortAudio: p'PaStreamCallbackTimeInfo'currentTime :: Ptr (C'PaStreamCallbackTimeInfo) -> Ptr (CDouble)
+ Bindings.PortAudio: p'PaStreamCallbackTimeInfo'currentTime :: Ptr C'PaStreamCallbackTimeInfo -> Ptr CDouble
- Bindings.PortAudio: p'PaStreamCallbackTimeInfo'inputBufferAdcTime :: Ptr (C'PaStreamCallbackTimeInfo) -> Ptr (CDouble)
+ Bindings.PortAudio: p'PaStreamCallbackTimeInfo'inputBufferAdcTime :: Ptr C'PaStreamCallbackTimeInfo -> Ptr CDouble
- Bindings.PortAudio: p'PaStreamCallbackTimeInfo'outputBufferDacTime :: Ptr (C'PaStreamCallbackTimeInfo) -> Ptr (CDouble)
+ Bindings.PortAudio: p'PaStreamCallbackTimeInfo'outputBufferDacTime :: Ptr C'PaStreamCallbackTimeInfo -> Ptr CDouble
- Bindings.PortAudio: p'PaStreamInfo'inputLatency :: Ptr (C'PaStreamInfo) -> Ptr (CDouble)
+ Bindings.PortAudio: p'PaStreamInfo'inputLatency :: Ptr C'PaStreamInfo -> Ptr CDouble
- Bindings.PortAudio: p'PaStreamInfo'outputLatency :: Ptr (C'PaStreamInfo) -> Ptr (CDouble)
+ Bindings.PortAudio: p'PaStreamInfo'outputLatency :: Ptr C'PaStreamInfo -> Ptr CDouble
- Bindings.PortAudio: p'PaStreamInfo'sampleRate :: Ptr (C'PaStreamInfo) -> Ptr (CDouble)
+ Bindings.PortAudio: p'PaStreamInfo'sampleRate :: Ptr C'PaStreamInfo -> Ptr CDouble
- Bindings.PortAudio: p'PaStreamInfo'structVersion :: Ptr (C'PaStreamInfo) -> Ptr (CInt)
+ Bindings.PortAudio: p'PaStreamInfo'structVersion :: Ptr C'PaStreamInfo -> Ptr CInt
- Bindings.PortAudio: p'PaStreamParameters'channelCount :: Ptr (C'PaStreamParameters) -> Ptr (CInt)
+ Bindings.PortAudio: p'PaStreamParameters'channelCount :: Ptr C'PaStreamParameters -> Ptr CInt
- Bindings.PortAudio: p'PaStreamParameters'device :: Ptr (C'PaStreamParameters) -> Ptr (CInt)
+ Bindings.PortAudio: p'PaStreamParameters'device :: Ptr C'PaStreamParameters -> Ptr CInt
- Bindings.PortAudio: p'PaStreamParameters'hostApiSpecificStreamInfo :: Ptr (C'PaStreamParameters) -> Ptr (Ptr ())
+ Bindings.PortAudio: p'PaStreamParameters'hostApiSpecificStreamInfo :: Ptr C'PaStreamParameters -> Ptr (Ptr ())
- Bindings.PortAudio: p'PaStreamParameters'sampleFormat :: Ptr (C'PaStreamParameters) -> Ptr (CULong)
+ Bindings.PortAudio: p'PaStreamParameters'sampleFormat :: Ptr C'PaStreamParameters -> Ptr CULong
- Bindings.PortAudio: p'PaStreamParameters'suggestedLatency :: Ptr (C'PaStreamParameters) -> Ptr (CDouble)
+ Bindings.PortAudio: p'PaStreamParameters'suggestedLatency :: Ptr C'PaStreamParameters -> Ptr CDouble

Files

+ CHANGELOG.md view
System/PortAudio.hs view
@@ -152,9 +152,11 @@  newtype StreamFlags = StreamFlags CULong +instance Semigroup StreamFlags where+  StreamFlags a <> StreamFlags b = StreamFlags (a .|. b)+ instance Monoid StreamFlags where   mempty = StreamFlags 0-  StreamFlags a `mappend` StreamFlags b = StreamFlags (a .|. b)  clipOff :: StreamFlags clipOff = StreamFlags 0x00000001@@ -168,23 +170,25 @@ primeOutputBuffersUsingStreamCallback :: StreamFlags primeOutputBuffersUsingStreamCallback = StreamFlags 0x00000008 -w :: IO CInt -> IO ()-w n = do+wrap :: IO CInt -> IO ()+wrap n = do   r <- n   unless (r == 0) $ throwIO $ fromErrorCode r  withPortAudio :: IO a -> IO a-withPortAudio = bracket_ (w c'Pa_Initialize) (w c'Pa_Terminate)+withPortAudio = bracket_ (wrap c'Pa_Initialize) (wrap c'Pa_Terminate)  data StreamCallbackResult = Continue | Complete | Abort deriving (Show, Eq, Ord, Enum) +instance Semigroup StreamCallbackResult where+  Complete <> x = x+  x <> Complete = x+  Abort <> _ = Abort+  _ <> Abort = Abort+  Continue <> Continue = Continue+ instance Monoid StreamCallbackResult where   mempty = Complete-  mappend Complete x = x-  mappend x Complete = x-  mappend Abort _ = Abort-  mappend _ Abort = Abort-  mappend Continue Continue = Continue  data Status = Status   { currentTime :: !Double@@ -208,9 +212,8 @@ withStream rate buf paramI paramO (StreamFlags flags) f m =   withMaybe paramI $ \pin -> withMaybe paramO $ \pout -> do     cb <- mk'PaStreamCallback $ callback f-    let opener = do-          ps <- malloc-          w $ c'Pa_OpenStream ps+    let opener ps = do+          wrap $ c'Pa_OpenStream ps               (castPtr pin)               (castPtr pout)               (CDouble rate)@@ -219,8 +222,8 @@               cb               nullPtr           peek ps-    bracket opener (\s -> w (c'Pa_CloseStream s) >> free s)-      $ \s -> bracket_ (w $ c'Pa_StartStream s) (w $ c'Pa_StopStream s) m+    alloca $ \ps -> bracket (opener ps) (wrap . c'Pa_CloseStream)+      $ \s -> bracket_ (wrap $ c'Pa_StartStream s) (wrap $ c'Pa_StopStream s) m  data Closed = Closed 
bindings-portaudio.cabal view
@@ -1,16 +1,16 @@+cabal-version: 2.4 name:         bindings-portaudio-version:      0.2+version:      0.2.1 category:     Sound  author:       Fumiaki Kinoshita <fumiexcel@gmail.com> maintainer:   Fumiaki Kinoshita <fumiexcel@gmail.com> -license:      BSD3+license:      BSD-3-Clause license-file: LICENSE  synopsis:     Low-level bindings to portaudio library description:-cabal-version: >= 1.10 build-type:    Simple  extra-source-files:@@ -26,6 +26,7 @@   extra.c   LICENSE   README.md+  CHANGELOG.md   example/*.hs   example/example-portaudio.cabal   example/LICENSE@@ -63,7 +64,7 @@     hsc2hs    build-depends:-    base          < 5, bindings-DSL == 1.0.*, vector+    base          < 5, bindings-DSL ^>= 1.0, vector    cc-options: -g 
example/example-portaudio.cabal view
@@ -21,7 +21,7 @@   -- other-extensions:   build-depends:       base >=4.6 && < 5                      , bindings-portaudio-                     , vector >= 0.10 && < 0.12+                     , vector >= 0.10 && < 0.13                      , linear   -- hs-source-dirs:   ghc-options: -threaded -Wall -O2
example/sine.hs view
@@ -1,51 +1,46 @@-{-# LANGUAGE ViewPatterns, LambdaCase #-}
-import System.PortAudio
-import Control.Applicative
-import Control.Concurrent
-import Control.Monad
-import Foreign.C.String
-import Foreign.C.Types
-import Foreign hiding (void)
-import Linear (V2(..))
-import qualified Data.Vector as V
-import qualified Data.Vector.Storable.Mutable as MV
-import System.Environment
-import System.Exit
-
-period :: Int
-period = 128
-
-table :: V.Vector Float
-table = V.fromList [sin t | i <- [0..period - 1], let t = fromIntegral i / fromIntegral period * 2 * pi]
-
-callback :: MVar Int -> Status -> input -> MV.IOVector (V2 Float) -> IO StreamCallbackResult
-callback phase _ _ o = do
-  i0 <- takeMVar phase
-  go i0 0
-  putMVar phase $ i0 + n
-  return Continue
-  where
-    n = MV.length o
-    go :: Int -> Int -> IO ()
-    go i0 i
-      | i == n = return ()
-      | otherwise = do
-        let v = table V.! ((i0 + i) `mod` period)
-        MV.write o i (V2 v v)
-        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
-
-usageExit :: IO ()
-usageExit = do
-  pname <- getProgName
-  putStrLn $ "\nUsage: " ++ pname ++ " <sample rate> <buffer size>\n"
-  exitSuccess
+{-# LANGUAGE ViewPatterns, LambdaCase #-}+import System.PortAudio+import Control.Concurrent+import Linear (V2(..))+import qualified Data.Vector as V+import qualified Data.Vector.Storable.Mutable as MV+import System.Environment+import System.Exit++period :: Int+period = 128++table :: V.Vector Float+table = V.fromList [sin t | i <- [0..period - 1], let t = fromIntegral i / fromIntegral period * 2 * pi]++callback :: MVar Int -> Status -> input -> MV.IOVector (V2 Float) -> IO StreamCallbackResult+callback phase _ _ o = do+  i0 <- takeMVar phase+  go i0 0+  putMVar phase $ i0 + n+  return Continue+  where+    n = MV.length o+    go :: Int -> Int -> IO ()+    go i0 i+      | i == n = return ()+      | otherwise = do+        let v = table V.! ((i0 + i) `mod` period)+        MV.write o i (V2 v v)+        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++usageExit :: IO ()+usageExit = do+  pname <- getProgName+  putStrLn $ "\nUsage: " ++ pname ++ " <sample rate> <buffer size>\n"+  exitSuccess