module Synthesizer.LLVM.Server.Scalar.Run where
import qualified Synthesizer.LLVM.Server.Scalar.Instrument as Instr
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 Data.StorableVector.Lazy as SVL
import qualified Sound.MIDI.Message.Channel.Voice as VoiceMsg
import Control.Arrow ((<<<), arr, )
import Control.Monad.Trans.State (evalState, )
import qualified Algebra.Additive as Additive
import NumericPrelude.Numeric (zero, (*>), )
import Prelude hiding (Real, break, )
withMIDIEvents ::
(Double -> Double -> a -> IO b) ->
(EventList.T Ev.StrictTime [Event.T] -> a) -> IO b
withMIDIEvents action proc =
let rate = sampleRate
per = periodTime
in Ev.withMIDIEvents per rate $
action per rate . proc
pitchBend :: IO ()
pitchBend = do
osc <-
SigP.runChunky
((CausalP.osciSimple WaveL.triangle $<# (zero::Real))
$* piecewiseConstant (arr id))
withMIDIEvents play $
(id :: SigSt.T Real -> SigSt.T Real) .
osc chunkSize .
evalState (PC.pitchBend channel 2 (880/sampleRate::Real))
frequencyModulation :: IO ()
frequencyModulation = do
osc <-
SigP.runChunky
(((CausalP.osciSimple WaveL.triangle $<# (zero::Real))
<<< (MIDIL.frequencyFromBendModulation $# (10/sampleRate::Real)))
$* piecewiseConstant (arr (transposeModulation 880)))
withMIDIEvents play $
(id :: SigSt.T Real -> SigSt.T Real) .
osc chunkSize .
evalState (PC.bendWheelPressure channel 2 0.04 (0.03::Real))
keyboard :: IO ()
keyboard = do
sound <- Instr.pingRelease $/ 0.4 $/ 0.1
amp <- CausalP.runStorableChunky (CausalP.amplify $# 0.2)
arrange <- SigStL.makeArranger
withMIDIEvents play $
(amp () :: SigSt.T Real -> SigSt.T Real) .
evalState (Gen.sequence (arrange chunkSize) channel sound)
keyboardStereo :: IO ()
keyboardStereo = do
sound <- Instr.pingStereoRelease $/ 0.4 $/ 0.1
amp <- CausalP.runStorableChunky (CausalP.amplifyStereo $# 0.2)
arrange <- SigStL.makeArranger
withMIDIEvents play $
(amp () :: SigSt.T (Stereo.T Real) -> SigSt.T (Stereo.T Real)) .
evalState (Gen.sequence (arrange chunkSize) channel sound)
keyboardMulti :: IO ()
keyboardMulti = do
png <- Instr.pingDur
pngRel <- Instr.pingRelease $/ 0.4 $/ 0.1
tin <- Instr.tine $/ 0.4 $/ 0.1
arrange <- SigStL.makeArranger
withMIDIEvents play $
SigSt.map (0.2*) .
evalState (Gen.sequenceMultiProgram (arrange chunkSize) channel
(VoiceMsg.toProgram 2)
[png, pngRel, tin])
keyboardStereoMulti :: IO ()
keyboardStereoMulti = do
png <- Instr.pingStereoRelease $/ 0.4 $/ 0.1
tin <- Instr.tineStereo $/ 0.4 $/ 0.1
str <- Instr.softString
arrange <- SigStL.makeArranger
withMIDIEvents play $
SigSt.map ((0.2::Real)*>) .
evalState (Gen.sequenceMultiProgram (arrange chunkSize) channel
(VoiceMsg.toProgram 1)
[png, tin, str])