diff --git a/haskore-realtime.cabal b/haskore-realtime.cabal
--- a/haskore-realtime.cabal
+++ b/haskore-realtime.cabal
@@ -1,12 +1,11 @@
 Name:           haskore-realtime
-Version:        0.0.2
+Version:        0.1
 License:        GPL
 License-File:   LICENSE
 Author:         Henning Thielemann <haskell@henning-thielemann.de>
 Maintainer:     Henning Thielemann <haskell@henning-thielemann.de>
 Homepage:       http://www.haskell.org/haskellwiki/Haskore/
-Package-URL:    http://darcs.haskell.org/haskore-realtime/
-Category:       Sound
+Category:       Sound, Music
 Synopsis:       Routines for realtime playback of Haskore songs
 Description:
   This package contains support for realtime playback of Haskore songs.
@@ -16,23 +15,32 @@
   Thus we have removed this part from core Haskore.
 Stability:      Experimental
 Tested-With:    GHC==6.4.1, GHC==6.8.2
-Cabal-Version:  >=1.2
+Cabal-Version:  >=1.6
 Build-Type:     Simple
 
+Source-Repository head
+  type:     darcs
+  location: http://darcs.haskell.org/haskore-realtime/
+
+Source-Repository this
+  type:     darcs
+  location: http://darcs.haskell.org/haskore-realtime/
+  tag:      0.1
+
 Flag splitBase
   description: Choose the new smaller, split-up base package.
 
 Library
   Build-Depends:
-    haskore >=0.0.5 && <0.1,
+    haskore >=0.1 && <0.2,
     midi >=0.1.1 && <0.2,
     bytestring >=0.9 && <1.0,
     -- dependency on non-negative for Haddock
     non-negative >=0.0.1 && <0.1,
     event-list >=0.0.6 && <0.1,
-    data-accessor >=0.1 && <0.2,
+    data-accessor >=0.2 && <0.3,
     unix >= 2.0 && <3,
-    mtl >=1.0 && <2
+    transformers >=0.0 && <0.2
 
   If flag(splitBase)
     Build-Depends:
diff --git a/src/Haskore/Interface/CSound/Play.hs b/src/Haskore/Interface/CSound/Play.hs
--- a/src/Haskore/Interface/CSound/Play.hs
+++ b/src/Haskore/Interface/CSound/Play.hs
@@ -12,10 +12,10 @@
 import System.IO (IO)
 import qualified System.IO as IO
 import qualified System.Posix.Signals as Signals
-import System.Cmd(system)
-import System.Directory(doesFileExist,removeFile)
+import System.Cmd (system, )
+import System.Directory(doesFileExist, removeFile, )
 
-import           Haskore.Interface.CSound(Name)
+import           Haskore.Interface.CSound (Name, )
 import qualified Haskore.Interface.CSound.Orchestra as Orchestra
 import qualified Haskore.Interface.CSound.Score     as Score
 
diff --git a/src/Haskore/Interface/MIDI/Play.hs b/src/Haskore/Interface/MIDI/Play.hs
--- a/src/Haskore/Interface/MIDI/Play.hs
+++ b/src/Haskore/Interface/MIDI/Play.hs
@@ -33,7 +33,6 @@
 import System.IO (IO)
 import qualified System.IO as IO
 import qualified System.Posix.Signals as Signals
-import Haskore.General.IO (ByteString, stringCharFromByte, )
 
 import qualified Haskore.Music.GeneralMIDI   as MidiMusic
 import qualified Haskore.Music.Rhythmic      as RhyMusic
@@ -47,6 +46,10 @@
 
 import qualified Numeric.NonNegative.Class as NonNeg
 
+import Data.Char (chr, )
+import Data.Word (Word8, )
+
+
 play ::
    (Ord instr, Ord drum,
     NonNeg.C time, RealFrac time, Fractional time, RealFrac dyn) =>
@@ -60,7 +63,7 @@
 playSimple :: MidiMusic.T -> IO ()
 playSimple = playRaw [] . SaveMidi.toByteList . Render.mixedGeneralMidi
 
-playRaw :: [String] -> ByteString -> IO ()
+playRaw :: [String] -> ByteList -> IO ()
 playRaw args stream =
    do
       -- Disable sigPIPE.  This means that the whole program
@@ -77,3 +80,9 @@
           (["timidity", "-B", "8,9"] ++ args ++ ["-"])
       IO.hPutStr input (stringCharFromByte stream)
       IO.hClose input
+
+
+type ByteList = [Word8]
+
+stringCharFromByte :: ByteList -> String
+stringCharFromByte = map (chr . fromIntegral)
diff --git a/src/Haskore/RealTime/EventList/TimeBody.hs b/src/Haskore/RealTime/EventList/TimeBody.hs
--- a/src/Haskore/RealTime/EventList/TimeBody.hs
+++ b/src/Haskore/RealTime/EventList/TimeBody.hs
@@ -29,9 +29,8 @@
 import qualified Numeric.NonNegative.Wrapper as NonNegW
 
 import qualified Control.Monad as Monad
-import Control.Monad.Trans (MonadIO, liftIO)
 
-import Prelude hiding (null, foldr, mapM, mapM_, concat, cycle)
+import Prelude hiding (null, foldr, mapM, mapM_, concat, cycle, )
 
 
 -- * Run actions according to an event list
@@ -43,17 +42,17 @@
 It is not very useful in practice, but very simple.
 -}
 
-runRelative :: (NonNeg.C time, RealFrac time, MonadIO io) =>
-   Timer.T -> (body -> io a) -> T time body -> io [a]
+runRelative :: (NonNeg.C time, RealFrac time, Monad m) =>
+   Timer.T m -> (body -> m a) -> T time body -> m [a]
 runRelative timer action =
    runRelativeCore timer action .
    resample (fromIntegral $ Timer.resolution timer)
 
-runRelativeCore :: MonadIO io =>
-   Timer.T -> (body -> io a) -> T NonNegW.Integer body -> io [a]
+runRelativeCore :: Monad m =>
+   Timer.T m -> (body -> m a) -> T NonNegW.Integer body -> m [a]
 runRelativeCore timer action =
    Monad.liftM getBodies .
-   mapM (liftIO . Timer.wait timer) action
+   mapM (Timer.wait timer) action
 
 {- |
 The next set of routines is more precise.
@@ -67,8 +66,8 @@
 so have to make our ones absolute as well.
 -}
 
-run :: (RealFrac time, MonadIO io) =>
-   Timer.T -> (body -> io a) -> T time body -> io [a]
+run :: (RealFrac time, Monad m) =>
+   Timer.T m -> (body -> m a) -> T time body -> m [a]
 run timer action = runTimeStamp timer (const action)
 
 {- |
@@ -76,8 +75,8 @@
 but the time passed to the action is not quantized.
 -}
 
-runTimeStamp :: (RealFrac time, MonadIO io) =>
-   Timer.T -> (time -> body -> io a) -> T time body -> io [a]
+runTimeStamp :: (RealFrac time, Monad m) =>
+   Timer.T m -> (time -> body -> m a) -> T time body -> m [a]
 runTimeStamp =
    runCore id
 
@@ -88,23 +87,23 @@
 That is, collectCoincident will split events which actually belong together.
 -}
 
-runTimeStampGrouped :: (RealFrac time, MonadIO io) =>
-   Timer.T -> (time -> [body] -> io a) -> T time body -> io [a]
+runTimeStampGrouped :: (RealFrac time, Monad m) =>
+   Timer.T m -> (time -> [body] -> m a) -> T time body -> m [a]
 runTimeStampGrouped =
    runCore AbsList.collectCoincident
 
-runCore :: (Fractional time0, RealFrac time1, MonadIO io) =>
+runCore :: (Fractional time0, RealFrac time1, Monad m) =>
    (AbsList.T time0 body0 -> AbsList.T time1 body1) ->
-   Timer.T -> (time1 -> body1 -> io a) -> T time0 body0 -> io [a]
+   Timer.T m -> (time1 -> body1 -> m a) -> T time0 body0 -> m [a]
 runCore convertAbs timer action evs =
    Monad.liftM AbsList.getBodies .
    AbsList.mapM
-      (liftIO . Timer.waitUntilSeconds timer)
+      (Timer.waitUntilSeconds timer)
       (uncurry action) .
    attachTime .
    convertAbs .
    flip toAbsoluteEventList evs =<<
-   liftIO (Timer.getTimeSeconds timer)
+   Timer.getTimeSeconds timer
 
 {- |
 We export this function only for use in "Haskore.RealTime.EventList.TimeTime".
diff --git a/src/Haskore/RealTime/EventList/TimeTime.hs b/src/Haskore/RealTime/EventList/TimeTime.hs
--- a/src/Haskore/RealTime/EventList/TimeTime.hs
+++ b/src/Haskore/RealTime/EventList/TimeTime.hs
@@ -37,46 +37,45 @@
 -- import qualified Numeric.NonNegative.Wrapper as NonNegW
 
 import qualified Control.Monad as Monad
-import Control.Monad.Trans (MonadIO, liftIO)
 
 import Prelude hiding (concat, filter, foldr, mapM, mapM_)
 
 
 
-runRelative :: (NonNeg.C time, RealFrac time, MonadIO io) =>
-   Timer.T -> (body -> io a) -> T time body -> io [a]
+runRelative :: (NonNeg.C time, RealFrac time, Monad m) =>
+   Timer.T m -> (body -> m a) -> T time body -> m [a]
 runRelative timer action =
    Monad.liftM getBodies .
-   mapM (liftIO . Timer.wait timer) action .
+   mapM (Timer.wait timer) action .
    resample (fromIntegral $ Timer.resolution timer)
 
 
-run :: (RealFrac time, MonadIO io) =>
-   Timer.T -> (body -> io a) -> T time body -> io [a]
+run :: (RealFrac time, Monad m) =>
+   Timer.T m -> (body -> m a) -> T time body -> m [a]
 run timer action = runTimeStamp timer (const action)
 
-runTimeStamp :: (RealFrac time, MonadIO io) =>
-   Timer.T -> (time -> body -> io a) -> T time body -> io [a]
+runTimeStamp :: (RealFrac time, Monad m) =>
+   Timer.T m -> (time -> body -> m a) -> T time body -> m [a]
 runTimeStamp =
    runCore id
 
-runTimeStampGrouped :: (RealFrac time, MonadIO io) =>
-   Timer.T -> (time -> [body] -> io a) -> T time body -> io [a]
+runTimeStampGrouped :: (RealFrac time, Monad m) =>
+   Timer.T m -> (time -> [body] -> m a) -> T time body -> m [a]
 runTimeStampGrouped =
    runCore AbsList.collectCoincident
 
-runCore :: (Fractional time0, RealFrac time1, MonadIO io) =>
+runCore :: (Fractional time0, RealFrac time1, Monad m) =>
    (AbsList.T time0 body0 -> AbsList.T time1 body1) ->
-   Timer.T -> (time1 -> body1 -> io a) -> T time0 body0 -> io [a]
+   Timer.T m -> (time1 -> body1 -> m a) -> T time0 body0 -> m [a]
 runCore convertAbs timer action evs =
    Monad.liftM AbsList.getBodies .
    AbsList.mapM
-      (liftIO . Timer.waitUntilSeconds timer)
+      (Timer.waitUntilSeconds timer)
       (uncurry action) .
    attachTime .
    convertAbs .
    flip toAbsoluteEventList evs =<<
-   liftIO (Timer.getTimeSeconds timer)
+   Timer.getTimeSeconds timer
 
 attachTime :: AbsList.T time body -> AbsList.T time (time, body)
 attachTime =
diff --git a/src/Haskore/RealTime/Timer.hs b/src/Haskore/RealTime/Timer.hs
--- a/src/Haskore/RealTime/Timer.hs
+++ b/src/Haskore/RealTime/Timer.hs
@@ -1,21 +1,30 @@
 module Haskore.RealTime.Timer where
 
-import System.Time(ClockTime(TOD))
-import Control.Monad(replicateM_)
+import System.Time (ClockTime(TOD))
+import Control.Monad (liftM, replicateM_, )
 
+import qualified Control.Monad.Trans as Trans
+
 import qualified Numeric.NonNegative.Wrapper as NonNeg
 -- import Numeric.NonNegative.Class ((-|))
 
 
-data T = Cons {
-     getClockTime :: IO ClockTime,
-     waitInt      :: NonNeg.Int -> IO (),
+data T m = Cons {
+     getClockTime :: m ClockTime,
+     waitInt      :: NonNeg.Int -> m (),
      resolution   :: NonNeg.Integer
   }
 
-getTime :: T -> IO Integer
+lift :: (Trans.MonadTrans t, Monad m) => T m -> T (t m)
+lift (Cons g w r) = Cons (Trans.lift g) (Trans.lift . w) r
+
+liftIO :: Trans.MonadIO io => T IO -> T io
+liftIO (Cons g w r) = Cons (Trans.liftIO g) (Trans.liftIO . w) r
+
+
+getTime :: (Monad m) => T m -> m Integer
 getTime timer =
-   fmap (clockTimeToWaitTime (resolution timer)) $
+   liftM (clockTimeToWaitTime (resolution timer)) $
    getClockTime timer
 
 clockTimeToWaitTime :: NonNeg.Integer -> ClockTime -> Integer
@@ -23,10 +32,10 @@
    let res = NonNeg.toNumber res0
    in  secs * res + div (picos * res) (10^(12::Int))
 
-getTimeSeconds :: Fractional time =>
-   T -> IO time
+getTimeSeconds :: (Fractional time, Monad m) =>
+   T m -> m time
 getTimeSeconds timer =
-   fmap clockTimeToSeconds $
+   liftM clockTimeToSeconds $
    getClockTime timer
 
 clockTimeToSeconds :: Fractional time => ClockTime -> time
@@ -37,7 +46,7 @@
 The range of 32 bit Ints does not suffice for waiting an hour
 measured in microseconds.
 -}
-wait :: T -> NonNeg.Integer -> IO ()
+wait :: (Monad m) => T m -> NonNeg.Integer -> m ()
 wait timer time =
    let blockSize = maxBound
        {- Negative delays can occur if multiple events should be scheduled
@@ -54,12 +63,12 @@
        replicateM_ (fromIntegral reps) (waitInt timer blockSize) >>
        waitInt timer (fromIntegral remainder)
 
-waitUntil :: T -> Integer -> IO ()
+waitUntil :: (Monad m) => T m -> Integer -> m ()
 waitUntil timer time =
    do tcur <- getTime timer
       wait timer (NonNeg.fromNumberClip (time - tcur))
 
-waitUntilSeconds :: (RealFrac time) =>
-   T -> time -> IO ()
+waitUntilSeconds :: (RealFrac time, Monad m) =>
+   T m -> time -> m ()
 waitUntilSeconds timer time =
    waitUntil timer (floor (time * fromIntegral (resolution timer)))
diff --git a/src/Haskore/RealTime/Timer/Immediate.hs b/src/Haskore/RealTime/Timer/Immediate.hs
--- a/src/Haskore/RealTime/Timer/Immediate.hs
+++ b/src/Haskore/RealTime/Timer/Immediate.hs
@@ -10,16 +10,16 @@
 import qualified Numeric.NonNegative.Wrapper as NonNeg
 
 
-timer :: Timer.T
+timer :: (Monad m) => Timer.T m
 timer = Timer.Cons getClockTime wait resolution
 
-getClockTime :: IO ClockTime
+getClockTime :: (Monad m) => m ClockTime
 getClockTime = return $ TOD 0 0
 
 {- |
 Wait the given number of @(recip resolution)@ seconds.
 -}
-wait :: NonNeg.Int -> IO ()
+wait :: (Monad m) => NonNeg.Int -> m ()
 wait _ = return ()
 
 resolution :: Num a => a
diff --git a/src/Haskore/RealTime/Timer/Posix.hs b/src/Haskore/RealTime/Timer/Posix.hs
--- a/src/Haskore/RealTime/Timer/Posix.hs
+++ b/src/Haskore/RealTime/Timer/Posix.hs
@@ -7,7 +7,7 @@
 import qualified Numeric.NonNegative.Wrapper as NonNeg
 
 
-timer :: Timer.T
+timer :: Timer.T IO
 timer = Timer.Cons getClockTime wait resolution
 
 
diff --git a/src/Haskore/RealTime/Timer/Thread.hs b/src/Haskore/RealTime/Timer/Thread.hs
--- a/src/Haskore/RealTime/Timer/Thread.hs
+++ b/src/Haskore/RealTime/Timer/Thread.hs
@@ -9,7 +9,7 @@
 import qualified Numeric.NonNegative.Wrapper as NonNeg
 
 
-timer :: Timer.T
+timer :: Timer.T IO
 timer = Timer.Cons getClockTime wait resolution
 
 
