]> Git — Sourcephile - tmp/julm/arpeggigon.git/blob - RCMA/Layer/Layer.hs
Simpler thread waiting system.
[tmp/julm/arpeggigon.git] / RCMA / Layer / Layer.hs
1 {-# LANGUAGE Arrows #-}
2
3 module RCMA.Layer.Layer where
4
5 import Data.CBMVar
6 import Data.ReactiveValue
7 import FRP.Yampa
8 import RCMA.Global.Clock
9 import RCMA.Semantics
10
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
16 , beatCounter :: BeatNo
17 }
18
19 layerTempo :: SF (Tempo, Layer) LTempo
20 layerTempo = proc (t, Layer { relTempo = r }) -> do
21 returnA -< floor $ r * fromIntegral t
22
23 -- The layer is modified after the beat as been
24 layerMetronome :: SF (Tempo, Layer) (Event (BeatNo, Layer))
25 layerMetronome = proc (t, l@Layer { beatCounter = b , beatsPerBar = bpb}) -> do
26 eb <- metronome <<< layerTempo -< (t, l)
27 returnA -< eb `tag` let nb = nextBeatNo b bpb in (nb, l { beatCounter = nb })
28
29 layerRV :: CBMVar Layer -> ReactiveFieldReadWrite IO Layer
30 layerRV mvar = ReactiveFieldReadWrite setter getter notifier
31 where setter :: Layer -> IO ()
32 setter = writeCBMVar mvar
33
34 getter :: IO Layer
35 getter = readCBMVar mvar
36
37 notifier :: IO () -> IO ()
38 notifier = installCallbackCBMVar mvar
39
40 getDefaultLayerRV :: IO (ReactiveFieldReadWrite IO Layer)
41 getDefaultLayerRV = layerRV <$> newCBMVar dl
42 where dl = Layer { relTempo = 1
43 , relPitch = 0
44 , strength = 127
45 , beatsPerBar = 4
46 , beatCounter = 0
47 }