mirror of
https://github.com/9x/sheetmusictrainer.git
synced 2026-11-03 22:03:54 +01:00
- Phrase Mode (sync to metronome): the run's scheduler is the single click source (with count-in); the metronome widget is muted and its pendulum mirrors the run's beats via the new phraseBeatBus (audio-timestamp scheduled). No more double clicks; clicks only while the run is active (phraseRunBus gates the widget's own ticking). - Schedule entries now carry continuous beat index + accent flag (downbeats accented, count-in beat 1 accented). - 'At your pace': optional click via the metronome toggle (kept explicit). - Metronome widget: gate prop; in gated mode it listens to the beat bus instead of running its own scheduler.
27 lines
707 B
TypeScript
27 lines
707 B
TypeScript
/**
|
|
* Tiny pub/sub for the phrase trainer's running state.
|
|
*
|
|
* Lets the (global) metronome widget gate its pendulum/click on the phrase
|
|
* run: in Phrase Mode the metronome should only be active while the trainer
|
|
* is counting in or playing, not while idle.
|
|
*/
|
|
type Listener = (running: boolean) => void;
|
|
|
|
const listeners = new Set<Listener>();
|
|
let running = false;
|
|
|
|
export const phraseRunBus = {
|
|
set(v: boolean): void {
|
|
if (v === running) return;
|
|
running = v;
|
|
listeners.forEach(l => l(v));
|
|
},
|
|
get(): boolean {
|
|
return running;
|
|
},
|
|
subscribe(l: Listener): () => void {
|
|
listeners.add(l);
|
|
return () => { listeners.delete(l); };
|
|
},
|
|
};
|