module Synthesizer.Storable.ALSA.Server.Run where import qualified Synthesizer.Storable.ALSA.Server.Instrument as Instr import Synthesizer.Storable.ALSA.Server.Common (Real, withMIDIEvents, play, playAndRecord, sampleRate, lazySize, chunkSize, channel, ) import qualified Synthesizer.Storable.ALSA.MIDI as AlsaSt import Synthesizer.Storable.ALSA.MIDI (applyModulation, ) import qualified Synthesizer.Basic.Wave as Wave import qualified Synthesizer.Interpolation.Module as Ip import qualified Synthesizer.Storable.Oscillator as OsciSt import qualified Synthesizer.Storable.Signal as SigSt import qualified Data.StorableVector.Lazy as SVL import qualified Synthesizer.Generic.Loop as LoopG import qualified Synthesizer.State.Signal as SigS import qualified Synthesizer.Plain.Filter.Recursive as FiltR import qualified Synthesizer.Plain.Filter.Recursive.Universal as UniFilter import qualified Sound.MIDI.Message.Channel.Voice as VoiceMsg import Control.Monad.Trans.State (evalState, ) import Control.Category ((.), ) import qualified Algebra.Additive as Additive import Data.Tuple.HT (mapSnd, ) import NumericPrelude.Numeric (zero, (*>), (^?), ) import Prelude hiding (Real, round, break, id, (.), ) volume :: IO () volume = putStrLn "run 'aconnect' to connect to the MIDI controller" >> (withMIDIEvents play $ SigSt.zipWith (*) (OsciSt.static chunkSize Wave.sine zero (800/sampleRate)) . evalState (AlsaSt.controllerLinear channel VoiceMsg.mainVolume (0,1) (0::Real))) frequency :: IO () frequency = withMIDIEvents play $ OsciSt.freqMod chunkSize Wave.sine zero . evalState (AlsaSt.controllerLinear channel VoiceMsg.mainVolume (400/sampleRate, 1200/sampleRate) (800/sampleRate::Real)) pitchBend :: IO () pitchBend = withMIDIEvents play $ OsciSt.freqMod chunkSize Wave.sine zero . evalState (AlsaSt.pitchBend channel 2 (880/sampleRate::Real)) volumeFrequency :: IO () volumeFrequency = putStrLn "run 'aconnect' to connect to the MIDI controller" >> (withMIDIEvents play $ evalState (do vol <- AlsaSt.controllerLinear channel VoiceMsg.mainVolume (0,1) 0.5 freq <- AlsaSt.pitchBend channel 2 (880/sampleRate::Real) return $ SigSt.zipWith (*) vol (OsciSt.freqMod chunkSize Wave.sine zero freq))) keyboard :: IO () keyboard = withMIDIEvents play $ -- playALSA (Bld.put :: Int16 -> Bld.Builder Int16) (sampleRate::Real) . SigSt.map (0.2*) . evalState (AlsaSt.sequence chunkSize channel Instr.tine) keyboardMulti :: IO () keyboardMulti = withMIDIEvents play $ -- playALSA (Bld.put :: Int16 -> Bld.Builder Int16) (sampleRate::Real) . SigSt.map (0.2*) . evalState (AlsaSt.sequenceMultiProgram chunkSize channel (VoiceMsg.toProgram 2) [Instr.pingDur, Instr.pingRelease, Instr.tine]) keyboardStereo :: IO () keyboardStereo = withMIDIEvents play $ -- playALSA (Bld.put :: Int16 -> Bld.Builder Int16) (sampleRate::Real) . SigSt.map ((0.2::Real)*>) . evalState (AlsaSt.sequenceMultiProgram chunkSize channel (VoiceMsg.toProgram 1) [Instr.pingStereoRelease, Instr.tineStereo, Instr.softString, Instr.softStringCausal]) keyboardPitchbend :: IO () keyboardPitchbend = withMIDIEvents play $ SigSt.map ((0.2::Real)*>) . evalState (do bend <- AlsaSt.pitchBend channel (2^?(2/12)) 1 AlsaSt.sequenceModulated chunkSize bend channel Instr.stringStereoFM) keyboardFM :: IO () keyboardFM = withMIDIEvents play $ SigSt.map ((0.2::Real)*>) . evalState (do fm <- AlsaSt.bendWheelPressure channel 2 (10/sampleRate) 0.04 0.03 AlsaSt.sequenceModulated chunkSize fm channel Instr.stringStereoFM) keyboardDetuneFM :: IO () keyboardDetuneFM = withMIDIEvents play $ SigSt.map ((0.2::Real)*>) . evalState (do fm <- AlsaSt.bendWheelPressure channel 2 (10/sampleRate) 0.04 0.03 detune <- AlsaSt.controllerLinear channel VoiceMsg.vectorX (0,0.005) 0 AlsaSt.sequenceMultiModulated chunkSize channel Instr.stringStereoDetuneFM (applyModulation fm . applyModulation detune)) keyboardFilter :: IO () keyboardFilter = withMIDIEvents play $ SigSt.map (0.2*) . evalState (do music <- AlsaSt.sequence chunkSize channel Instr.pingRelease freq <- AlsaSt.controllerLinear channel -- VoiceMsg.vectorY (VoiceMsg.toController 21) (100/sampleRate, 5000/sampleRate) (700/sampleRate) return $ SigS.toStorableSignal chunkSize $ SigS.map UniFilter.lowpass $ SigS.modifyModulated UniFilter.modifier (SigS.map UniFilter.parameter $ SigS.zipWith FiltR.Pole (SigS.repeat (5 :: Real)) (SigS.fromStorableSignal freq)) $ SigS.fromStorableSignal music) keyboardSample :: IO () keyboardSample = do piano <- Instr.readPianoSample string <- Instr.readStringSample let loopedString = mapSnd (LoopG.simple 8750 500) string fadedString = mapSnd (LoopG.fade (undefined::Real) 8750 500) string timeSineString = LoopG.timeReverse lazySize Ip.linear Ip.linear LoopG.timeControlSine 8750 500 string timeZigZagString = LoopG.timeReverse lazySize Ip.linear Ip.linear LoopG.timeControlZigZag 8750 500 string withMIDIEvents play $ SigSt.map (0.2*) . evalState (AlsaSt.sequenceMultiProgram chunkSize channel (VoiceMsg.toProgram 5) $ Instr.sampledSound piano : Instr.sampledSound string : Instr.sampledSound loopedString : Instr.sampledSound fadedString : Instr.sampledSound timeSineString : Instr.sampledSound timeZigZagString : Instr.sampledSoundTimeLoop Instr.loopTimeModSine string 8750 500 : Instr.sampledSoundTimeLoop Instr.loopTimeModZigZag string 8750 500 : []) keyboardVariousStereo :: IO () keyboardVariousStereo = do piano <- Instr.readPianoSample string <- Instr.readStringSample let loopedString = LoopG.timeReverse lazySize Ip.linear Ip.linear LoopG.timeControlZigZag 8750 500 string withMIDIEvents (playAndRecord "session.wav") $ SigSt.map ((0.2::Real)*>) . evalState (AlsaSt.sequenceMultiProgram chunkSize channel (VoiceMsg.toProgram 0) $ Instr.pingStereoRelease : Instr.tineStereo : Instr.softString : Instr.sampledSoundDetuneStereo 0.001 piano : Instr.sampledSoundDetuneStereo 0.002 loopedString : Instr.sampledSoundDetuneStereoRelease 0.1 0.001 piano : Instr.sampledSoundDetuneStereoRelease 0.3 0.002 loopedString : []) keyboardSampleTFM :: IO () keyboardSampleTFM = do instr <- Instr.readPianoSample withMIDIEvents play $ evalState (do fm <- AlsaSt.bendWheelPressure channel 2 (10/sampleRate) 0.04 0.03 speed <- AlsaSt.controllerLinear channel (VoiceMsg.toController 22) (0,2) 1 offset <- AlsaSt.controllerLinear channel (VoiceMsg.toController 21) (0, fromIntegral (SVL.length (snd instr))) 0 AlsaSt.sequenceMultiModulated chunkSize channel (Instr.timeModulatedSample instr) (applyModulation fm . applyModulation speed . applyModulation offset)) keyboardNoisePipe :: IO () keyboardNoisePipe = withMIDIEvents play $ evalState (do fm <- AlsaSt.bendWheelPressure channel 2 (10/sampleRate) 0.04 0.03 resonance <- AlsaSt.controllerExponential channel (VoiceMsg.toController 23) (1, 100) 10 AlsaSt.sequenceMultiModulated chunkSize channel Instr.colourNoise (applyModulation fm . applyModulation resonance)) keyboardNoisyTone :: IO () keyboardNoisyTone = withMIDIEvents play $ evalState (do fm <- AlsaSt.bendWheelPressure channel 2 (10/sampleRate) 0.04 0.03 speed <- AlsaSt.controllerLinear channel (VoiceMsg.toController 21) (0,0.5) 0.1 AlsaSt.sequenceMultiModulated chunkSize channel Instr.toneFromNoise (applyModulation fm . applyModulation speed)) keyboardFilteredNoisyTone :: IO () keyboardFilteredNoisyTone = withMIDIEvents play $ evalState (do fm <- AlsaSt.bendWheelPressure channel 2 (10/sampleRate) 0.04 0.03 {- speed must never be zero, since this requires to fetch unlimited data from future. -} speed <- AlsaSt.controllerLinear channel (VoiceMsg.toController 21) (0.05,0.5) 0.1 cutoff <- AlsaSt.controllerExponential channel (VoiceMsg.toController 22) (1, 30) 10 resonance <- AlsaSt.controllerExponential channel (VoiceMsg.toController 23) (1, 20) 5 AlsaSt.sequenceMultiModulated chunkSize channel Instr.toneFromFilteredNoise (applyModulation fm . applyModulation speed . applyModulation cutoff . applyModulation resonance))