module Haskore.Interface.CSound.Play where
import Haskore.RealTime.ShellPipe (launch)
import System.IO (IO)
import qualified System.IO as IO
import qualified System.Posix.Signals as Signals
import System.Cmd(system)
import System.Directory(doesFileExist,removeFile)
import Haskore.Interface.CSound(Name)
import qualified Haskore.Interface.CSound.Orchestra as Orchestra
import qualified Haskore.Interface.CSound.Score as Score
play :: Orchestra.Output out => Orchestra.T out -> Score.T -> IO ()
play orc sco = playV4 "/tmp" ("tmp", orc, sco)
scorePipe, tmpWave :: FilePath
scorePipe = "/tmp/pipe.sco"
tmpWave = "/tmp/csound.wav"
playV4, playV5 :: Orchestra.Output out =>
FilePath -> (Name, Orchestra.T out, Score.T) -> IO ()
playV4 dir (name, o@(Orchestra.Cons (rate, _) _), s) =
playNamedPipe ("csound32 -d -o stdout -s ", " 2>/dev/null" ++
" | play -t sw -r " ++ show rate ++
" -c " ++ show (Orchestra.channelCount o) ++
" - &")
dir name o s
playV5 dir (name, o, s) =
playNamedPipe ("csound5 -d -o dac -s ", " >/dev/null &") dir name o s
playNamedPipe :: Orchestra.Output out =>
(String, String) -> FilePath -> Name -> Orchestra.T out -> Score.T -> IO ()
playNamedPipe cmd dir name o s =
let orchName = dir ++ "/" ++ name ++ ".orc"
in do
exists <- doesFileExist scorePipe
if exists
then putStrLn (scorePipe ++ " already exists")
else system ("mkfifo " ++ scorePipe) >> return ()
writeFile orchName (Orchestra.toString o)
system (fst cmd ++ orchName ++ " " ++ scorePipe ++ snd cmd)
writeFile scorePipe (Score.toString s)
removeFile scorePipe
playV5NamedPipe :: Orchestra.Output out =>
FilePath -> (Name, Score.T, Orchestra.T out) -> IO ()
playV5NamedPipe dir (name, s, o) =
let orchName = dir ++ "/" ++ name ++ ".orc"
in do
Signals.installHandler Signals.sigPIPE
Signals.Ignore Nothing
writeFile orchName (Orchestra.toString o)
(input,_,_) <- launch "csound"
["csound", "-d", "-odac", orchName, scorePipe]
IO.hClose input
writeFile scorePipe (Score.toString s)
return ()
playV4NamedPipe :: Orchestra.Output out =>
FilePath -> (Name, Score.T, Orchestra.T out) -> IO ()
playV4NamedPipe dir (name, s, o) =
let orchName = dir ++ "/" ++ name ++ ".orc"
Orchestra.Cons (rate, _) _ = o
in do
Signals.installHandler Signals.sigPIPE
Signals.Ignore Nothing
writeFile orchName (Orchestra.toString o)
(input,_,_) <- launch "play"
["play", "-r", show rate,
"-c", show (Orchestra.channelCount o),
"-"]
(_,_,output) <- launch "csound32"
["csound32", "-d", "-o", tmpWave, "-s",
orchName, scorePipe]
writeFile scorePipe (Score.toString s)
IO.hGetContents output >>= IO.hPutStr input
IO.hClose input
IO.hClose output
playV4AnonymousPipe :: Orchestra.Output out =>
FilePath -> (Name, Score.T, Orchestra.T out) -> IO ()
playV4AnonymousPipe dir (name, s, o) =
let orchName = dir ++ "/" ++ name ++ ".orc"
in do
Signals.installHandler Signals.sigPIPE
Signals.Ignore Nothing
writeFile orchName (Orchestra.toString o)
(input,_,_) <- launch "csound32"
["csound32", "-d", "-o", tmpWave, "-W",
"-L", "stdin", orchName]
IO.hPutStr input (Score.toString s)
IO.hClose input