Optionalcontext: BaseContext
Audio context to use. If omitted, a fresh AudioContext
is constructed (which on mobile will be suspended until a user
gesture, triggering the auto-unlock path described above).
Optionalcache: ICache
Optional cache implementation. Defaults to AudioCache.
Optional runtime configuration including the
autoUnlock opt-out and a createAudioWorkletNode factory override.
The master bus — master.input IS globalGainNode (literally the same
GainNode), so every existing .connect(globalGainNode) call in the
codebase remains correct. cacophony.volume and cacophony.mute still
read and write master.input.gain.value through that alias.
Returns true if this instance is backed by an offline audio context (i.e., the context has a startRendering method).
Returns true while the audio context is suspended — i.e. the library
cannot produce sound until the context is resumed (typically by a user
gesture). After the auto-unlock fires (or resume() is called manually),
this becomes false.
Mirrors Howler's Howler.ctx.state === 'suspended' check via the
Howler global's _audioUnlocked. Use this to gate UI that hints to
the user that an interaction is required to start audio.
The single worklet-effect construction seam (WorkletEffectHost).
Idempotently registers worklet's module on context — or this host's own
context when omitted, honoring the cross-context contract that effects'
build(context) promises — then constructs the AudioWorkletNode with
parameterData. Every worklet-backed CacophonyEffect routes through
here, as does the phase-vocoder pitch-shift path (Playback.setPitchShift).
Optionalcontext: BaseContextOptionalnodeOptions: AudioWorkletNodeOptionsCreates a TremoloEffect preset as an AUTO-PAN — a tremolo with
stereoPhase: 180, so the left and right channel gains modulate in
anti-phase (the sound swings hard between the speakers). The 180-deg
per-channel LFO offset is Dattorro's stereo-modulation convention (p.776). A
convenience wrapper over createTremolo; caller options override the
preset.
Creates the spectral-delay SSB barberpole effect from Esqueda, Valimaki &
Parker (DAFx-15, Fig. 12): notches travel indefinitely in the direction
selected by the sign of rate, rather than reversing like a normal phaser.
Creates a ModulatedDelayEffect preset as a (white) CHORUS — Dattorro
Table 6 white-chorus knobs blend: 0.7071, feedforward: 1,
feedback: 0.7071 (blend = feedback, feedforward = 1, the negative-feedback
path that minimizes the spectral aberration of a plain dry+wet chorus). A
9 ms tap modulated 4 ms at 0.5 Hz sits in the chorus range (Table 7).
NOTE: Dattorro's white chorus (p.776) combines this negative-feedback path with ALLPASS fractional-delay interpolation. This implementation uses the white-chorus knob settings but substitutes cubic-Lagrange interpolation (Laakso 1996) — transient-safe under modulation (Laakso p.52), trading some high-frequency trough depth versus a true allpass-interpolated white chorus.
Creates a dynamics CacophonyEffect configured as a COMPRESSOR
(ratio > 1 reduces the level of signals above threshold). Implements the
feed-forward design of Giannoulis, Massberg & Reiss 2012. Add the returned
effect to a Bus via bus.addFilter(effect). The same machinery
(gain computer + log-domain smooth-branching detector) backs the limiter
and gate presets below.
Creates a ModulatedDelayEffect preset as a DELAY / ECHO — Dattorro's
unified modulated-delay circuit (JAES 1997, Fig. 36) with the modulation OFF
(depth: 0, rate: 0). Echo knobs (Table 6): full dry blend: 1 plus a
unity wet tap feedforward: 1; feedback defaults to 0 (a single tap) but is
caller-configurable for a regenerating echo (|feedback| < 1, Table 6). The
250 ms tap sits in the echo range (Table 7). All knobs are exposed.
Creates a WaveshaperEffect preset as a DISTORTION — the tanh soft
clipper (shape: 1, F0 = log cosh, Parker 2016 eq.20) with a default drive
of 4 for an audible saturated tone. A convenience wrapper over
createWaveshaper; caller-supplied options override the defaults.
Creates a ModulatedDelayEffect preset as DOUBLING ("double tracking")
— Dattorro Table 6 doubling knobs blend: 0.7071, feedforward: 0.7071,
feedback: 0 (no feedback). A ~20 ms tap (Table 7 doubling nominal) with a
gentle 1 ms / 0.4 Hz wobble fattens a single take into two.
Creates a Feedback Delay Network (FDN) CacophonyEffect — an
algorithmic reverb with a lossless degree-0 paraunitary Hadamard feedback
matrix (Schlecht & Habets 2019), per-delay-line absorption filters setting
the reverberation time T60 (Jot & Chaigne 1991), and multiplication-free
velvet-noise input diffusion (Fagerström et al. 2020). The effect's
build lazily registers the worklet module (no-op if already loaded) and
constructs the AudioWorkletNode with the supplied FdnReverbOptions
as parameterData. Add the returned effect to a Bus via
bus.addFilter(effect).
Creates a ModulatedDelayEffect preset as a FLANGER — Dattorro Table 6
flanger knobs blend: 0.7071, feedforward: 0.7071 (blend = feedforward for
the deepest comb trough), feedback: -0.7071 (negative feedback deepens the
troughs). A short 5 ms tap swept 4 ms at 0.25 Hz gives the classic flange
(Table 7).
Creates a FoaDecoder — a standalone first-order ambisonic (FOA) ->
binaural FORMAT CONVERTER built from native Web Audio nodes (no worklet).
It decodes a 4-channel ACN/SN3D [W, Y, Z, X] signal to headphone stereo
via the per-SH-channel HRIR decode of Ahrens 2022 (eq.31), using
Omnitone's WY/ZX 2-stereo-ConvolverNode packing and the bundled order-1
SH-HRIR.
It is 4-channel-in / 2-channel-out; this method returns the explicit
endpoint object for custom graph wiring:
feed FOA into decoder.input (4-ch) and route decoder.output (2-ch
stereo) downstream:
const decoder = await cacophony.createFoaDecoder();
foaSource.connect(decoder.input);
decoder.output.connect(bus.input); // or context.destination
Build is async (the bundled HRIR is fetched + decoded). Pair it with
encodeMonoToFoaSN3D (clean, physically correct) or with
createStereoToBFormatNode (the perceptual, approximate stereo-upmix path).
Optionalcontext: BaseContextCreates a bus-filter wrapper around FoaDecoder. Use this on a dedicated 4-channel ACN/SN3D FOA bus, typically as the first and only filter that converts that bus to stereo binaural output. For custom manual wiring, use createFoaDecoder instead.
Creates a Hilbert-transform single-sideband frequency shifter (Wardle, DAFx-98). Unlike pitch shifting, every partial moves by the same signed number of hertz, deliberately breaking harmonic ratios.
Creates a dynamics CacophonyEffect preset as a downward EXPANDER /
GATE — ratio < 1 so signals BELOW the threshold are pushed further down
(Giannoulis 2012 p.403). The default ratio of 0.1 gives gate-like
downward expansion; pass a ratio closer to 1 for gentler expansion.
Adds two identity-phase-locked pitch voices in one Laroche-Dolson STFT pass.
Creates a native ConvolverNode impulse-response effect. Pass an AudioBuffer
for an already-decoded IR or a URL to fetch/decode through the per-context
IR cache. The default is wet-only (dry: 0, wet: 1) and returns a single
ConvolverNode when added to a bus; setting dry or non-unity wet builds
an owned dry/wet endpoint graph exposing dry and wet automation params.
Creates a dynamics CacophonyEffect preset as a LIMITER — a
compressor with an effectively infinite ratio so output is clamped at the
threshold (Giannoulis 2012 eqs 18-19). The ratio is fixed to the worklet's
limiter sentinel; caller-supplied ratio is ignored. Other params
(threshold, knee, attack, release, makeup) remain configurable.
Creates an ITU-R BS.1770-5 LoudnessMeter that TAPS the output of a target node without altering the audible path. The meter reports momentary (400 ms), short-term (3 s), and gated integrated loudness in LKFS/LUFS, plus true-peak level in dBTP (Annex 2 4× oversampling).
The tap is a BRANCH: the target's output is connected to the metering
worklet in ADDITION to its existing forward edge, and the worklet's output
is routed through an owned zero-gain sink to keep the branch silent and live.
By default the target is the
master bus output (master.output), measuring everything that reaches the
destination — the integrated-loudness target. Pass a Bus to meter
one bus's output, or any AudioNode to meter that node.
Lazily registers the loudness-meter worklet module (no-op if already
loaded) on the target's context, then constructs the node and branch-taps.
A LoudnessMeter handle exposing the live readings.
Optionaloptions: MediaStreamSoundOptionsCreates a PannerNode with the specified options.
An object containing the options to use when creating the PannerNode.
A new PannerNode instance with the specified options.
Creates a push-based PCM source backed by a fixed-size AudioWorklet ring buffer. Each write is an interleaved Float32Array at this context's sample rate.
Creates a PhaserEffect — a classic MXR/Univibe-style phase shifter: a
cascade of first-order allpass sections at a common LFO-swept break frequency
summed additively with the dry signal to sweep notches through the spectrum
(Smith STAN-M-21; PASP §8.9). Two allpass sections per notch (default 4
sections = 2 notches). Add the returned effect to a Bus via
bus.addFilter(effect).
Creates a DattorroReverb CacophonyEffect. The effect's build
lazily registers the worklet module (no-op if already loaded) and
constructs the AudioWorkletNode with the supplied ReverbOptions
as parameterData. Add the returned effect to a Bus's filter
chain via bus.addFilter(effect).
Creates a Sound instance from an AudioBuffer or URL.
OptionalsoundType: SoundType
Type of sound (Buffer, HTML, Streaming)
OptionalpanType: PanType
Type of panning (HRTF or stereo)
Optionalsignal: AbortSignal
Optional AbortSignal to cancel the operation
Promise that resolves to a Sound instance
Creates a Sound instance from an AudioBuffer or URL.
Promise that resolves to a Sound instance
Creates a Sound from the first playable URL in a Howler-style fallback
array. The browser's HTMLAudioElement.canPlayType is queried per
extension; the first source it reports as supported ('probably' or
'maybe') is fetched and decoded. If decoding rejects for a candidate,
the next playable candidate is tried — a 'maybe' can still fail at
decode time.
MIME types are inferred from file extensions: .webm → audio/webm,
.mp3 → audio/mpeg, .ogg → audio/ogg, .wav → audio/wav,
.flac → audio/flac, .m4a → audio/mp4, .aac → audio/aac,
.opus → audio/ogg; codecs=opus.
Cache and loading events fire only for the URL actually fetched.
v1 limitation: only the default 'buffer' sound type participates in
fallback. Passing an array with any non-'buffer' soundType (e.g.
'html', 'streaming', 'oscillator') rejects with a clear "not yet
supported" error.
Captures and sustains a spectrum while continuing each bin's measured
phase advance. Automate the freeze AudioParam to capture/release.
Create ordinary, independently configurable Sounds over named regions of one shared buffer.
Optionalsignal: AbortSignalCreates an explicit-stereo sparse decorrelator with transient protection.
Creates a sample-accurate URL stream when WebCodecs can decode the primary audio track. Encoded media is fetched and demuxed incrementally, then its PCM is fed into the same routable AudioWorklet source returned by createPcmStreamSound. Browsers without WebCodecs, or without a decoder for the track, fall back to the media-element streaming tier.
Encoded audio stream URL.
Optionalsignal: AbortSignal
Optional cancellation signal retained as the second parameter for backwards compatibility.
Type of panning (HRTF or stereo).
Creates a TremoloEffect — LFO-driven amplitude modulation (a VCA
swung by a low-frequency oscillator). The gain swings between (1 - depth)
and 1, never inverting (a true tremolo, not ring modulation). Anchored to
standard AM theory, Dattorro 1997 (p.776) for the quadrature stereo LFO, and
Mitcheltree et al. (DAFx23) for the LFO-driven-effect framing. shape selects
the LFO waveform (0 = sine, 1 = triangle, 2 = square); stereoPhase offsets
the per-channel LFO. Add the returned effect to a Bus via
bus.addFilter(effect).
Creates a ModulatedDelayEffect preset as a VIBRATO — Dattorro Table 6
vibrato knobs blend: 0, feedforward: 1, feedback: 0 (100% wet, no dry
path, no feedback), so only the pitch-modulated delayed signal is heard. A
5 ms tap swept 3 ms at 5 Hz (Table 7).
Creates a WaveshaperEffect — an antialiased distortion/waveshaper
implementing first-order Antiderivative Antialiasing (Parker, Zavalishin &
Le Bivic 2016, DAFx-16): y[n] = (F0(x_n) - F0(x_{n-1}))/(x_n - x_{n-1})
(eq.9), with an f(midpoint) fallback at the 0/0 singularity (eq.10). Ships
two nonlinearities — shape: 0 hard clip (polynomial F0, eq.25), shape: 1
tanh soft clip (F0 = log cosh, eq.20). Carries an inherent 0.5-sample group
delay (eq.17). Add the returned effect to a Bus via
bus.addFilter(effect).
Optionalsignal: AbortSignalOptionaloptions: AudioWorkletNodeOptionsOptionalcontext: BaseContextThe default audio context for this Cacophony instance (used by FoaDecoder when no explicit context is supplied).
Retrieves a bus by name from the named-bus registry. Returns undefined
if no bus with that name exists. The special name 'master' returns
the auto-created master bus.
Returns the names of every registered named bus. Anonymous buses are
not included. The master bus's name ('master') is included.
Fetches and decodes the bundled order-1 SH-HRIR
(sh_hrir_order_1.wav, from Omnitone, Apache-2.0 — see
src/assets/NOTICE) into an AudioBuffer, memoized per context. The
buffer is the 4-channel (ACN rows W,Y,Z,X) SH-domain HRIR consumed by
FoaDecoder to drive its WY/ZX stereo ConvolverNodes
(Ahrens 2022 eq.31 decode).
The WAV is 48 kHz; decodeAudioData resamples it to the context's sample
rate automatically when they differ (standard Web Audio behavior, which
Omnitone relies on).
Optionalcontext: BaseContext
Optional BaseContext to decode on. Defaults to this host's
own context. Supplied so a FoaDecoder added to a bus on
a different context decodes the HRIR on the right context.
Fetches and decodes an impulse response URL on the requested audio context, memoized per context and URL. Buffers decoded by one context are not reused on another context, matching Web Audio's context-bound decode behavior.
Impulse-response audio URL.
Optionalcontext: BaseContext
Optional decode context. Defaults to this Cacophony instance.
Optionalsignal: AbortSignal
Optional abort signal for the fetch. Decode itself is not abortable in Web Audio, but an already-aborted signal is honored before decode starts.
Optionalsignal: AbortSignalEagerly registers every bundled AudioWorklet module on this context. This is
OPTIONAL — effects load their own worklet lazily in build, and the
pitch-shift path loads the phase-vocoder on first use. Call this up front to
pay the registration cost ahead of time. Idempotent per context (each module
short-circuits via the per-context loadedAudioWorklets set).
Optionalsignal: AbortSignalRemove event listener.
Register event listener.
Cleanup function
Suspends the audio context.
Resolves after the underlying AudioContext transition completes, then
emits the suspend event. If the context is already suspended (per this
instance's view), resolves immediately as a no-op. If the underlying
suspend() call rejects, the rejection is propagated and no event fires.
Internal
Resumes the audio context. This method is required to resume the audio context on mobile devices. On desktop, the audio context will automatically resume when a sound is played.
Resolves after the underlying AudioContext transition completes, then
emits the resume event. If the underlying resume() call rejects, the
rejection is propagated and no event fires.
Wraps a raw AudioNode in a CacophonyEffect so it can be added
to a Bus filter chain. By default Bus.addFilter rejects raw
AudioNodes — wrapping via shareEffect is the explicit opt-in that
signals "yes, I understand this single node will be shared across every
bus I add it to."
Renders the offline audio graph to a buffer. Only available when the context has a startRendering method.
Promise that resolves to the rendered AudioBuffer
OFFLINE independent time-stretch: change an AudioBuffer's tempo WITHOUT
changing its pitch, returning a NEW AudioBuffer of length ≈
round(buffer.length · factor) at the same sample rate.
Algorithm: Phase Gradient Heap Integration (PGHI) per Zdeněk Průša & Nicki Holighaus, "Phase Vocoder Done Right" (EUSIPCO 2017 / arXiv:2202.07382). The signal is STFT'd, the synthesis phase is reconstructed by integrating the analysis-phase time/frequency gradients along the magnitude ridges (max-heap), then overlap-added at the stretched synthesis hop. No peak picking and no transient detection. Each channel is processed independently.
This is an OFFLINE buffer transform, NOT a real-time worklet: the project's OLA worklet base is unity-rate (analysis hop == synthesis hop, fixed to the 128-sample render quantum) and cannot change the time base in real time. A genuine independent stretch needs analysis hop ≠ synthesis hop, which only the whole-buffer offline path provides.
The source AudioBuffer to time-stretch.
Stretch factor (> 0). > 1 lengthens (slower tempo), < 1
shortens (faster tempo); pitch is preserved either way.
Optionaloptions: TimeStretchOptions
Optional PGHI parameters (fftSize, analysisHop, tol, seed).
A new, time-stretched AudioBuffer.
Internal
StaticcreateCreates a Cacophony instance backed by an OfflineAudioContext. Use this for rendering, bouncing, precomputing processed output, or non-realtime scenarios.
Offline context configuration (channels, length, sampleRate)
Optionalcache: ICache
Optional cache implementation
OptionalruntimeOptions: RuntimeOptions
Optional runtime configuration
A Cacophony instance backed by OfflineAudioContext
Constructs a new Cacophony instance.
If the supplied (or auto-constructed) audio context is in
suspendedstate andruntimeOptions.autoUnlockistrue(default), one-timetouchend/click/keydownlisteners are installed ondocument.bodyso the first user gesture transparently unlocks audio — matching Howler'sautoUnlockbehavior. See RuntimeOptions.autoUnlock for the opt-out and the iOS primer rationale.