]> Git — Sourcephile - tmp/julm/arpeggigon.git/blob - Reactogon/Translator/Filter.hs
Added incomplete main.
[tmp/julm/arpeggigon.git] / Reactogon / Translator / Filter.hs
1 -- Contains function for scheduling and filtering events given the
2 -- correct informations.
3
4 module Reactogon.Translator.Filter where
5
6 import Data.Bifunctor as BF
7 import Data.List (group, sortBy)
8 import Data.Ord
9 import FRP.Yampa
10 import Reactogon.Semantics
11 import Reactogon.Translator.Message
12 import Sound.JACK (NFrames (NFrames))
13
14 -- Takes a list of time stamped "things", a sample rate and a buffer
15 -- size. The function argument is a function that needs to tell which
16 -- arguments are kept in the case where two would come into
17 -- contact. On the left are the events that can be thrown into the
18 -- buffer, on the right are the events that will need to wait. Both
19 -- list are sorted.
20 --
21 -- /!\ The time is relative. A preprocessing operation removing all
22 -- events too soon to be happening and shifting them is necessary.
23 schedule :: (Eq a) =>
24 SampleRate
25 -> NFrames
26 -> [(Time, a)]
27 -> ([(NFrames,a)], [(Time,a)])
28 schedule sr (NFrames size) = BF.first convertTime . break ((>= maxTime) . fst)
29 . sortBy (comparing fst)
30 where srd = fromIntegral sr
31 maxTime = fromIntegral size / srd
32 convertTime :: (Eq a) => [(Time, a)] -> [(NFrames, a)]
33 convertTime = map (BF.first (NFrames . floor . (srd *)))
34
35 -- The function choose between the event in case two are in conflict.
36 --
37 -- /!\ That functional argument is a bit unsatisfying, it would be
38 -- probably better if we'd try to push events to the next frame if
39 -- they conflict and only remove them if it's impossible to do
40 -- otherwise.
41 nubDuplicate :: (Eq a) => ([a] -> a) -> [(NFrames, a)] -> [(NFrames, a)]
42 nubDuplicate f = map (BF.second f)
43 . map (\l@((n,_):_) -> (n,map snd l)) . group
44
45 chooseDuplicate :: [a] -> a
46 chooseDuplicate = undefined