packages feed

alsa 0.2 → 0.4

raw patch · 7 files changed

Files

LICENSE view
@@ -1,3 +1,4 @@+Copyright (c) 2009 Henning Thielemann Copyright (c) 2006 Bjorn Bringert Copyright (c) 2006 Iavor S. Diatchki 
Sound/Alsa.hs view
@@ -1,9 +1,11 @@ module Sound.Alsa     (SampleFmt(..),      SampleFreq,+     Time,      SoundFmt(..),      SoundSource(..),      SoundSink(..),+     SoundBufferTime(..),      withSoundSource,      withSoundSourceRunning,      withSoundSink,@@ -13,60 +15,74 @@      audioBytesPerFrame,      soundSourceBytesPerFrame,      soundSinkBytesPerFrame,-     soundSourceReadBytes,-     soundSinkWriteBytes,      copySound,      alsaSoundSource,      alsaSoundSink,+     alsaSoundSourceTime,+     alsaSoundSinkTime,      fileSoundSource,-     fileSoundSink+     fileSoundSink,     ) where  import Sound.Alsa.Core-import Sound.Alsa.Error+import Sound.Alsa.Error (rethrowAlsaExceptions, catchXRun, ) -import Control.Concurrent-import Control.Exception (bracket, bracket_)-import Control.Monad (liftM,when)-import Foreign-import Foreign.C+import qualified Sound.Frame as Frame+import qualified Sound.Frame.Stereo as Stereo+import qualified Sound.Frame.MuLaw  as MuLaw++import Data.Word (Word8, Word16, Word32, )+import Data.Int (Int8, Int16, Int32, )++import Control.Concurrent (myThreadId, )+import Control.Exception (bracket, bracket_, )+import Control.Monad (liftM, when, )+import Foreign.Marshal.Array (advancePtr, allocaArray, )+import Foreign.C (CSize, CInt, )+import Foreign (Storable, Ptr, minusPtr, )+import qualified System.IO as IO import System.IO+   (IOMode(ReadMode, WriteMode), Handle, openBinaryFile, hClose, )  -- -- * Generic sound API -- -data SampleFmt = SampleFmtLinear16BitSignedLE-               | SampleFmtMuLaw8Bit-  deriving (Show)+class (Storable y, Frame.C y) => SampleFmt y where+   sampleFmtToPcmFormat :: y -> PcmFormat  type SampleFreq = Int -data SoundFmt = SoundFmt {-	sampleFmt :: SampleFmt,-	sampleFreq :: SampleFreq,- 	numChannels :: Int+data SoundFmt y = SoundFmt {+	sampleFreq :: SampleFreq 	}   deriving (Show) +type Time = Int +data SoundBufferTime = SoundBufferTime {+	bufferTime, periodTime :: Time+	}+  deriving (Show)++ -- | Counts are in samples, not bytes. Multi-channel data is interleaved.-data SoundSource handle =+data SoundSource y handle =     SoundSource {-                 soundSourceFmt   :: SoundFmt,+                 soundSourceFmt   :: SoundFmt y,                  soundSourceOpen  :: IO handle,                  soundSourceClose :: handle -> IO (),                  soundSourceStart :: handle -> IO (),                  soundSourceStop  :: handle -> IO (),-                 soundSourceRead  :: handle -> Ptr () -> Int -> IO Int+                 soundSourceRead  :: handle -> Ptr y -> Int -> IO Int                 } -data SoundSink handle =+data SoundSink y handle =     SoundSink {-                 soundSinkFmt   :: SoundFmt,+                 soundSinkFmt   :: SoundFmt y,                  soundSinkOpen  :: IO handle,                  soundSinkClose :: handle -> IO (),-                 soundSinkWrite :: handle -> Ptr () -> Int -> IO (),+                 soundSinkWrite :: handle -> Ptr y -> Int -> IO (),                  soundSinkStart :: handle -> IO (),                  soundSinkStop  :: handle -> IO ()                 }@@ -75,7 +91,14 @@ -- -- -nullSoundSource :: SoundFmt -> SoundSource h+defaultBufferTime :: SoundBufferTime+defaultBufferTime =+    SoundBufferTime {+        bufferTime = 500000, -- 0.5s+        periodTime = 100000  -- 0.1s+    }++nullSoundSource :: SoundFmt y -> SoundSource y h nullSoundSource fmt =     SoundSource { 	         soundSourceFmt   = fmt,@@ -86,7 +109,7 @@                  soundSourceRead  = \_ _ _ -> return 0                 } -nullSoundSink :: SoundFmt -> SoundSink h+nullSoundSink :: SoundFmt y -> SoundSink y h nullSoundSink fmt =     SoundSink { 	       soundSinkFmt   = fmt,@@ -98,65 +121,101 @@               }  -withSoundSource :: SoundSource h -> (h -> IO a) -> IO a+withSoundSource :: SoundSource y h -> (h -> IO a) -> IO a withSoundSource source =     bracket (soundSourceOpen source) (soundSourceClose source) -withSoundSourceRunning :: SoundSource h -> h -> IO a -> IO a+withSoundSourceRunning :: SoundSource y h -> h -> IO a -> IO a withSoundSourceRunning src h = bracket_ (soundSourceStart src h) (soundSourceStop src h) -withSoundSink :: SoundSink h -> (h -> IO a) -> IO a+withSoundSink :: SoundSink y h -> (h -> IO a) -> IO a withSoundSink sink =     bracket (soundSinkOpen sink) (soundSinkClose sink) -withSoundSinkRunning :: SoundSink h -> h -> IO a -> IO a+withSoundSinkRunning :: SoundSink y h -> h -> IO a -> IO a withSoundSinkRunning src h = bracket_ (soundSinkStart src h) (soundSinkStop src h) -soundFmtMIME :: SoundFmt -> String++instance SampleFmt Word8 where+   sampleFmtToPcmFormat _ = PcmFormatU8++instance SampleFmt Int8 where+   sampleFmtToPcmFormat _ = PcmFormatS8++instance SampleFmt Word16 where+   sampleFmtToPcmFormat _ = PcmFormatU16++instance SampleFmt Int16 where+   sampleFmtToPcmFormat _ = PcmFormatS16++instance SampleFmt Word32 where+   sampleFmtToPcmFormat _ = PcmFormatU32++instance SampleFmt Int32 where+   sampleFmtToPcmFormat _ = PcmFormatS32++instance SampleFmt Float where+   sampleFmtToPcmFormat _ = PcmFormatFloat++instance SampleFmt Double where+   sampleFmtToPcmFormat _ = PcmFormatFloat64++instance SampleFmt MuLaw.T where+   sampleFmtToPcmFormat _ = PcmFormatMuLaw++instance SampleFmt a => SampleFmt (Stereo.T a) where+   sampleFmtToPcmFormat y =+      sampleFmtToPcmFormat (Stereo.left y)++withSampleFmt :: (y -> a) -> (SoundFmt y -> a)+withSampleFmt f _ = f undefined+++soundFmtMIME :: SampleFmt y => SoundFmt y -> String soundFmtMIME fmt = t ++ r ++ c-  where t = case sampleFmt fmt of+  where t = "audio/basic"+{-+        t = case sampleFmt fmt of 		SampleFmtLinear16BitSignedLE -> "audio/L16" 		SampleFmtMuLaw8Bit           -> "audio/basic"+-}         r = ";rate=" ++ show (sampleFreq fmt)         c | numChannels fmt == 1 = "" 	  | otherwise = ";channels=" ++ show (numChannels fmt) -audioBytesPerSample :: SoundFmt -> Int-audioBytesPerSample fmt =-	case sampleFmt fmt of-		SampleFmtLinear16BitSignedLE -> 2-		SampleFmtMuLaw8Bit           -> 1+numChannels :: SampleFmt y => SoundFmt y -> Int+numChannels = withSampleFmt Frame.numberOfChannels --- assumes interleaved data-audioBytesPerFrame :: SoundFmt -> Int+audioBytesPerSample :: SampleFmt y => SoundFmt y -> Int+audioBytesPerSample = withSampleFmt Frame.sizeOfElement++{-+assumes interleaved data++Due to alignment constraints+a frame might occupy more than the calculated size+in an array in memory.+-}+audioBytesPerFrame :: SampleFmt y => SoundFmt y -> Int audioBytesPerFrame fmt = numChannels fmt * audioBytesPerSample fmt -soundSourceBytesPerFrame :: SoundSource h -> Int+soundSourceBytesPerFrame :: SampleFmt y => SoundSource y h -> Int soundSourceBytesPerFrame = audioBytesPerFrame . soundSourceFmt -soundSinkBytesPerFrame :: SoundSink h -> Int+soundSinkBytesPerFrame :: SampleFmt y => SoundSink y h -> Int soundSinkBytesPerFrame = audioBytesPerFrame . soundSinkFmt -soundSourceReadBytes :: SoundSource h -> h -> Ptr () -> Int -> IO Int-soundSourceReadBytes src h buf n =-	liftM (* c) $ soundSourceRead src h buf (n `div` c)-  where c = soundSourceBytesPerFrame src--soundSinkWriteBytes :: SoundSink h -> h -> Ptr () -> Int -> IO ()-soundSinkWriteBytes src h buf n =-	soundSinkWrite src h buf (n `div` c)-  where c = soundSinkBytesPerFrame src--copySound :: SoundSource h1-          -> SoundSink h2-          -> Int -- ^ Buffer size (in bytes) to use+copySound :: SampleFmt y =>+             SoundSource y h1+          -> SoundSink y h2+          -> Int -- ^ Buffer size (in sample frames) to use           -> IO () copySound source sink bufSize =-    allocaBytes     bufSize $ \buf ->+    allocaArray     bufSize $ \buf ->     withSoundSource source  $ \from ->     withSoundSink   sink    $ \to ->-       let loop = do n <- soundSourceReadBytes source from buf bufSize-                     when (n > 0) $ do soundSinkWriteBytes sink to buf n+       let loop = do n <- soundSourceRead source from buf bufSize+                     when (n > 0) $ do soundSinkWrite sink to buf n                                        loop         in loop @@ -165,23 +224,26 @@ --  +debug :: String -> IO () debug s =     do t <- myThreadId-       hPutStrLn stderr $ show t ++ ": " ++ s+       IO.hPutStrLn IO.stderr $ show t ++ ": " ++ s -alsaOpen :: String -- ^ device, e.g @"default"@-	-> SoundFmt -> PcmStream -> IO Pcm-alsaOpen dev fmt stream = rethrowAlsaExceptions $+alsaOpen :: SampleFmt y =>+           String -- ^ device, e.g @"default"@+	-> SoundFmt y+	-> SoundBufferTime+	-> PcmStream+	-> IO Pcm+alsaOpen dev fmt time stream = rethrowAlsaExceptions $     do debug "alsaOpen"        h <- pcm_open dev stream 0-       let buffer_time = 500000 -- 0.5s-           period_time = 100000 -- 0.1s        (buffer_time,buffer_size,period_time,period_size) <--           setHwParams h (sampleFmtToPcmFormat (sampleFmt fmt))+           setHwParams h (withSampleFmt sampleFmtToPcmFormat fmt)                          (numChannels fmt)                          (sampleFreq fmt)-                         buffer_time-                         period_time+                         (bufferTime time)+                         (periodTime time)        setSwParams h buffer_size period_size        pcm_prepare h        debug $ "buffer_time = " ++ show buffer_time@@ -189,21 +251,18 @@        debug $ "period_time = " ++ show period_time        debug $ "period_size = " ++ show period_size        when (stream == PcmStreamPlayback) $-         callocaBytes (audioBytesPerFrame fmt * period_size) $ \buf ->+         callocaArray fmt period_size $ \buf -> 	   do pcm_writei h buf period_size               return ()        return h -sampleFmtToPcmFormat :: SampleFmt -> PcmFormat-sampleFmtToPcmFormat SampleFmtLinear16BitSignedLE = PcmFormatS16Le-sampleFmtToPcmFormat SampleFmtMuLaw8Bit           = PcmFormatMuLaw  setHwParams :: Pcm             -> PcmFormat             -> Int -- ^ number of channels-            -> Int -- ^ sample frequency-            -> Int -- ^ buffer time-            -> Int -- ^ period time+            -> SampleFreq -- ^ sample frequency+            -> Time -- ^ buffer time+            -> Time -- ^ period time             -> IO (Int,Int,Int,Int)                -- ^ (buffer_time,buffer_size,period_time,period_size) setHwParams h format channels rate buffer_time period_time@@ -212,21 +271,22 @@        pcm_hw_params_set_format h p format        pcm_hw_params_set_channels h p channels        pcm_hw_params_set_rate h p rate EQ-       (buffer_time,_) <-+       (actual_buffer_time,_) <-            pcm_hw_params_set_buffer_time_near h p buffer_time EQ        buffer_size <- pcm_hw_params_get_buffer_size p-       (period_time,_) <-+       (actual_period_time,_) <-            pcm_hw_params_set_period_time_near h p period_time EQ        (period_size,_) <- pcm_hw_params_get_period_size p-       return (buffer_time,buffer_size,period_time,period_size)+       return (actual_buffer_time,buffer_size,+               actual_period_time,period_size)  setSwParams :: Pcm             -> Int -- ^ buffer size             -> Int -- ^ period size             -> IO ()-setSwParams h buffer_size period_size = withSwParams h $ \p ->-    do let start_threshold =-               (buffer_size `div` period_size) * period_size+setSwParams h _buffer_size period_size = withSwParams h $ \p ->+    do -- let start_threshold =+       --        (buffer_size `div` period_size) * period_size        --pcm_sw_params_set_start_threshold h p start_threshold        pcm_sw_params_set_start_threshold h p 0        pcm_sw_params_set_avail_min h p period_size@@ -272,96 +332,152 @@     do debug "alsaStop"        pcm_drain pcm -alsaRead :: SoundFmt -> Pcm -> Ptr () -> Int -> IO Int-alsaRead fmt h buf n = rethrowAlsaExceptions $+alsaRead ::+   SampleFmt y =>+   Pcm -> Ptr y -> Int -> IO Int+alsaRead h buf n = rethrowAlsaExceptions $      do --debug $ "Reading " ++ show n ++ " samples..."         n' <- pcm_readi h buf n `catchXRun` handleOverRun         --debug $ "Got " ++ show n' ++ " samples." 	if n' < n-          then do n'' <- alsaRead fmt h (buf `plusPtr` (n' * c)) (n - n')+          then do n'' <- alsaRead h (advancePtr buf n') (n - n') 	          return (n' + n'')           else return n'-  where c = audioBytesPerFrame fmt-        handleOverRun = do debug "snd_pcm_readi reported buffer over-run"+  where handleOverRun = do debug "snd_pcm_readi reported buffer over-run"                            pcm_prepare h-                           alsaRead fmt h buf n+                           alsaRead h buf n -alsaWrite :: SoundFmt -> Pcm -> Ptr () -> Int -> IO ()-alsaWrite fmt h buf n = rethrowAlsaExceptions $-    do alsaWrite_ fmt h buf n+alsaWrite ::+   SampleFmt y =>+   Pcm -> Ptr y -> Int -> IO ()+alsaWrite h buf n = rethrowAlsaExceptions $+    do alsaWrite_ h buf n        return () -alsaWrite_ :: SoundFmt -> Pcm -> Ptr () -> Int -> IO Int-alsaWrite_ fmt h buf n =+alsaWrite_ ::+   SampleFmt y =>+   Pcm -> Ptr y -> Int -> IO Int+alsaWrite_ h buf n =      do --debug $ "Writing " ++ show n ++ " samples..."         n' <- pcm_writei h buf n `catchXRun` handleUnderRun         --debug $ "Wrote " ++ show n' ++ " samples." 	if (n' /= n)-            then do n'' <- alsaWrite_ fmt h (buf `plusPtr` (n' * c)) (n - n')+            then do n'' <- alsaWrite_ h (advancePtr buf n') (n - n')                     return (n' + n'')             else return n'-  where c = audioBytesPerFrame fmt-        handleUnderRun = do debug "snd_pcm_writei reported buffer under-run"+  where handleUnderRun = do debug "snd_pcm_writei reported buffer under-run"                             pcm_prepare h-                            alsaWrite_ fmt h buf n+                            alsaWrite_ h buf n  -alsaSoundSource :: String -> SoundFmt -> SoundSource Pcm+alsaSoundSource ::+   SampleFmt y =>+   String -> SoundFmt y -> SoundSource y Pcm alsaSoundSource dev fmt =     (nullSoundSource fmt) {-                           soundSourceOpen  = alsaOpen dev fmt PcmStreamCapture,-                           soundSourceClose = alsaClose,-                           soundSourceStart = alsaStart,-                           soundSourceStop  = alsaStop,-                           soundSourceRead  = alsaRead fmt-                          }+        soundSourceOpen  = alsaOpen dev fmt defaultBufferTime PcmStreamCapture,+        soundSourceClose = alsaClose,+        soundSourceStart = alsaStart,+        soundSourceStop  = alsaStop,+        soundSourceRead  = alsaRead+    } -alsaSoundSink :: String -> SoundFmt -> SoundSink Pcm+alsaSoundSink ::+   SampleFmt y =>+   String -> SoundFmt y -> SoundSink y Pcm alsaSoundSink dev fmt =     (nullSoundSink fmt) {-                         soundSinkOpen  = alsaOpen dev fmt PcmStreamPlayback,-                         soundSinkClose = alsaClose,-                         soundSinkStart = alsaStart,-                         soundSinkStop  = alsaStop,-                         soundSinkWrite = alsaWrite fmt-                        }+        soundSinkOpen  = alsaOpen dev fmt defaultBufferTime PcmStreamPlayback,+        soundSinkClose = alsaClose,+        soundSinkStart = alsaStart,+        soundSinkStop  = alsaStop,+        soundSinkWrite = alsaWrite+    } +alsaSoundSourceTime ::+   SampleFmt y =>+   String -> SoundFmt y -> SoundBufferTime -> SoundSource y Pcm+alsaSoundSourceTime dev fmt time =+    (nullSoundSource fmt) {+        soundSourceOpen  = alsaOpen dev fmt time PcmStreamCapture,+        soundSourceClose = alsaClose,+        soundSourceStart = alsaStart,+        soundSourceStop  = alsaStop,+        soundSourceRead  = alsaRead+    }++alsaSoundSinkTime ::+   SampleFmt y =>+   String -> SoundFmt y -> SoundBufferTime -> SoundSink y Pcm+alsaSoundSinkTime dev fmt time =+    (nullSoundSink fmt) {+        soundSinkOpen  = alsaOpen dev fmt time PcmStreamPlayback,+        soundSinkClose = alsaClose,+        soundSinkStart = alsaStart,+        soundSinkStop  = alsaStop,+        soundSinkWrite = alsaWrite+    }+ -- -- * File stuff -- -fileRead :: SoundFmt -> Handle -> Ptr () -> Int -> IO Int-fileRead fmt h buf n = liftM (`div` c) $ hGetBuf h buf (n * c)-  where c = audioBytesPerSample fmt+{- |+This expects pad bytes that are needed in memory+in order to satisfy aligment constraints.+This is only a problem for samples sizes like 24 bit.+-}+fileRead ::+   SampleFmt y =>+   Handle -> Ptr y -> Int -> IO Int+fileRead h buf n =+   liftM (`div` arraySize buf 1) $+   IO.hGetBuf h buf (arraySize buf n) -fileWrite :: SoundFmt -> Handle -> Ptr () -> Int -> IO ()-fileWrite fmt h buf n = hPutBuf h buf (n * c)-  where c = audioBytesPerSample fmt+{- |+Same restrictions as for 'fileRead'.+-}+fileWrite ::+   SampleFmt y =>+   Handle -> Ptr y -> Int -> IO ()+fileWrite h buf n =+   IO.hPutBuf h buf (arraySize buf n) -fileSoundSource :: FilePath -> SoundFmt -> SoundSource Handle+fileSoundSource ::+   SampleFmt y =>+   FilePath -> SoundFmt y -> SoundSource y Handle fileSoundSource file fmt =     (nullSoundSource fmt) {                            soundSourceOpen  = openBinaryFile file ReadMode,                            soundSourceClose = hClose,-                           soundSourceRead  = fileRead fmt+                           soundSourceRead  = fileRead                           } -fileSoundSink :: FilePath -> SoundFmt -> SoundSink Handle+fileSoundSink ::+   SampleFmt y =>+   FilePath -> SoundFmt y -> SoundSink y Handle fileSoundSink file fmt =     (nullSoundSink fmt) {                          soundSinkOpen  = openBinaryFile file WriteMode,                          soundSinkClose = hClose,-                         soundSinkWrite = fileWrite fmt+                         soundSinkWrite = fileWrite                         }  -- -- * Marshalling utilities -- -callocaBytes :: Int -> (Ptr a -> IO b) -> IO b-callocaBytes n f = allocaBytes n (\p -> clearBytes p n >> f p)+callocaArray :: Storable y => SoundFmt y -> Int -> (Ptr y -> IO b) -> IO b+callocaArray _ n f =+   allocaArray n $ \p ->+      clearBytes p (arraySize p n) >>+      f p  clearBytes :: Ptr a -> Int -> IO () clearBytes p n = memset p 0 (fromIntegral n) >> return ()++{-# INLINE arraySize #-}+arraySize :: Storable y => Ptr y -> Int -> Int+arraySize p n = advancePtr p n `minusPtr` p  foreign import ccall unsafe "string.h" memset :: Ptr a -> CInt -> CSize -> IO (Ptr a)
Sound/Alsa/Error.hs view
@@ -3,10 +3,11 @@   #-} module Sound.Alsa.Error where -import Control.Exception (catchDyn,throwDyn)-import Data.Typeable-import Foreign.C.Error-import Foreign.C.String+import Control.Exception.Extensible (Exception, throw, catch, )+import Data.Typeable (Typeable, )+import Foreign.C.Error (Errno(Errno), ePIPE, errnoToIOError, )+import Foreign.C.String (CString, peekCString, )+import Prelude hiding (catch, )  data AlsaException =   AlsaException { exception_location    :: String@@ -14,6 +15,16 @@                 , exception_code        :: Errno                 } deriving (Typeable) +instance Show AlsaException where+   showsPrec p (AlsaException l d (Errno c)) =+      showParen (p>10)+         (showString "AlsaException " .+          shows l . showString " " .+          shows d . showString " " .+          showParen True (showString "Errno " . shows c))++instance Exception AlsaException where+ checkResult :: Integral a => String -> a -> IO a checkResult f r   | r < 0 = throwAlsa f (Errno (negate (fromIntegral r)))@@ -24,21 +35,21 @@  throwAlsa :: String -> Errno -> IO a throwAlsa fun err = do d <- strerror err-                       throwDyn AlsaException+                       throw AlsaException                          { exception_location = fun                          , exception_description = d                          , exception_code = err                          }  catchAlsa :: IO a -> (AlsaException -> IO a) -> IO a-catchAlsa = catchDyn+catchAlsa = catch  catchAlsaErrno :: Errno                -> IO a -- ^ Action                -> IO a -- ^ Handler                -> IO a catchAlsaErrno e x h =-    catchAlsa x (\ex -> if exception_code ex == e then h else throwDyn ex)+    catchAlsa x (\ex -> if exception_code ex == e then h else throw ex)  catchXRun :: IO a -- ^ Action           -> IO a -- ^ Handler
Sound/Alsa/Sequencer/Client.hs view
@@ -108,7 +108,7 @@ query_first_client h =   do x <- client_info_malloc      with_client_info x (`snd_seq_client_info_set_client` (-1))-     b <- query_next_client h x+     _b <- query_next_client h x      -- XXX: check that we did get the first client (should be System)      return x 
Sound/Alsa/Sequencer/Errors.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE ForeignFunctionInterface #-} -------------------------------------------------------------------------------- -- | -- Module    : Sound.Alsa.Sequencer.Errors@@ -12,16 +13,18 @@  module Sound.Alsa.Sequencer.Errors where -import Foreign.C.Types(CInt)-import Foreign.C.String(CString,peekCString)-import Control.Exception(throwDyn,catchDyn)-import Data.Word-import Data.Typeable+import Foreign.C.Types (CInt, )+import Foreign.C.String (CString, peekCString, )+import Control.Exception.Extensible (Exception, throw, catch, )+import Data.Word (Word, )+import Data.Typeable (Typeable(typeOf), mkTyCon, mkTyConApp, )+import Prelude hiding (catch, ) + data AlsaException = AlsaException   { exception_code :: !Word           -- ^ the (positive) error code   , exception_description :: !String  -- ^ a text description of the problem-  }+  } deriving Show  instance Eq AlsaException where   x == y = exception_code x == exception_code y@@ -32,6 +35,7 @@ instance Typeable AlsaException where   typeOf _ = mkTyConApp (mkTyCon "Sound.Alsa.Sequencer.AlsaException") [] +instance Exception AlsaException where   -- | Returns the message for an error code.@@ -43,7 +47,7 @@  -- | Catch an exception generated by the binding. alsa_catch :: IO a -> (AlsaException -> IO a) -> IO a-alsa_catch = catchDyn+alsa_catch = catch  check_error :: CInt -> IO Word check_error = check_error' fromIntegral (const Nothing)@@ -54,7 +58,7 @@   | otherwise = case err x of                   Just a -> return a                   _ -> do msg <- strerror x-                          throwDyn AlsaException+                          throw AlsaException                             { exception_code        = fromIntegral (negate x)                             , exception_description = msg                             }
Sound/Alsa/Sequencer/Event.hs view
@@ -99,7 +99,7 @@ event_output (SndSeq h) e =   alloca_ev e $ \p -> check_error =<< snd_seq_event_output h p -foreign import ccall "alsa/asoundlib.h snd_seq_event_output "+foreign import ccall "alsa/asoundlib.h snd_seq_event_output"   snd_seq_event_output :: Ptr SndSeq_ -> Ptr Event -> IO CInt  
alsa.cabal view
@@ -1,14 +1,17 @@ Name: alsa-Version: 0.2-Copyright: Bjorn Bringert, Iavor S. Diatchki-Maintainer: bjorn@bringert.net, iavor.diatchki@gmail.com-Author: Bjorn Bringert, Iavor S. Diatchki+Version: 0.4+Copyright: Bjorn Bringert, Iavor S. Diatchki, Henning Thielemann+Maintainer: Henning Thielemann <alsa@henning-thielemann.de>+Author: Bjorn Bringert <bjorn@bringert.net>, Iavor S. Diatchki <iavor.diatchki@gmail.com> Category: Sound, Music License: BSD3-License-file:   LICENSE+License-file: LICENSE+Homepage: http://www.haskell.org/haskellwiki/ALSA Build-depends:-  base >= 3,-  array >= 0.1 && <0.3+  sample-frame >=0.0.1 && <0.1,+  array >= 0.1 && <0.4,+  extensible-exceptions >=0.1.1 && <0.2,+  base >= 3 && <6 Stability: Experimental Extensions: ForeignFunctionInterface, GeneralizedNewtypeDeriving, EmptyDataDecls Build-Type: Simple