-- | A @VividAction m => m a@ can either be run immediately, be scheduled to run at a -- precise future time, or be used for non-realtime synthesis. -- -- Note that at the moment VividAction has MonadIO, but this won't be true in -- upcoming versions (as early as the next release) - so don't get used -- to it! {-# LANGUAGE KindSignatures #-} {-# LANGUAGE NoIncoherentInstances #-} {-# LANGUAGE NoMonomorphismRestriction #-} {-# LANGUAGE NoUndecidableInstances #-} module Vivid.Actions.Class ( VividAction(..) , callOSCAndSync ) where import Vivid.OSC import Vivid.SCServer.State (BufferId, NodeId, SyncId(..)) import Vivid.SynthDef.Types (SynthDef) import Data.ByteString (ByteString) import qualified Data.ByteString.Char8 as BS8 (pack) import Control.Monad.IO.Class (MonadIO) class (Monad m , MonadIO m) => VividAction (m :: * -> *) where -- | Send an 'OSC' message to the SuperCollider server callOSC :: OSC -> m () callOSC = callBS . encodeOSC -- | Send a ByteString to the SuperCollider server. -- You usually want to use 'call' instead. callBS :: ByteString -> m () -- | Blocks until the server finishes processing commands sync :: m () -- | As the user, you probably don't want to use this: -- -- Many commands already include a \"sync\" -- e.g. -- 'makeBuffer' already syncs. -- -- When you do want to do an -- explicit sync you probably want to use 'sync' instead, or -- 'callOSCAndSync' waitForSync :: SyncId -> m () -- | Wait, in seconds wait :: RealFrac n => n -> m () getTime :: m Timestamp newBufferId :: m BufferId newNodeId :: m NodeId newSyncId :: m SyncId fork :: m () -> m () -- | Send a synth definition to be loaded on the SC server -- -- Note that this is sort of optional -- if you don't call it, it'll be called the first time -- you call 'synth' with the SynthDef defineSD :: SynthDef a -> m () -- | Send an OSC message and wait for it to complete before returning callOSCAndSync :: VividAction m => OSC -> m () callOSCAndSync message = do now <- getTime sid@(SyncId syncId) <- newSyncId callBS $ encodeOSCBundle $ OSCBundle now [Right message, Right $ OSC (BS8.pack "/sync") [OSC_I syncId]] waitForSync sid