hunk ./src/Reactive/Banana/ALSA/Sequencer.hs 133 -reserveSchedule :: - (RBF.Frameworks t) => - Reactor t (RB.Event t AlsaTime.AbsoluteTicks, [AlsaTime.AbsoluteTicks] -> IO (), IO ()) -reserveSchedule = Reactor $ ReaderT $ \(addH,h) -> do - sched <- MS.get - MS.modify nextSchedule - eEcho <- - MT.lift $ - fmap (fmap AlsaTime.fromEvent . - RB.filterE (checkSchedule sched)) $ - RBF.fromAddHandler addH - return (eEcho, sendEchos h sched, cancelEchos h sched) - hunk ./src/Reactive/Banana/ALSA/Sequencer.hs 134 - reserveSchedule = - fmap (\(eEcho, send, _) -> (send, eEcho)) reserveSchedule + reserveSchedule = Reactor $ ReaderT $ \(addH,h) -> do + sched <- MS.get + MS.modify nextSchedule + eEcho <- + MT.lift $ + fmap (fmap AlsaTime.fromEvent . + RB.filterE (checkSchedule sched)) $ + RBF.fromAddHandler addH + return (sendEchos h sched, cancelEchos h sched, eEcho) hunk ./src/Reactive/Banana/ALSA/Sequencer.hs 176 - (eEcho, send, cancel) <- reserveSchedule + (send, cancel, eEcho) <- Process.reserveSchedule replace ./src/Reactive/Banana/ALSA/Example.hs [A-Za-z_0-9\-\.] Seq.beatVar Process.beatVar hunk ./src/Reactive/Banana/ALSA/Sequencer.hs 31 -import Control.Monad.IO.Class (MonadIO, liftIO, ) -import Control.Monad (forever, liftM2, ) +import Control.Monad (forever, ) hunk ./src/Reactive/Banana/ALSA/Sequencer.hs 157 - - - --- * examples - -{- | -Similar to 'beat' but it reacts immediately to tempo changes. -This requires the ability of ALSA to cancel sent Echo messages -and it requires to know the precise time points of tempo changes, -thus we need the Discrete input instead of Behaviour -and we need a behaviour for the current time. --} -beatVar :: - (RBF.Frameworks t) => - RB.Behavior t AlsaTime.AbsoluteTicks -> - RB.Behavior t AlsaTime.RelativeTicks -> - Reactor t (RB.Event t AlsaTime.AbsoluteTicks) -beatVar time tempo = do - (send, cancel, eEcho) <- Process.reserveSchedule - - liftIO $ send [mempty] - - (tempoInit, tempoChanges) <- - Process.liftMoment $ - liftM2 (,) (RBF.initial tempo) (RBF.changes tempo) - - let change :: - AlsaTime.RelativeTicks -> AlsaTime.AbsoluteTicks -> - MS.State - (AlsaTime.AbsoluteTicks, Double, AlsaTime.RelativeTicks) - (Maybe AlsaTime.AbsoluteTicks, IO ()) - - next _t = do - (t0,r,p) <- MS.get - {- - It should be t1==t, - where t is the timestamp from an Echo message - and t1 is the computed time. - In principle we could use t, - but this will be slightly later than the reference time t1. - -} - let t1 = Time.inc (Time.scale r p) t0 - MS.put (t1,1,p) - return (Just t1, send [Time.inc p t1]) - - change p1 t1 = do - (t0,r0,p0) <- MS.get - let r1 = max 0 $ r0 - Time.div (Time.subSat t1 t0) p0 - MS.put (t1,r1,p1) - return - (Nothing, - cancel >> - send [Time.inc (Time.scale r1 p1) t1]) - - eEchoEvent = - fst $ RBU.sequence (mempty, 0, tempoInit) $ - RB.union - (fmap next eEcho) - (fmap (flip change) time <@> tempoChanges) - - reactimate $ fmap snd eEchoEvent - return $ RBU.mapMaybe fst eEchoEvent