Skip to content

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 ​

typescript
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 ​

TransportOptions

Returns ​

Transport

Overrides ​

TypedEventEmitter.constructor

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 ​
typescript
transport.loopEnd = '2m'
transport.loop = true
Returns ​

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 ​
typescript
transport.loopEnd = '2m' // 8 beats in 4/4
Returns ​

number

Set Signature ​

set loopEnd(value): void

Defined in: packages/core/src/transport.ts:322

Parameters ​
value ​

MusicalTimeNotation

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 ​
ts
Example ​
typescript
transport.loopStart = '1m' // 4 beats in 4/4
Returns ​

number

Set Signature ​

set loopStart(value): void

Defined in: packages/core/src/transport.ts:302

Parameters ​
value ​

MusicalTimeNotation

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 ​

TransportPosition


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 ​
typescript
transport.swing = 0.55 // MPC-style swing feel
Returns ​

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 ​
typescript
transport.swingSubdivision = 1 / 8
Returns ​

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() ​

protected emit<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 ​

TypedEventEmitter.emit


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 ​

typescript
const handler = (e) => console.log(e.detail)
emitter.on('play', handler)
// later...
emitter.off('play', handler)

Inherited from ​

TypedEventEmitter.off


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 ​

typescript
emitter.on('play', handlePlay).on('stop', handleStop)
emitter.on(['play', 'stop'], handleBoth)

Inherited from ​

TypedEventEmitter.on


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 ​

typescript
emitter.once('end', () => console.log('Finished'))

Inherited from ​

TypedEventEmitter.once


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