1 -- Contains function for scheduling and filtering events given the
2 -- correct informations.
4 module RCMA.Translator.Filter where
6 import Data.Bifunctor as BF
7 import Data.Function (on)
8 import Data.List (group, groupBy, sortBy)
12 import RCMA.Translator.Message
13 import Sound.JACK (NFrames (NFrames))
15 -- Takes a list of time stamped "things", a sample rate and a buffer
16 -- size. The function argument is a function that needs to tell which
17 -- arguments are kept in the case where two would come into
18 -- contact. On the left are the events that can be thrown into the
19 -- buffer, on the right are the events that will need to wait. Both
22 -- /!\ The time is relative. A preprocessing operation removing all
23 -- events too soon to be happening and shifting them is necessary.
27 -> ([(Frames,a)], [(Frames,a)])
28 schedule size = BF.first scatterEvents
29 . break ((>= size) . fst) . sortBy (comparing fst)
32 -- The function choose between the event in case two are in conflict.
34 -- /!\ That functional argument is a bit unsatisfying, it would be
35 -- probably better if we'd try to push events to the next frame if
36 -- they conflict and only remove them if it's impossible to do
38 nubDuplicate :: (Eq a) => ([a] -> a) -> [(Frames, a)] -> [(Frames, a)]
39 nubDuplicate f = map (BF.second f) . scatterEvents
40 . map (\l@((n,_):_) -> (n,map snd l)) . group
42 -- /!\ May not terminate…
44 -- When to events are at the same frame, shift them so that they are
45 -- all separated by one frame. Repeat until each event is on its own
47 scatterEvents :: [(Frames, a)] -> [(Frames, a)]
49 | all ((== 1) . length) l = u
50 | otherwise = scatterEvents $ scat l
51 where l = groupBy ((==) `on` fst) u
52 scat = concat . map (zip <$> enumFrom . fst . head <*> map snd)
54 chooseDuplicate :: [a] -> a
55 chooseDuplicate = undefined