EZ Web Audio / LayeredSound
Class: LayeredSound
Defined in: packages/core/src/layered-sound.ts:45
LayeredSound synchronizes multiple Sound/Oscillator instances for simultaneous playback with master gain/pan control and individual layer access.
All layers start at exactly the same audioContext.currentTime for precise sync. Layers end independently - LayeredSound emits 'end' when the last layer finishes.
Layers are constructor-only. There is no addLayer()/removeLayer() — the layer set passed to the constructor is fixed for the lifetime of the instance. To change layers at runtime, dispose this instance and construct a new LayeredSound with the desired layer array.
Example
const bass = await createSound('bass.mp3')
const melody = await createSound('melody.mp3')
const synth = await createOscillator({ frequency: 440 })
const layered = new LayeredSound(audioContext, [bass, melody, synth])
layered.play() // All layers start at exact same time
layered.changeGainTo(0.5) // Affects all layers
layered.getLayer(2)?.changeGainTo(0.8) // Control individual layerExtends
Constructors
Constructor
new LayeredSound(
audioContext,layers,opts?):LayeredSound
Defined in: packages/core/src/layered-sound.ts:57
Parameters
audioContext
AudioContext
layers
(Oscillator | Sound<BaseSoundEventMap> | null | undefined)[]
opts?
Returns
LayeredSound
Overrides
Properties
name
name:
string
Defined in: packages/core/src/layered-sound.ts:55
Accessors
disposed
Get Signature
get disposed():
boolean
Defined in: packages/core/src/layered-sound.ts:108
Whether this LayeredSound has been disposed.
Returns
boolean
layerCount
Get Signature
get layerCount():
number
Defined in: packages/core/src/layered-sound.ts:125
Get the number of valid layers in this LayeredSound.
Returns
number
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
addEffect()
addEffect(
effect,position?):this
Defined in: packages/core/src/layered-sound.ts:279
Add an effect to the shared output bus. All layers route through this bus, so the effect applies to all layers.
Parameters
effect
The effect to add
position?
number
Optional insert position (defaults to end)
Returns
this
this for chaining
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 "play" | "dispose" | "stop" | "end" | "warning"
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
changeGainTo()
changeGainTo(
value):this
Defined in: packages/core/src/layered-sound.ts:224
Set the gain for all layers via the shared output bus.
Validated identically to BaseSound.changeGainTo: throws a ValidationError for negative values, warns on the console for values above 1 (R1#1 — previously this bypassed validation entirely via a raw setValueAtTime call).
Parameters
value
number
The gain value (0-1 typical range)
Returns
this
this for chaining
changePanTo()
changePanTo(
value):this
Defined in: packages/core/src/layered-sound.ts:252
Set the pan for all layers.
Validated identically to BaseSound.changePanTo: warns on the console for values outside [-1, 1] (R1#1).
Parameters
value
number
The pan value (-1 to 1, where -1 is full left, 1 is full right)
Returns
this
this for chaining
dispose()
dispose():
void
Defined in: packages/core/src/layered-sound.ts:332
Stop all layers and dispose them. Releases resources and prevents further use.
After disposal, calling play() will throw an error. Dispose is idempotent — calling it multiple times is safe.
Returns
void
Example
const layered = await createLayeredSound([bass, melody])
layered.play()
// When done:
layered.dispose()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 "play" | "dispose" | "stop" | "end" | "warning"
Parameters
type
K
The event type to emit (key of TMap)
detail
LayeredSoundEventMap[K]["detail"]
The event detail object (typed by TMap)
Returns
void
Inherited from
getEffects()
getEffects(): readonly
Effect[]
Defined in: packages/core/src/layered-sound.ts:314
Get a readonly copy of the effects array.
Returns
readonly Effect[]
A copy of the effects array
getLayer()
getLayer(
index):Oscillator|Sound<BaseSoundEventMap> |undefined
Defined in: packages/core/src/layered-sound.ts:118
Get a layer by index for individual control.
Parameters
index
number
The layer index (0-based)
Returns
Oscillator | Sound<BaseSoundEventMap> | undefined
The Sound or Oscillator at that index, or undefined if out of bounds
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 "play" | "dispose" | "stop" | "end" | "warning"
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 "play" | "dispose" | "stop" | "end" | "warning"
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 "play" | "dispose" | "stop" | "end" | "warning"
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
play()
play():
Promise<void>
Defined in: packages/core/src/layered-sound.ts:133
Play all layers simultaneously at exactly the same audioContext.currentTime. This ensures perfect synchronization across all layers.
Returns
Promise<void>
playFor()
playFor(
duration):Promise<void>
Defined in: packages/core/src/layered-sound.ts:191
Play all layers simultaneously for a specified duration, then stop.
Parameters
duration
number
Duration in seconds before stopping all layers
Returns
Promise<void>
Example
const layered = await createLayeredSound([kick, snare])
layered.playFor(0.1) // Play for 100ms then auto-stopremoveEffect()
removeEffect(
effect):this
Defined in: packages/core/src/layered-sound.ts:298
Remove an effect from the shared output bus.
Parameters
effect
The effect to remove
Returns
this
this for chaining
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 "play" | "dispose" | "stop" | "end" | "warning"
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
setGain()
setGain(
value):void
Defined in: packages/core/src/layered-sound.ts:239
Parameters
value
number
The gain value (0-1 typical range)
Returns
void
Deprecated
Use changeGainTo instead — identical behavior, renamed for API symmetry with BaseSound/Sampler (R1#1). Will be removed in a future major version.
setPan()
setPan(
value):void
Defined in: packages/core/src/layered-sound.ts:267
Parameters
value
number
The pan value (-1 to 1, where -1 is full left, 1 is full right)
Returns
void
Deprecated
Use changePanTo instead — identical behavior, renamed for API symmetry with BaseSound/Sampler (R1#1). Will be removed in a future major version.
stop()
stop():
Promise<void>
Defined in: packages/core/src/layered-sound.ts:202
Stop all layers.
Returns
Promise<void>