module Sound.SC3.Server.NRT where
import qualified Data.ByteString.Lazy as B
import Data.Maybe
import Sound.OpenSoundControl
import Sound.OpenSoundControl.Coding.Byte
import System.Exit
import System.IO
import System.Process
oscWithSize :: Bundle -> B.ByteString
oscWithSize o =
let b = encodeBundle o
l = encode_i32 (fromIntegral (B.length b))
in B.append l b
data NRT = NRT {nrt_bundles :: [Bundle]} deriving (Show)
encodeNRT :: NRT -> B.ByteString
encodeNRT = B.concat . map oscWithSize . nrt_bundles
writeNRT :: FilePath -> NRT -> IO ()
writeNRT fn = B.writeFile fn . encodeNRT
putNRT :: Handle -> NRT -> IO ()
putNRT h = B.hPut h . encodeNRT
decode_nrt_bundles :: B.ByteString -> [Bundle]
decode_nrt_bundles s =
let (p,q) = B.splitAt 4 s
n = fromIntegral (decode_i32 p)
(r,s') = B.splitAt n q
r' = decodeBundle r
in if B.null s'
then [r']
else r' : decode_nrt_bundles s'
decodeNRT :: B.ByteString -> NRT
decodeNRT = NRT . decode_nrt_bundles
readNRT :: FilePath -> IO NRT
readNRT = fmap decodeNRT . B.readFile
data NRT_File_Format = AIFF | FLAC | NeXT | WAVE deriving (Eq,Show)
data NRT_Sample_Format = I16 | I24 | I32 | F32 | F64 deriving (Eq,Show)
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}
nrt_sf_pp :: NRT_Sample_Format -> String
nrt_sf_pp f =
case f of
I16 -> "int16"
I24 -> "int24"
I32 -> "int32"
F32 -> "float"
F64 -> "double"
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_cmd :: [String] -> NRT_Render -> String
renderNRT_cmd x =
let protect s = '\'' : s ++ "\'"
in unwords . ("scsynth" :) . map protect . (x ++) . renderNRT_opt
renderNRT :: [String] -> NRT_Render -> IO ExitCode
renderNRT o = rawSystem "scsynth" . (o ++ ) . renderNRT_opt