1 {-# LANGUAGE Arrows, FlexibleContexts #-}
3 module RCMA.Layer.Board where
6 import RCMA.Layer.Layer
8 import RCMA.Auxiliary.Curry
9 import Data.ReactiveValue
13 -- The state of the board is described by the list of the playheads
14 -- and the different actions onto the board.
15 -- It can then be modified discretly when a beat is received or
16 -- continuously when the user acts on it.
18 -> SF (Layer, [PlayHead], Event BeatNo)
19 (Event ([PlayHead], [Note]))
20 boardAction board = proc (Layer { relPitch = rp
24 ahSF <<^ arr propEvent -< (ebn, rp, s, pl)
26 ahSF :: SF (Event (BeatNo, RelPitch, Strength, [PlayHead]))
27 (Event ([PlayHead], [Note]))
28 ahSF = arr $ fmap (uncurry4 $ advanceHeads board)
29 propEvent (a,b,c,d) = if isEvent a
30 then Event (fromEvent a,b,c,d)
33 boardSF :: Board -> SF (Layer, [PlayHead], Tempo) (Event ([PlayHead], [Note]))
34 boardSF board = proc (l, ph, t) -> do
35 (ebno, el) <- splitE ^<< layerMetronome -< (t, l)
36 boardAction board -< (l, ph, ebno)
38 boardInit :: (ReactiveValueRead tempo Tempo IO,
39 ReactiveValueRead ph [PlayHead] IO) =>
43 -> ReactiveFieldReadWrite IO Layer
45 boardInit board tempoRV phRV layerRV = do
46 layer <- reactiveValueRead layerRV
47 tempo <- reactiveValueRead tempoRV
48 ph <- reactiveValueRead phRV
49 (inBoard, outBoard) <- yampaReactiveDual (layer, ph, tempo) (boardSF board)
52 boardRun :: (ReactiveValueRead tempo Tempo IO,
53 ReactiveValueRead ph [PlayHead] IO) =>
57 -> ReactiveFieldReadWrite IO Layer
59 boardRun board tempoRV phRV layerRV = do
60 layer <- reactiveValueRead layerRV
61 tempo <- reactiveValueRead tempoRV
62 ph <- reactiveValueRead phRV
63 (inBoard, outBoard) <- yampaReactiveDual (layer, tempo, ph) (boardAction board)