synthesizer-llvm-0.3: src/Synthesizer/LLVM/Server/Scalar/Run.hs
module Synthesizer.LLVM.Server.Scalar.Run where
import qualified Synthesizer.LLVM.Server.Scalar.Instrument as Instr
import qualified Synthesizer.LLVM.Server.Option as Option
import Synthesizer.LLVM.Server.Common
import qualified Sound.ALSA.Sequencer.Event as Event
import qualified Data.EventList.Relative.TimeBody as EventList
import qualified Synthesizer.EventList.ALSA.MIDI as Ev
import qualified Synthesizer.PiecewiseConstant.ALSA.MIDI as PC
import qualified Synthesizer.Generic.ALSA.MIDI as Gen
import qualified Synthesizer.LLVM.Frame.Stereo as Stereo
import qualified Synthesizer.LLVM.ALSA.MIDI as MIDIL
import qualified Synthesizer.LLVM.CausalParameterized.Process as CausalP
import qualified Synthesizer.LLVM.Parameterized.Signal as SigP
import qualified Synthesizer.LLVM.Storable.Signal as SigStL
import qualified Synthesizer.LLVM.Wave as WaveL
import Synthesizer.LLVM.CausalParameterized.Process (($<#), ($*), )
import Synthesizer.LLVM.Parameterized.Signal (($#), )
import qualified Synthesizer.Storable.Signal as SigSt
import qualified Sound.MIDI.Message.Channel.Voice as VoiceMsg
import Control.Arrow ((<<<), arr, )
import Control.Monad.Trans.State (evalState, )
import NumericPrelude.Numeric (zero, (*>), )
import Prelude hiding (Real, break, )
sampleRate :: Num a => Option.T -> a
sampleRate opt =
case Option.sampleRate opt of
SampleRate sr -> sr
{-# INLINE withMIDIEvents #-}
withMIDIEvents ::
Option.T ->
(Option.T -> Double -> a -> IO b) ->
(EventList.T Ev.StrictTime [Event.T] -> a) -> IO b
withMIDIEvents opt action proc =
let rate = sampleRate opt
in do
putStrLn startMessage
Ev.withMIDIEvents
(Option.clientName opt) (Option.periodTime opt) rate $
action opt rate . proc
pitchBend :: IO ()
pitchBend = do
opt <- Option.get
osc <-
SigP.runChunky
((CausalP.osciSimple WaveL.triangle $<# (zero::Real))
$* piecewiseConstant (arr id))
withMIDIEvents opt play $
(id :: SigSt.T Real -> SigSt.T Real) .
osc (Option.chunkSize opt) .
evalState (PC.pitchBend (Option.channel opt) 2 (880/sampleRate opt::Real))
frequencyModulation :: IO ()
frequencyModulation = do
opt <- Option.get
osc <-
SigP.runChunky
(((CausalP.osciSimple WaveL.triangle $<# (zero::Real))
<<< (MIDIL.frequencyFromBendModulation $# (10/sampleRate opt::Real)))
$* piecewiseConstant (arr (transposeModulation (Option.sampleRate opt) 880)))
withMIDIEvents opt play $
(id :: SigSt.T Real -> SigSt.T Real) .
osc (Option.chunkSize opt) .
evalState (PC.bendWheelPressure (Option.channel opt) 2 0.04 (0.03::Real))
keyboard :: IO ()
keyboard = do
opt <- Option.get
-- sound <- Instr.pingDur
{-
sound <-
fmap (\s vel _freq dur -> s vel dur) $
(Instr.pingReleaseEnvelope $/ 0.4 $/ 0.1)
-}
sound <- Instr.pingRelease $/ 0.4 $/ 0.1
amp <- CausalP.runStorableChunky (CausalP.amplify $# 0.2)
arrange <- SigStL.makeArranger
withMIDIEvents opt play $
(amp () :: SigSt.T Real -> SigSt.T Real) .
arrange (Option.chunkSize opt) .
evalState
(Gen.sequence
(Option.channel opt)
(sound (Option.chunkSize opt) (Option.sampleRate opt)))
keyboardStereo :: IO ()
keyboardStereo = do
opt <- Option.get
sound <- Instr.pingStereoRelease $/ 0.4 $/ 0.1
amp <- CausalP.runStorableChunky (CausalP.amplifyStereo $# 0.2)
arrange <- SigStL.makeArranger
withMIDIEvents opt play $
(amp () :: SigSt.T (Stereo.T Real) -> SigSt.T (Stereo.T Real)) .
arrange (Option.chunkSize opt) .
evalState
(Gen.sequence
(Option.channel opt)
(sound (Option.chunkSize opt) (Option.sampleRate opt)))
keyboardMulti :: IO ()
keyboardMulti = do
opt <- Option.get
png <- Instr.pingDur
pngRel <- Instr.pingRelease $/ 0.4 $/ 0.1 $/ Option.chunkSize opt
tin <- Instr.tine $/ 0.4 $/ 0.1 $/ Option.chunkSize opt
arrange <- SigStL.makeArranger
withMIDIEvents opt play $
-- playALSA (Bld.put :: Int16 -> Bld.Builder Int16) (sampleRate opt::Real) .
SigSt.map (0.2*) .
arrange (Option.chunkSize opt) .
evalState (Gen.sequenceMultiProgram (Option.channel opt)
(VoiceMsg.toProgram 2)
(map (\sound -> sound $ Option.sampleRate opt) $
[png, pngRel, tin]))
keyboardStereoMulti :: IO ()
keyboardStereoMulti = do
opt <- Option.get
png <- Instr.pingStereoRelease $/ 0.4 $/ 0.1 $/ Option.chunkSize opt
tin <- Instr.tineStereo $/ 0.4 $/ 0.1 $/ Option.chunkSize opt
str <- Instr.softString
arrange <- SigStL.makeArranger
withMIDIEvents opt play $
-- playALSA (Bld.put :: Int16 -> Bld.Builder Int16) (sampleRate opt::Real) .
SigSt.map ((0.2::Real)*>) .
arrange (Option.chunkSize opt) .
evalState (Gen.sequenceMultiProgram (Option.channel opt)
(VoiceMsg.toProgram 1)
(map (\sound -> sound $ Option.sampleRate opt) $
[png, tin, str]))