diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,3 +1,4 @@
+Copyright (c) 2009 Henning Thielemann
 Copyright (c) 2006 Bjorn Bringert
 Copyright (c) 2006 Iavor S. Diatchki
 
diff --git a/Sound/Alsa.hs b/Sound/Alsa.hs
--- a/Sound/Alsa.hs
+++ b/Sound/Alsa.hs
@@ -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)
diff --git a/Sound/Alsa/Error.hs b/Sound/Alsa/Error.hs
--- a/Sound/Alsa/Error.hs
+++ b/Sound/Alsa/Error.hs
@@ -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
diff --git a/Sound/Alsa/Sequencer/Client.hs b/Sound/Alsa/Sequencer/Client.hs
--- a/Sound/Alsa/Sequencer/Client.hs
+++ b/Sound/Alsa/Sequencer/Client.hs
@@ -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
 
diff --git a/Sound/Alsa/Sequencer/Errors.hs b/Sound/Alsa/Sequencer/Errors.hs
--- a/Sound/Alsa/Sequencer/Errors.hs
+++ b/Sound/Alsa/Sequencer/Errors.hs
@@ -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
                             }
diff --git a/Sound/Alsa/Sequencer/Event.hs b/Sound/Alsa/Sequencer/Event.hs
--- a/Sound/Alsa/Sequencer/Event.hs
+++ b/Sound/Alsa/Sequencer/Event.hs
@@ -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
 
 
diff --git a/alsa.cabal b/alsa.cabal
--- a/alsa.cabal
+++ b/alsa.cabal
@@ -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
