module Reactive.Banana.ALSA.Private where
import qualified Reactive.Banana.MIDI.Process as Process
import qualified Reactive.Banana.MIDI.Time as Time
import qualified Reactive.Banana.Bunch.Combinators as RB
import qualified Reactive.Banana.Bunch.Frameworks as RBF
import qualified Sound.ALSA.Sequencer as SndSeq
import qualified Sound.ALSA.Sequencer.Client as Client
import qualified Sound.ALSA.Sequencer.Port as Port
import qualified Sound.ALSA.Sequencer.Queue as Queue
import qualified Sound.ALSA.Sequencer.Event as Event
import qualified Control.Monad.Trans.Class as MT
import qualified Control.Monad.Trans.State as MS
import qualified Control.Monad.Trans.Reader as MR
import Control.Monad.IO.Class (MonadIO, )
import Control.Monad.Fix (MonadFix, )
import Control.Applicative (Applicative, )
data Handle =
Handle {
sequ :: SndSeq.T SndSeq.DuplexMode,
client :: Client.T,
portPublic, portPrivate :: Port.T,
queue :: Queue.T
}
newtype Reactor a =
Reactor {
runReactor ::
MR.ReaderT
(RBF.AddHandler Event.T, Handle)
(MS.StateT Schedule RBF.MomentIO)
a
} deriving (Functor, Applicative, Monad, MonadIO, MonadFix)
instance RB.MonadMoment Reactor where
liftMoment = Process.liftMomentIO . RB.liftMoment
instance Process.MomentIO Reactor where
liftMomentIO = Reactor . MT.lift . MT.lift
instance Time.Timed Reactor where
ticksFromSeconds =
return .
Time.cons . Time.Ticks .
round . (nano *) .
Time.unSeconds . Time.decons
nano :: Num a => a
nano = 1000^(3::Int)
type Schedule = Event.Tag