synthesizer-llvm-1.1.0.1: alsa/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.ALSA (Output, play, startMessage)
import Synthesizer.LLVM.Server.CausalPacked.Common (transposeModulation)
import Synthesizer.LLVM.Server.Common hiding (transposeModulation)
import qualified Sound.ALSA.Sequencer.Event as Event
import qualified Data.EventList.Relative.TimeBody as EventList
import qualified Synthesizer.LLVM.MIDI.BendModulation as BM
import qualified Synthesizer.LLVM.MIDI as MIDIL
import qualified Synthesizer.LLVM.Frame.Stereo as Stereo
import qualified Synthesizer.LLVM.Causal.Render as CausalRender
import qualified Synthesizer.LLVM.Causal.Process as Causal
import qualified Synthesizer.LLVM.Generator.Render as Render
import qualified Synthesizer.LLVM.Storable.Signal as SigStL
import qualified Synthesizer.LLVM.Wave as WaveL
import Synthesizer.LLVM.Causal.Process (($<), ($*))
import qualified Synthesizer.Storable.Signal as SigSt
import qualified Synthesizer.ALSA.EventList as Ev
import qualified Synthesizer.MIDI.PiecewiseConstant as PC
import qualified Synthesizer.MIDI.Generic as Gen
import qualified Sound.MIDI.Message.Channel.Voice as VoiceMsg
import Control.Arrow ((^<<), (<<^))
import Control.Monad.Trans.State (evalState)
import Control.Applicative ((<$>))
import Control.Exception (bracket)
import NumericPrelude.Numeric (fromIntegral, zero, (*), (*>), (/))
import NumericPrelude.Base
import Prelude (Double)
{-# INLINE withMIDIEvents #-}
withMIDIEvents ::
Option.T ->
Output handle signal a ->
(SigSt.ChunkSize -> SampleRate Real ->
EventList.T Ev.StrictTime [Event.T] -> signal) -> IO a
withMIDIEvents opt output process = do
putStrLn startMessage
case output opt of
(open,close,write) ->
bracket open (close . snd) $ \((chunkSize,rate),h) ->
let rrate = fromIntegral rate :: Double
in Ev.withMIDIEvents
(Option.clientName opt)
(fromIntegral chunkSize / rrate)
rrate
(write h .
process (SigSt.chunkSize chunkSize)
(Option.SampleRate $ fromIntegral rate))
pitchBend :: IO ()
pitchBend = do
opt <- Option.get
osc <-
Render.run $ \fm ->
Causal.osci WaveL.triangle $< zero $* piecewiseConstant fm
withMIDIEvents opt play $ \chunkSize sampleRate ->
(id :: SigSt.T Real -> SigSt.T Real) .
osc chunkSize .
evalState (PC.pitchBend (Option.channel opt) 2 (frequency sampleRate 880))
frequencyModulation :: IO ()
frequencyModulation = do
opt <- Option.get
osc <-
Render.run $
constant frequency 10 $ \speed _sr fm ->
Causal.osci WaveL.triangle
$< zero
$* (MIDIL.frequencyFromBendModulation speed
$* piecewiseConstant (fmap BM.unMultiValue <$> fm))
withMIDIEvents opt play $ \chunkSize sampleRate ->
(id :: SigSt.T Real -> SigSt.T Real) .
osc chunkSize sampleRate . transposeModulation sampleRate 880 .
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 <- CausalRender.run Causal.amplify
arrange <- SigStL.makeArranger
withMIDIEvents opt play $ \chunkSize sampleRate ->
pioApply (amp (0.2 :: Real)) .
arrange chunkSize .
evalState
(Gen.sequence
(Option.channel opt)
(sound chunkSize sampleRate))
keyboardStereo :: IO ()
keyboardStereo = do
opt <- Option.get
sound <- Instr.pingStereoRelease $/ 0.4 $/ 0.1
amp <-
CausalRender.run $ \vol ->
Stereo.multiValue ^<< Causal.amplifyStereo vol <<^ Stereo.unMultiValue
arrange <- SigStL.makeArranger
withMIDIEvents opt play $ \chunkSize sampleRate ->
pioApply (amp (0.2 :: Real)) .
arrange chunkSize .
evalState
(Gen.sequence
(Option.channel opt)
(sound chunkSize sampleRate))
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 $ \chunkSize sampleRate ->
-- playALSA (Bld.put :: Int16 -> Bld.Builder Int16) (sampleRate opt::Real) .
SigSt.map (0.2*) .
arrange chunkSize .
evalState (Gen.sequenceMultiProgram (Option.channel opt)
(VoiceMsg.toProgram 2)
(map ($ sampleRate) [png, pngRel, tin]))
keyboardStereoMulti :: IO ()
keyboardStereoMulti = do
opt <- Option.get
png <- Instr.pingStereoRelease $/ 0.4 $/ 0.1
tin <- Instr.tineStereo $/ 0.4 $/ 0.1
str <- Instr.softString
arrange <- SigStL.makeArranger
withMIDIEvents opt play $ \chunkSize sampleRate ->
-- playALSA (Bld.put :: Int16 -> Bld.Builder Int16) (sampleRate opt::Real) .
SigSt.map ((0.2::Real)*>) .
arrange chunkSize .
evalState (Gen.sequenceMultiProgram (Option.channel opt)
(VoiceMsg.toProgram 1)
(map (\sound -> sound chunkSize sampleRate) [png, tin, const str]))