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