1 {-# LANGUAGE Arrows #-}
3 module RMCA.Layer.Board ( boardRun
7 import qualified Data.IntMap as M
8 import Data.List ((\\))
11 import RMCA.Layer.Layer
14 data BoardRun = BoardStart | BoardStop deriving Eq
16 singleBoard :: [PlayHead]
17 -> SF (Board, Layer, Event BeatNo) (Event ([PlayHead], [Note]))
18 singleBoard iPh = proc (board, Layer { relPitch = rp
21 accumBy advanceHeads' (iPh,[]) -< ebno `tag` (board, fromEvent ebno, rp, s)
22 where advanceHeads' (ph,_) (board,bno,rp,s) = uncurry5 advanceHeads (board,bno,rp,s,ph)
24 boardSF :: SF (Board, Layer, Tempo, BoardRun) (Event ([PlayHead], [Note]))
25 boardSF = proc (board, l, t, br) -> do
26 ebno <- layerMetronome -< (t,l)
28 boardSwitch [] -< ((board, l, ebno), ess `tag` (br, startHeads board))
30 boardSwitch :: [PlayHead]
31 -> SF ((Board, Layer,Event BeatNo), Event (BoardRun, [PlayHead]))
32 (Event ([PlayHead],[Note]))
33 boardSwitch rPh = dSwitch (singleBoard rPh *** (identity >>> notYet)) fnSwitch
34 where fnSwitch (BoardStart, iPh) = boardSwitch iPh
35 fnSwitch (BoardStop, _) = boardSwitch []
37 routeBoard :: M.IntMap a -> M.IntMap sf -> M.IntMap (a,sf)
38 routeBoard = M.intersectionWith (,)
40 -- On the left are the disappearing signals, on the right the
42 lengthChange :: M.IntMap b -> SF (M.IntMap a, M.IntMap sf) (Event ([Int],[Int]))
43 lengthChange iSig = proc (mapSig, _) -> do
44 kSig <- arr M.keys -< mapSig
45 --kSF <- arr M.keys -< mapSF
46 edgeBy diffSig ik -< kSig
47 where ik = M.keys iSig
48 -- Old elements removed in nL are on the left, new elements added to
49 -- nL are on the right.
50 diffSig :: [Int] -> [Int] -> Maybe ([Int],[Int])
53 | otherwise = Just (oL \\ nL, nL \\ oL)
55 boardRun' :: M.IntMap (SF (Board,Layer,Tempo,BoardRun)
56 (Event ([PlayHead],[Note])))
57 -> SF (M.IntMap (Board,Layer,Tempo,BoardRun))
58 (M.IntMap (Event ([PlayHead],[Note])))
59 boardRun' iSF = pSwitch routeBoard iSF (lengthChange iSF) contSwitch
60 where contSwitch contSig (newSig, oldSig) = boardRun' newSF
61 where newSF = foldr (\k m -> M.insert k boardSF m)
62 (foldr M.delete contSig oldSig) newSig
64 boardRun :: M.IntMap (Board,Layer,Tempo,BoardRun)
65 -> SF (M.IntMap (Board,Layer,Tempo,BoardRun))
66 (M.IntMap (Event ([PlayHead],[Note])))
67 boardRun iSig = boardRun' (iSig $> boardSF)