Skip to content

EZ Web Audio / BeatTrack

Class: BeatTrack

Defined in: packages/core/src/beat-track.ts:55

Drum machine lane with rhythmic beat patterns.

BeatTrack manages an array of Beat instances for creating drum patterns. It extends Sampler for round-robin sample variation and adds tempo-synced playback with beat events for visual synchronization.

Example

typescript
import { createBeatTrack } from 'ez-web-audio'

const kick = await createBeatTrack(['kick.mp3'], { numBeats: 8 })

// Set a basic 4-on-the-floor pattern
kick.beats[0].active = true  // beat 1
kick.beats[2].active = true  // beat 3
kick.beats[4].active = true  // beat 5
kick.beats[6].active = true  // beat 7

kick.playBeats(120, 1/4) // Play quarter notes at 120 BPM

// Listen for beat events
kick.on('beat', (e) => {
  console.log(`Beat ${e.detail.beatIndex}`)
})

Extends

Implements

  • SyncableBeatTrack

Constructors

Constructor

new BeatTrack(audioContext, sounds, opts?): BeatTrack

Defined in: packages/core/src/beat-track.ts:118

Parameters

audioContext

AudioContext

sounds

Playable & Connectable[]

opts?

BeatTrackOptions

Returns

BeatTrack

Overrides

Sampler.constructor

Properties

duration

duration: number = 100

Defined in: packages/core/src/beat-track.ts:154

How long (in milliseconds) the isPlaying flag stays true after a beat plays. Useful for visual feedback in the UI.

Default

ts
100

muted

muted: boolean = false

Defined in: packages/core/src/beat-track.ts:100

Whether this track is muted. When muted, beat scheduling continues (events still fire for UI sync) but audio playback is silenced.


name

name: string

Defined in: packages/core/src/sampler.ts:53

Optional name to aid in identification.

Inherited from

Sampler.name


numBeats

numBeats: number = 4

Defined in: packages/core/src/beat-track.ts:147

Number of beats in this track.

Default

ts
4

solo

solo: boolean = false

Defined in: packages/core/src/beat-track.ts:107

Whether this track is soloed. Solo is stackable — when any synced track has solo=true, only soloed tracks produce audio. When no tracks are soloed, all unmuted tracks produce audio.

Accessors

beats

Get Signature

get beats(): Beat[]

Defined in: packages/core/src/beat-track.ts:174

Array of Beat instances in this track.

The array length always matches numBeats. Beats are reused when the count changes, preserving their active state.

Example
typescript
// Toggle individual beats
track.beats[0].active = true
track.beats[1].active = false

// Check all beat states
track.beats.forEach((beat, i) => {
  console.log(`Beat ${i}: ${beat.active ? 'on' : 'off'}`)
})
Returns

Beat[]

Implementation of

SyncableBeatTrack.beats


gain

Get Signature

get gain(): number

Defined in: packages/core/src/sampler.ts:75

Gain level applied to each sample when played. This value is applied to the underlying Sound on every play() call, overriding any per-sound gain customization.

Validated the same way as Sampler.changeGainTo / BaseSound.changeGainTo: throws a ValidationError for negative values, warns on the console for values above 1 (R1#1 — previously this was a raw mutable field with no validation at all). Defaults to 1.

Returns

number

Set Signature

set gain(value): void

Defined in: packages/core/src/sampler.ts:79

Parameters
value

number

Returns

void

Inherited from

Sampler.gain


isSynced

Get Signature

get isSynced(): boolean

Defined in: packages/core/src/beat-track.ts:411

Whether this BeatTrack is currently synced to a Transport.

Returns

boolean


pan

Get Signature

get pan(): number

Defined in: packages/core/src/sampler.ts:92

Stereo pan position applied to each sample (-1 = left, 0 = center, 1 = right). This value is applied to the underlying Sound on every play() call, overriding any per-sound pan customization.

Validated the same way as Sampler.changePanTo / BaseSound.changePanTo: warns on the console for values outside [-1, 1] (R1#1). Defaults to 0.

Returns

number

Set Signature

set pan(value): void

Defined in: packages/core/src/sampler.ts:96

Parameters
value

number

Returns

void

Inherited from

Sampler.pan

Methods

addEventListener()

addEventListener<K>(type, listener, options?): void

Defined in: packages/core/src/beat-track.ts:710

Add a typed event listener for BeatTrack lifecycle events.

Type Parameters

K

K extends keyof BeatTrackEventMap

Parameters

type

K

Event type: 'beat', 'stop', 'pause', 'resume'

listener

(event) => void

Handler function

options?

Standard addEventListener options

boolean | AddEventListenerOptions

Returns

void


changeGainTo()

changeGainTo(value): this

Defined in: packages/core/src/sampler.ts:108

Set the gain level applied to each sample. Equivalent to sampler.gain = value, provided for API symmetry with BaseSound.changeGainTo() / LayeredSound.changeGainTo().

Parameters

value

number

The gain value (0-1 typical range)

Returns

this

this for chaining

Inherited from

Sampler.changeGainTo


changePanTo()

changePanTo(value): this

Defined in: packages/core/src/sampler.ts:120

Set the pan position applied to each sample. Equivalent to sampler.pan = value, provided for API symmetry with BaseSound.changePanTo() / LayeredSound.changePanTo().

Parameters

value

number

The pan value (-1 to 1)

Returns

this

this for chaining

Inherited from

Sampler.changePanTo


dispose()

dispose(): void

Defined in: packages/core/src/beat-track.ts:747

Dispose this BeatTrack, stopping playback, clearing beats, and releasing all audio resources.

After disposal, the BeatTrack should not be used. Create a new instance instead.

Returns

void

Example

typescript
const track = await createBeatTrack(['kick.mp3'], { numBeats: 8 })
track.playBeats(120, 1/4)
// When done:
track.dispose()

getSounds()

getSounds(): readonly Playable & Connectable[]

Defined in: packages/core/src/sampler.ts:208

Get a readonly snapshot of the sampler's sounds.

Returns a shallow copy as an array so callers can inspect which sounds are loaded without mutating the internal Set.

Returns

readonly Playable & Connectable[]

Readonly array of sounds in the sampler

Example

typescript
const sampler = await createSampler(['kick-1.mp3', 'kick-2.mp3'])
const sounds = sampler.getSounds()
console.log(sounds.length) // 2

Inherited from

Sampler.getSounds


off()

off<K>(type, listener): this

Defined in: packages/core/src/beat-track.ts:806

Unsubscribe from an event. Supports chaining.

Type Parameters

K

K extends keyof BeatTrackEventMap

Parameters

type

K

Event type to unsubscribe from

listener

(event) => void

Handler function to remove

Returns

this

this for chaining


on()

on<K>(type, listener): this

Defined in: packages/core/src/beat-track.ts:791

Subscribe to an event. Supports chaining.

Type Parameters

K

K extends keyof BeatTrackEventMap

Parameters

type

K

Event type: 'beat', 'stop', 'pause', 'resume'

listener

(event) => void

Handler function

Returns

this

this for chaining

Example

typescript
track.on('beat', (e) => {
  console.log(`Beat ${e.detail.beatIndex}`)
  highlightBeat(e.detail.beatIndex)
}).on('stop', () => {
  console.log('Stopped')
})

once()

once<K>(type, listener): this

Defined in: packages/core/src/beat-track.ts:828

Subscribe to an event once. Handler is removed after first invocation.

Type Parameters

K

K extends keyof BeatTrackEventMap

Parameters

type

K

Event type to listen for

listener

(event) => void

Handler function (called only once)

Returns

this

this for chaining

Example

typescript
track.once('stop', () => {
  console.log('Track stopped for the first time')
})

pause()

pause(): void

Defined in: packages/core/src/beat-track.ts:340

Pause playback at the current position.

Emits a 'pause' event with the current beat index. Use resume() to continue from where you left off.

Returns

void

Example

typescript
track.pause()
// later...
track.resume()

play()

play(velocity): void

Defined in: packages/core/src/sampler.ts:149

Play the next sound in the rotation immediately.

Parameters

velocity

number = 1

Gain multiplier (0–1) applied on top of the sampler's gain. Defaults to 1 (no attenuation).

Returns

void

Example

typescript
sampler.play() // plays sound 1
sampler.play() // plays sound 2
sampler.play(0.4) // plays sound 3 at 40% of the sampler's gain (then wraps to 1)

Inherited from

Sampler.play


playActiveBeats()

playActiveBeats(bpm, noteType): void

Defined in: packages/core/src/beat-track.ts:292

Start playing only active beats in the pattern continuously.

Same as playBeats(), but only plays beats where active === true. Inactive beats become rests (silence), maintaining timing.

Parameters

bpm

number

Tempo in beats per minute

noteType

number

Rhythmic subdivision as a fraction. Common values: 1/4 (quarter notes), 1/8 (eighth notes), 1/16 (sixteenth notes). The beat duration in seconds is calculated as: (240 * noteType) / bpm.

Returns

void

Example

typescript
// Set up a pattern with rests
track.beats[0].active = true
track.beats[2].active = true
track.playActiveBeats(120, 1/4)  // Only beats 0 and 2 play

playAt()

playAt(time, velocity): void

Defined in: packages/core/src/sampler.ts:186

Play the next sound at a specific AudioContext time.

Parameters

time

number

The AudioContext.currentTime value when to play

velocity

number = 1

Gain multiplier (0–1) applied on top of the sampler's gain. Defaults to 1 (no attenuation).

Returns

void

Example

typescript
const startTime = audioContext.currentTime + 1
sampler.playAt(startTime) // plays next sound at exactly startTime
sampler.playAt(startTime, 0.8) // plays next sound at exactly startTime at 80% gain

Inherited from

Sampler.playAt


playBeats()

playBeats(bpm, noteType): void

Defined in: packages/core/src/beat-track.ts:256

Start playing all beats in the pattern continuously.

Starts a lookahead scheduler that triggers beats at precise audio times. Emits 'beat' events for UI synchronization.

Unlike playActiveBeats(), this plays ALL beats regardless of their active flag.

Parameters

bpm

number

Tempo in beats per minute

noteType

number

Rhythmic subdivision as a fraction. Common values: 1/4 (quarter notes), 1/8 (eighth notes), 1/16 (sixteenth notes). The beat duration in seconds is calculated as: (240 * noteType) / bpm.

Returns

void

Example

typescript
track.playBeats(120, 1/4)  // 120 BPM, quarter notes — all beats play
track.playBeats(140, 1/8)  // 140 BPM, eighth notes

playIn()

playIn(seconds, velocity): void

Defined in: packages/core/src/sampler.ts:169

Play the next sound in the rotation after a delay.

Parameters

seconds

number

Number of seconds from now to play the sound

velocity

number = 1

Gain multiplier (0–1) applied on top of the sampler's gain. Defaults to 1 (no attenuation).

Returns

void

Example

typescript
sampler.playIn(0.5) // plays next sound in 0.5 seconds
sampler.playIn(0.5, 0.6) // plays next sound in 0.5 seconds at 60% gain

Inherited from

Sampler.playIn


removeEventListener()

removeEventListener<K>(type, listener, options?): void

Defined in: packages/core/src/beat-track.ts:725

Remove a typed event listener.

Type Parameters

K

K extends keyof BeatTrackEventMap

Parameters

type

K

Event type to unsubscribe from

listener

(event) => void

Handler function to remove

options?

Standard removeEventListener options

boolean | EventListenerOptions

Returns

void


resume()

resume(): void

Defined in: packages/core/src/beat-track.ts:366

Resume playback from where it was paused.

Emits a 'resume' event with the beat index where playback resumes. Has no effect if not paused.

Returns

void

Example

typescript
track.pause()
// ...user clicks play button...
track.resume() // continues from paused position

setPattern()

setPattern(pattern): this

Defined in: packages/core/src/beat-track.ts:227

Set beat active states (and velocities) from a pattern array.

Each element maps to a beat: truthy values (1, true) set the beat active, falsy values (0, false) set it inactive. If the array is shorter than the number of beats, remaining beats are set inactive. If longer, extra values are ignored.

Numeric values greater than 0 also set the beat's velocity — a gain multiplier for that hit (clamped to a max of 1). Booleans, and numbers that are 0 or negative, leave velocity at its current/default value of 1, matching prior boolean-only behavior.

Parameters

pattern

(number | boolean)[]

Array of numbers (0-1 velocity, or any non-zero value as "on") or booleans representing the beat pattern

Returns

this

this for chaining

Example

typescript
const kick = await createBeatTrack(['kick.mp3'], { numBeats: 8 })

// 4-on-the-floor pattern
kick.setPattern([1, 0, 1, 0, 1, 0, 1, 0])

// Ghost notes via velocity — 0.6 = quieter hit
kick.setPattern([1, 0, 0.6, 0])

// Shorter array — remaining beats inactive
kick.setPattern([1, 0, 1]) // beats 3-7 become inactive

// Chainable
kick.setPattern([1, 0, 1, 0]).playActiveBeats(120, 1/4)

setTempo()

setTempo(bpm): void

Defined in: packages/core/src/beat-track.ts:400

Change the tempo while playing.

The new tempo takes effect on the next scheduled beat.

Parameters

bpm

number

New tempo in beats per minute

Returns

void

Example

typescript
track.playBeats(120, 1/4)
// later, speed up...
track.setTempo(140)

stop()

stop(): void

Defined in: packages/core/src/beat-track.ts:322

Stop playback and reset to the beginning.

Emits a 'stop' event. Use pause() instead if you want to resume later.

Returns

void

Example

typescript
track.stop()
track.on('stop', () => console.log('Stopped'))

syncTo()

syncTo(transport, opts): void

Defined in: packages/core/src/beat-track.ts:435

Sync this BeatTrack to a Transport for clock-driven playback.

When synced, the Transport's scheduler drives this track's beats. Standalone methods (playBeats, playActiveBeats, stop, pause, resume, setTempo) throw an error while synced — use transport.start()/stop() instead.

Parameters

transport

Transport

The Transport to sync to

opts

Sync options

noteType

number

Rhythmic subdivision (e.g., 1/4, 1/16)

Returns

void

Example

typescript
const transport = await createTransport({ bpm: 120 })
const kick = await createBeatTrack(['kick.mp3'], { numBeats: 4 })

kick.syncTo(transport, { noteType: 1/4 })
transport.start() // kicks play quarter notes at 120 BPM

unsync()

unsync(): void

Defined in: packages/core/src/beat-track.ts:457

Unsync this BeatTrack from its Transport.

Re-enables standalone methods (playBeats, playActiveBeats, stop, etc.). If the track was playing via Transport, it stops cleanly.

Returns

void

Example

typescript
kick.unsync()
kick.playBeats(120, 1/4) // standalone mode works again