module Sound.SC3.Server.PlayEasy (
play, stop, reset, audition,
withSC3, withSC3UDP, withSC3TCP, withSC3File,
NodeId, noId, autoId, lastId, rootId, homeId,
set, setMulti, setId,
playIdCustomOut, playId, stopId,
sync, d_recv',
simpleSync, mceDegree,
) where
import Sound.SC3.UGen.IO (out)
import Sound.SC3.UGen.UGen (UGen(..))
import Sound.SC3.UGen.Graph (graph)
import Sound.SC3.Server.Graphdef (graphdef)
import Sound.SC3.Server.Command
(AddAction(AddToTail), s_new, d_recv, g_new, g_freeAll,
n_set, n_free)
import Sound.OpenSoundControl (OSC)
import Sound.OpenSoundControl.Transport.TCP (TCP)
import Sound.OpenSoundControl.Transport.UDP (UDP)
import Sound.OpenSoundControl.Transport.File (File)
import Sound.OpenSoundControl.Transport.Monad
(Transport, send, wait, withTransport)
import qualified Sound.OpenSoundControl.Transport.TCP as TCP
import qualified Sound.OpenSoundControl.Transport.UDP as UDP
import qualified Sound.OpenSoundControl.Transport.File as File
import qualified Sound.OpenSoundControl.Transport.Monad as Trans
type NodeId = Int
play :: Transport t => UGen -> Trans.IO t OSC
play u =
do send (d_recv' "Anonymous" (addOut u))
r <- wait "/done"
send (s_new "Anonymous" autoId AddToTail homeId [])
return r
stop :: Transport t => Trans.IO t ()
stop = send (g_freeAll [homeId])
reset :: Transport t => Trans.IO t ()
reset = send (g_freeAll [rootId]) >> init_
withSC3 :: Trans.IO UDP a -> IO a
withSC3 = withSC3UDP
withSC3UDP :: Trans.IO UDP a -> IO a
withSC3UDP = withTransport (UDP.openUDP "127.0.0.1" 57110)
withSC3TCP :: Trans.IO TCP a -> IO a
withSC3TCP = withTransport (TCP.openTCP "127.0.0.1" 57110)
withSC3File :: FilePath -> Trans.IO File a -> IO a
withSC3File fn = withTransport (File.open fn)
audition :: UGen -> IO OSC
audition = withSC3 . play
d_recv' :: String -> UGen -> OSC
d_recv' n = d_recv . graphdef n . graph
noId :: NodeId
noId = 1
autoId :: NodeId
autoId = 1
lastId :: NodeId
lastId = 1
rootId :: NodeId
rootId = 0
homeId :: NodeId
homeId = 1
sync :: Transport t => OSC -> Trans.IO t OSC
sync o = send o >> wait "/done"
simpleSync :: Transport t => OSC -> Trans.IO t ()
simpleSync o = sync o >> return ()
init_ :: Transport t => Trans.IO t ()
init_ = send (g_new [(homeId, AddToTail, rootId)])
playIdCustomOut :: Transport t => NodeId -> UGen -> Trans.IO t OSC
playIdCustomOut sid u =
do r <- sync (d_recv' "Anonymous" u)
send (s_new "Anonymous" sid AddToTail homeId [])
return r
set :: Transport t => String -> Double -> Trans.IO t ()
set = setId lastId
setMulti :: Transport t => [(String, Double)] -> Trans.IO t ()
setMulti = setMultiId lastId
playId :: Transport t => NodeId -> UGen -> Trans.IO t OSC
playId sid u = playIdCustomOut sid (addOut u)
stopId :: Transport t => NodeId -> Trans.IO t ()
stopId sid = send (n_free [sid])
setId :: Transport t => NodeId -> String -> Double -> Trans.IO t ()
setId sid name value = send (n_set sid [(name, value)])
setMultiId :: Transport t => NodeId -> [(String, Double)] -> Trans.IO t ()
setMultiId sid attrs = send (n_set sid attrs)
addOut :: UGen -> UGen
addOut u = if hasOutputs u then out (Constant 0) u else u
hasOutputs :: UGen -> Bool
hasOutputs (UGen _ _ _ o _ _) = not (null o)
hasOutputs (MCE l) = any hasOutputs l
hasOutputs (MRG l) = any hasOutputs l
hasOutputs (Proxy _ _) = True
hasOutputs _ = False
mceDegree :: UGen -> Int
mceDegree (UGen _ _ _ _ _ _) = 1
mceDegree (MCE l) = length l
mceDegree _ = error "mceDegree: illegal ugen"