1 {-# LANGUAGE Arrows #-}
3 module RMCA.Layer.Layer where
6 import Data.ReactiveValue
8 import RMCA.Global.Clock
11 -- Data representing the state of a layer. It is updated continuously.
12 data Layer = Layer { relTempo :: Double
13 , relPitch :: RelPitch
14 , strength :: Strength
15 , beatsPerBar :: BeatsPerBar
18 layerTempo :: SF (Tempo, Layer) LTempo
19 layerTempo = proc (t, Layer { relTempo = r }) ->
20 returnA -< floor $ r * fromIntegral t
22 -- The layer is modified after the beat as been
23 layerMetronome' :: BeatNo -> SF (Tempo, Layer) (Event BeatNo)
24 layerMetronome' b = proc (t, l@Layer { beatsPerBar = bpb }) -> do
25 eb <- metronome <<< layerTempo -< (t, l)
26 returnA -< eb `tag` nextBeatNo bpb b
28 layerMetronome :: SF (Tempo, Layer) (Event BeatNo)
29 layerMetronome = layerMetronome'' 0
30 where layerMetronome'' no = dSwitch (layerMetronome' no >>^ dup)
33 layerRV :: CBMVar Layer -> ReactiveFieldReadWrite IO Layer
34 layerRV mvar = ReactiveFieldReadWrite setter getter notifier
35 where setter :: Layer -> IO ()
36 setter = writeCBMVar mvar
39 getter = readCBMVar mvar
41 notifier :: IO () -> IO ()
42 notifier = installCallbackCBMVar mvar
44 getDefaultLayerRV :: IO (ReactiveFieldReadWrite IO Layer)
45 getDefaultLayerRV = layerRV <$> newCBMVar dl
46 where dl = Layer { relTempo = 1