module Sound.SC3.Server.Graphdef (graphdef) where import Sound.OpenSoundControl.Byte import Sound.OpenSoundControl.Cast import Sound.SC3.UGen.UGen (UGen(..), Special(..)) import Sound.SC3.UGen.Rate (rateId) import Sound.SC3.UGen.Graph import Data.Word import qualified Data.ByteString.Lazy as B -- | Byte-encode Input value. encode_input :: Input -> B.ByteString encode_input (Input u p) = B.append (encode_i16 u) (encode_i16 p) -- | Byte-encode Control value. encode_control :: Graph -> UGen -> B.ByteString encode_control g c@(Control _ n _) = B.concat [ B.pack (str_pstr n) , encode_i16 (nodeIndex g c)] encode_control _ _ = error "encode_control: illegal input" -- | Byte-encode UGen value. encode_ugen :: Graph -> UGen -> B.ByteString encode_ugen g (UGen r n i o s _) = B.concat [ B.pack (str_pstr n) , encode_i8 (rateId r) , encode_i16 (length i) , encode_i16 (length o) , encode_i16 s' , B.concat i' , B.concat o' ] where i' = map (encode_input . makeInput g) i o' = map (encode_i8 . rateId) o (Special s') = s encode_ugen _ _ = error "encode_ugen: illegal input" -- | Construct instrument definition bytecode. encode_graphdef :: String -> Graph -> B.ByteString encode_graphdef s g = B.concat [ encode_str "SCgf" , encode_i32 0 , encode_i16 1 , B.pack (str_pstr s) , encode_i16 (length n) , B.concat (map (encode_f32 . constantValue) n) , encode_i16 (length c) , B.concat (map (encode_f32 . controlDefault) c) , encode_i16 (length c) , B.concat (map (encode_control g) c) , encode_i16 (length u) , B.concat (map (encode_ugen g) u) ] where (Graph n c u _) = g -- | Construct instrument definition bytecode. graphdef :: String -> Graph -> [Word8] graphdef s g = B.unpack (encode_graphdef s g)