module Main where
import Synthesizer.Storable.ALSA.Server.Test (makeNote, )
import qualified Synthesizer.PiecewiseConstant.ALSA.MIDI as PC
import qualified Sound.ALSA.Sequencer.Event as Event
import qualified Synthesizer.Generic.ALSA.MIDI as Gen
import qualified Synthesizer.Storable.ALSA.Play as Play
import qualified Synthesizer.Storable.ALSA.MIDI as AlsaSt
import Synthesizer.Storable.ALSA.MIDI (
Instrument, chunkSizesFromLazyTime, )
import qualified Synthesizer.Basic.Wave as Wave
import qualified Synthesizer.Frame.Stereo as Stereo
import Foreign.Storable (Storable, )
import qualified Synthesizer.Storable.Cut as CutSt
import qualified Synthesizer.Storable.Signal as SigSt
import qualified Data.StorableVector.Lazy as SVL
import qualified Synthesizer.State.Signal as SigS
import qualified Synthesizer.State.Oscillator as OsciS
import qualified Synthesizer.State.Filter.NonRecursive as FiltNRS
import qualified Sound.MIDI.Message.Channel as ChannelMsg
import Sound.MIDI.Message.Channel (Channel, )
import qualified Data.EventList.Relative.TimeBody as EventList
import qualified Data.EventList.Relative.BodyTime as EventListBT
-- import Data.EventList.Relative.MixedBody ((/.), (./), )
import Control.Monad.Trans.State (evalState, )
import Control.Monad (when, )
import qualified Algebra.Additive as Additive
import NumericPrelude.Numeric (zero, (^?), )
import Prelude hiding (Real, break, )
import qualified System.IO as IO
channel :: Channel
channel = ChannelMsg.toChannel 0
sampleRate :: Num a => a
-- sampleRate = 24000
-- sampleRate = 48000
sampleRate = 44100
latency :: Int
latency = 0
-- latency = 256
-- latency = 1000
chunkSize :: SVL.ChunkSize
chunkSize = Play.defaultChunkSize
consNone ::
time ->
EventList.T time [body] ->
EventList.T time [body]
consNone t = EventList.cons t []
consSingle ::
time -> body ->
EventList.T time [body] ->
EventList.T time [body]
consSingle t b = EventList.cons t [b]
type Real = Float
evaluatePrefix ::
(Storable a, Additive.C a, Eq a) =>
SVL.Vector a -> Bool
evaluatePrefix =
(\x -> x==x) .
SVL.foldl' (Additive.+) zero .
SVL.take 100000
sequenceSpaceLeakEmpty :: Bool
sequenceSpaceLeakEmpty =
evaluatePrefix $
evalState (Gen.sequence (CutSt.arrange chunkSize) channel
(error "no sound" :: Instrument Real Real)) $
let evs = consNone 10 evs
in evs
sequenceSpaceLeakModulatedEmpty :: Bool
sequenceSpaceLeakModulatedEmpty =
evaluatePrefix $
evalState
(Gen.sequenceModulated (CutSt.arrange chunkSize)
(SigSt.iterate chunkSize (1+) 0) channel
(error "no sound" :: SigSt.T Real -> Instrument Real Real)) $
let evs = consNone 10 evs
in evs
sequenceSpaceLeakLazyDrop :: Bool
sequenceSpaceLeakLazyDrop =
evaluatePrefix $
evalState
(let fm y = (EventListBT.cons $! y) 10 (fm (2-y))
in Gen.sequenceModulated (CutSt.arrange chunkSize) (fm 1) channel
(error "no sound" ::
PC.T Real -> Instrument Real Real)) $
let evs = consNone 10 evs
in evs
stringStereoFM :: SigSt.T Real -> Instrument Real (Stereo.T Real)
stringStereoFM fmSt vel freq dur =
let fm = SigS.fromStorableSignal fmSt
in SigS.toStorableSignalVary (chunkSizesFromLazyTime dur) $
FiltNRS.amplifyVector (4^?vel) $
SigS.zipWith Stereo.cons
(OsciS.freqMod Wave.saw zero $
FiltNRS.amplify (freq*0.999/sampleRate) fm)
(OsciS.freqMod Wave.saw zero $
FiltNRS.amplify (freq*1.001/sampleRate) fm)
sequenceSpaceLeakModulatedInfinite :: Bool
sequenceSpaceLeakModulatedInfinite =
evaluatePrefix $
evalState
(Gen.sequenceModulated (CutSt.arrange chunkSize)
(SigSt.iterate chunkSize (1e-7 +) 1) channel
stringStereoFM) $
let evs t = consNone t (evs (20-t))
in consSingle 10 (makeNote Event.NoteOn 60) $
evs 10
sequenceSpaceLeakModulatedChordStep :: Bool
sequenceSpaceLeakModulatedChordStep =
evaluatePrefix $
evalState
(Gen.sequenceModulated (CutSt.arrange chunkSize)
(SigSt.iterate chunkSize (1e-7 +) 1) channel
stringStereoFM) $
let evs t = consNone t (evs (20-t))
in consSingle 10 (makeNote Event.NoteOn 60) $
consSingle 10 (makeNote Event.NoteOn 64) $
consSingle 10 (makeNote Event.NoteOn 67) $
evs 10
sequenceSpaceLeakModulatedChordSimultaneous :: Bool
sequenceSpaceLeakModulatedChordSimultaneous =
evaluatePrefix $
evalState
(Gen.sequenceModulated (CutSt.arrange chunkSize)
(SigSt.iterate chunkSize (1e-7 +) 1) channel
stringStereoFM) $
let evs t = EventList.cons t [] (evs (20-t))
in EventList.cons 10
[makeNote Event.NoteOn 60,
makeNote Event.NoteOn 64,
makeNote Event.NoteOn 67] $
evs 10
sequenceSpaceLeakStaccato :: Bool
sequenceSpaceLeakStaccato =
evaluatePrefix $
evalState
(Gen.sequenceModulated (CutSt.arrange chunkSize)
(SigSt.iterate chunkSize (1e-7 +) 1) channel
stringStereoFM) $
let evs t =
consSingle t (makeNote Event.NoteOn 60) $
consSingle t (makeNote Event.NoteOff 60) $
evs (20-t)
in evs 10
test :: String -> Bool -> IO ()
test name result = do
putStr name
IO.hFlush IO.stdout
when result (putStrLn " ok")
main :: IO ()
main = do
test "sequenceSpaceLeakEmpty" sequenceSpaceLeakEmpty
test "sequenceSpaceLeakModulatedEmpty" sequenceSpaceLeakModulatedEmpty
test "sequenceSpaceLeakLazyDrop" sequenceSpaceLeakLazyDrop
test "sequenceSpaceLeakModulatedInfinite" sequenceSpaceLeakModulatedInfinite
test "sequenceSpaceLeakModulatedChordStep" sequenceSpaceLeakModulatedChordStep
test "sequenceSpaceLeakModulatedChordSimultaneous" sequenceSpaceLeakModulatedChordSimultaneous
test "sequenceSpaceLeakStaccato" sequenceSpaceLeakStaccato