EZ Web Audio / Transport
Class: Transport
Defined in: packages/core/src/transport.ts:101
Global Transport clock for multi-track synchronization.
Transport provides a Worker-backed clock that multiple BeatTracks can lock to, enabling perfect multi-track synchronization that survives background tab throttling. It manages tempo, time signature, position tracking, and lifecycle events.
Example
import { createTransport, createBeatTrack } from 'ez-web-audio'
const transport = await createTransport({ bpm: 120, timeSignature: [4, 4] })
const kick = await createBeatTrack(['kick.mp3'], { numBeats: 4 })
const hihat = await createBeatTrack(['hihat.mp3'], { numBeats: 16 })
kick.setPattern([1, 0, 1, 0])
hihat.setPattern([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
kick.syncTo(transport, { noteType: 1/4 })
hihat.syncTo(transport, { noteType: 1/16 })
transport.on('tick', (e) => {
console.log(`Position: ${e.detail.bar}:${e.detail.beat}:${e.detail.tick}`)
})
transport.start()Extends
Constructors
Constructor
new Transport(
audioContext,options):Transport
Defined in: packages/core/src/transport.ts:146
Parameters
audioContext
AudioContext
options
Returns
Transport
Overrides
Accessors
bpm
Get Signature
get bpm():
number
Defined in: packages/core/src/transport.ts:162
Current tempo in beats per minute. Can be changed during playback.
Returns
number
Set Signature
set bpm(
value):void
Defined in: packages/core/src/transport.ts:166
Parameters
value
number
Returns
void
loop
Get Signature
get loop():
boolean
Defined in: packages/core/src/transport.ts:279
Whether the transport loops over the region [loopStart, loopEnd). When enabled, position and synced-track pattern indices wrap at loopEnd and a 'loop' event fires on each wrap. Sequences are not remapped — they loop at their own length; give them the same length as the loop region for lockstep.
Default
false
The [loopStart, loopEnd) region is only validated (loopEnd must be greater than loopStart) at the moment playback actually (re)starts — see start. Setting loop, loopStart, or loopEnd to an invalid combination while the Transport is already playing does NOT throw immediately: playback silently continues without looping (as if loop were false) until the next start()/resume, at which point an invalid region throws.
Example
transport.loopEnd = '2m'
transport.loop = trueReturns
boolean
Set Signature
set loop(
value):void
Defined in: packages/core/src/transport.ts:283
Parameters
value
boolean
Returns
void
loopEnd
Get Signature
get loopEnd():
number
Defined in: packages/core/src/transport.ts:318
Loop region end. Set with musical notation ('2m') or a numeric beat count; reads back as beats. Must be greater than loopStart when loop is enabled — validated only at the next start call, not immediately on assignment; see loop for what happens to an invalid region set while already playing.
Example
transport.loopEnd = '2m' // 8 beats in 4/4Returns
number
Set Signature
set loopEnd(
value):void
Defined in: packages/core/src/transport.ts:322
Parameters
value
Returns
void
loopStart
Get Signature
get loopStart():
number
Defined in: packages/core/src/transport.ts:298
Loop region start. Set with musical notation ('1m', '2:1:0') or a numeric beat count; reads back as beats. Not validated against loopEnd until the next start call — see loop.
Default
Example
transport.loopStart = '1m' // 4 beats in 4/4Returns
number
Set Signature
set loopStart(
value):void
Defined in: packages/core/src/transport.ts:302
Parameters
value
Returns
void
paused
Get Signature
get paused():
boolean
Defined in: packages/core/src/transport.ts:194
Whether the Transport is currently paused.
Returns
boolean
playing
Get Signature
get playing():
boolean
Defined in: packages/core/src/transport.ts:189
Whether the Transport is currently playing.
Returns
boolean
position
Get Signature
get position():
TransportPosition
Defined in: packages/core/src/transport.ts:184
Current playback position in musical time.
Returns
swing
Get Signature
get swing():
number
Defined in: packages/core/src/transport.ts:225
Swing amount (0–1). 0 = straight; 1 = full triplet feel — every other swing subdivision is delayed to the triplet position. Applies to synced BeatTrack beats and Sequence events that land exactly on an odd subdivision; position/tick events are unaffected. Live-changeable — safe to set while the Transport is playing.
For synced Sequences, event positions are sequence-relative rather than transport-absolute. Swing parity is only guaranteed correct when the Sequence starts on a bar boundary and its length is a whole, even number of subdivisions — true for all Nm (measure) lengths.
Default: 0
Example
transport.swing = 0.55 // MPC-style swing feelReturns
number
Set Signature
set swing(
value):void
Defined in: packages/core/src/transport.ts:229
Parameters
value
number
Returns
void
swingSubdivision
Get Signature
get swingSubdivision():
number
Defined in: packages/core/src/transport.ts:247
The subdivision swing applies to: 1/8 (eighth notes) or 1/16 (sixteenth notes, MPC-style).
Default: 1/16
Example
transport.swingSubdivision = 1 / 8Returns
number
Set Signature
set swingSubdivision(
value):void
Defined in: packages/core/src/transport.ts:251
Parameters
value
number
Returns
void
ticksPerBeat
Get Signature
get ticksPerBeat():
number
Defined in: packages/core/src/transport.ts:179
Number of ticks per beat (position resolution).
Returns
number
timeSignature
Get Signature
get timeSignature(): [
number,number]
Defined in: packages/core/src/transport.ts:174
Time signature as [beatsPerBar, beatUnit].
Returns
[number, number]
tracks
Get Signature
get tracks(): readonly
SyncableBeatTrack[]
Defined in: packages/core/src/transport.ts:199
Read-only array of BeatTracks currently synced to this Transport. Cached for performance.
Returns
readonly SyncableBeatTrack[]
Methods
_clearListeners()
protected_clearListeners():void
Defined in: packages/core/src/events/typed-event-emitter.ts:192
Remove every listener registered through this emitter (via addEventListener(), on(), or once()), regardless of how many or what event type they're bound to.
Native EventTarget has no removeAllListeners(). This works around that by aborting a shared AbortSignal threaded through every addEventListener() call this class makes, then swapping in a fresh AbortController so the instance can keep accepting new listeners afterward (e.g. if it's reused before being garbage collected).
Subclasses call this from their dispose() alongside neutering dispatchEvent — the neuter stops future emits, this stops stale listener closures from being retained/invoked at all.
Returns
void
Inherited from
TypedEventEmitter._clearListeners
addEventListener()
Call Signature
addEventListener<
K>(type,listener,options?):void
Defined in: packages/core/src/events/typed-event-emitter.ts:44
Add a typed event listener for known event types. Overloaded to provide type safety for known event types while remaining compatible with the native EventTarget API.
Type Parameters
K
K extends "error" | "pause" | "loop" | "start" | "stop" | "resume" | "tick"
Parameters
type
K
The event type (key of TMap)
listener
(event) => void
Typed event handler
options?
Standard addEventListener options
boolean | AddEventListenerOptions
Returns
void
Inherited from
TypedEventEmitter.addEventListener
Call Signature
addEventListener(
type,listener,options?):void
Defined in: packages/core/src/events/typed-event-emitter.ts:49
Add a typed event listener for known event types. Overloaded to provide type safety for known event types while remaining compatible with the native EventTarget API.
Parameters
type
string
The event type (key of TMap)
listener
Typed event handler
EventListenerOrEventListenerObject | null
options?
Standard addEventListener options
boolean | AddEventListenerOptions
Returns
void
Inherited from
TypedEventEmitter.addEventListener
dispose()
dispose():
void
Defined in: packages/core/src/transport.ts:487
Dispose the Transport, terminating the Worker and releasing all resources. After disposal, the Transport should not be used.
Returns
void
emit()
protectedemit<K>(type,detail):void
Defined in: packages/core/src/events/typed-event-emitter.ts:95
Emit a typed event with the given detail.
Creates a CustomEvent with the provided detail and dispatches it on this target. Subclasses call this internally to fire lifecycle events.
Type Parameters
K
K extends "error" | "pause" | "loop" | "start" | "stop" | "resume" | "tick"
Parameters
type
K
The event type to emit (key of TMap)
detail
TransportEventMap[K]["detail"]
The event detail object (typed by TMap)
Returns
void
Inherited from
off()
off<
K>(type,listener):this
Defined in: packages/core/src/events/typed-event-emitter.ts:167
Unsubscribe from an event.
Note: Due to native EventTarget limitations, you must provide the same listener function reference that was used when subscribing.
Type Parameters
K
K extends "error" | "pause" | "loop" | "start" | "stop" | "resume" | "tick"
Parameters
type
K
The event type to unsubscribe from
listener
(event) => void
The event handler function to remove
Returns
this
this for chaining
Example
const handler = (e) => console.log(e.detail)
emitter.on('play', handler)
// later...
emitter.off('play', handler)Inherited from
on()
on<
K>(type,listener):this
Defined in: packages/core/src/events/typed-event-emitter.ts:116
Subscribe to one or more events. Supports chaining.
Type Parameters
K
K extends "error" | "pause" | "loop" | "start" | "stop" | "resume" | "tick"
Parameters
type
The event type(s) to subscribe to (key or array of keys of TMap)
K | K[]
listener
(event) => void
The event handler function
Returns
this
this for chaining
Example
emitter.on('play', handlePlay).on('stop', handleStop)
emitter.on(['play', 'stop'], handleBoth)Inherited from
once()
once<
K>(type,listener):this
Defined in: packages/core/src/events/typed-event-emitter.ts:141
Subscribe to an event once. Handler is removed after first invocation.
Type Parameters
K
K extends "error" | "pause" | "loop" | "start" | "stop" | "resume" | "tick"
Parameters
type
K
The event type to subscribe to
listener
(event) => void
The event handler function
Returns
this
this for chaining
Example
emitter.once('end', () => console.log('Finished'))Inherited from
pause()
pause():
void
Defined in: packages/core/src/transport.ts:423
Pause playback. Freezes position for later resume via start(). No-op if not playing or already paused.
Returns
void
removeEventListener()
Call Signature
removeEventListener<
K>(type,listener,options?):void
Defined in: packages/core/src/events/typed-event-emitter.ts:70
Remove a typed event listener for known event types. Overloaded to provide type safety for known event types while remaining compatible with the native EventTarget API.
Type Parameters
K
K extends "error" | "pause" | "loop" | "start" | "stop" | "resume" | "tick"
Parameters
type
K
The event type (key of TMap)
listener
(event) => void
Typed event handler to remove
options?
Standard removeEventListener options
boolean | EventListenerOptions
Returns
void
Inherited from
TypedEventEmitter.removeEventListener
Call Signature
removeEventListener(
type,listener,options?):void
Defined in: packages/core/src/events/typed-event-emitter.ts:75
Remove a typed event listener for known event types. Overloaded to provide type safety for known event types while remaining compatible with the native EventTarget API.
Parameters
type
string
The event type (key of TMap)
listener
Typed event handler to remove
EventListenerOrEventListenerObject | null
options?
Standard removeEventListener options
boolean | EventListenerOptions
Returns
void
Inherited from
TypedEventEmitter.removeEventListener
start()
start():
void
Defined in: packages/core/src/transport.ts:332
Start playback. Begins the Worker-driven scheduler and starts all synced tracks. No-op if already playing.
Returns
void
stop()
stop():
void
Defined in: packages/core/src/transport.ts:448
Stop playback and reset position to the beginning.
Returns
void