module Haskore.Interface.MIDI.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 qualified Haskore.Music.GeneralMIDI as MidiMusic
import qualified Haskore.Music.Rhythmic as RhyMusic
import qualified Haskore.Performance.Context as Context
import qualified Haskore.Interface.MIDI.InstrumentMap as InstrMap
import qualified Haskore.Interface.MIDI.Write as WriteMidi
import qualified Haskore.Interface.MIDI.Render as Render
import qualified Sound.MIDI.File.Save as SaveMidi
import qualified Numeric.NonNegative.Class as NonNeg
import Data.Char (chr, )
import Data.Word (Word8, )
play ::
(Ord instr, Ord drum,
NonNeg.C time, RealFrac time, Fractional time, RealFrac dyn) =>
(InstrMap.ChannelProgramPitchTable drum,
InstrMap.ChannelProgramTable instr,
Context.T time dyn (RhyMusic.Note drum instr),
RhyMusic.T drum instr)
-> IO ()
play = playRaw [] . SaveMidi.toByteList . WriteMidi.fromRhythmicMusicMixed
playSimple :: MidiMusic.T -> IO ()
playSimple = playRaw [] . SaveMidi.toByteList . Render.mixedGeneralMidi
playRaw :: [String] -> ByteList -> IO ()
playRaw args stream =
do
Signals.installHandler Signals.sigPIPE
Signals.Ignore Nothing
(input,_,_) <- launch "timidity"
(["timidity", "-B", "8,9"] ++ args ++ ["-"])
IO.hPutStr input (stringCharFromByte stream)
IO.hClose input
type ByteList = [Word8]
stringCharFromByte :: ByteList -> String
stringCharFromByte = map (chr . fromIntegral)