Summary
Param stores the native Web Audio AudioParam as protected _param, with no public accessor. Applications that need direct access to the underlying AudioParam — for native Web Audio automation scheduling or for working around suspended AudioContext behavior — must cast and access the private field.
Use Cases
1. Native Web Audio fade automation
When building a multi-track audio editor, fade envelopes (fade in/out on clips) are scheduled using native AudioParam methods (setValueAtTime, linearRampToValueAtTime, setValueCurveAtTime, cancelScheduledValues). These envelopes are managed entirely outside Tone.js's event tracking because:
- The fades are re-scheduled frequently (on every play, pause, seek, and loop iteration)
- They need to be cancelled atomically without affecting other Tone.js-managed parameters
- Using
Param's wrapper methods would add entries to Param._events, causing stale automation state that conflicts with our own envelope management
The cleanest approach is direct AudioParam access, keeping Tone.js's internal timeline and our automation completely separate.
2. Immediate value changes on suspended AudioContext
Setting .value on a Tone.js Param calls cancelScheduledValues(this.now()) + setValueAtTime(value, this.now()). When the AudioContext is suspended (e.g., before user gesture, or mobile Safari backgrounding), this.now() is frozen. While this does technically schedule the value, in practice we've observed that calling setValueAtTime(value, 0) directly on the native AudioParam gives more reliable immediate-effect behavior for mute toggling during suspended state — preventing brief audio glitches where all tracks are audible before solo muting takes effect on context resume.
Current Workaround
We access the private _param field via type casting:
let hasWarned = false;
export function getUnderlyingAudioParam(signal: unknown): AudioParam | undefined {
const param = (signal as { _param?: AudioParam })._param;
if (!param && !hasWarned) {
hasWarned = true;
console.warn(
'Unable to access Tone.js internal _param. ' +
'This likely means the Tone.js version is incompatible.'
);
}
return param;
}
This works on Tone.js 15.x but is fragile across version upgrades and relies on internal implementation details.
Suggested API
A read-only public property on Param:
// In Param class
get nativeParam(): AudioParam {
return this._param;
}
Or alternatively on Signal:
// In Signal class
get nativeParam(): AudioParam {
return this._param._param;
}
This would allow legitimate use cases that need native Web Audio API access without breaking encapsulation of Tone.js's internal state management.
Environment
Summary
Paramstores the native Web AudioAudioParamasprotected _param, with no public accessor. Applications that need direct access to the underlyingAudioParam— for native Web Audio automation scheduling or for working around suspended AudioContext behavior — must cast and access the private field.Use Cases
1. Native Web Audio fade automation
When building a multi-track audio editor, fade envelopes (fade in/out on clips) are scheduled using native
AudioParammethods (setValueAtTime,linearRampToValueAtTime,setValueCurveAtTime,cancelScheduledValues). These envelopes are managed entirely outside Tone.js's event tracking because:Param's wrapper methods would add entries toParam._events, causing stale automation state that conflicts with our own envelope managementThe cleanest approach is direct
AudioParamaccess, keeping Tone.js's internal timeline and our automation completely separate.2. Immediate value changes on suspended AudioContext
Setting
.valueon a Tone.jsParamcallscancelScheduledValues(this.now())+setValueAtTime(value, this.now()). When theAudioContextis suspended (e.g., before user gesture, or mobile Safari backgrounding),this.now()is frozen. While this does technically schedule the value, in practice we've observed that callingsetValueAtTime(value, 0)directly on the nativeAudioParamgives more reliable immediate-effect behavior for mute toggling during suspended state — preventing brief audio glitches where all tracks are audible before solo muting takes effect on context resume.Current Workaround
We access the private
_paramfield via type casting:This works on Tone.js 15.x but is fragile across version upgrades and relies on internal implementation details.
Suggested API
A read-only public property on
Param:Or alternatively on
Signal:This would allow legitimate use cases that need native Web Audio API access without breaking encapsulation of Tone.js's internal state management.
Environment