diff --git a/Sound/SC3/Server/Internal.hs b/Sound/SC3/Server/Internal.hs
deleted file mode 100644
--- a/Sound/SC3/Server/Internal.hs
+++ /dev/null
@@ -1,179 +0,0 @@
-module Sound.SC3.Server.Internal (
-    InternalTransport
-  , withInternal
-) where
-
-import           Bindings.Sound.SC3
-import           Control.Concurrent.Chan
-import           Control.Concurrent.MVar
-import           Control.Exception (bracket)
-import           Control.Monad
-import           Control.Monad.IO.Class (liftIO)
-import           Control.Monad.Trans.State (execStateT, get, put)
-import qualified Data.ByteString as BS
-import qualified Data.ByteString.Internal as BS
-import qualified Data.ByteString.Lazy as BL
-import qualified Data.List as L
-import           Foreign.C
-import           Foreign.ForeignPtr
-import           Foreign.Marshal
-import           Foreign.Ptr
-import           Foreign.Storable
-import           Foreign.StablePtr
-import           Sound.OpenSoundControl (OSC)
-import qualified Sound.OpenSoundControl as OSC
-import qualified Sound.SC3 as SC
-import           Sound.SC3.Server.Options
-import           Sound.SC3.Server.Process (OutputHandler(..))
-
-data InternalTransport = InternalTransport {
-    world         :: MVar (Ptr C'World)     -- ^The World pointer, wrapped in an MVar.
-  , recvChan      :: Chan OSC               -- ^The channel messages received from the library are written to.
-  , replyFunc     :: C'ReplyFunc            -- ^Reply callback function pointer.
-  , replyFuncData :: StablePtr (Chan OSC)   -- ^Data for the reply callback (a pointer to the receive channel).
-  , printFunc     :: C'HaskellPrintFunc     -- ^Print callback function pointer.
-  }
-
-withInternal ::
-    ServerOptions
- -> RTOptions
- -> OutputHandler
- -> (InternalTransport -> IO a)
- -> IO a
-withInternal serverOptions rtOptions handler =
-    bracket (withWorldOptions (newIT handler) serverOptions rtOptions)
-            OSC.close
-
-newIT :: OutputHandler -> Ptr C'WorldOptions -> IO InternalTransport
-newIT handler options = do
-    pf <- mk'HaskellPrintFunc (\cs -> mapM_ (onPutString handler) . lines =<< peekCString cs)
-    c'SetHaskellPrintFunc pf
-    w <- newMVar =<< c'World_New options
-    c <- newChan
-    f <- mk'ReplyFunc it_replyFunc
-    p <- newStablePtr c
-    return $ InternalTransport w c f p pf
-
-it_replyFunc :: Ptr C'ReplyAddress -> Ptr CChar -> CInt -> IO ()
-it_replyFunc replyAddress cbuf csize = do
-    -- putStrLn $ "it_replyFunc: " ++ show (replyAddress, cbuf, csize)
-    buf <- BS.packCStringLen (cbuf, fromIntegral csize)
-    ptr <- liftM castPtrToStablePtr (c'ReplyAddress_ReplyData replyAddress)
-    chan <- deRefStablePtr ptr
-    let osc = OSC.decodeOSC (BL.fromChunks [buf])
-    -- putStrLn $ "it_replyFunc: " ++ show osc
-    writeChan chan osc
-
-copyChunks :: Ptr CChar -> [BS.ByteString] -> IO ()
-copyChunks dst = foldM_ f 0
-    where
-        f i b = do
-            let (fp, o, n) = BS.toForeignPtr b
-            -- putStrLn $ "copyChunks " ++ show (i, o, n)
-            withForeignPtr fp $ \src ->
-                copyBytes (dst `plusPtr` i)
-                          (src `plusPtr` o)
-                          n
-            return (i + n)
-
-copyByteString :: Ptr CChar -> BL.ByteString -> IO ()
-copyByteString dst = copyChunks dst . BL.toChunks
-
-sendIT :: InternalTransport -> OSC -> IO ()
-sendIT t osc = withMVar (world t) $ \w -> do
-    let buf = OSC.encodeOSC osc
-        n = BL.length buf
-    when (w /= nullPtr) $ do
-        -- TODO: Check return value and throw exception
-        _ <- allocaArray (fromIntegral n) $ \cbuf -> do
-            copyByteString cbuf buf
-            c'World_SendPacketWithContext
-                w
-                (fromIntegral n)
-                cbuf
-                (replyFunc t)
-                (castStablePtrToPtr (replyFuncData t))
-        return ()
-
-recvIT :: InternalTransport -> IO OSC
-recvIT = readChan . recvChan
-
-closeIT :: InternalTransport -> IO ()
-closeIT t = do
-    sendIT t SC.quit
-    modifyMVar_ (world t) $ \w -> do
-        when (w /= nullPtr) $ do
-            c'World_WaitForQuit w
-            freeHaskellFunPtr (replyFunc t)
-            freeStablePtr (replyFuncData t)
-            freeHaskellFunPtr (printFunc t)
-        return nullPtr
-
-withWorldOptions :: (Ptr C'WorldOptions -> IO a) -> ServerOptions -> RTOptions -> IO a
-withWorldOptions f so ro = do
-    (fs, cs) <- flip execStateT ([], []) $ do
-        -- c'WorldOptions'mPassword :: CString
-        setOpt (\x -> x { c'WorldOptions'mNumBuffers = int (numberOfSampleBuffers so) })
-        setOpt (\x -> x { c'WorldOptions'mMaxLogins  = int (maxNumberOfLogins ro) })
-        setOpt (\x -> x { c'WorldOptions'mMaxNodes   = int (maxNumberOfNodes so) })
-        setOpt (\x -> x { c'WorldOptions'mMaxGraphDefs = int (maxNumberOfSynthDefs so) })
-        setOpt (\x -> x { c'WorldOptions'mMaxWireBufs = int (numberOfWireBuffers so) })
-        setOpt (\x -> x { c'WorldOptions'mNumAudioBusChannels = int (numberOfAudioBusChannels so) })
-        setOpt (\x -> x { c'WorldOptions'mNumInputBusChannels = int (numberOfInputBusChannels so) })
-        setOpt (\x -> x { c'WorldOptions'mNumOutputBusChannels = int (numberOfOutputBusChannels so) })
-        setOpt (\x -> x { c'WorldOptions'mNumControlBusChannels = int (numberOfControlBusChannels so) })
-        setOpt (\x -> x { c'WorldOptions'mBufLength = int (blockSize so) })
-        setOpt (\x -> x { c'WorldOptions'mRealTimeMemorySize = int (realtimeMemorySize so) })
-        -- TODO: Make shared controls accessible
-        setOpt (\x -> x { c'WorldOptions'mNumSharedControls = 0 })
-        setOpt (\x -> x { c'WorldOptions'mSharedControls = nullPtr })
-        -- TODO
-        -- tell (\x -> x { c'WorldOptions'mRealTime })
-        -- TODO
-        -- tell (\x -> x { c'WorldOptions'mMemoryLocking :: CInt
-        -- tell (\x -> x { c'WorldOptions'mNonRealTimeCmdFilename :: CString
-        -- tell (\x -> x { c'WorldOptions'mNonRealTimeInputFilename :: CString
-        -- tell (\x -> x { c'WorldOptions'mNonRealTimeOutputFilename :: CString
-        -- tell (\x -> x { c'WorldOptions'mNonRealTimeOutputHeaderFormat :: CString
-        -- tell (\x -> x { c'WorldOptions'mNonRealTimeOutputSampleFormat :: CString
-        setOpt (\x -> x { c'WorldOptions'mPreferredSampleRate = int (hardwareSampleRate ro) })
-        setOpt (\x -> x { c'WorldOptions'mNumRGens = int (numberOfRandomSeeds so) })
-        setOpt (\x -> x { c'WorldOptions'mPreferredHardwareBufferFrameSize = int (hardwareBufferSize ro) })
-        setOpt (\x -> x { c'WorldOptions'mLoadGraphDefs = bool (loadSynthDefs so) })
-        -- tell (\x -> x { c'WorldOptions'mInputStreamsEnabled :: CString
-        -- tell (\x -> x { c'WorldOptions'mOutputStreamsEnabled :: CString
-        -- TODO: Make input and output device configurable separately
-        case hardwareDeviceName ro of
-            Nothing -> return ()
-            Just name -> do
-                setOptS (\x s -> x { c'WorldOptions'mInDeviceName = s }) name
-                setOptS (\x s -> x { c'WorldOptions'mOutDeviceName = s }) name
-        setOpt (\x -> x { c'WorldOptions'mVerbosity = int (fromEnum (verbosity so)) })
-        setOpt (\x -> x { c'WorldOptions'mRendezvous = bool (useZeroconf ro) })
-        maybe (return ()) (setOptS (\x s -> x { c'WorldOptions'mUGensPluginPath = s }) . path) (ugenPluginPath so)
-        maybe (return ()) (setOptS (\x s -> x { c'WorldOptions'mRestrictedPath = s })) (restrictedPath so)
-    opts <- liftM (flip (foldl (flip ($))) fs) (c'kDefaultWorldOptions >>= peek)
-    a <- alloca $ \ptr -> do
-        ptr `poke` opts
-        f ptr
-    mapM_ free cs
-    return a
-    where
-        int :: (Integral a, Num b) => a -> b
-        int = fromIntegral
-        bool :: Num a => Bool -> a
-        bool b = int (if b then 1 else 0)
-        path :: [String] -> String
-        path = L.intercalate ":"
-        setOpt f = do
-            (fs, cs) <- get
-            put (f:fs, cs)
-        setOptS f s = do
-            ptr <- liftIO (newCString s)
-            (fs, cs) <- get
-            put (flip f ptr:fs, ptr:cs)
-            
-instance OSC.Transport InternalTransport where
-    send  = sendIT
-    recv  = recvIT
-    close = closeIT
diff --git a/Sound/SC3/Server/Options.hs b/Sound/SC3/Server/Options.hs
deleted file mode 100644
--- a/Sound/SC3/Server/Options.hs
+++ /dev/null
@@ -1,184 +0,0 @@
-{-# LANGUAGE TemplateHaskell #-}
-module Sound.SC3.Server.Options
-  ( Verbosity(..)
-  , ServerOptions(..)
-  , defaultServerOptions
-  , NetworkPort(..)
-  , defaultUDPPort
-  , defaultTCPPort
-  , RTOptions(..)
-  , defaultRTOptions
-  , defaultRTOptionsUDP
-  , defaultRTOptionsTCP
-  , NRTOptions(..)
-  , defaultNRTOptions
-  ) where
-
--- import           Control.Monad.Error
--- import qualified Data.ConfigFile as CF
-
--- | Used with the 'verbosity' field in 'ServerOptions'.
-data Verbosity =
-    Silent
-  | Quiet
-  | Normal
-  | Verbose
-  | VeryVerbose
-  | ExtremelyVerbose
-  deriving (Eq, Read, Show)
-
-instance Enum Verbosity where
-    fromEnum Silent           = -2
-    fromEnum Quiet            = -1
-    fromEnum Normal           = 0
-    fromEnum Verbose          = 1
-    fromEnum VeryVerbose      = 2
-    fromEnum ExtremelyVerbose = 3
-    toEnum (-2)               = Silent
-    toEnum (-1)               = Quiet
-    toEnum 0                  = Normal
-    toEnum 1                  = Verbose
-    toEnum 2                  = VeryVerbose
-    toEnum 3                  = ExtremelyVerbose
-    toEnum _                  = error "Verbosity (toEnum): bad argument"
-
--- instance CF.Get_C Verbosity where
---     get parser section option = do
---         s <- CF.get parser section option
---         case s of
---             "Silent"           -> return Silent
---             "Quiet"            -> return Quiet
---             "Normal"           -> return Normal
---             "Verbose"          -> return Verbose
---             "VeryVerbose"      -> return VeryVerbose
---             "ExtremelyVerbose" -> return ExtremelyVerbose
---             _ -> throwError $ (CF.ParseError $ "Invalid Verbosity value: " ++ s, "")
-
--- ====================================================================
--- * Server options
-
--- | Specify general server options used both in realtime and non-realtime
--- mode.
-data ServerOptions = ServerOptions {
-    serverProgram               :: FilePath          -- ^ Path to the @scsynth@ program
-  , numberOfControlBusChannels  :: Int               -- ^ Number of allocated control bus channels
-  , numberOfAudioBusChannels    :: Int               -- ^ Number of allocated audio bus channels
-  , numberOfInputBusChannels    :: Int               -- ^ Number of physical input channels
-  , numberOfOutputBusChannels   :: Int               -- ^ Number of physical output channels
-  , blockSize                   :: Int               -- ^ Synthesis block size
-  , numberOfSampleBuffers       :: Int               -- ^ Number of allocated sample buffers
-  , maxNumberOfNodes            :: Int               -- ^ Maximum number of synthesis nodes
-  , maxNumberOfSynthDefs        :: Int               -- ^ Maximum number of synth definitions
-  , realtimeMemorySize          :: Int               -- ^ Realtime memory size in bytes
-  , numberOfWireBuffers         :: Int               -- ^ Number of unit generator connection buffers
-  , numberOfRandomSeeds         :: Int               -- ^ Number of random number generator seeds
-  , loadSynthDefs               :: Bool              -- ^ If 'True', load synth definitions from /synthdefs/ directory on startup
-  , verbosity                   :: Verbosity         -- ^ 'Verbosity' level
-  , ugenPluginPath				:: Maybe [FilePath]  -- ^ List of UGen plugin search paths
-  , restrictedPath              :: Maybe FilePath    -- ^ Sandbox path to restrict OSC command filesystem access
-  } deriving (Eq, Show)
-
--- | Default server options.
-defaultServerOptions :: ServerOptions
-defaultServerOptions = ServerOptions {
-    serverProgram              = "scsynth"
-  , numberOfControlBusChannels = 4096
-  , numberOfAudioBusChannels   = 128
-  , numberOfInputBusChannels   = 8
-  , numberOfOutputBusChannels  = 8
-  , blockSize                  = 64
-  , numberOfSampleBuffers      = 1024
-  , maxNumberOfNodes           = 1024
-  , maxNumberOfSynthDefs       = 1024
-  , realtimeMemorySize         = 8192
-  , numberOfWireBuffers        = 64
-  , numberOfRandomSeeds        = 64
-  , loadSynthDefs              = True
-  , verbosity                  = Normal
-  , ugenPluginPath             = Nothing
-  , restrictedPath             = Nothing
-  }
-
--- ====================================================================
--- * Realtime options
-
-data NetworkPort =
-    UDPPort Int
-  | TCPPort Int
-  deriving (Eq, Show)
-
--- | Default network port number.
-defaultPortNumber :: Int
-defaultPortNumber = 57110
-
--- | Default UDP port.
-defaultUDPPort :: NetworkPort
-defaultUDPPort = UDPPort defaultPortNumber
-
--- | Default TCP port.
-defaultTCPPort :: NetworkPort
-defaultTCPPort = TCPPort defaultPortNumber
-
--- | Realtime server options, parameterized by the OpenSoundControl
--- 'Transport' to be used.
-data RTOptions = RTOptions {
-    -- Network control
-    networkPort             :: NetworkPort     -- ^ Network port
-  , useZeroconf             :: Bool            -- ^ If 'True', publish scsynth service through Zeroconf
-  , maxNumberOfLogins       :: Int             -- ^ Max number of supported logins if 'sessionPassword' is set
-  , sessionPassword         :: Maybe String    -- ^ Session password
-  -- Audio device control
-  , hardwareDeviceName      :: Maybe String    -- ^ Hardware device name (JACK client:server name on Linux)
-  , hardwareBufferSize      :: Int             -- ^ Hardware buffer size (no effect with JACK)
-  , hardwareSampleRate      :: Int             -- ^ Hardware buffer size (no effect with JACK)
-  , inputStreamsEnabled     :: Maybe Int       -- ^ Enabled input streams (CoreAudio only)
-  , outputStreamsEnabled    :: Maybe Int       -- ^ Enabled output streams (CoreAudio only)
-  } deriving (Eq, Show)
-
--- | Default realtime server options.
-defaultRTOptions :: RTOptions
-defaultRTOptions = RTOptions {
-    -- Network control
-    networkPort             = defaultUDPPort
-  , useZeroconf             = False
-  , maxNumberOfLogins       = 16
-  , sessionPassword         = Nothing
-    -- Audio device control
-  , hardwareDeviceName      = Nothing
-  , hardwareBufferSize      = 0
-  , hardwareSampleRate      = 0
-  , inputStreamsEnabled     = Nothing
-  , outputStreamsEnabled    = Nothing
-  }
-
--- | Default realtime server options (UDP transport).
-defaultRTOptionsUDP :: RTOptions
-defaultRTOptionsUDP =  defaultRTOptions { networkPort = defaultUDPPort }
-
--- | Default realtime server options (TCP transport).
-defaultRTOptionsTCP :: RTOptions
-defaultRTOptionsTCP = defaultRTOptions { networkPort = defaultTCPPort }
-
--- ====================================================================
--- * Non-Realtime options
-
--- | Non-realtime server options.
-data NRTOptions = NRTOptions {
-    commandFilePath    :: Maybe FilePath    -- ^ Path to OSC command file ('Nothing' for stdin)
-  , inputFilePath      :: Maybe FilePath    -- ^ Path to input sound file ('Nothing' for no audio input)
-  , outputFilePath     :: FilePath          -- ^ Path to output sound file
-  , outputSampleRate   :: Int               -- ^ Output sound file sample rate
-  , outputHeaderFormat :: String            -- ^ Output sound file header format
-  , outputSampleFormat :: String            -- ^ Output sound file sample format
-} deriving (Eq, Show)
-
--- | Default non-realtime server options.
-defaultNRTOptions :: NRTOptions
-defaultNRTOptions = NRTOptions {
-    commandFilePath    = Nothing
-  , inputFilePath      = Nothing
-  , outputFilePath     = "output.wav"
-  , outputSampleRate   = 44100
-  , outputHeaderFormat = "wav"
-  , outputSampleFormat = "int16"
-  }
diff --git a/Sound/SC3/Server/Process.hs b/Sound/SC3/Server/Process.hs
--- a/Sound/SC3/Server/Process.hs
+++ b/Sound/SC3/Server/Process.hs
@@ -3,7 +3,7 @@
 -- | This module includes utilities for spawning an external scsynth process,
 -- either for realtime or non-realtime execution.
 module Sound.SC3.Server.Process
-  ( module Sound.SC3.Server.Options
+  ( module Sound.SC3.Server.Process.Options
   , OutputHandler(..)
   , defaultOutputHandler
   , NetworkTransport
@@ -20,8 +20,8 @@
 import           Sound.OpenSoundControl (Transport(..))
 import qualified Sound.OpenSoundControl as OSC
 import           Sound.SC3 (quit)
-import           Sound.SC3.Server.Options
 import           Sound.SC3.Server.Process.CommandLine
+import           Sound.SC3.Server.Process.Options
 import           System.Exit (ExitCode(..))
 import           System.IO (Handle, hFlush, hGetLine, hIsEOF, hPutStrLn, stderr, stdout)
 import           System.Process (runInteractiveProcess, waitForProcess)
@@ -94,49 +94,27 @@
  -> IO a
 withSynth serverOptions rtOptions handler action = do
     (_, hOut, hErr, hProc) <- runInteractiveProcess exe args Nothing Nothing
-    forkIO $ putStderr hErr
-    result <- newEmptyMVar
-    thread <- forkIO (loop hOut result)
-    exitCode <- waitForProcess hProc
-    case exitCode of
-        ExitSuccess -> do
-            a <- readMVar result
-            case a of
-                Left e  -> throw e
-                Right a -> return a
-        ExitFailure _ -> do
-            killThread thread
-            throw (toException exitCode)
+    forkPipe onPutError hErr
+    exitCode <- newEmptyMVar
+    forkIO $ waitForProcess hProc >>= putMVar exitCode
+    a <- loop hOut
+    e <- takeMVar exitCode
+    case e of
+        ExitSuccess -> return a
+        ExitFailure _ -> throw e
     where
         (exe:args) = rtCommandLine serverOptions rtOptions
-        loop h result = do
-            l <- try (hGetLine h)
-            case l of
-                Left (ex :: IOException) -> returnExc (toException ex)
-                Right l ->
-                    if "SuperCollider 3 server ready" `isPrefixOf` l
-                        then do
-                            e <- try (onPutString handler l)
-                            case e of
-                                Left (ex :: IOException) -> returnExc (toException ex)
-                                _                        -> do
-                                    forkIO $ putStdout h
-                                    fd <- openTransport (networkPort rtOptions)
-                                    a <- try (action fd >>= evaluate)
-                                    OSC.send fd quit
-                                    case a of
-                                        Left (ex :: SomeException) -> returnExc (toException ex)
-                                        Right a -> returnRes a
-                        else do
-                            e <- try (onPutString handler l)
-                            case e of
-                                Left (ex :: IOException) -> returnExc (toException ex)
-                                _                        -> loop h result -- recurse
-            where
-                returnRes a = putMVar result (Right a)
-                returnExc e = putMVar result (Left e)
-        putStdout = pipeOutput (onPutString handler)
-        putStderr = pipeOutput (onPutError  handler)
+        loop h = do
+            l <- hGetLine h
+            onPutString handler l
+            if "SuperCollider 3 server ready" `isPrefixOf` l
+                then cont h
+                else loop h
+        cont h = do
+            forkPipe onPutString h
+            fd <- openTransport (networkPort rtOptions)
+            action fd `finally` OSC.send fd quit
+        forkPipe f = forkIO . pipeOutput (f handler)
 
 -- ====================================================================
 -- * Non-Realtime scsynth execution
diff --git a/Sound/SC3/Server/Process/CommandLine.hs b/Sound/SC3/Server/Process/CommandLine.hs
--- a/Sound/SC3/Server/Process/CommandLine.hs
+++ b/Sound/SC3/Server/Process/CommandLine.hs
@@ -6,7 +6,7 @@
 
 import Data.List (intercalate)
 import Data.Maybe (fromMaybe)
-import Sound.SC3.Server.Options
+import Sound.SC3.Server.Process.Options
 
 -- ====================================================================
 -- scsynth commandline options
diff --git a/Sound/SC3/Server/Process/Options.hs b/Sound/SC3/Server/Process/Options.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/Server/Process/Options.hs
@@ -0,0 +1,183 @@
+module Sound.SC3.Server.Process.Options
+  ( Verbosity(..)
+  , ServerOptions(..)
+  , defaultServerOptions
+  , NetworkPort(..)
+  , defaultUDPPort
+  , defaultTCPPort
+  , RTOptions(..)
+  , defaultRTOptions
+  , defaultRTOptionsUDP
+  , defaultRTOptionsTCP
+  , NRTOptions(..)
+  , defaultNRTOptions
+  ) where
+
+-- import           Control.Monad.Error
+-- import qualified Data.ConfigFile as CF
+
+-- | Used with the 'verbosity' field in 'ServerOptions'.
+data Verbosity =
+    Silent
+  | Quiet
+  | Normal
+  | Verbose
+  | VeryVerbose
+  | ExtremelyVerbose
+  deriving (Eq, Read, Show)
+
+instance Enum Verbosity where
+    fromEnum Silent           = -2
+    fromEnum Quiet            = -1
+    fromEnum Normal           = 0
+    fromEnum Verbose          = 1
+    fromEnum VeryVerbose      = 2
+    fromEnum ExtremelyVerbose = 3
+    toEnum (-2)               = Silent
+    toEnum (-1)               = Quiet
+    toEnum 0                  = Normal
+    toEnum 1                  = Verbose
+    toEnum 2                  = VeryVerbose
+    toEnum 3                  = ExtremelyVerbose
+    toEnum _                  = error "Verbosity (toEnum): bad argument"
+
+-- instance CF.Get_C Verbosity where
+--     get parser section option = do
+--         s <- CF.get parser section option
+--         case s of
+--             "Silent"           -> return Silent
+--             "Quiet"            -> return Quiet
+--             "Normal"           -> return Normal
+--             "Verbose"          -> return Verbose
+--             "VeryVerbose"      -> return VeryVerbose
+--             "ExtremelyVerbose" -> return ExtremelyVerbose
+--             _ -> throwError $ (CF.ParseError $ "Invalid Verbosity value: " ++ s, "")
+
+-- ====================================================================
+-- * Server options
+
+-- | Specify general server options used both in realtime and non-realtime
+-- mode.
+data ServerOptions = ServerOptions {
+    serverProgram               :: FilePath          -- ^ Path to the @scsynth@ program
+  , numberOfControlBusChannels  :: Int               -- ^ Number of allocated control bus channels
+  , numberOfAudioBusChannels    :: Int               -- ^ Number of allocated audio bus channels
+  , numberOfInputBusChannels    :: Int               -- ^ Number of physical input channels
+  , numberOfOutputBusChannels   :: Int               -- ^ Number of physical output channels
+  , blockSize                   :: Int               -- ^ Synthesis block size
+  , numberOfSampleBuffers       :: Int               -- ^ Number of allocated sample buffers
+  , maxNumberOfNodes            :: Int               -- ^ Maximum number of synthesis nodes
+  , maxNumberOfSynthDefs        :: Int               -- ^ Maximum number of synth definitions
+  , realtimeMemorySize          :: Int               -- ^ Realtime memory size in bytes
+  , numberOfWireBuffers         :: Int               -- ^ Number of unit generator connection buffers
+  , numberOfRandomSeeds         :: Int               -- ^ Number of random number generator seeds
+  , loadSynthDefs               :: Bool              -- ^ If 'True', load synth definitions from /synthdefs/ directory on startup
+  , verbosity                   :: Verbosity         -- ^ 'Verbosity' level
+  , ugenPluginPath              :: Maybe [FilePath]  -- ^ List of UGen plugin search paths
+  , restrictedPath              :: Maybe FilePath    -- ^ Sandbox path to restrict OSC command filesystem access
+  } deriving (Eq, Show)
+
+-- | Default server options.
+defaultServerOptions :: ServerOptions
+defaultServerOptions = ServerOptions {
+    serverProgram              = "scsynth"
+  , numberOfControlBusChannels = 4096
+  , numberOfAudioBusChannels   = 128
+  , numberOfInputBusChannels   = 8
+  , numberOfOutputBusChannels  = 8
+  , blockSize                  = 64
+  , numberOfSampleBuffers      = 1024
+  , maxNumberOfNodes           = 1024
+  , maxNumberOfSynthDefs       = 1024
+  , realtimeMemorySize         = 8192
+  , numberOfWireBuffers        = 64
+  , numberOfRandomSeeds        = 64
+  , loadSynthDefs              = True
+  , verbosity                  = Normal
+  , ugenPluginPath             = Nothing
+  , restrictedPath             = Nothing
+  }
+
+-- ====================================================================
+-- * Realtime options
+
+data NetworkPort =
+    UDPPort Int
+  | TCPPort Int
+  deriving (Eq, Show)
+
+-- | Default network port number.
+defaultPortNumber :: Int
+defaultPortNumber = 57110
+
+-- | Default UDP port.
+defaultUDPPort :: NetworkPort
+defaultUDPPort = UDPPort defaultPortNumber
+
+-- | Default TCP port.
+defaultTCPPort :: NetworkPort
+defaultTCPPort = TCPPort defaultPortNumber
+
+-- | Realtime server options, parameterized by the OpenSoundControl
+-- 'Transport' to be used.
+data RTOptions = RTOptions {
+    -- Network control
+    networkPort             :: NetworkPort     -- ^ Network port
+  , useZeroconf             :: Bool            -- ^ If 'True', publish scsynth service through Zeroconf
+  , maxNumberOfLogins       :: Int             -- ^ Max number of supported logins if 'sessionPassword' is set
+  , sessionPassword         :: Maybe String    -- ^ Session password
+  -- Audio device control
+  , hardwareDeviceName      :: Maybe String    -- ^ Hardware device name (JACK client:server name on Linux)
+  , hardwareBufferSize      :: Int             -- ^ Hardware buffer size (no effect with JACK)
+  , hardwareSampleRate      :: Int             -- ^ Hardware buffer size (no effect with JACK)
+  , inputStreamsEnabled     :: Maybe Int       -- ^ Enabled input streams (CoreAudio only)
+  , outputStreamsEnabled    :: Maybe Int       -- ^ Enabled output streams (CoreAudio only)
+  } deriving (Eq, Show)
+
+-- | Default realtime server options.
+defaultRTOptions :: RTOptions
+defaultRTOptions = RTOptions {
+    -- Network control
+    networkPort             = defaultUDPPort
+  , useZeroconf             = False
+  , maxNumberOfLogins       = 16
+  , sessionPassword         = Nothing
+    -- Audio device control
+  , hardwareDeviceName      = Nothing
+  , hardwareBufferSize      = 0
+  , hardwareSampleRate      = 0
+  , inputStreamsEnabled     = Nothing
+  , outputStreamsEnabled    = Nothing
+  }
+
+-- | Default realtime server options (UDP transport).
+defaultRTOptionsUDP :: RTOptions
+defaultRTOptionsUDP =  defaultRTOptions { networkPort = defaultUDPPort }
+
+-- | Default realtime server options (TCP transport).
+defaultRTOptionsTCP :: RTOptions
+defaultRTOptionsTCP = defaultRTOptions { networkPort = defaultTCPPort }
+
+-- ====================================================================
+-- * Non-Realtime options
+
+-- | Non-realtime server options.
+data NRTOptions = NRTOptions {
+    commandFilePath    :: Maybe FilePath    -- ^ Path to OSC command file ('Nothing' for stdin)
+  , inputFilePath      :: Maybe FilePath    -- ^ Path to input sound file ('Nothing' for no audio input)
+  , outputFilePath     :: FilePath          -- ^ Path to output sound file
+  , outputSampleRate   :: Int               -- ^ Output sound file sample rate
+  , outputHeaderFormat :: String            -- ^ Output sound file header format
+  , outputSampleFormat :: String            -- ^ Output sound file sample format
+} deriving (Eq, Show)
+
+-- | Default non-realtime server options.
+defaultNRTOptions :: NRTOptions
+defaultNRTOptions = NRTOptions {
+    commandFilePath    = Nothing
+  , inputFilePath      = Nothing
+  , outputFilePath     = "output.wav"
+  , outputSampleRate   = 44100
+  , outputHeaderFormat = "wav"
+  , outputSampleFormat = "int16"
+  }
diff --git a/hsc3-process.cabal b/hsc3-process.cabal
--- a/hsc3-process.cabal
+++ b/hsc3-process.cabal
@@ -1,7 +1,10 @@
 Name:               hsc3-process
-Version:            0.6.0
+Version:            0.7.0
 Synopsis:           Create and control scsynth processes
-Description:        Create and control scsynth processes.
+Description:
+    This library allows to create and control scsynth processes.
+    .
+    ChangeLog: <https://github.com/kaoskorobase/hsc3-process/blob/master/ChangeLog.md>
 License:            GPL
 License-File:       LICENSE
 Category:           Sound
@@ -10,7 +13,7 @@
 Maintainer:         Stefan Kersten
 Stability:          experimental
 Homepage:           http://space.k-hornz.de/software/hsc3-process
-Tested-With:        GHC == 6.10.1, GHC == 6.12.3, GHC == 7.0.1
+Tested-With:        GHC == 6.10, GHC == 6.12, GHC == 7.0, GHC == 7.2
 Build-Type:         Simple
 Cabal-Version:      >= 1.6
 
@@ -19,27 +22,17 @@
                     examples/sine.hs
 
 Library
-  Exposed-Modules:  Sound.SC3.Server.Internal
-                    Sound.SC3.Server.Options
-                    Sound.SC3.Server.Process
+  Exposed-Modules:  Sound.SC3.Server.Process
                     Sound.SC3.Server.Process.CommandLine
-                    -- Sound.SC3.Server.Process.ConfigFile
-  -- Other-Modules:    Sound.SC3.Server.Process.Accessor
+                    Sound.SC3.Server.Process.Options
 
   Build-Depends:    base >= 3 && < 5
-                  , bindings-sc3 >= 0.3.0
-                  , bytestring >= 0.8
-                  -- , ConfigFile >= 1
-                  , containers >= 0.2
-                  , data-accessor >= 0.2
-                  -- , data-accessor-template >= 0.2
-                  -- , data-accessor-transformers >= 0.2
-                  , hosc >= 0.7
-                  , hsc3 >= 0.7
-                  , mtl >= 2.0 && < 2.1
-                  , process >= 1.0
-                  , regex-compat >= 0.9
-                  , transformers >= 0.2.0 && < 0.3.0
+                  , bytestring >= 0.8 && < 0.10
+                  , containers >= 0.2 && < 0.6
+                  , hosc >= 0.7 && < 0.12
+                  , hsc3 >= 0.7 && < 0.12
+                  , process >= 1.0 && < 1.2
+                  , transformers >= 0.2 && < 0.4
 
   Ghc-Options:      -W
  
