module Haskore.Interface.SuperCollider.Render (
fileFromMelody, fileFromMelodyMonad,
byteStringFromSchedule, runSCSynth,
HeaderFormat(..), SampleFormat(..),
) where
import qualified Haskore.Interface.SuperCollider.Schedule as Schedule
import qualified Haskore.Interface.SuperCollider.Play as Play
import Haskore.Interface.SuperCollider.SoundMap (Instrument)
import qualified Sound.SC3.Server.NRT as SCNRT
import qualified Sound.SC3.Server.PlayEasy as SCPlay
import qualified Data.ByteString.Lazy as B
import qualified Haskore.Melody as Melody
import qualified Haskore.RealTime.Timer.Immediate as TimerImmediate
import System.Cmd (rawSystem)
import System.Exit (ExitCode)
import Data.Array(Array, Ix, (!), listArray)
fileFromMelody :: FilePath -> Instrument -> Melody.T () -> IO ()
fileFromMelody fileName sound =
B.writeFile fileName .
byteStringFromSchedule .
Schedule.fromMelody sound
fileFromMelodyMonad :: FilePath -> Instrument -> Melody.T () -> IO ()
fileFromMelodyMonad fileName sound =
SCPlay.withSC3File fileName .
Play.scheduleWithPlayer
(Play.messagesGrouped TimerImmediate.timer 0) .
Schedule.fromMelody sound
data HeaderFormat = AIFF | Wave | NeXT
deriving (Read, Show, Eq, Ord, Ix, Bounded)
headerExtension :: Array HeaderFormat String
headerExtension =
listArray (minBound,maxBound) ["aiff", "wav", "au"]
headerName :: Array HeaderFormat String
headerName =
listArray (minBound,maxBound) ["AIFF", "WAVE", "NeXT"]
data SampleFormat = Int16 | Int24 | Int32 | Float | Double
deriving (Read, Show, Eq, Ord, Ix, Bounded)
sampleName :: Array SampleFormat String
sampleName =
listArray (minBound,maxBound)
["int16", "int24", "int32", "float", "double"]
runSCSynth ::
[String] ->
Int ->
HeaderFormat ->
SampleFormat ->
Int ->
FilePath ->
IO ExitCode
runSCSynth
options numChannels headerFormat sampleFormat sampleRate fileName =
rawSystem "scsynth"
(options ++
["-D", "0", "-o", show numChannels, "-N",
fileName++".osc", "_", fileName ++ '.' : headerExtension ! headerFormat,
show sampleRate, headerName ! headerFormat, sampleName ! sampleFormat])
byteStringFromSchedule :: Schedule.T -> B.ByteString
byteStringFromSchedule =
SCNRT.encodeNRT .
Schedule.toStream