diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 .PHONY:	ghci jack jack-rt supercollider supercollider-rt scj
 
 ghci:
-	ghci -i:src
+	ghci -i:src src/Haskore/Interface/SuperCollider/Example.hs
 
 jack:
 # -n 2 is default, larger values are not supported
diff --git a/haskore-supercollider.cabal b/haskore-supercollider.cabal
--- a/haskore-supercollider.cabal
+++ b/haskore-supercollider.cabal
@@ -1,11 +1,10 @@
 Name:           haskore-supercollider
-Version:        0.0.2
+Version:        0.1
 License:        GPL
 License-File:   LICENSE
 Author:         Henning Thielemann <haskell@henning-thielemann.de>
 Homepage:       http://www.haskell.org/haskellwiki/SuperCollider
-Package-URL:    http://darcs.haskell.org/haskore-supercollider/
-Category:       Sound
+Category:       Sound, Music
 Synopsis:       Haskore back-end for SuperCollider
 Description:
   This package lets you play Haskore music via Supercollider
@@ -14,13 +13,21 @@
   We support realtime replay and rendering to disk.
 Stability:      Experimental
 Tested-With:    GHC==6.4.1, GHC==6.8.2
-Cabal-Version:  >=1.2
+Cabal-Version:  >=1.6
 Build-Type:     Simple
-
 Extra-Source-Files:
   Makefile
   Readme
 
+Source-Repository head
+  type:     darcs
+  location: http://darcs.haskell.org/haskore-supercollider/
+
+Source-Repository this
+  type:     darcs
+  location: http://darcs.haskell.org/haskore-supercollider/
+  tag:      0.1
+
 Flag splitBase
   description: Choose the new smaller, split-up base package.
 
@@ -30,21 +37,27 @@
 
 Library
   Build-Depends:
-    haskore-realtime >= 0.0.2 && < 0.1,
-    haskore >=0.0.5 && <0.1,
+    haskore-realtime >= 0.1 && < 0.2,
+    haskore >=0.1 && <0.2,
     -- for SuperCollider support
-    hosc >=0.1 && <0.2, hsc3 >=0.1 && <0.2, supercollider-ht >=0.0 && <0.1,
+    hosc >=0.6 && <0.7, hsc3 >=0.6 && <0.7,
+    opensoundcontrol-ht >=0.1 && <0.2, supercollider-ht >=0.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,
+    utility-ht >=0.0.3 && <0.1,
     unix >= 2.0 && <3,
-    mtl >=1.0 && <2
+    transformers >=0.0 && <0.2
 
   If flag(splitBase)
     Build-Depends:
-      base >= 3, random >= 1.0 && < 1.1, array >= 0.1 && < 1, process >= 1.0 && < 1.1
+      base >= 3,
+      array >= 0.1 && <1.0,
+      containers >=0.1 && <1.0,
+      random >= 1.0 && <2.0,
+      process >= 1.0 && <1.1
   Else
     Build-Depends:
       base >= 1.0 && < 2
@@ -71,6 +84,11 @@
     Haskore.Interface.SuperCollider.Schedule.Install,
     Haskore.Interface.SuperCollider.Schedule.Channel
   Other-modules:
+    Haskore.Interface.SuperCollider.Timer,
+    Haskore.General.IdGenerator,
+    Haskore.General.IdGenerator.Modulo,
+    Haskore.General.IdGenerator.Set,
+    Haskore.General.IdGenerator.Simple,
     Haskore.Interface.SuperCollider.Example.Air,
     Haskore.Interface.SuperCollider.Example.Morph
 
diff --git a/src/Haskore/General/IdGenerator.hs b/src/Haskore/General/IdGenerator.hs
new file mode 100644
--- /dev/null
+++ b/src/Haskore/General/IdGenerator.hs
@@ -0,0 +1,85 @@
+{- | Identifier generator
+
+Generates unique elements but elements can be declared as unused, again.
+
+-}
+
+module Haskore.General.IdGenerator where
+
+import Data.Set (Set)
+import qualified Data.Set as Set
+import Control.Monad.Trans.State(State, state, evalState, modify, get, )
+import Control.Monad (when, )
+import Data.Tuple.HT (mapFst, )
+
+{- |
+
+The generator is a state monad
+where the state consists of the set of the explicitly unused elements
+and a lower bound for another set of ids that are still unused.
+Essentially, the Set stores all recycled ids,
+and the lower bound stores the ids not used so far.
+All elements in the explicit set must be below the bound.
+
+-}
+
+type T i a = State (St i) a
+
+type St i = (Set i, i)
+
+run :: i -> T i a -> a
+run start gen = evalState gen (Set.empty, start)
+
+{- |
+
+Reserve a new id.
+
+-}
+
+alloc :: (Ord i, Enum i) => T i i
+alloc =
+   state $ \(set, next) ->
+      if Set.null set
+        then (next, (set, succ next))
+        else let (newId, newSet) = Set.deleteFindMin set
+             in  (newId, (newSet, next))
+
+{- |
+
+Return an id.
+
+We call reduce in order to prevent the set from growing too much.
+We call it only once in order to prevent a heavy CPU lead
+when the last id of a sequence is returned.
+So the reduction is spread over several calls to 'free'.
+
+-}
+
+free :: (Ord i, Enum i) => i -> T i ()
+free oldId =
+   do s <- get
+      when (isFree s oldId)
+           (error "IdGenerator.free: id freed twice")
+      modify (mapFst (Set.insert oldId))
+      modify reduce
+
+{- |
+
+If the largest free id and the lower bound of free ids are successive elements
+then we can decrease the lower bound.
+This procedure can be iterated.
+This way we can save storage in the set.
+
+-}
+
+reduce :: (Ord i, Enum i) => St i -> St i
+reduce (set, next) =
+   if not (Set.null set) && Set.findMax set == pred next
+     then (Set.deleteMax set, pred next)
+     else (set, next)
+
+isFree :: (Ord i) => St i -> i -> Bool
+isFree (set,next) i = Set.member i set || i >= next
+
+isValid :: (Ord i) => St i -> Bool
+isValid (set,next) = Set.findMax set < next
diff --git a/src/Haskore/General/IdGenerator/Modulo.hs b/src/Haskore/General/IdGenerator/Modulo.hs
new file mode 100644
--- /dev/null
+++ b/src/Haskore/General/IdGenerator/Modulo.hs
@@ -0,0 +1,43 @@
+{- | Identifier generator
+
+A simple test of whether identifiers can be re-used in SuperCollider.
+This has no practical use.
+
+-}
+
+module Haskore.General.IdGenerator.Modulo where
+
+import Control.Monad.Trans.State (State, evalState, modify, get, )
+
+{- |
+
+The generator is a simple state monad.
+
+-}
+
+type T i a = State i a
+
+run :: i -> T i a -> a
+run = flip evalState
+
+{- |
+
+Reserve a new id.
+
+-}
+
+alloc :: (Integral i) => T i i
+alloc =
+   do newId <- get
+      modify (flip mod 50 . succ)
+      return (newId+2)
+
+{- |
+
+Unreserve an id.
+In this implementation it performs essentially nothing.
+
+-}
+
+free :: i -> T i ()
+free _ = return ()
diff --git a/src/Haskore/General/IdGenerator/Set.hs b/src/Haskore/General/IdGenerator/Set.hs
new file mode 100644
--- /dev/null
+++ b/src/Haskore/General/IdGenerator/Set.hs
@@ -0,0 +1,52 @@
+{- | Identifier generator
+
+Generates unique elements but elements can be declared as unused, again.
+
+-}
+
+module Haskore.General.IdGenerator.Set where
+
+import Data.Set (Set)
+import qualified Data.Set as Set
+import Control.Monad.Trans.RWS(RWS, evalRWS, modify, get, ask, )
+import Control.Monad (when, )
+
+{- |
+
+The generator is a reader+state monad
+where the state consists of the allocated identifiers
+and the reader source is the least element ever used.
+
+-}
+
+type T i a = RWS i () (Set i) a
+
+run :: i -> T i a -> a
+run start gen = fst $ evalRWS gen start Set.empty
+
+{- |
+
+Reserve a new id.
+
+-}
+
+alloc :: (Ord i, Enum i) => T i i
+alloc =
+   do start <- ask
+      allocated <- get
+      let newId = head $ filter (not . flip Set.member allocated) [start ..]
+      modify (Set.insert newId)
+      return newId
+
+{- |
+
+Deallocate an id.
+
+-}
+
+free :: (Ord i, Enum i) => i -> T i ()
+free oldId =
+   do allocated <- get
+      when (not $ Set.member oldId allocated)
+           (error "IdGeneratorSet.free: deallocated free identifier")
+      modify (Set.delete oldId)
diff --git a/src/Haskore/General/IdGenerator/Simple.hs b/src/Haskore/General/IdGenerator/Simple.hs
new file mode 100644
--- /dev/null
+++ b/src/Haskore/General/IdGenerator/Simple.hs
@@ -0,0 +1,46 @@
+{- | Identifier generator
+
+Generates unique elements without recycling of identifiers.
+
+-}
+
+module Haskore.General.IdGenerator.Simple where
+
+import Control.Monad.Trans.State (State, evalState, modify, get, )
+import Control.Monad (when, )
+
+{- |
+
+The generator is a simple state monad.
+
+-}
+
+type T i a = State i a
+
+run :: i -> T i a -> a
+run = flip evalState
+
+{- |
+
+Reserve a new id.
+
+-}
+
+alloc :: (Enum i) => T i i
+alloc =
+   do newId <- get
+      modify succ
+      return newId
+
+{- |
+
+Unreserve an id.
+In this implementation it performs essentially nothing.
+
+-}
+
+free :: (Ord i) => i -> T i ()
+free oldId =
+   do freeId <- get
+      when (freeId <= oldId)
+           (error "IdGeneratorSimple.free: freed unreserved id")
diff --git a/src/Haskore/Interface/SuperCollider/Channel/State.hs b/src/Haskore/Interface/SuperCollider/Channel/State.hs
--- a/src/Haskore/Interface/SuperCollider/Channel/State.hs
+++ b/src/Haskore/Interface/SuperCollider/Channel/State.hs
@@ -4,8 +4,8 @@
 -}
 module Haskore.Interface.SuperCollider.Channel.State where
 
-import qualified Control.Monad.State as State
-import Control.Monad.State (StateT)
+import qualified Control.Monad.Trans.State as State
+import Control.Monad.Trans.State (StateT)
 
 import qualified Haskore.Interface.SuperCollider.Channel as ChannelMng
 import Haskore.Interface.SuperCollider.Channel
diff --git a/src/Haskore/Interface/SuperCollider/Note.hs b/src/Haskore/Interface/SuperCollider/Note.hs
--- a/src/Haskore/Interface/SuperCollider/Note.hs
+++ b/src/Haskore/Interface/SuperCollider/Note.hs
@@ -12,9 +12,11 @@
 
 import qualified Numeric.NonNegative.Wrapper as NonNeg
 
-import Haskore.General.Utility
-          (compareRecord, compareField, equalRecord, equalField)
+import qualified Data.Record.HT as Record
+import Data.Ord.HT (comparing, )
+import Data.Eq.HT  (equating, )
 
+
 data T =
    Cons {
      parameters  :: [Attribute],
@@ -32,15 +34,15 @@
 
 instance Eq T where
    (==) =
-      equalRecord
-         [equalField pitch,
-          equalField velocity]
+      Record.equal
+         [equating pitch,
+          equating velocity]
 
 instance Ord T where
    compare =
-      compareRecord
-         [compareField pitch,
-          compareField velocity]
+      Record.compare
+         [comparing pitch,
+          comparing velocity]
 
 type FromNote dyn note =
         dyn -> Pitch.Relative -> note -> T
diff --git a/src/Haskore/Interface/SuperCollider/Play.hs b/src/Haskore/Interface/SuperCollider/Play.hs
--- a/src/Haskore/Interface/SuperCollider/Play.hs
+++ b/src/Haskore/Interface/SuperCollider/Play.hs
@@ -25,23 +25,23 @@
 
 -- import Sound.SC3.UGen.UGen (UGen)
 
-import Sound.OpenSoundControl.Transport (Transport)
 import qualified Sound.OpenSoundControl.Transport.Monad as Trans
--- import qualified Sound.OpenSoundControl.Transport.UDP      as UDP
--- import qualified Sound.OpenSoundControl.UDPMonad as UDP
-import Sound.OpenSoundControl.OSC (OSC)
+import Sound.OpenSoundControl.OSC (OSC(Bundle))
+import qualified Sound.OpenSoundControl.Time as OSCTime
 
+
 import qualified Haskore.Melody            as Melody
 -- import qualified Haskore.Music.Rhythmic    as RhyMusic
 import qualified Haskore.Music             as Music
 
-import qualified Haskore.RealTime.EventList.TimeBody    as TimeList
+import qualified Haskore.Interface.SuperCollider.Timer as SCTimer
+import qualified Haskore.RealTime.Timer                as Timer
+import qualified Haskore.RealTime.EventList.TimeBody   as TimeList
 
-import qualified Haskore.RealTime.Timer           as Timer
-import qualified Haskore.RealTime.Timer.Thread    as TimerThread
+import qualified Numeric.NonNegative.Wrapper as NonNeg
 
--- import Control.Monad.Trans (liftIO)
--- import Control.Monad (when)
+import Control.Monad.Trans (MonadIO, )
+import Control.Monad (liftM, )
 
 
 
@@ -83,14 +83,14 @@
    Schedule.fromMelody sound
 
 
-performanceTrans :: Transport t =>
+performanceTrans :: (Trans.C m, MonadIO m) =>
    Time ->
    [OSC] ->
    SCPf.T Time ->
-   Trans.IO t ()
+   m ()
 performanceTrans latency installMsgs =
    scheduleWithPlayer
-      (messagesGrouped TimerThread.timer latency) .
+      (messagesGrouped SCTimer.timer latency) .
    Schedule.fromPerformance installMsgs []
 
 performance ::
@@ -110,7 +110,7 @@
 schedule latency =
    SCPlay.withSC3 .
    scheduleWithPlayer
-      (messagesGrouped TimerThread.timer latency)
+      (messagesGrouped SCTimer.timer latency)
 
 
 shutUp :: IO ()
@@ -131,23 +131,23 @@
 
 -- should be moved to Hsc or supercollider-ht
 timeStamp :: Time -> Time -> [OSC] -> OSC
-timeStamp start t = Schedule.timeStamp (start+t)
+timeStamp start t = Bundle $ OSCTime.UTCr $ NonNeg.toNumber (start+t)
 
 
 installSound ::
-   (Transport t, SoundMap.SoundParameters params) =>
+   (Trans.C m, SoundMap.SoundParameters params) =>
    String ->
    Sound params ->
-   Trans.IO t ()
+   m ()
 installSound name instr =
    SCPlay.simpleSync $ Schedule.installSoundMsg name Schedule.defaultChannel instr
 
 
-playAtom :: Transport t =>
+playAtom :: Trans.C m =>
       SCPlay.NodeId
    -> String
    -> [(String,Double)]
-   -> Trans.IO t ()
+   -> m ()
 playAtom sid name params =
    Trans.send (Schedule.atomPlayMsg sid name params)
 
@@ -186,10 +186,10 @@
 
 -}
 
-scheduleWithPlayer :: Transport t =>
-   (TimeList.T Time OSC -> Trans.IO t ()) ->
+scheduleWithPlayer :: Trans.C m =>
+   (TimeList.T Time OSC -> m ()) ->
    Schedule.T ->
-   Trans.IO t ()
+   m ()
 scheduleWithPlayer player sc =
    do {- both variants do only work,
          if only synchronous commands are contained -}
@@ -218,12 +218,12 @@
 that is, the maximal expected delay of creating and sending messages
 to the SuperCollider server.
 -}
-messagesGrouped :: Transport t =>
-   Timer.T ->
+messagesGrouped :: (Trans.C m) =>
+   Timer.T m ->
    Time ->
-   TimeList.T Time OSC -> Trans.IO t ()
+   TimeList.T Time OSC -> m ()
 messagesGrouped timer latency =
-   fmap (const ()) .
+   liftM (const ()) .
    TimeList.runTimeStampGrouped timer
       (\time -> Trans.send . timeStamp latency time)
 {-
@@ -237,12 +237,12 @@
 This results in splitted events which actually should occur at the same time.
 This makes SuperCollider switching the order messages in certain occasions.
 -}
-messagesGroupedManual :: Transport t =>
-   Timer.T ->
+messagesGroupedManual :: (Trans.C m) =>
+   Timer.T m ->
    Time ->
-   TimeList.T Time OSC -> Trans.IO t ()
+   TimeList.T Time OSC -> m ()
 messagesGroupedManual timer latency =
-   fmap (const ()) .
+   liftM (const ()) .
    -- (\ pf -> liftIO Timer.getTimeSeconds >>= \startTime ->
    TimeList.runTimeStamp timer
       (\time ->
@@ -258,22 +258,22 @@
          (Trans.send . timeStamp latency time)) -- pf)
      . TimeList.collectCoincident
 
-messagesSingly :: Transport t =>
-   Timer.T ->
+messagesSingly :: (Trans.C m) =>
+   Timer.T m ->
    Time ->
-   TimeList.T Time OSC -> Trans.IO t ()
+   TimeList.T Time OSC -> m ()
 messagesSingly timer latency =
-   fmap (const ()) .
+   liftM (const ()) .
    TimeList.runTimeStamp timer
       (\time ->
          -- (liftIO $ print $ eventToMark e) >>
          (Trans.send . timeStamp latency time . (:[])))
 
 
-messagesSimple :: Transport t =>
-   Timer.T ->
+messagesSimple :: (Trans.C m) =>
+   Timer.T m ->
    TimeList.T Time OSC ->
-   Trans.IO t ()
+   m ()
 messagesSimple timer =
-   fmap (const ()) .
+   liftM (const ()) .
    TimeList.run timer Trans.send
diff --git a/src/Haskore/Interface/SuperCollider/Play/Channel.hs b/src/Haskore/Interface/SuperCollider/Play/Channel.hs
--- a/src/Haskore/Interface/SuperCollider/Play/Channel.hs
+++ b/src/Haskore/Interface/SuperCollider/Play/Channel.hs
@@ -20,8 +20,7 @@
 
 import Sound.OpenSoundControl.Transport (Transport)
 import Sound.OpenSoundControl.Transport.UDP  (UDP)
-import Sound.OpenSoundControl.Transport.File (File)
-import qualified Sound.OpenSoundControl.Transport.Monad as Trans
+import qualified Sound.OpenSoundControl.Transport.File  as File
 
 import qualified Haskore.Interface.SuperCollider.Channel.State as ChannelState
 import qualified Haskore.Interface.SuperCollider.Channel as Channel
@@ -45,14 +44,15 @@
 import           Haskore.Music.Rhythmic (qn)
 import           Haskore.Melody         as Melody
 
-import qualified Haskore.RealTime.Timer.Thread    as TimerThread
--- import qualified Haskore.RealTime.Timer.Immediate as TimerImmediate
+import qualified Haskore.Interface.SuperCollider.Timer as SCTimer
 
 import qualified Haskore.General.IdGenerator      as IdGen
 
-import qualified Control.Monad.State as State
-import Control.Monad.State  (StateT, evalStateT, lift, liftM2)
-import Control.Monad.Reader (ReaderT)
+import qualified Control.Monad.Trans.State as State
+import Control.Monad.Trans.State  (StateT, evalStateT, )
+import Control.Monad.Trans.Reader (ReaderT, )
+import Control.Monad.Trans (lift, )
+import Control.Monad (liftM2, )
 
 
 
@@ -122,7 +122,7 @@
              always adds new nodes to the head.
              This way, the effect is run after the instrument nodes. -}
           Play.scheduleWithPlayer
-             (Play.messagesGrouped TimerThread.timer Play.defaultLatency)
+             (Play.messagesGrouped SCTimer.timer Play.defaultLatency)
              (Schedule.fromPerformance
                 [Schedule.installUGenMsg effectsName
                     Schedule.defaultChannel effect]
@@ -135,7 +135,7 @@
 run act =
    SCPlay.withSC3 (evalStateT act Channel.least)
 
-writeScript :: FilePath -> Environment File a -> IO a
+writeScript :: FilePath -> Environment File.T a -> IO a
 writeScript fn act =
    SCPlay.withSC3File fn (evalStateT act Channel.least)
 
diff --git a/src/Haskore/Interface/SuperCollider/Play/Install.hs b/src/Haskore/Interface/SuperCollider/Play/Install.hs
--- a/src/Haskore/Interface/SuperCollider/Play/Install.hs
+++ b/src/Haskore/Interface/SuperCollider/Play/Install.hs
@@ -16,7 +16,6 @@
 
 import Sound.SC3.UGen.UGen (UGen)
 
-import Sound.OpenSoundControl.Transport (Transport)
 import qualified Sound.OpenSoundControl.Transport.Monad as Trans
 
 import Haskore.Interface.SuperCollider.Schedule.Install
@@ -37,48 +36,49 @@
 import qualified Haskore.Music          as Music
 import           Haskore.Melody         as Melody
 
+import Control.Monad.Trans (MonadIO, )
 
 
 installSound ::
-   (Transport t, SoundMap.SoundParameters params) =>
+   (Trans.C m, SoundMap.SoundParameters params) =>
    (parameterTuple -> AttributeList, graph -> SoundMap.Sound params) ->
    String ->
    graph ->
-   Trans.IO t (Sound params parameterTuple)
+   m (Sound params parameterTuple)
 installSound (makeAttributeList, makeSoundUGen) name instr =
    Play.installSound name (makeSoundUGen instr) >>
    return (Sound name makeAttributeList)
 
 
 installSound0 ::
-   (Transport t, SoundMap.SoundParameters params) =>
+   (Trans.C m, SoundMap.SoundParameters params) =>
    String ->
    SoundMap.Sound params ->
-   Trans.IO t (Sound params ())
+   m (Sound params ())
 installSound0 =
    installSound SoundMap.with0Attributes
 
 installSound1 ::
-   (Transport t, SoundMap.SoundParameters params) =>
+   (Trans.C m, SoundMap.SoundParameters params) =>
    String ->
    (UGen -> SoundMap.Sound params) ->
-   Trans.IO t (Sound params Double)
+   m (Sound params Double)
 installSound1 =
    installSound SoundMap.with1Attribute
 
 installSound2 ::
-   (Transport t, SoundMap.SoundParameters params) =>
+   (Trans.C m, SoundMap.SoundParameters params) =>
    String ->
    (UGen -> UGen -> SoundMap.Sound params) ->
-   Trans.IO t (Sound params (Double,Double))
+   m (Sound params (Double,Double))
 installSound2 =
    installSound SoundMap.with2Attributes
 
 
 
 
-playMusic :: Transport t =>
-   RhyMusic.T DrumAttributes InstrumentAttributes -> Trans.IO t ()
+playMusic :: (Trans.C m, MonadIO m) =>
+   RhyMusic.T DrumAttributes InstrumentAttributes -> m ()
 playMusic =
    Play.performanceTrans Play.defaultLatency [] .
    SCPf.fixNodeIds .
diff --git a/src/Haskore/Interface/SuperCollider/Play/Life.hs b/src/Haskore/Interface/SuperCollider/Play/Life.hs
--- a/src/Haskore/Interface/SuperCollider/Play/Life.hs
+++ b/src/Haskore/Interface/SuperCollider/Play/Life.hs
@@ -59,7 +59,7 @@
 import qualified Haskore.Basic.Duration as Dur
 import           Haskore.Basic.Duration ((%+))
 
-import qualified Haskore.RealTime.Timer.Thread    as TimerThread
+import qualified Haskore.Interface.SuperCollider.Timer as SCTimer
 
 import qualified Haskore.General.IdGenerator      as IdGen
 
@@ -152,7 +152,7 @@
       let numChan = SCPlay.mceDegree ugen
       chan <- Channel.next ChannelEnv.manager numChan
       SCPlay.withSC3 $
-         SCPlay.simpleSync $ SCPlay.d_recv' name $
+         SCPlay.simpleSync $ SCPlay.d_recv_synthdef name $
          SCIO.out (SCUGen.Constant (fromIntegral chan)) ugen
       return (chan, numChan)
 
@@ -226,7 +226,7 @@
              always adds new nodes to the head.
              This way, the effect is run after the instrument nodes. -}
           Play.scheduleWithPlayer
-             (Play.messagesGrouped TimerThread.timer Play.defaultLatency)
+             (Play.messagesGrouped SCTimer.timer Play.defaultLatency)
              (Schedule.fromPerformance
                 [Schedule.installUGenMsg effectsName
                     Schedule.defaultChannel effect]
@@ -268,14 +268,14 @@
 -}
 playKeyboard :: ISched.Instrument () -> IO ()
 playKeyboard instr =
-   let recurse =
+   let recourse =
           do char <- getChar
              if char == '\004'
                then putStrLn ""
                else do putChar '\008'
                        playKey instr char
-                       recurse
-   in  recurse
+                       recourse
+   in  recourse
 
 
 
diff --git a/src/Haskore/Interface/SuperCollider/Render.hs b/src/Haskore/Interface/SuperCollider/Render.hs
--- a/src/Haskore/Interface/SuperCollider/Render.hs
+++ b/src/Haskore/Interface/SuperCollider/Render.hs
@@ -8,6 +8,7 @@
 import qualified Haskore.Interface.SuperCollider.Schedule as Schedule
 import qualified Haskore.Interface.SuperCollider.Play     as Play
 
+import Haskore.Interface.SuperCollider.Schedule (Time)
 import Haskore.Interface.SuperCollider.SoundMap (Instrument)
 
 import qualified Sound.SC3.Server.NRT       as SCNRT
@@ -16,12 +17,20 @@
 -- import Sound.OpenSoundControl.Transport (Transport)
 -- import qualified Sound.OpenSoundControl.Transport.Monad as Trans
 
+import Sound.OpenSoundControl.OSC (OSC(Bundle))
+import qualified Sound.OpenSoundControl.Time as OSCTime
+
 import qualified Data.ByteString.Lazy as B
 
 import qualified Haskore.Melody as Melody
 
 import qualified Haskore.RealTime.Timer.Immediate as TimerImmediate
+import qualified Haskore.RealTime.EventList.TimeBody as TimeList
 
+import qualified Data.EventList.Absolute.TimeBody as AbsoluteEventList
+
+import qualified Numeric.NonNegative.Wrapper as NonNeg
+
 import System.Cmd (rawSystem)
 import System.Exit (ExitCode)
 
@@ -92,6 +101,25 @@
 
 byteStringFromSchedule :: Schedule.T -> B.ByteString
 byteStringFromSchedule =
-   SCNRT.encodeNRT .
-   Schedule.toStream
+   SCNRT.encodeNRT . scheduleToStream
 
+scheduleToStream ::
+   Schedule.T ->
+   [OSC]
+scheduleToStream sc =
+   timeStamp 0 (Schedule.initial sc) :
+   messagesToStream (Schedule.body sc)
+
+messagesToStream ::
+   TimeList.T Time OSC ->
+   [OSC]
+messagesToStream =
+   map (uncurry timeStamp) .
+   AbsoluteEventList.toPairList .
+   {- first absolutize, then collectCoincident in order to catch
+      coincidences caused by rounding -}
+   AbsoluteEventList.collectCoincident .
+   TimeList.toAbsoluteEventList 0
+
+timeStamp :: Time -> [OSC] -> OSC
+timeStamp = Bundle . OSCTime.NTPr . NonNeg.toNumber
diff --git a/src/Haskore/Interface/SuperCollider/Schedule.hs b/src/Haskore/Interface/SuperCollider/Schedule.hs
--- a/src/Haskore/Interface/SuperCollider/Schedule.hs
+++ b/src/Haskore/Interface/SuperCollider/Schedule.hs
@@ -9,13 +9,9 @@
     -- for Play module
     installUGenMsg, installSoundMsg,
     defaultChannel, atomPlayMsg,
-    timeStamp,
 
-    -- for Render module
-    toStream,
-
     -- for suppression of "unused" warnings :-)
-    fromMusicMsgs, messagesToStream, eventToMark,
+    fromMusicMsgs, eventToMark,
 
     -- testing
     -- fromMelodyPerformance,
@@ -28,9 +24,7 @@
 
 import Sound.SC3.UGen.UGen (UGen)
 
--- import qualified Sound.OpenSoundControl.Transport.UDP      as UDP
--- import qualified Sound.OpenSoundControl.UDPMonad as UDP
-import Sound.OpenSoundControl.OSC (OSC(Bundle))
+import Sound.OpenSoundControl.OSC (OSC)
 
 import qualified Haskore.Interface.SuperCollider.Note          as Note
 import qualified Haskore.Interface.SuperCollider.Performance   as SCPf
@@ -46,17 +40,16 @@
 import qualified Haskore.Music             as Music
 
 import qualified Haskore.Performance.BackEnd      as PfBE
-import qualified Haskore.RealTime.EventList.TimeBody    as TimeList
+import qualified Haskore.RealTime.EventList.TimeBody as TimeList
 import qualified Haskore.RealTime.EventList.TimeTime as TimeListPad
-import qualified Data.EventList.Absolute.TimeBody as AbsoluteEventList
 
 import qualified Haskore.General.IdGenerator      as IdGen
 
 import qualified Numeric.NonNegative.Wrapper as NonNeg
 
-import Control.Monad (liftM2)
+import Control.Monad (liftM2, )
 
-import Data.Maybe(fromMaybe,maybeToList)
+import Data.Maybe(fromMaybe, maybeToList, )
 
 
 {- * Schedule data structure -}
@@ -235,32 +228,7 @@
    TimeListPad.mapBody (uncurry eventToMsg)
 
 
-toStream ::
-   T ->
-   [OSC]
-toStream sc =
-   timeStamp 0 (initial sc) :
-   messagesToStream (body sc)
 
-messagesToStream ::
-   TimeList.T Time OSC ->
-   [OSC]
-messagesToStream =
-   map (uncurry timeStamp) .
-   AbsoluteEventList.toPairList .
-   {- first absolutize, then collectCoincident in order to catch
-      coincidences caused by rounding -}
-   AbsoluteEventList.collectCoincident .
-   TimeList.toAbsoluteEventList 0
-
-timeStamp :: Time -> [OSC] -> OSC
-timeStamp = Bundle . NonNeg.toNumber
-
-
-
-
-
-
 {- * Construction of OpenSoundControl messages -}
 
 stopMsg :: OSC
@@ -289,7 +257,7 @@
    UGen ->
    OSC
 installUGenMsg name chan =
-   SCPlay.d_recv' name .
+   SCPlay.d_recv_synthdef name .
    Channel.writeUGen chan
 
 installSoundMsg ::
diff --git a/src/Haskore/Interface/SuperCollider/Schedule/Channel.hs b/src/Haskore/Interface/SuperCollider/Schedule/Channel.hs
--- a/src/Haskore/Interface/SuperCollider/Schedule/Channel.hs
+++ b/src/Haskore/Interface/SuperCollider/Schedule/Channel.hs
@@ -42,9 +42,11 @@
 
 import qualified Haskore.General.IdGenerator      as IdGen
 
-import qualified Control.Monad.State as State
-import Control.Monad.State  (StateT, runStateT, lift, liftM2, get, put)
-import Control.Monad.Writer (Writer, tell, runWriter)
+import qualified Control.Monad.Trans.State as State
+import Control.Monad.Trans.State  (StateT, runStateT, get, put, )
+import Control.Monad.Trans.Writer (Writer, tell, runWriter, )
+import Control.Monad.Trans (lift, )
+import Control.Monad (liftM2, )
 
 
 
diff --git a/src/Haskore/Interface/SuperCollider/Schedule/Install.hs b/src/Haskore/Interface/SuperCollider/Schedule/Install.hs
--- a/src/Haskore/Interface/SuperCollider/Schedule/Install.hs
+++ b/src/Haskore/Interface/SuperCollider/Schedule/Install.hs
@@ -28,7 +28,7 @@
 import           Haskore.Melody         as Melody
 
 
-import Control.Monad.Writer (MonadWriter, Writer, tell, runWriter)
+import Control.Monad.Trans.Writer (Writer, tell, runWriter)
 
 
 
diff --git a/src/Haskore/Interface/SuperCollider/SoundMap.hs b/src/Haskore/Interface/SuperCollider/SoundMap.hs
--- a/src/Haskore/Interface/SuperCollider/SoundMap.hs
+++ b/src/Haskore/Interface/SuperCollider/SoundMap.hs
@@ -13,8 +13,8 @@
 
 import Sound.SC3.UGen.UGen (UGen)
 
-import Haskore.General.Utility (toMaybe)
-import Data.Maybe (mapMaybe)
+import Data.Maybe.HT (toMaybe, )
+import Data.Maybe (mapMaybe, )
 
 
 {- * Generic definitions -}
diff --git a/src/Haskore/Interface/SuperCollider/Timer.hs b/src/Haskore/Interface/SuperCollider/Timer.hs
new file mode 100644
--- /dev/null
+++ b/src/Haskore/Interface/SuperCollider/Timer.hs
@@ -0,0 +1,10 @@
+module Haskore.Interface.SuperCollider.Timer where
+
+import qualified Haskore.RealTime.Timer           as Timer
+import qualified Haskore.RealTime.Timer.Thread as TimerThread
+
+import Control.Monad.Trans (MonadIO, )
+
+
+timer :: MonadIO io => Timer.T io
+timer = Timer.liftIO TimerThread.timer
