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