| Safe Haskell | None |
|---|---|
| Language | GHC2021 |
Termtab.Audio.PlaybackThread
Description
Background-thread transport for playing back a whole Song with
pause/resume/stop, driven from the UI without blocking it.
The design: startPlayback forks one "tick" thread that walks the
song's measures/beats and sleeps between them; all coordination with
that thread happens through the STM TVars in PlaybackEnv rather than
by killing and restarting it on every command — pausePlayback,
stopPlayback, and resumePlayback just post a PlaybackCommand that
the tick thread notices between beats (see playMeasureBeats in the
internals). startPlayback is the one exception: it kills any
already-running tick thread before forking a new one, since "start"
means "play from here," not "resume."
Synopsis
- data PlaybackCommand
- data PlaybackEnv = PlaybackEnv {
- peAudioEngine :: AudioEngine
- pePositionVar :: TVar (MeasureIndex, BeatIndex)
- peCommandVar :: TVar (Maybe PlaybackCommand)
- peStatusVar :: TVar PlaybackStatus
- peNotify :: IO ()
- peThreadId :: TVar (Maybe ThreadId)
- initPlaybackEnv :: AudioConfig -> IO () -> IO PlaybackEnv
- destroyPlaybackEnv :: PlaybackEnv -> IO ()
- startPlayback :: PlaybackEnv -> Song -> MeasureIndex -> IO ()
- pausePlayback :: PlaybackEnv -> IO ()
- stopPlayback :: PlaybackEnv -> IO ()
- resumePlayback :: PlaybackEnv -> MeasureIndex -> IO ()
Documentation
data PlaybackCommand Source #
A message posted to peCommandVar for the running tick thread to act
on at its next beat boundary. Distinct from
AudioCommand — that type is for a queue-based
design that isn't what this module implements; this one is consumed
directly out of a single-slot TVar.
Constructors
| CmdStartPlayback MeasureIndex | |
| CmdPausePlayback | |
| CmdStopPlayback |
Instances
| Show PlaybackCommand Source # | |
Defined in Termtab.Audio.PlaybackThread Methods showsPrec :: Int -> PlaybackCommand -> ShowS # show :: PlaybackCommand -> String # showList :: [PlaybackCommand] -> ShowS # | |
| Eq PlaybackCommand Source # | |
Defined in Termtab.Audio.PlaybackThread Methods (==) :: PlaybackCommand -> PlaybackCommand -> Bool # (/=) :: PlaybackCommand -> PlaybackCommand -> Bool # | |
data PlaybackEnv Source #
Shared state between the caller (typically the UI) and the tick
thread forked by startPlayback. All fields are TVars so both sides
can read/write them without explicit locking.
Constructors
| PlaybackEnv | |
Fields
| |
initPlaybackEnv :: AudioConfig -> IO () -> IO PlaybackEnv Source #
Start a FluidSynth AudioEngine with cfg and build a fresh,
stopped PlaybackEnv around it. notify is stashed as peNotify and
invoked by the tick thread on every position/status change — pass
whatever hook wakes the UI's event loop (e.g. a Brick BChan write).
destroyPlaybackEnv :: PlaybackEnv -> IO () Source #
Kill any running tick thread and shut down the underlying
AudioEngine. Call this once when playback is no longer needed at all
(not for pausing — use pausePlayback for that).
startPlayback :: PlaybackEnv -> Song -> MeasureIndex -> IO () Source #
Kill any tick thread already running under env, then fork a fresh
one (tickThread) that plays song starting at startMeasure from
beat 0. Marks peStatusVar Playing immediately, without waiting for
the new thread to actually begin.
pausePlayback :: PlaybackEnv -> IO () Source #
Ask the running tick thread to pause at its next beat boundary (silences all notes and records the current position; does not stop the thread). No-op if nothing is playing.
stopPlayback :: PlaybackEnv -> IO () Source #
Ask the running tick thread to stop at its next beat boundary
(silences all notes and resets peStatusVar to Stopped). Unlike
startPlayback, this does not kill the thread directly — it just posts
the command and lets the thread exit on its own.
resumePlayback :: PlaybackEnv -> MeasureIndex -> IO () Source #
Resume a thread that is currently blocked waiting inside
waitForResume after a pause, continuing from measure mi (in practice
the measure it was paused at). Has no effect on a thread that isn't
paused, since nothing is polling peCommandVar for a resume in that
state.