# TransportScheduler The `TransportScheduler` class drives the lookahead loop that polls the transport and fires scheduled callbacks. It bridges the `Transport` and the wall clock, ensuring that musical events are delivered with sample-accurate timing even when the underlying poll timer is coarse. _(no submodules)_ ## Purpose In real-time audio systems, callbacks must fire at precise musical times. A naive approach would poll the transport on every sample, which is prohibitively expensive. Instead, `TransportScheduler` polls at a coarse interval (~100 Hz) and asks the transport to process the entire time window in one go. The transport then uses `TickSource.forEachTickBetween` to visit every musical tick in the window and invoke callbacks at their exact audio times. ## Features - Poll-driven lookahead using `@suaveplan/timing`'s `createScheduler` - `start()` / `stop()` lifecycle - `AbortSignal` support for mid-run cancellation - OpenTelemetry `transport.tick` span per poll - Throws `AUDIO_TRANSPORT_SCHEDULER_NOT_STARTED` for invalid operations ## Usage: Basic ```ts import { Transport, TransportScheduler } from "@suaveplan/audio-transport"; const tr = new Transport(); const scheduler = new TransportScheduler(tr, () => Date.now() / 1000); tr.start(); scheduler.start(); ``` ## Usage: Advanced ```ts const ac = new AbortController(); scheduler.start({ signal: ac.signal }); // Later: ac.abort(); ``` ## API Reference ### Constructor `new TransportScheduler(transport, clock, options?)` ### Methods - `start(options?)` — begin polling; accepts `AbortSignal` - `stop()` — halt polling ### Properties - `running` — boolean ## Implementation Notes The scheduler uses real timers via `createScheduler`. Each poll creates an OpenTelemetry span named `transport.tick`. Calling `stop()` before `start()` throws `AUDIO_TRANSPORT_SCHEDULER_NOT_STARTED`. The scheduler does not emit FSM events directly; those are emitted synchronously by the `Transport` when `start`, `stop`, or `pause` are called. The `_tick` and `_scheduleNextPoll` methods contain defensive guards for the case where `stop()` races with a scheduled callback.