diff --git a/Help/Server/dumpOSC.help.lhs b/Help/Server/dumpOSC.help.lhs
--- a/Help/Server/dumpOSC.help.lhs
+++ b/Help/Server/dumpOSC.help.lhs
@@ -1,1 +1,8 @@
 > Sound.SC3.Server.Help.viewServerHelp "/dumpOSC"
+
+> import Sound.SC3.ID
+
+> withSC3 (send (dumpOSC TextPrinter))
+> audition (out 0 (sinOsc AR (rand 'a' 440 880) 0 * 0.1))
+> withSC3 reset
+> withSC3 (send (dumpOSC NoPrinter))
diff --git a/Help/UGen/IO/offsetOut.help.lhs b/Help/UGen/IO/offsetOut.help.lhs
--- a/Help/UGen/IO/offsetOut.help.lhs
+++ b/Help/UGen/IO/offsetOut.help.lhs
@@ -16,15 +16,15 @@
 Phase cancellation, the 'offsetOut' at bus 0 cancels, the 'out'
 at bus 1 doesn't (or at least is exceedingly unlikely to).
 > let a = do
->       {t <- utcr
+>       {t <- time
 >       ;sr <- serverSampleRateActual
 >       ;let {f = sr / 100
 >            ;c = 1 / f
 >            ;g = let o = sinOsc AR (constant f) 0 * 0.2
 >                 in synthdef "g" (mrg [offsetOut 0 o,out 1 o])
 >            ;m = s_new "g" (-1) AddToTail 1 []
->            ;p = Bundle (UTCr (t + 0.1)) [m]
->            ;q = Bundle (UTCr (t + 0.1 + c/2)) [m]}
+>            ;p = bundle (t + 0.1) [m]
+>            ;q = bundle (t + 0.1 + c/2) [m]}
 >       ;_ <- async (d_recv g)
 >       ;mapM_ sendBundle [p,q]}
 > in withSC3 a
diff --git a/Help/UGen/Information/subsampleOffset.help.lhs b/Help/UGen/Information/subsampleOffset.help.lhs
--- a/Help/UGen/Information/subsampleOffset.help.lhs
+++ b/Help/UGen/Information/subsampleOffset.help.lhs
@@ -19,12 +19,12 @@
 oscilloscope.
 > let run s = do
 >       {_ <- async (d_recv s)
->       ;t <- utcr
+>       ;t <- time
 >       ;sr <- serverSampleRateActual
 >       ;let {t' = t + 0.2
 >            ;dt = 1 / sr
 >            ;m n = s_new "s" (-1) AddToTail 1 [("a", n)]}
->        in do {sendBundle (Bundle (UTCr t') [m 3])
->              ;sendBundle (Bundle (UTCr (t' + dt)) [m 0]) }}
+>        in do {sendBundle (bundle t' [m 3])
+>              ;sendBundle (bundle (t' + dt) [m 0]) }}
 
 > withSC3 (run g)
diff --git a/Help/UGen/Trigger/sendReply.help.lhs b/Help/UGen/Trigger/sendReply.help.lhs
--- a/Help/UGen/Trigger/sendReply.help.lhs
+++ b/Help/UGen/Trigger/sendReply.help.lhs
@@ -8,4 +8,4 @@
 >     ;o = sinOsc AR (s0 * 200 + 500) 0 * s1 * 0.1}
 > in audition (mrg [sendReply s0 0 "/send-reply" [s0,s1],out 0 o])
 
-> withSC3 (withNotifications (wait "/send-reply"))
+> withSC3 (withNotifications (waitReply "/send-reply"))
diff --git a/Help/UGen/Trigger/sendTrig.help.lhs b/Help/UGen/Trigger/sendTrig.help.lhs
--- a/Help/UGen/Trigger/sendTrig.help.lhs
+++ b/Help/UGen/Trigger/sendTrig.help.lhs
@@ -8,4 +8,4 @@
 > in audition (mrg [sendTrig s 0 s,out 0 o])
 
 Retrieve a single message
-> withSC3 (withNotifications (wait "/tr"))
+> withSC3 (withNotifications (waitReply "/tr"))
diff --git a/Sound/SC3/Server.hs b/Sound/SC3/Server.hs
--- a/Sound/SC3/Server.hs
+++ b/Sound/SC3/Server.hs
@@ -4,6 +4,7 @@
 module Sound.SC3.Server (module S) where
 
 import Sound.SC3.Server.Command as S
+import Sound.SC3.Server.Enum as S
 import Sound.SC3.Server.Synthdef as S
 import Sound.SC3.Server.Synthdef.Type as S
 import Sound.SC3.Server.Status as S
diff --git a/Sound/SC3/Server/Command.hs b/Sound/SC3/Server/Command.hs
--- a/Sound/SC3/Server/Command.hs
+++ b/Sound/SC3/Server/Command.hs
@@ -4,6 +4,7 @@
 
 import Data.Maybe
 import Sound.OpenSoundControl {- hosc -}
+import Sound.SC3.Server.Enum
 import Sound.SC3.Server.Utilities
 import Sound.SC3.Server.Synthdef
 import Sound.SC3.Server.Synthdef.Type
@@ -264,8 +265,8 @@
     where f (i,d) = Int i : Int (length d) : map Float d
 
 -- | Write sound file data. (Asynchronous)
-b_write :: Int -> String -> String -> String -> Int -> Int -> Bool -> Message
-b_write nid p h t f s z = message "/b_write" [Int nid, String p, String h, String t, Int f, Int s, Int (fromEnum z)]
+b_write :: Int -> String -> SoundFileFormat -> SampleFormat -> Int -> Int -> Bool -> Message
+b_write nid p h t f s z = message "/b_write" [Int nid, String p, String (soundFileFormatString h), String (sampleFormatString t), Int f, Int s, Int (fromEnum z)]
 
 -- | Zero sample data. (Asynchronous)
 b_zero :: Int -> Message
@@ -308,8 +309,8 @@
                   deriving (Eq, Show, Enum)
 
 -- | Select printing of incoming Open Sound Control messages.
-dumpMessage :: PrintLevel -> Message
-dumpMessage c = message "/dumpMessage" [Int (fromEnum c)]
+dumpOSC :: PrintLevel -> Message
+dumpOSC c = message "/dumpOSC" [Int (fromEnum c)]
 
 -- | Select reception of notification messages. (Asynchronous)
 notify :: Bool -> Message
@@ -404,15 +405,16 @@
 isAsync :: Message -> Bool
 isAsync (Message a _) = a `elem` async_cmds
 
--- | Add a completion message to an existing asynchronous command.
+-- | Add a completion message (or bundle, the name is misleading) to
+-- an existing asynchronous command.
 --
 -- > let {m = n_set1 0 "0" 0
 -- >     ;m' = encodeMessage m}
 -- > in withCM (b_close 0) m == Message "/b_close" [Int 0,Blob m']
-withCM :: Message -> Message -> Message
+withCM :: OSC o => Message -> o -> Message
 withCM (Message c xs) cm =
     if c `elem` async_cmds
-    then let xs' = xs ++ [Blob (encodeMessage cm)]
+    then let xs' = xs ++ [Blob (encodeOSC cm)]
          in message c xs'
     else error ("withCM: not async: " ++ c)
 
diff --git a/Sound/SC3/Server/Command/Completion.hs b/Sound/SC3/Server/Command/Completion.hs
--- a/Sound/SC3/Server/Command/Completion.hs
+++ b/Sound/SC3/Server/Command/Completion.hs
@@ -25,60 +25,61 @@
   ) where
 
 import Sound.OpenSoundControl
+import Sound.SC3.Server.Enum
 import Sound.SC3.Server.Synthdef
 import Sound.SC3.Server.Synthdef.Type
 
 -- Encode an OSC packet as an OSC blob.
-encode_message_blob :: Message -> Datum
-encode_message_blob = Blob . encodeMessage
+encode_blob :: OSC o => o -> Datum
+encode_blob = Blob . encodeOSC
 
 -- | Install a bytecode instrument definition. (Asynchronous)
-d_recv' :: Message -> Synthdef -> Message
-d_recv' osc d = message "/d_recv" [Blob (synthdefData d), encode_message_blob osc]
+d_recv' :: OSC o => o -> Synthdef -> Message
+d_recv' osc d = message "/d_recv" [Blob (synthdefData d), encode_blob osc]
 
 -- | Load an instrument definition from a named file. (Asynchronous)
-d_load' :: Message -> String -> Message
-d_load' osc p = message "/d_load" [String p, encode_message_blob osc]
+d_load' :: OSC o => o -> String -> Message
+d_load' osc p = message "/d_load" [String p, encode_blob osc]
 
 -- | Load a directory of instrument definitions files. (Asynchronous)
-d_loadDir' :: Message -> String -> Message
-d_loadDir' osc p = message "/d_loadDir" [String p, encode_message_blob osc]
+d_loadDir' :: OSC o => o -> String -> Message
+d_loadDir' osc p = message "/d_loadDir" [String p, encode_blob osc]
 
 -- | Allocates zero filled buffer to number of channels and samples. (Asynchronous)
-b_alloc' :: Message -> Int -> Int -> Int -> Message
-b_alloc' osc nid frames channels = message "/b_alloc" [Int nid, Int frames, Int channels, encode_message_blob osc]
+b_alloc' :: OSC o => o -> Int -> Int -> Int -> Message
+b_alloc' osc nid frames channels = message "/b_alloc" [Int nid, Int frames, Int channels, encode_blob osc]
 
 -- | Allocate buffer space and read a sound file. (Asynchronous)
-b_allocRead' :: Message -> Int -> String -> Int -> Int -> Message
-b_allocRead' osc nid p f n = message "/b_allocRead" [Int nid, String p, Int f, Int n, encode_message_blob osc]
+b_allocRead' :: OSC o => o -> Int -> String -> Int -> Int -> Message
+b_allocRead' osc nid p f n = message "/b_allocRead" [Int nid, String p, Int f, Int n, encode_blob osc]
 
 -- | Allocate buffer space and read a sound file, picking specific channels. (Asynchronous)
-b_allocReadChannel' :: Message -> Int -> String -> Int -> Int -> [Int] -> Message
-b_allocReadChannel' osc nid p f n cs = message "/b_allocReadChannel" ([Int nid, String p, Int f, Int n] ++ map Int cs ++ [encode_message_blob osc])
+b_allocReadChannel' :: OSC o => o -> Int -> String -> Int -> Int -> [Int] -> Message
+b_allocReadChannel' osc nid p f n cs = message "/b_allocReadChannel" ([Int nid, String p, Int f, Int n] ++ map Int cs ++ [encode_blob osc])
 
 -- | Free buffer data. (Asynchronous)
-b_free' :: Message -> Int -> Message
-b_free' osc nid = message "/b_free" [Int nid, encode_message_blob osc]
+b_free' :: OSC o => o -> Int -> Message
+b_free' osc nid = message "/b_free" [Int nid, encode_blob osc]
 
 -- | Close attached soundfile and write header information. (Asynchronous)
-b_close' :: Message -> Int -> Message
-b_close' osc nid = message "/b_close" [Int nid, encode_message_blob osc]
+b_close' :: OSC o => o -> Int -> Message
+b_close' osc nid = message "/b_close" [Int nid, encode_blob osc]
 
 -- | Read sound file data into an existing buffer. (Asynchronous)
-b_read' :: Message -> Int -> String -> Int -> Int -> Int -> Bool -> Message
-b_read' osc nid p f n f' z = message "/b_read" [Int nid, String p, Int f, Int n, Int f', Int (fromEnum z), encode_message_blob osc]
+b_read' :: OSC o => o -> Int -> String -> Int -> Int -> Int -> Bool -> Message
+b_read' osc nid p f n f' z = message "/b_read" [Int nid, String p, Int f, Int n, Int f', Int (fromEnum z), encode_blob osc]
 
 -- | Read sound file data into an existing buffer. (Asynchronous)
-b_readChannel' :: Message -> Int -> String -> Int -> Int -> Int -> Bool -> [Int] -> Message
-b_readChannel' osc nid p f n f' z cs = message "/b_readChannel" ([Int nid, String p, Int f, Int n, Int f', Int (fromEnum z)] ++ map Int cs ++ [encode_message_blob osc])
+b_readChannel' :: OSC o => o -> Int -> String -> Int -> Int -> Int -> Bool -> [Int] -> Message
+b_readChannel' osc nid p f n f' z cs = message "/b_readChannel" ([Int nid, String p, Int f, Int n, Int f', Int (fromEnum z)] ++ map Int cs ++ [encode_blob osc])
 
 -- | Write sound file data. (Asynchronous)
-b_write' :: Message -> Int -> String -> String -> String -> Int -> Int -> Bool -> Message
-b_write' osc nid p h t f s z = message "/b_write" [Int nid, String p, String h, String t, Int f, Int s, Int (fromEnum z), encode_message_blob osc]
+b_write' :: OSC o => o -> Int -> String -> SoundFileFormat -> SampleFormat -> Int -> Int -> Bool -> Message
+b_write' osc nid p h t f s z = message "/b_write" [Int nid, String p, String (soundFileFormatString h), String (sampleFormatString t), Int f, Int s, Int (fromEnum z), encode_blob osc]
 
 -- | Zero sample data. (Asynchronous)
-b_zero' :: Message -> Int -> Message
-b_zero' osc nid = message "/b_zero" [Int nid, encode_message_blob osc]
+b_zero' :: OSC o => o -> Int -> Message
+b_zero' osc nid = message "/b_zero" [Int nid, encode_blob osc]
 
 -- Local Variables:
 -- truncate-lines:t
diff --git a/Sound/SC3/Server/Enum.hs b/Sound/SC3/Server/Enum.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/Server/Enum.hs
@@ -0,0 +1,35 @@
+-- | Server input enumerations.
+module Sound.SC3.Server.Enum where
+
+-- | Sound file format.
+data SoundFileFormat = Aiff | Flac | Ircam | Next | Raw | Wave
+  deriving (Enum, Eq, Read, Show)
+
+-- | Sample format.
+data SampleFormat =
+    PcmInt8 | PcmInt16 | PcmInt24 | PcmInt32
+  | PcmFloat | PcmDouble
+  | PcmMulaw | PcmAlaw
+  deriving (Enum, Eq, Read, Show)
+
+soundFileFormatString :: SoundFileFormat -> String
+soundFileFormatString f =
+    case f of
+      Aiff -> "aiff"
+      Flac -> "flac"
+      Ircam -> "ircam"
+      Next -> "next"
+      Raw -> "raw"
+      Wave -> "wav"
+
+sampleFormatString :: SampleFormat -> String
+sampleFormatString f =
+    case f of
+      PcmInt8 -> "int8"
+      PcmInt16 -> "int16"
+      PcmInt24 -> "int24"
+      PcmInt32 -> "int32"
+      PcmFloat -> "float"
+      PcmDouble -> "double"
+      PcmMulaw -> "mulaw"
+      PcmAlaw -> "alaw"
diff --git a/Sound/SC3/Server/NRT.hs b/Sound/SC3/Server/NRT.hs
--- a/Sound/SC3/Server/NRT.hs
+++ b/Sound/SC3/Server/NRT.hs
@@ -2,12 +2,9 @@
 module Sound.SC3.Server.NRT where
 
 import qualified Data.ByteString.Lazy as B {- bytestring -}
-import Data.Maybe
 import Sound.OpenSoundControl {- hosc -}
 import Sound.OpenSoundControl.Coding.Byte
-import System.Exit
 import System.IO
-import System.Process {- process -}
 
 -- | Encode and prefix with encoded length.
 oscWithSize :: Bundle -> B.ByteString
@@ -49,55 +46,3 @@
 -- | 'decodeNRT' of 'B.readFile'.
 readNRT :: FilePath -> IO NRT
 readNRT = fmap decodeNRT . B.readFile
-
--- | File formats @scsynth@ renders to.
-data NRT_File_Format = AIFF | FLAC | NeXT | WAVE deriving (Eq,Show)
-
--- | Sample formats @scsynth@ renders to.
-data NRT_Sample_Format = I16 | I24 | I32 | F32 | F64 deriving (Eq,Show)
-
--- | Data required to render an 'NRT' score using @scsynth@.  The
--- input file is optional.
-data NRT_Render = NRT_Render {nrt_score :: FilePath
-                             ,nrt_input_file ::Maybe FilePath
-                             ,nrt_output_file :: FilePath
-                             ,nrt_channels :: Int
-                             ,nrt_sample_rate :: Double
-                             ,nrt_file_format :: NRT_File_Format
-                             ,nrt_sample_format :: NRT_Sample_Format}
-
--- | Format 'NRT_Sample_Format' for @scsynth@.
-nrt_sf_pp :: NRT_Sample_Format -> String
-nrt_sf_pp f =
-    case f of
-         I16 -> "int16"
-         I24 -> "int24"
-         I32 -> "int32"
-         F32 -> "float"
-         F64 -> "double"
-
--- | Format 'NRT_Render' as list of arguments to @scsynth@.
---
--- > let {r = NRT_Render "x.osc" Nothing "x.aif" 2 44100 AIFF I16
--- >     ;a = ["-o","2","-N","x.osc","_","x.aif","44100","AIFF","int16"]}
--- > in renderNRT_opt r == a
-renderNRT_opt :: NRT_Render -> [String]
-renderNRT_opt (NRT_Render c_fn i_fn o_fn nc sr hdr fmt) =
-    let i_fn' = fromMaybe "_" i_fn
-        nc' = show nc
-        sr' = show (round sr :: Integer)
-        hdr' = show hdr
-        fmt' = nrt_sf_pp fmt
-    in ["-o",nc',"-N",c_fn,i_fn',o_fn,sr',hdr',fmt']
-
--- | 'renderNRT' command as 'String', with shell protected arguments.
---
--- > renderNRT_cmd [] (NRT_Render "s.osc" Nothing "s.flac" 2 44100 FLAC I24)
-renderNRT_cmd :: [String] -> NRT_Render -> String
-renderNRT_cmd x =
-    let protect s = '\'' : s ++ "\'"
-    in unwords . ("scsynth" :) . map protect . (x ++) . renderNRT_opt
-
--- | Run @scsynth@ to render 'NRT_Render' with given @scsynth@ options.
-renderNRT :: [String] -> NRT_Render -> IO ExitCode
-renderNRT o = rawSystem "scsynth" . (o ++ ) . renderNRT_opt
diff --git a/Sound/SC3/Server/Transport/FD.hs b/Sound/SC3/Server/Transport/FD.hs
--- a/Sound/SC3/Server/Transport/FD.hs
+++ b/Sound/SC3/Server/Transport/FD.hs
@@ -19,13 +19,9 @@
 send :: (Transport t) => t -> Message -> IO ()
 send = sendMessage
 
--- | Synonym for 'waitReply'.
-wait :: Transport t => t -> String -> IO Message
-wait = waitReply
-
--- | Send a 'Message' and 'wait' for a @\/done@ reply.
+-- | Send a 'Message' and 'waitReply' for a @\/done@ reply.
 async :: Transport t => t -> Message -> IO Message
-async fd m = sendMessage fd m >> wait fd "/done"
+async fd m = sendMessage fd m >> waitReply fd "/done"
 
 -- | Bracket @SC3@ communication.
 withSC3 :: (UDP -> IO a) -> IO a
@@ -56,23 +52,20 @@
 -- * Non-real time
 
 -- | Wait ('pauseThreadUntil') until bundle is due to be sent relative
--- to initial 'UTCr' time, then send each message, asynchronously if
+-- to initial 'Time', then send each message, asynchronously if
 -- required.
-run_bundle :: Transport t => t -> Double -> Bundle -> IO ()
-run_bundle fd i (Bundle t x) =
-    let wr m = if isAsync m
-               then void (async fd m)
-               else sendMessage fd m
-    in case t of
-          NTPr n -> do
-                pauseThreadUntil (i + n)
-                mapM_ wr x
-          _ -> error "run_bundle: non-NTPr bundle"
+run_bundle :: Transport t => t -> Time -> Bundle -> IO ()
+run_bundle fd i (Bundle t x) = do
+  let wr m = if isAsync m
+             then void (async fd m)
+             else sendMessage fd m
+  pauseThreadUntil (i + t)
+  mapM_ wr x
 
 -- | Perform an 'NRT' score (as would be rendered by 'writeNRT').  In
 -- particular note that all timestamps /must/ be in 'NTPr' form.
 performNRT :: Transport t => t -> NRT -> IO ()
-performNRT fd s = utcr >>= \i -> mapM_ (run_bundle fd i) (nrt_bundles s)
+performNRT fd s = time >>= \i -> mapM_ (run_bundle fd i) (nrt_bundles s)
 
 -- * Audible
 
diff --git a/Sound/SC3/Server/Transport/Monad.hs b/Sound/SC3/Server/Transport/Monad.hs
--- a/Sound/SC3/Server/Transport/Monad.hs
+++ b/Sound/SC3/Server/Transport/Monad.hs
@@ -13,76 +13,69 @@
 -- * hosc variants
 
 -- | Synonym for 'sendMessage'.
-send :: (Transport m) => Message -> m ()
+send :: SendOSC m => Message -> m ()
 send = sendMessage
 
--- | Synonym for 'waitReply'.
-wait :: Transport m => String -> m Message
-wait = waitReply
-
--- | Send a 'Message' and 'wait' for a @\/done@ reply.
-async :: Transport m => Message -> m Message
-async m = send m >> wait "/done"
+-- | Send a 'Message' and 'waitReply' for a @\/done@ reply.
+async :: DuplexOSC m => Message -> m Message
+async m = send m >> waitReply "/done"
 
 -- | Bracket @SC3@ communication. 'withTransport' at standard SC3 UDP
 -- port.
 --
 -- > import Sound.SC3.Server.Command
 --
--- > withSC3 (send status >> wait "/status.reply")
+-- > withSC3 (send status >> waitReply "/status.reply")
 withSC3 :: Connection UDP a -> IO a
 withSC3 = withTransport (openUDP "127.0.0.1" 57110)
 
 -- * Server control
 
 -- | Free all nodes ('g_freeAll') at group @1@.
-stop :: Transport m => m ()
+stop :: SendOSC m => m ()
 stop = send (g_freeAll [1])
 
 -- | Free all nodes ('g_freeAll') at and re-create groups @1@ and @2@.
-reset :: Transport m => m ()
+reset :: SendOSC m => m ()
 reset =
     let m = [g_freeAll [1,2],g_new [(1,AddToTail,0),(2,AddToTail,0)]]
-    in sendBundle (Bundle immediately m)
+    in sendBundle (bundle immediately m)
 
 
 -- | Send 'd_recv' and 's_new' messages to scsynth.
-playSynthdef :: Transport m => Synthdef -> m ()
+playSynthdef :: DuplexOSC m => Synthdef -> m ()
 playSynthdef s = do
   _ <- async (d_recv s)
   send (s_new (synthdefName s) (-1) AddToTail 1 [])
 
 -- | Send an /anonymous/ instrument definition using 'playSynthdef'.
-playUGen :: Transport m => UGen -> m ()
+playUGen :: DuplexOSC m => UGen -> m ()
 playUGen = playSynthdef . synthdef "Anonymous"
 
 -- * NRT
 
 -- | Wait ('pauseThreadUntil') until bundle is due to be sent relative
--- to initial 'UTCr' time, then send each message, asynchronously if
+-- to the initial 'Time', then send each message, asynchronously if
 -- required.
-run_bundle :: (Transport m) => Double -> Bundle -> m ()
-run_bundle i (Bundle t x) =
-    let wr m = if isAsync m
-               then void (async m)
-               else send m
-    in case t of
-          NTPr n -> do
-                liftIO (pauseThreadUntil (i + n))
-                mapM_ wr x
-          _ -> error "run_bundle: non-NTPr bundle"
+run_bundle :: Transport m => Time -> Bundle -> m ()
+run_bundle i (Bundle t x) = do
+  let wr m = if isAsync m
+             then async m >> return ()
+             else send m
+  liftIO (pauseThreadUntil (i + t))
+  mapM_ wr x
 
 -- | Perform an 'NRT' score (as would be rendered by 'writeNRT').  In
 -- particular note that all timestamps /must/ be in 'NTPr' form.
-performNRT :: (Transport m) => NRT -> m ()
-performNRT s = liftIO utcr >>= \i -> mapM_ (run_bundle i) (nrt_bundles s)
+performNRT :: Transport m => NRT -> m ()
+performNRT s = liftIO time >>= \i -> mapM_ (run_bundle i) (nrt_bundles s)
 
 -- * Audible
 
 -- | Class for values that can be encoded and send to @scsynth@ for
 -- audition.
 class Audible e where
-    play :: (Transport m) => e -> m ()
+    play :: Transport m => e -> m ()
 
 instance Audible Graph where
     play g = playSynthdef (Synthdef "Anonymous" g)
@@ -103,7 +96,7 @@
 
 -- | Turn on notifications, run /f/, turn off notifications, return
 -- result.
-withNotifications :: Transport m => m a -> m a
+withNotifications :: DuplexOSC m => m a -> m a
 withNotifications f = do
   _ <- async (notify True)
   r <- f
@@ -115,26 +108,26 @@
 -- | Variant of 'b_getn1' that waits for return message and unpacks it.
 --
 -- > withSC3 (b_getn1_data 0 (0,5))
-b_getn1_data :: Transport m => Int -> (Int,Int) -> m [Double]
+b_getn1_data :: DuplexOSC m => Int -> (Int,Int) -> m [Double]
 b_getn1_data b s = do
   let f d = case d of
               Int _:Int _:Int _:x -> map datum_real_err x
               _ -> error "b_getn1_data"
   sendMessage (b_getn1 b s)
-  fmap f (waitDatum "/b_setn")
+  liftM f (waitDatum "/b_setn")
 
 -- | Variant of 'b_getn1_data' that segments individual 'b_getn'
 -- messages to /n/ elements.
 --
 -- > withSC3 (b_getn1_data_segment 1 0 (0,5))
-b_getn1_data_segment :: Transport m => Int -> Int -> (Int,Int) -> m [Double]
+b_getn1_data_segment :: DuplexOSC m => Int -> Int -> (Int,Int) -> m [Double]
 b_getn1_data_segment n b (i,j) = do
   let ix = b_indices n j i
   d <- mapM (b_getn1_data b) ix
   return (concat d)
 
 -- | Variant of 'b_getn1_data_segment' that gets the entire buffer.
-b_fetch :: Transport m => Int -> Int -> m [Double]
+b_fetch :: DuplexOSC m => Int -> Int -> m [Double]
 b_fetch n b = do
   let f d = case d of
               [Int _,Int nf,Int nc,Float _] ->
@@ -147,19 +140,19 @@
 -- * Status
 
 -- | Collect server status information.
-serverStatus :: Transport m => m [String]
+serverStatus :: DuplexOSC m => m [String]
 serverStatus = liftM statusFormat serverStatusData
 
 -- | Read nominal sample rate of server.
-serverSampleRateNominal :: (Transport m) => m Double
+serverSampleRateNominal :: DuplexOSC m => m Double
 serverSampleRateNominal = liftM (extractStatusField 7) serverStatusData
 
 -- | Read actual sample rate of server.
-serverSampleRateActual :: (Transport m) => m Double
+serverSampleRateActual :: DuplexOSC m => m Double
 serverSampleRateActual = liftM (extractStatusField 8) serverStatusData
 
 -- | Retrieve status data from server.
-serverStatusData :: Transport m => m [Datum]
+serverStatusData :: DuplexOSC m => m [Datum]
 serverStatusData = do
   sendMessage status
   waitDatum "/status.reply"
diff --git a/Sound/SC3/UGen/FFT.hs b/Sound/SC3/UGen/FFT.hs
--- a/Sound/SC3/UGen/FFT.hs
+++ b/Sound/SC3/UGen/FFT.hs
@@ -32,6 +32,18 @@
 convolution :: UGen -> UGen -> UGen -> UGen
 convolution i kernel frameSize = mkOsc AR "Convolution" [i, kernel, frameSize] 1
 
+-- | Real-time fixed kernel convolver.
+convolution2 :: UGen -> UGen -> UGen -> UGen -> UGen
+convolution2 in_ kernel trigger framesize = mkOsc AR "Convolution2" [in_,kernel,trigger,framesize] 1
+
+-- | Real-time convolver with linear interpolation
+convolution2L :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+convolution2L in_ kernel trigger framesize crossfade = mkOsc AR "Convolution2L" [in_,kernel,trigger,framesize,crossfade] 1
+
+-- | Time based convolver.
+convolution3 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+convolution3 rate in_ kernel trigger framesize = mkOscR [AR,KR] rate "Convolution3" [in_,kernel,trigger,framesize] 1
+
 -- | Pack demand-rate FFT bin streams into an FFT chain.
 packFFT :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 packFFT b sz from to z mp =
diff --git a/hsc3.cabal b/hsc3.cabal
--- a/hsc3.cabal
+++ b/hsc3.cabal
@@ -1,5 +1,5 @@
 Name:              hsc3
-Version:           0.12
+Version:           0.13
 Synopsis:          Haskell SuperCollider
 Description:       Haskell client for the SuperCollider synthesis server,
                    <http://audiosynth.com/>.
@@ -52,7 +52,7 @@
                    containers,
                    directory,
                    filepath,
-                   hosc == 0.12.*,
+                   hosc == 0.13.*,
                    murmur-hash,
                    network,
                    process,
@@ -69,6 +69,7 @@
                    Sound.SC3.Server
                    Sound.SC3.Server.Command
                    Sound.SC3.Server.Command.Completion
+                   Sound.SC3.Server.Enum
                    Sound.SC3.Server.FD
                    Sound.SC3.Server.Help
                    Sound.SC3.Server.Monad
