module Sound.Sc3.Server.Transport.Fd where
import Control.Monad
import qualified Data.ByteString.Lazy as L
import Data.List
import qualified Data.List.Split as Split
import System.FilePath
import Sound.Osc.Fd
import Sound.Sc3.Server.Command
import Sound.Sc3.Server.Enum
import qualified Sound.Sc3.Server.Graphdef as Graphdef
import qualified Sound.Sc3.Server.Graphdef.Binary as Graphdef
import Sound.Sc3.Server.Nrt
import Sound.Sc3.Server.Options
import Sound.Sc3.Server.Status
import Sound.Sc3.Server.Synthdef
import Sound.Sc3.Ugen.Ugen
async :: Transport t => t -> Message -> IO Message
async :: forall t. Transport t => t -> Message -> IO Message
async t
fd Message
m = forall t. Transport t => t -> Message -> IO ()
sendMessage t
fd Message
m forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall t. Transport t => t -> Address_Pattern -> IO Message
waitReply t
fd Address_Pattern
"/done"
maybe_async :: (Transport t) => t -> Message -> IO ()
maybe_async :: forall t. Transport t => t -> Message -> IO ()
maybe_async t
fd Message
m = if Message -> Bool
isAsync Message
m then forall (f :: * -> *) a. Functor f => f a -> f ()
void (forall t. Transport t => t -> Message -> IO Message
async t
fd Message
m) else forall t. Transport t => t -> Message -> IO ()
sendMessage t
fd Message
m
maybe_async_at :: (Transport t) => t -> Time -> Message -> IO ()
maybe_async_at :: forall t. Transport t => t -> Time -> Message -> IO ()
maybe_async_at t
fd Time
t Message
m =
if Message -> Bool
isAsync Message
m
then forall (f :: * -> *) a. Functor f => f a -> f ()
void (forall t. Transport t => t -> Message -> IO Message
async t
fd Message
m)
else forall t. Transport t => t -> Bundle -> IO ()
sendBundle t
fd (Time -> [Message] -> Bundle
bundle Time
t [Message
m])
withSc3 :: (Udp -> IO a) -> IO a
withSc3 :: forall a. (Udp -> IO a) -> IO a
withSc3 = forall t a. Transport t => IO t -> (t -> IO a) -> IO a
withTransport (Address_Pattern -> Int -> IO Udp
openUdp Address_Pattern
"127.0.0.1" forall i. Num i => i
sc3_port_def)
stop :: Transport t => t -> IO ()
stop :: forall t. Transport t => t -> IO ()
stop t
fd = forall t. Transport t => t -> Message -> IO ()
sendMessage t
fd ([Int] -> Message
g_freeAll [Int
1])
reset :: Transport t => t -> IO ()
reset :: forall t. Transport t => t -> IO ()
reset t
fd = do
forall t. Transport t => t -> Message -> IO ()
sendMessage t
fd ([Int] -> Message
g_freeAll [Int
1,Int
2])
forall t. Transport t => t -> Message -> IO ()
sendMessage t
fd ([(Int, AddAction, Int)] -> Message
g_new [(Int
1,AddAction
AddToTail,Int
0),(Int
2,AddAction
AddToTail,Int
0)])
playGraphdef :: Transport t => Int -> t -> Graphdef.Graphdef -> IO ()
playGraphdef :: forall t. Transport t => Int -> t -> Graphdef -> IO ()
playGraphdef Int
k t
fd Graphdef
g = do
let nm :: Address_Pattern
nm = Ascii -> Address_Pattern
ascii_to_string (Graphdef -> Ascii
Graphdef.graphdef_name Graphdef
g)
fn :: Address_Pattern
fn = Address_Pattern
"/tmp" Address_Pattern -> Address_Pattern -> Address_Pattern
</> Address_Pattern
nm Address_Pattern -> Address_Pattern -> Address_Pattern
<.> Address_Pattern
"scsyndef"
by :: ByteString
by = Graphdef -> ByteString
Graphdef.encode_graphdef Graphdef
g
sz :: Int64
sz = ByteString -> Int64
L.length ByteString
by
if Int64
sz forall a. Ord a => a -> a -> Bool
< Int64
65507
then forall (f :: * -> *) a. Functor f => f a -> f ()
void (forall t. Transport t => t -> Message -> IO Message
async t
fd (ByteString -> Message
d_recv_bytes ByteString
by))
else Address_Pattern -> Graphdef -> IO ()
Graphdef.graphdefWrite Address_Pattern
fn Graphdef
g forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall t. Transport t => t -> Message -> IO Message
async t
fd (Address_Pattern -> Message
d_load Address_Pattern
fn) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall t. Transport t => t -> Message -> IO ()
sendMessage t
fd (Address_Pattern -> Int -> AddAction -> Int -> Message
s_new0 Address_Pattern
nm Int
k AddAction
AddToTail Int
1)
playSynthdef :: Transport t => Int -> t -> Synthdef -> IO ()
playSynthdef :: forall t. Transport t => Int -> t -> Synthdef -> IO ()
playSynthdef Int
k t
fd = forall t. Transport t => Int -> t -> Graphdef -> IO ()
playGraphdef Int
k t
fd forall b c a. (b -> c) -> (a -> b) -> a -> c
. Synthdef -> Graphdef
synthdef_to_graphdef
playUgen :: Transport t => Int -> t -> Ugen -> IO ()
playUgen :: forall t. Transport t => Int -> t -> Ugen -> IO ()
playUgen Int
k t
fd = forall t. Transport t => Int -> t -> Synthdef -> IO ()
playSynthdef Int
k t
fd forall b c a. (b -> c) -> (a -> b) -> a -> c
. Address_Pattern -> Ugen -> Synthdef
synthdef Address_Pattern
"Anonymous"
run_bundle :: Transport t => t -> Time -> Bundle -> IO ()
run_bundle :: forall t. Transport t => t -> Time -> Bundle -> IO ()
run_bundle t
fd Time
t0 Bundle
b = do
let t :: Time
t = Time
t0 forall a. Num a => a -> a -> a
+ Bundle -> Time
bundleTime Bundle
b
latency :: Time
latency = Time
0.1
forall (m :: * -> *) n. (MonadIO m, RealFrac n) => n -> m ()
pauseThreadUntil (Time
t forall a. Num a => a -> a -> a
- Time
latency)
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (forall t. Transport t => t -> Time -> Message -> IO ()
maybe_async_at t
fd Time
t) (Bundle -> [Message]
bundleMessages Bundle
b)
nrt_play :: Transport t => t -> Nrt -> IO ()
nrt_play :: forall t. Transport t => t -> Nrt -> IO ()
nrt_play t
fd Nrt
sc = forall (m :: * -> *). MonadIO m => m Time
time forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Time
t0 -> forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (forall t. Transport t => t -> Time -> Bundle -> IO ()
run_bundle t
fd Time
t0) (Nrt -> [Bundle]
nrt_bundles Nrt
sc)
nrt_audition :: Nrt -> IO ()
nrt_audition :: Nrt -> IO ()
nrt_audition Nrt
sc = forall a. (Udp -> IO a) -> IO a
withSc3 (forall t. Transport t => t -> Nrt -> IO ()
`nrt_play` Nrt
sc)
class Audible e where
play_id :: Transport t => Int -> t -> e -> IO ()
play :: Transport t => t -> e -> IO ()
play = forall e t. (Audible e, Transport t) => Int -> t -> e -> IO ()
play_id (-Int
1)
instance Audible Graphdef.Graphdef where
play_id :: forall t. Transport t => Int -> t -> Graphdef -> IO ()
play_id = forall t. Transport t => Int -> t -> Graphdef -> IO ()
playGraphdef
instance Audible Synthdef where
play_id :: forall t. Transport t => Int -> t -> Synthdef -> IO ()
play_id = forall t. Transport t => Int -> t -> Synthdef -> IO ()
playSynthdef
instance Audible Ugen where
play_id :: forall t. Transport t => Int -> t -> Ugen -> IO ()
play_id = forall t. Transport t => Int -> t -> Ugen -> IO ()
playUgen
audition_id :: Audible e => Int -> e -> IO ()
audition_id :: forall e. Audible e => Int -> e -> IO ()
audition_id Int
k e
e = forall a. (Udp -> IO a) -> IO a
withSc3 (\Udp
fd -> forall e t. (Audible e, Transport t) => Int -> t -> e -> IO ()
play_id Int
k Udp
fd e
e)
audition :: Audible e => e -> IO ()
audition :: forall e. Audible e => e -> IO ()
audition = forall e. Audible e => Int -> e -> IO ()
audition_id (-Int
1)
withNotifications :: Transport t => t -> (t -> IO a) -> IO a
withNotifications :: forall t a. Transport t => t -> (t -> IO a) -> IO a
withNotifications t
fd t -> IO a
f = do
Message
_ <- forall t. Transport t => t -> Message -> IO Message
async t
fd (Bool -> Message
notify Bool
True)
a
r <- t -> IO a
f t
fd
Message
_ <- forall t. Transport t => t -> Message -> IO Message
async t
fd (Bool -> Message
notify Bool
False)
forall (m :: * -> *) a. Monad m => a -> m a
return a
r
b_getn1_data :: Transport t => t -> Int -> (Int,Int) -> IO [Double]
b_getn1_data :: forall t. Transport t => t -> Int -> (Int, Int) -> IO [Time]
b_getn1_data t
fd Int
b (Int, Int)
s = do
let f :: Message -> [Time]
f Message
m = let (Int
_,Int
_,Int
_,[Time]
r) = Message -> (Int, Int, Int, [Time])
unpack_b_setn_err Message
m in [Time]
r
forall t. Transport t => t -> Message -> IO ()
sendMessage t
fd (Int -> (Int, Int) -> Message
b_getn1 Int
b (Int, Int)
s)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Message -> [Time]
f (forall t. Transport t => t -> Address_Pattern -> IO Message
waitReply t
fd Address_Pattern
"/b_setn")
b_getn1_data_segment :: Transport t => t -> Int -> Int -> (Int,Int) -> IO [Double]
b_getn1_data_segment :: forall t. Transport t => t -> Int -> Int -> (Int, Int) -> IO [Time]
b_getn1_data_segment t
fd Int
n Int
b (Int
i,Int
j) = do
let ix :: [(Int, Int)]
ix = Int -> Int -> Int -> [(Int, Int)]
b_indices Int
n Int
j Int
i
[[Time]]
d <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall t. Transport t => t -> Int -> (Int, Int) -> IO [Time]
b_getn1_data t
fd Int
b) [(Int, Int)]
ix
forall (m :: * -> *) a. Monad m => a -> m a
return (forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Time]]
d)
b_fetch :: Transport t => t -> Int -> Int -> IO [[Double]]
b_fetch :: forall t. Transport t => t -> Int -> Int -> IO [[Time]]
b_fetch t
fd Int
n Int
b = do
let f :: Message -> IO [[Time]]
f Message
m = let (Int
_,Int
nf,Int
nc,Time
_) = Message -> (Int, Int, Int, Time)
unpack_b_info_err Message
m
ix :: (Int, Int)
ix = (Int
0,Int
nf forall a. Num a => a -> a -> a
* Int
nc)
deinterleave :: [a] -> [[a]]
deinterleave = forall a. [[a]] -> [[a]]
transpose forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e. Int -> [e] -> [[e]]
Split.chunksOf Int
nc
in forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall {a}. [a] -> [[a]]
deinterleave (forall t. Transport t => t -> Int -> Int -> (Int, Int) -> IO [Time]
b_getn1_data_segment t
fd Int
n Int
b (Int, Int)
ix)
forall t. Transport t => t -> Message -> IO ()
sendMessage t
fd (Int -> Message
b_query1 Int
b)
forall t. Transport t => t -> Address_Pattern -> IO Message
waitReply t
fd Address_Pattern
"/b_info" forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Message -> IO [[Time]]
f
b_fetch1 :: Transport t => t -> Int -> Int -> IO [Double]
b_fetch1 :: forall t. Transport t => t -> Int -> Int -> IO [Time]
b_fetch1 t
fd Int
n Int
b = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. [a] -> a
head (forall t. Transport t => t -> Int -> Int -> IO [[Time]]
b_fetch t
fd Int
n Int
b)
serverStatus :: Transport t => t -> IO [String]
serverStatus :: forall t. Transport t => t -> IO [Address_Pattern]
serverStatus = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Datum] -> [Address_Pattern]
statusFormat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t. Transport t => t -> IO [Datum]
serverStatusData
serverSampleRateNominal :: Transport t => t -> IO Double
serverSampleRateNominal :: forall t. Transport t => t -> IO Time
serverSampleRateNominal = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall n. Floating n => Int -> [Datum] -> n
extractStatusField Int
7) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t. Transport t => t -> IO [Datum]
serverStatusData
serverSampleRateActual :: Transport t => t -> IO Double
serverSampleRateActual :: forall t. Transport t => t -> IO Time
serverSampleRateActual = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall n. Floating n => Int -> [Datum] -> n
extractStatusField Int
8) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t. Transport t => t -> IO [Datum]
serverStatusData
serverStatusData :: Transport t => t -> IO [Datum]
serverStatusData :: forall t. Transport t => t -> IO [Datum]
serverStatusData t
fd = do
forall t. Transport t => t -> Message -> IO ()
sendMessage t
fd Message
status
forall t. Transport t => t -> Address_Pattern -> IO [Datum]
waitDatum t
fd Address_Pattern
"/status.reply"