cacophony 0.23.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cacophony.d.ts +358 -1
- package/dist/context.d.ts +15 -0
- package/dist/effects.d.ts +428 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +10 -2
- package/dist/index.mjs +2555 -1245
- package/dist/index.mjs.map +1 -1
- package/dist/meters/loudness-core.d.ts +179 -0
- package/dist/meters/loudness-core.test.d.ts +1 -0
- package/dist/meters/loudness-meter.d.ts +60 -0
- package/dist/meters/loudness-meter.test.d.ts +1 -0
- package/dist/meters/truepeak-core.d.ts +104 -0
- package/dist/meters/truepeak-core.test.d.ts +1 -0
- package/dist/playback.d.ts +35 -0
- package/dist/sound.d.ts +41 -0
- package/dist/spatial/foa-encode.d.ts +37 -0
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/AudioCache.html +7 -7
- package/docs/classes/BiquadEffect.html +2 -2
- package/docs/classes/Bus.html +15 -15
- package/docs/classes/Cacophony.html +300 -28
- package/docs/classes/DynamicsEffect.html +11 -0
- package/docs/classes/FdnReverbEffect.html +12 -0
- package/docs/classes/FoaDecoder.html +79 -0
- package/docs/classes/Group.html +13 -13
- package/docs/classes/KWeightingFilter.html +10 -0
- package/docs/classes/LoudnessMeter.html +39 -0
- package/docs/classes/MediaStreamPlayback.html +19 -19
- package/docs/classes/MediaStreamSound.html +19 -19
- package/docs/classes/MicrophonePlayback.html +3 -3
- package/docs/classes/ModulatedDelayEffect.html +12 -0
- package/docs/classes/PhaserEffect.html +11 -0
- package/docs/classes/Playback.html +58 -33
- package/docs/classes/ReverbEffect.html +2 -2
- package/docs/classes/ShareEffect.html +2 -2
- package/docs/classes/Sound.html +57 -28
- package/docs/classes/Synth.html +22 -22
- package/docs/classes/SynthGroup.html +2 -2
- package/docs/classes/TremoloEffect.html +11 -0
- package/docs/classes/TruePeakDetector.html +29 -0
- package/docs/classes/WaveshaperEffect.html +12 -0
- package/docs/functions/encodeMonoToFoaSN3D.html +31 -0
- package/docs/functions/integratedLoudness.html +12 -0
- package/docs/functions/integratedUngatedLoudness.html +7 -0
- package/docs/functions/loudnessRange.html +7 -0
- package/docs/functions/timeStretch.html +20 -0
- package/docs/functions/timeStretchChannels.html +4 -0
- package/docs/functions/truePeakDb.html +4 -0
- package/docs/hierarchy.html +1 -1
- package/docs/interfaces/AudioBuffer.html +2 -2
- package/docs/interfaces/AudioBufferSourceNode.html +4 -4
- package/docs/interfaces/AudioEventCallbacks.html +1 -1
- package/docs/interfaces/AudioListener.html +2 -2
- package/docs/interfaces/AudioNode.html +3 -3
- package/docs/interfaces/AudioParam.html +2 -2
- package/docs/interfaces/AudioWorklet.html +2 -2
- package/docs/interfaces/AudioWorkletNode.html +9 -4
- package/docs/interfaces/BaseContext.html +4 -2
- package/docs/interfaces/BaseSound.html +2 -2
- package/docs/interfaces/BiquadCoefficients.html +8 -0
- package/docs/interfaces/BiquadFilterNode.html +4 -4
- package/docs/interfaces/CacheErrorEvent.html +2 -2
- package/docs/interfaces/CacheHitEvent.html +2 -2
- package/docs/interfaces/CacheMissEvent.html +2 -2
- package/docs/interfaces/CacophonyEffect.html +2 -2
- package/docs/interfaces/ChannelMergerNode.html +3 -3
- package/docs/interfaces/ChannelSplitterNode.html +3 -3
- package/docs/interfaces/DynamicsOptions.html +21 -0
- package/docs/interfaces/FadeStartEvent.html +2 -2
- package/docs/interfaces/FdnReverbOptions.html +19 -0
- package/docs/interfaces/FoaDecoderOptions.html +10 -0
- package/docs/interfaces/GainNode.html +3 -3
- package/docs/interfaces/GlobalPlaybackEvent.html +2 -2
- package/docs/interfaces/LoadingCompleteEvent.html +2 -2
- package/docs/interfaces/LoadingErrorEvent.html +2 -2
- package/docs/interfaces/LoadingProgressEvent.html +2 -2
- package/docs/interfaces/LoadingStartEvent.html +2 -2
- package/docs/interfaces/LoudnessChannelInput.html +4 -0
- package/docs/interfaces/LoudnessReading.html +10 -0
- package/docs/interfaces/MediaElementSourceNode.html +3 -3
- package/docs/interfaces/MediaStreamAudioSourceNode.html +3 -3
- package/docs/interfaces/MediaStreamSoundOptions.html +2 -2
- package/docs/interfaces/ModulatedDelayOptions.html +27 -0
- package/docs/interfaces/OfflineOptions.html +2 -2
- package/docs/interfaces/OscillatorNode.html +4 -4
- package/docs/interfaces/PannerNode.html +3 -3
- package/docs/interfaces/PhaserOptions.html +23 -0
- package/docs/interfaces/PlayOptions.html +2 -2
- package/docs/interfaces/PlaybackErrorEvent.html +2 -2
- package/docs/interfaces/ReverbOptions.html +13 -13
- package/docs/interfaces/RuntimeOptions.html +2 -2
- package/docs/interfaces/SoundCleanupHoldings.html +2 -2
- package/docs/interfaces/SoundErrorEvent.html +2 -2
- package/docs/interfaces/StereoPannerNode.html +3 -3
- package/docs/interfaces/TimeStretchOptions.html +16 -0
- package/docs/interfaces/TremoloOptions.html +21 -0
- package/docs/interfaces/WaveshaperOptions.html +18 -0
- package/docs/modules.html +32 -0
- package/docs/types/BaseAudioEvents.html +1 -1
- package/docs/types/BusConnectionTarget.html +1 -1
- package/docs/types/CacheEventCallback.html +1 -1
- package/docs/types/CacophonyEvents.html +1 -1
- package/docs/types/ErrorEventCallback.html +1 -1
- package/docs/types/FadeType.html +1 -1
- package/docs/types/HrtfPannerOptions.html +1 -1
- package/docs/types/LoadingEventCallback.html +1 -1
- package/docs/types/LoopCount.html +1 -1
- package/docs/types/LoudnessChannel.html +4 -0
- package/docs/types/Orientation.html +1 -1
- package/docs/types/PanCloneOverrides.html +1 -1
- package/docs/types/PanType.html +1 -1
- package/docs/types/PlaybackEvents.html +1 -1
- package/docs/types/Position.html +1 -1
- package/docs/types/SoundEvents.html +1 -1
- package/docs/types/SoundType.html +1 -1
- package/docs/types/SourceNode.html +1 -1
- package/docs/types/SynthEvents.html +1 -1
- package/docs/types/ThreeDOptions.html +1 -1
- package/docs/variables/CHANNEL_WEIGHTS.html +4 -0
- package/docs/variables/K_WEIGHTING_STAGE1_48K.html +4 -0
- package/docs/variables/K_WEIGHTING_STAGE2_48K.html +3 -0
- package/package.json +5 -1
package/dist/cacophony.d.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { Bus } from './bus';
|
|
2
2
|
import { ICache } from './cache';
|
|
3
3
|
import { AudioBuffer, AudioListener, AudioNode, AudioWorkletNode, BaseContext, BiquadFilterNode, ChannelMergerNode, ChannelSplitterNode, GainNode, PannerNode } from './context';
|
|
4
|
-
import { CacophonyEffect, ReverbEffect, ReverbOptions } from './effects';
|
|
4
|
+
import { CacophonyEffect, DynamicsEffect, DynamicsOptions, FdnReverbEffect, FdnReverbOptions, FoaDecoder, FoaDecoderOptions, ModulatedDelayEffect, ModulatedDelayOptions, PhaserEffect, PhaserOptions, ReverbEffect, ReverbOptions, TremoloEffect, TremoloOptions, WaveshaperEffect, WaveshaperOptions } from './effects';
|
|
5
5
|
import { CacophonyEvents } from './events';
|
|
6
6
|
import { Group } from './group';
|
|
7
7
|
import { MediaStreamSound, MediaStreamSoundOptions } from './mediaStream';
|
|
8
|
+
import { LoudnessMeter } from './meters/loudness-meter';
|
|
8
9
|
import { MicrophoneStream } from './microphone';
|
|
9
10
|
import { ThreeDOptions } from './pannerMixin';
|
|
11
|
+
import { TimeStretchOptions } from './processors/timestretch-core';
|
|
10
12
|
import { Sound } from './sound';
|
|
11
13
|
import { Synth } from './synth';
|
|
12
14
|
export type SoundType = "html" | "streaming" | "buffer" | "oscillator";
|
|
@@ -137,6 +139,15 @@ export declare class Cacophony {
|
|
|
137
139
|
* the second construct would throw with no module registered.
|
|
138
140
|
*/
|
|
139
141
|
private loadedAudioWorklets;
|
|
142
|
+
/**
|
|
143
|
+
* Per-context cache of the decoded order-1 SH-HRIR `AudioBuffer` used by
|
|
144
|
+
* {@link FoaDecoder}. Keyed on the context (like
|
|
145
|
+
* {@link loadedAudioWorklets}) because `decodeAudioData` produces a buffer
|
|
146
|
+
* bound to ONE context's sample rate; a buffer decoded on context A must not
|
|
147
|
+
* be reused on context B. Stores the in-flight Promise so concurrent
|
|
148
|
+
* `loadFoaHrir` calls share a single fetch/decode.
|
|
149
|
+
*/
|
|
150
|
+
private foaHrirCache;
|
|
140
151
|
private finalizationRegistry;
|
|
141
152
|
private eventEmitter;
|
|
142
153
|
private cache;
|
|
@@ -205,6 +216,32 @@ export declare class Cacophony {
|
|
|
205
216
|
* @throws Error if the context does not support offline rendering
|
|
206
217
|
*/
|
|
207
218
|
startRendering(): Promise<AudioBuffer>;
|
|
219
|
+
/**
|
|
220
|
+
* OFFLINE independent time-stretch: change an AudioBuffer's tempo WITHOUT
|
|
221
|
+
* changing its pitch, returning a NEW AudioBuffer of length ≈
|
|
222
|
+
* `round(buffer.length · factor)` at the same sample rate.
|
|
223
|
+
*
|
|
224
|
+
* Algorithm: Phase Gradient Heap Integration (PGHI) per Zdeněk Průša & Nicki
|
|
225
|
+
* Holighaus, "Phase Vocoder Done Right" (EUSIPCO 2017 / arXiv:2202.07382).
|
|
226
|
+
* The signal is STFT'd, the synthesis phase is reconstructed by integrating
|
|
227
|
+
* the analysis-phase time/frequency gradients along the magnitude ridges
|
|
228
|
+
* (max-heap), then overlap-added at the stretched synthesis hop. No peak
|
|
229
|
+
* picking and no transient detection. Each channel is processed independently.
|
|
230
|
+
*
|
|
231
|
+
* This is an OFFLINE buffer transform, NOT a real-time worklet: the project's
|
|
232
|
+
* OLA worklet base is unity-rate (analysis hop == synthesis hop, fixed to the
|
|
233
|
+
* 128-sample render quantum) and cannot change the time base in real time. A
|
|
234
|
+
* genuine independent stretch needs analysis hop ≠ synthesis hop, which only
|
|
235
|
+
* the whole-buffer offline path provides.
|
|
236
|
+
*
|
|
237
|
+
* @param buffer The source AudioBuffer to time-stretch.
|
|
238
|
+
* @param factor Stretch factor (`> 0`). `> 1` lengthens (slower tempo), `< 1`
|
|
239
|
+
* shortens (faster tempo); pitch is preserved either way.
|
|
240
|
+
* @param options Optional PGHI parameters (fftSize, analysisHop, tol, seed).
|
|
241
|
+
* @returns A new, time-stretched AudioBuffer.
|
|
242
|
+
* @throws If the context cannot create buffers, or `factor <= 0`.
|
|
243
|
+
*/
|
|
244
|
+
timeStretchBuffer(buffer: AudioBuffer, factor: number, options?: TimeStretchOptions): AudioBuffer;
|
|
208
245
|
/**
|
|
209
246
|
* Register event listener.
|
|
210
247
|
* @returns Cleanup function
|
|
@@ -218,6 +255,21 @@ export declare class Cacophony {
|
|
|
218
255
|
emitAsync<K extends keyof CacophonyEvents>(event: K, data: CacophonyEvents[K]): Promise<void>;
|
|
219
256
|
loadWorklets(signal?: AbortSignal): Promise<void>;
|
|
220
257
|
loadStereoToBFormatWorklet(signal?: AbortSignal): Promise<void>;
|
|
258
|
+
/**
|
|
259
|
+
* Idempotently registers the `phase-vocoder` AudioWorkletProcessor (peak-based
|
|
260
|
+
* pitch-shifter with Identity Phase-Locking, Laroche & Dolson 1999 WASPAA) on
|
|
261
|
+
* this context. Safe to call repeatedly — subsequent calls short-circuit via
|
|
262
|
+
* the per-context {@link loadedAudioWorklets} set. Cross-context: pass
|
|
263
|
+
* `context` so a node built against a bus on a different context loads there.
|
|
264
|
+
*/
|
|
265
|
+
loadPhaseVocoder(signal?: AbortSignal, context?: BaseContext): Promise<void>;
|
|
266
|
+
/**
|
|
267
|
+
* Constructs a `phase-vocoder` AudioWorkletNode. Caller is expected to have
|
|
268
|
+
* loaded the module already (via {@link loadPhaseVocoder} or {@link loadWorklets}).
|
|
269
|
+
* Uses the same construct/fallback path as {@link createWorkletNode}. The
|
|
270
|
+
* returned node carries a single `pitchFactor` AudioParam (1 = no shift).
|
|
271
|
+
*/
|
|
272
|
+
createPhaseVocoderNode(options?: AudioWorkletNodeOptions, context?: BaseContext): Promise<AudioWorkletNode>;
|
|
221
273
|
/**
|
|
222
274
|
* Idempotently registers the DattorroReverb AudioWorkletProcessor on this
|
|
223
275
|
* context. Safe to call repeatedly — subsequent calls short-circuit via
|
|
@@ -243,6 +295,137 @@ export declare class Cacophony {
|
|
|
243
295
|
* for the cross-context rationale.
|
|
244
296
|
*/
|
|
245
297
|
createDattorroReverbNode(options: AudioWorkletNodeOptions, context?: BaseContext): Promise<AudioWorkletNode>;
|
|
298
|
+
/**
|
|
299
|
+
* Idempotently registers the `dynamics` AudioWorkletProcessor (feed-forward
|
|
300
|
+
* compressor/limiter/expander/gate, Giannoulis 2012) on this context. Safe to
|
|
301
|
+
* call repeatedly — subsequent calls short-circuit via the per-context
|
|
302
|
+
* {@link loadedAudioWorklets} set. Cross-context: pass `context` so a
|
|
303
|
+
* {@link DynamicsEffect} added to a bus on a different context loads there.
|
|
304
|
+
*/
|
|
305
|
+
loadDynamics(signal?: AbortSignal, context?: BaseContext): Promise<void>;
|
|
306
|
+
/**
|
|
307
|
+
* Constructs a `dynamics` AudioWorkletNode. Caller is expected to have loaded
|
|
308
|
+
* the module already (via {@link loadDynamics} or by reaching here through
|
|
309
|
+
* {@link DynamicsEffect.build}). Uses the same construct/fallback path as
|
|
310
|
+
* {@link createWorkletNode}.
|
|
311
|
+
*/
|
|
312
|
+
createDynamicsNode(options: AudioWorkletNodeOptions, context?: BaseContext): Promise<AudioWorkletNode>;
|
|
313
|
+
/**
|
|
314
|
+
* Idempotently registers the `fdn-reverb` AudioWorkletProcessor (Feedback
|
|
315
|
+
* Delay Network reverb — lossless paraunitary Hadamard feedback per Schlecht
|
|
316
|
+
* & Habets 2019, per-line absorption T60 per Jot 1991, velvet-noise diffusion
|
|
317
|
+
* per Fagerström 2020) on this context. Safe to call repeatedly — subsequent
|
|
318
|
+
* calls short-circuit via the per-context {@link loadedAudioWorklets} set.
|
|
319
|
+
* Cross-context: pass `context` so an {@link FdnReverbEffect} added to a bus
|
|
320
|
+
* on a different context loads there.
|
|
321
|
+
*/
|
|
322
|
+
loadFdnReverb(signal?: AbortSignal, context?: BaseContext): Promise<void>;
|
|
323
|
+
/**
|
|
324
|
+
* Constructs an `fdn-reverb` AudioWorkletNode. Caller is expected to have
|
|
325
|
+
* loaded the module already (via {@link loadFdnReverb} or by reaching here
|
|
326
|
+
* through {@link FdnReverbEffect.build}). Uses the same construct/fallback
|
|
327
|
+
* path as {@link createWorkletNode}.
|
|
328
|
+
*/
|
|
329
|
+
createFdnReverbNode(options: AudioWorkletNodeOptions, context?: BaseContext): Promise<AudioWorkletNode>;
|
|
330
|
+
/**
|
|
331
|
+
* Idempotently registers the `waveshaper` AudioWorkletProcessor (antialiased
|
|
332
|
+
* distortion/waveshaper via first-order Antiderivative Antialiasing, Parker,
|
|
333
|
+
* Zavalishin & Le Bivic 2016, DAFx-16) on this context. Safe to call
|
|
334
|
+
* repeatedly — subsequent calls short-circuit via the per-context
|
|
335
|
+
* {@link loadedAudioWorklets} set. Cross-context: pass `context` so a
|
|
336
|
+
* {@link WaveshaperEffect} added to a bus on a different context loads there.
|
|
337
|
+
*/
|
|
338
|
+
loadWaveshaper(signal?: AbortSignal, context?: BaseContext): Promise<void>;
|
|
339
|
+
/**
|
|
340
|
+
* Constructs a `waveshaper` AudioWorkletNode. Caller is expected to have
|
|
341
|
+
* loaded the module already (via {@link loadWaveshaper} or by reaching here
|
|
342
|
+
* through {@link WaveshaperEffect.build}). Uses the same construct/fallback
|
|
343
|
+
* path as {@link createWorkletNode}.
|
|
344
|
+
*/
|
|
345
|
+
createWaveshaperNode(options: AudioWorkletNodeOptions, context?: BaseContext): Promise<AudioWorkletNode>;
|
|
346
|
+
/**
|
|
347
|
+
* Idempotently registers the `modulated-delay` AudioWorkletProcessor —
|
|
348
|
+
* Dattorro's unified modulated-delay circuit (JAES 1997, Fig. 36) backing
|
|
349
|
+
* delay/chorus/flanger/vibrato/doubling, with Lagrange FIR fractional-delay
|
|
350
|
+
* interpolation (Laakso 1996) — on this context. Safe to call repeatedly —
|
|
351
|
+
* subsequent calls short-circuit via the per-context {@link loadedAudioWorklets}
|
|
352
|
+
* set. Cross-context: pass `context` so a {@link ModulatedDelayEffect} added to
|
|
353
|
+
* a bus on a different context loads there.
|
|
354
|
+
*/
|
|
355
|
+
loadModulatedDelay(signal?: AbortSignal, context?: BaseContext): Promise<void>;
|
|
356
|
+
/**
|
|
357
|
+
* Constructs a `modulated-delay` AudioWorkletNode. Caller is expected to have
|
|
358
|
+
* loaded the module already (via {@link loadModulatedDelay} or by reaching here
|
|
359
|
+
* through {@link ModulatedDelayEffect.build}). Uses the same construct/fallback
|
|
360
|
+
* path as {@link createWorkletNode}.
|
|
361
|
+
*/
|
|
362
|
+
createModulatedDelayNode(options: AudioWorkletNodeOptions, context?: BaseContext): Promise<AudioWorkletNode>;
|
|
363
|
+
/**
|
|
364
|
+
* Idempotently registers the `phaser` AudioWorkletProcessor — a classic
|
|
365
|
+
* MXR/Univibe-style allpass-cascade phase shifter (Smith STAN-M-21; PASP §8.9:
|
|
366
|
+
* a cascade of first-order allpass sections at a common LFO-swept break
|
|
367
|
+
* frequency, summed additively with the dry signal to sweep notches) on this
|
|
368
|
+
* context. Safe to call repeatedly — subsequent calls short-circuit via the
|
|
369
|
+
* per-context {@link loadedAudioWorklets} set. Cross-context: pass `context` so
|
|
370
|
+
* a {@link PhaserEffect} added to a bus on a different context loads there.
|
|
371
|
+
*/
|
|
372
|
+
loadPhaser(signal?: AbortSignal, context?: BaseContext): Promise<void>;
|
|
373
|
+
/**
|
|
374
|
+
* Constructs a `phaser` AudioWorkletNode. Caller is expected to have loaded the
|
|
375
|
+
* module already (via {@link loadPhaser} or by reaching here through
|
|
376
|
+
* {@link PhaserEffect.build}). Uses the same construct/fallback path as
|
|
377
|
+
* {@link createWorkletNode}.
|
|
378
|
+
*/
|
|
379
|
+
createPhaserNode(options: AudioWorkletNodeOptions, context?: BaseContext): Promise<AudioWorkletNode>;
|
|
380
|
+
/**
|
|
381
|
+
* Idempotently registers the `tremolo` AudioWorkletProcessor — LFO-driven
|
|
382
|
+
* amplitude modulation (a VCA swung by a low-frequency oscillator; standard AM
|
|
383
|
+
* theory + Dattorro 1997 p.776 quadrature stereo LFO + Mitcheltree et al.
|
|
384
|
+
* DAFx23 LFO framing) on this context. Safe to call repeatedly — subsequent
|
|
385
|
+
* calls short-circuit via the per-context {@link loadedAudioWorklets} set.
|
|
386
|
+
* Cross-context: pass `context` so a {@link TremoloEffect} added to a bus on a
|
|
387
|
+
* different context loads there.
|
|
388
|
+
*/
|
|
389
|
+
loadTremolo(signal?: AbortSignal, context?: BaseContext): Promise<void>;
|
|
390
|
+
/**
|
|
391
|
+
* Constructs a `tremolo` AudioWorkletNode. Caller is expected to have loaded the
|
|
392
|
+
* module already (via {@link loadTremolo} or by reaching here through
|
|
393
|
+
* {@link TremoloEffect.build}). Uses the same construct/fallback path as
|
|
394
|
+
* {@link createWorkletNode}.
|
|
395
|
+
*/
|
|
396
|
+
createTremoloNode(options: AudioWorkletNodeOptions, context?: BaseContext): Promise<AudioWorkletNode>;
|
|
397
|
+
/**
|
|
398
|
+
* Idempotently registers the `loudness-meter` AudioWorkletProcessor (ITU-R
|
|
399
|
+
* BS.1770-5 momentary / short-term / integrated loudness + true-peak) on this
|
|
400
|
+
* context. Safe to call repeatedly — subsequent calls short-circuit via the
|
|
401
|
+
* per-context {@link loadedAudioWorklets} set. Cross-context: pass `context`
|
|
402
|
+
* so a meter tapping a bus on a different context loads there.
|
|
403
|
+
*/
|
|
404
|
+
loadLoudnessMeter(signal?: AbortSignal, context?: BaseContext): Promise<void>;
|
|
405
|
+
/**
|
|
406
|
+
* Constructs a `loudness-meter` AudioWorkletNode. Caller is expected to have
|
|
407
|
+
* loaded the module already (via {@link loadLoudnessMeter} or {@link createLoudnessMeter}).
|
|
408
|
+
* The node is a PASS-THROUGH metering tap (1 input, 1 output) that posts
|
|
409
|
+
* momentary/short-term/integrated loudness and true-peak back over its port.
|
|
410
|
+
*/
|
|
411
|
+
createLoudnessMeterNode(options?: AudioWorkletNodeOptions, context?: BaseContext): Promise<AudioWorkletNode>;
|
|
412
|
+
/**
|
|
413
|
+
* Fetches and decodes the bundled order-1 SH-HRIR
|
|
414
|
+
* (`sh_hrir_order_1.wav`, from Omnitone, Apache-2.0 — see
|
|
415
|
+
* `src/assets/NOTICE`) into an `AudioBuffer`, memoized per context. The
|
|
416
|
+
* buffer is the 4-channel (ACN rows W,Y,Z,X) SH-domain HRIR consumed by
|
|
417
|
+
* {@link FoaDecoder} to drive its WY/ZX stereo ConvolverNodes
|
|
418
|
+
* (Ahrens 2022 eq.31 decode).
|
|
419
|
+
*
|
|
420
|
+
* The WAV is 48 kHz; `decodeAudioData` resamples it to the context's sample
|
|
421
|
+
* rate automatically when they differ (standard Web Audio behavior, which
|
|
422
|
+
* Omnitone relies on).
|
|
423
|
+
*
|
|
424
|
+
* @param context Optional BaseContext to decode on. Defaults to this host's
|
|
425
|
+
* own `context`. Supplied so a {@link FoaDecoder} added to a bus on
|
|
426
|
+
* a different context decodes the HRIR on the right context.
|
|
427
|
+
*/
|
|
428
|
+
loadFoaHrir(context?: BaseContext): Promise<AudioBuffer>;
|
|
246
429
|
createWorkletNode(name: string, url: string, signal?: AbortSignal, options?: AudioWorkletNodeOptions, context?: BaseContext): Promise<AudioWorkletNode>;
|
|
247
430
|
createStereoToBFormatNode(signal?: AbortSignal): Promise<AudioWorkletNode>;
|
|
248
431
|
/**
|
|
@@ -346,6 +529,180 @@ export declare class Cacophony {
|
|
|
346
529
|
* chain via `bus.addFilter(effect)`.
|
|
347
530
|
*/
|
|
348
531
|
createReverb(options?: ReverbOptions): ReverbEffect;
|
|
532
|
+
/**
|
|
533
|
+
* Creates a Feedback Delay Network (FDN) {@link CacophonyEffect} — an
|
|
534
|
+
* algorithmic reverb with a lossless degree-0 paraunitary Hadamard feedback
|
|
535
|
+
* matrix (Schlecht & Habets 2019), per-delay-line absorption filters setting
|
|
536
|
+
* the reverberation time T60 (Jot & Chaigne 1991), and multiplication-free
|
|
537
|
+
* velvet-noise input diffusion (Fagerström et al. 2020). The effect's
|
|
538
|
+
* `build` lazily registers the worklet module (no-op if already loaded) and
|
|
539
|
+
* constructs the AudioWorkletNode with the supplied {@link FdnReverbOptions}
|
|
540
|
+
* as `parameterData`. Add the returned effect to a {@link Bus} via
|
|
541
|
+
* `bus.addFilter(effect)`.
|
|
542
|
+
*/
|
|
543
|
+
createFdnReverb(options?: FdnReverbOptions): FdnReverbEffect;
|
|
544
|
+
/**
|
|
545
|
+
* Creates a dynamics {@link CacophonyEffect} configured as a COMPRESSOR
|
|
546
|
+
* (ratio > 1 reduces the level of signals above threshold). Implements the
|
|
547
|
+
* feed-forward design of Giannoulis, Massberg & Reiss 2012. Add the returned
|
|
548
|
+
* effect to a {@link Bus} via `bus.addFilter(effect)`. The same machinery
|
|
549
|
+
* (gain computer + log-domain smooth-branching detector) backs the limiter
|
|
550
|
+
* and gate presets below.
|
|
551
|
+
*/
|
|
552
|
+
createCompressor(options?: DynamicsOptions): DynamicsEffect;
|
|
553
|
+
/**
|
|
554
|
+
* Creates a dynamics {@link CacophonyEffect} preset as a LIMITER — a
|
|
555
|
+
* compressor with an effectively infinite ratio so output is clamped at the
|
|
556
|
+
* threshold (Giannoulis 2012 eqs 18-19). The ratio is fixed to the worklet's
|
|
557
|
+
* limiter sentinel; caller-supplied `ratio` is ignored. Other params
|
|
558
|
+
* (threshold, knee, attack, release, makeup) remain configurable.
|
|
559
|
+
*/
|
|
560
|
+
createLimiter(options?: Omit<DynamicsOptions, "ratio">): DynamicsEffect;
|
|
561
|
+
/**
|
|
562
|
+
* Creates a dynamics {@link CacophonyEffect} preset as a downward EXPANDER /
|
|
563
|
+
* GATE — ratio < 1 so signals BELOW the threshold are pushed further down
|
|
564
|
+
* (Giannoulis 2012 p.403). The default `ratio` of 0.1 gives gate-like
|
|
565
|
+
* downward expansion; pass a `ratio` closer to 1 for gentler expansion.
|
|
566
|
+
*/
|
|
567
|
+
createGate(options?: DynamicsOptions): DynamicsEffect;
|
|
568
|
+
/**
|
|
569
|
+
* Creates a {@link WaveshaperEffect} — an antialiased distortion/waveshaper
|
|
570
|
+
* implementing first-order Antiderivative Antialiasing (Parker, Zavalishin &
|
|
571
|
+
* Le Bivic 2016, DAFx-16): y[n] = (F0(x_n) - F0(x_{n-1}))/(x_n - x_{n-1})
|
|
572
|
+
* (eq.9), with an f(midpoint) fallback at the 0/0 singularity (eq.10). Ships
|
|
573
|
+
* two nonlinearities — `shape: 0` hard clip (polynomial F0, eq.25), `shape: 1`
|
|
574
|
+
* tanh soft clip (F0 = log cosh, eq.20). Carries an inherent 0.5-sample group
|
|
575
|
+
* delay (eq.17). Add the returned effect to a {@link Bus} via
|
|
576
|
+
* `bus.addFilter(effect)`.
|
|
577
|
+
*/
|
|
578
|
+
createWaveshaper(options?: WaveshaperOptions): WaveshaperEffect;
|
|
579
|
+
/**
|
|
580
|
+
* Creates a {@link WaveshaperEffect} preset as a DISTORTION — the tanh soft
|
|
581
|
+
* clipper (`shape: 1`, F0 = log cosh, Parker 2016 eq.20) with a default drive
|
|
582
|
+
* of 4 for an audible saturated tone. A convenience wrapper over
|
|
583
|
+
* {@link createWaveshaper}; caller-supplied options override the defaults.
|
|
584
|
+
*/
|
|
585
|
+
createDistortion(options?: WaveshaperOptions): WaveshaperEffect;
|
|
586
|
+
/**
|
|
587
|
+
* Creates a {@link ModulatedDelayEffect} preset as a DELAY / ECHO — Dattorro's
|
|
588
|
+
* unified modulated-delay circuit (JAES 1997, Fig. 36) with the modulation OFF
|
|
589
|
+
* (`depth: 0`, `rate: 0`). Echo knobs (Table 6): full dry `blend: 1` plus a
|
|
590
|
+
* unity wet tap `feedforward: 1`; feedback defaults to 0 (a single tap) but is
|
|
591
|
+
* caller-configurable for a regenerating echo (|feedback| < 1, Table 6). The
|
|
592
|
+
* 250 ms tap sits in the echo range (Table 7). All knobs are exposed.
|
|
593
|
+
*/
|
|
594
|
+
createDelay(options?: ModulatedDelayOptions): ModulatedDelayEffect;
|
|
595
|
+
/**
|
|
596
|
+
* Creates a {@link ModulatedDelayEffect} preset as a (white) CHORUS — Dattorro
|
|
597
|
+
* Table 6 white-chorus knobs `blend: 0.7071`, `feedforward: 1`,
|
|
598
|
+
* `feedback: 0.7071` (blend = feedback, feedforward = 1, the negative-feedback
|
|
599
|
+
* path that minimizes the spectral aberration of a plain dry+wet chorus). A
|
|
600
|
+
* 9 ms tap modulated 4 ms at 0.5 Hz sits in the chorus range (Table 7).
|
|
601
|
+
*
|
|
602
|
+
* NOTE: Dattorro's white chorus (p.776) combines this negative-feedback path
|
|
603
|
+
* with ALLPASS fractional-delay interpolation. This implementation uses the
|
|
604
|
+
* white-chorus knob settings but substitutes cubic-Lagrange interpolation
|
|
605
|
+
* (Laakso 1996) — transient-safe under modulation (Laakso p.52), trading some
|
|
606
|
+
* high-frequency trough depth versus a true allpass-interpolated white chorus.
|
|
607
|
+
*/
|
|
608
|
+
createChorus(options?: ModulatedDelayOptions): ModulatedDelayEffect;
|
|
609
|
+
/**
|
|
610
|
+
* Creates a {@link ModulatedDelayEffect} preset as a FLANGER — Dattorro Table 6
|
|
611
|
+
* flanger knobs `blend: 0.7071`, `feedforward: 0.7071` (blend = feedforward for
|
|
612
|
+
* the deepest comb trough), `feedback: -0.7071` (negative feedback deepens the
|
|
613
|
+
* troughs). A short 5 ms tap swept 4 ms at 0.25 Hz gives the classic flange
|
|
614
|
+
* (Table 7).
|
|
615
|
+
*/
|
|
616
|
+
createFlanger(options?: ModulatedDelayOptions): ModulatedDelayEffect;
|
|
617
|
+
/**
|
|
618
|
+
* Creates a {@link ModulatedDelayEffect} preset as a VIBRATO — Dattorro Table 6
|
|
619
|
+
* vibrato knobs `blend: 0`, `feedforward: 1`, `feedback: 0` (100% wet, no dry
|
|
620
|
+
* path, no feedback), so only the pitch-modulated delayed signal is heard. A
|
|
621
|
+
* 5 ms tap swept 3 ms at 5 Hz (Table 7).
|
|
622
|
+
*/
|
|
623
|
+
createVibrato(options?: ModulatedDelayOptions): ModulatedDelayEffect;
|
|
624
|
+
/**
|
|
625
|
+
* Creates a {@link ModulatedDelayEffect} preset as DOUBLING ("double tracking")
|
|
626
|
+
* — Dattorro Table 6 doubling knobs `blend: 0.7071`, `feedforward: 0.7071`,
|
|
627
|
+
* `feedback: 0` (no feedback). A ~20 ms tap (Table 7 doubling nominal) with a
|
|
628
|
+
* gentle 1 ms / 0.4 Hz wobble fattens a single take into two.
|
|
629
|
+
*/
|
|
630
|
+
createDoubling(options?: ModulatedDelayOptions): ModulatedDelayEffect;
|
|
631
|
+
/**
|
|
632
|
+
* Creates a {@link PhaserEffect} — a classic MXR/Univibe-style phase shifter: a
|
|
633
|
+
* cascade of first-order allpass sections at a common LFO-swept break frequency
|
|
634
|
+
* summed additively with the dry signal to sweep notches through the spectrum
|
|
635
|
+
* (Smith STAN-M-21; PASP §8.9). Two allpass sections per notch (default 4
|
|
636
|
+
* sections = 2 notches). Add the returned effect to a {@link Bus} via
|
|
637
|
+
* `bus.addFilter(effect)`.
|
|
638
|
+
*/
|
|
639
|
+
createPhaser(options?: PhaserOptions): PhaserEffect;
|
|
640
|
+
/**
|
|
641
|
+
* Creates a {@link TremoloEffect} — LFO-driven amplitude modulation (a VCA
|
|
642
|
+
* swung by a low-frequency oscillator). The gain swings between (1 - depth)
|
|
643
|
+
* and 1, never inverting (a true tremolo, not ring modulation). Anchored to
|
|
644
|
+
* standard AM theory, Dattorro 1997 (p.776) for the quadrature stereo LFO, and
|
|
645
|
+
* Mitcheltree et al. (DAFx23) for the LFO-driven-effect framing. `shape` selects
|
|
646
|
+
* the LFO waveform (0 = sine, 1 = triangle, 2 = square); `stereoPhase` offsets
|
|
647
|
+
* the per-channel LFO. Add the returned effect to a {@link Bus} via
|
|
648
|
+
* `bus.addFilter(effect)`.
|
|
649
|
+
*/
|
|
650
|
+
createTremolo(options?: TremoloOptions): TremoloEffect;
|
|
651
|
+
/**
|
|
652
|
+
* Creates a {@link TremoloEffect} preset as an AUTO-PAN — a tremolo with
|
|
653
|
+
* `stereoPhase: 180`, so the left and right channel gains modulate in
|
|
654
|
+
* anti-phase (the sound swings hard between the speakers). The 180-deg
|
|
655
|
+
* per-channel LFO offset is Dattorro's stereo-modulation convention (p.776). A
|
|
656
|
+
* convenience wrapper over {@link createTremolo}; caller options override the
|
|
657
|
+
* preset.
|
|
658
|
+
*/
|
|
659
|
+
createAutoPan(options?: TremoloOptions): TremoloEffect;
|
|
660
|
+
/** The default audio context for this Cacophony instance (used by
|
|
661
|
+
* {@link FoaDecoder} when no explicit context is supplied). */
|
|
662
|
+
defaultContext(): BaseContext;
|
|
663
|
+
/**
|
|
664
|
+
* Creates a {@link FoaDecoder} — a standalone first-order ambisonic (FOA) ->
|
|
665
|
+
* binaural FORMAT CONVERTER built from native Web Audio nodes (no worklet).
|
|
666
|
+
* It decodes a 4-channel ACN/SN3D `[W, Y, Z, X]` signal to headphone stereo
|
|
667
|
+
* via the per-SH-channel HRIR decode of Ahrens 2022 (eq.31), using
|
|
668
|
+
* Omnitone's WY/ZX 2-stereo-ConvolverNode packing and the bundled order-1
|
|
669
|
+
* SH-HRIR.
|
|
670
|
+
*
|
|
671
|
+
* It is 4-channel-in / 2-channel-out, so it is NOT a `CacophonyEffect` and is
|
|
672
|
+
* NOT added via `bus.addFilter`. Wire it EXPLICITLY using its two endpoints:
|
|
673
|
+
* feed FOA into `decoder.input` (4-ch) and route `decoder.output` (2-ch
|
|
674
|
+
* stereo) downstream:
|
|
675
|
+
* ```ts
|
|
676
|
+
* const decoder = await cacophony.createFoaDecoder();
|
|
677
|
+
* foaSource.connect(decoder.input);
|
|
678
|
+
* decoder.output.connect(bus.input); // or context.destination
|
|
679
|
+
* ```
|
|
680
|
+
* Build is async (the bundled HRIR is fetched + decoded). Pair it with
|
|
681
|
+
* {@link encodeMonoToFoaSN3D} (clean, physically correct) or with
|
|
682
|
+
* `createStereoToBFormatNode` (the perceptual, approximate stereo-upmix path).
|
|
683
|
+
*/
|
|
684
|
+
createFoaDecoder(options?: FoaDecoderOptions, context?: BaseContext): Promise<FoaDecoder>;
|
|
685
|
+
/**
|
|
686
|
+
* Creates an ITU-R BS.1770-5 {@link LoudnessMeter} that TAPS the output of a
|
|
687
|
+
* target node without altering the audible path. The meter reports momentary
|
|
688
|
+
* (400 ms), short-term (3 s), and gated integrated loudness in LKFS/LUFS, plus
|
|
689
|
+
* true-peak level in dBTP (Annex 2 4× oversampling).
|
|
690
|
+
*
|
|
691
|
+
* The tap is a BRANCH: the target's output is connected to the metering
|
|
692
|
+
* worklet in ADDITION to its existing forward edge, and the worklet's output
|
|
693
|
+
* is routed through an owned zero-gain sink to keep the branch silent and live.
|
|
694
|
+
* By default the target is the
|
|
695
|
+
* master bus output (`master.output`), measuring everything that reaches the
|
|
696
|
+
* destination — the integrated-loudness target. Pass a {@link Bus} to meter
|
|
697
|
+
* one bus's output, or any {@link AudioNode} to meter that node.
|
|
698
|
+
*
|
|
699
|
+
* Lazily registers the `loudness-meter` worklet module (no-op if already
|
|
700
|
+
* loaded) on the target's context, then constructs the node and branch-taps.
|
|
701
|
+
*
|
|
702
|
+
* @param target Node or bus whose output to meter. Defaults to the master bus.
|
|
703
|
+
* @returns A {@link LoudnessMeter} handle exposing the live readings.
|
|
704
|
+
*/
|
|
705
|
+
createLoudnessMeter(target?: Bus | AudioNode): Promise<LoudnessMeter>;
|
|
349
706
|
/**
|
|
350
707
|
* Creates a new {@link Bus}. If `name` is provided, the bus is registered
|
|
351
708
|
* so {@link getBus} can look it up by name. Anonymous buses (no name) are
|
package/dist/context.d.ts
CHANGED
|
@@ -62,8 +62,21 @@ export interface ChannelSplitterNode extends AudioNode {
|
|
|
62
62
|
}
|
|
63
63
|
export interface ChannelMergerNode extends AudioNode {
|
|
64
64
|
}
|
|
65
|
+
export interface ConvolverNode extends AudioNode {
|
|
66
|
+
buffer: AudioBuffer | null;
|
|
67
|
+
normalize: boolean;
|
|
68
|
+
}
|
|
65
69
|
export interface AudioWorkletNode extends AudioNode {
|
|
66
70
|
readonly port: MessagePort;
|
|
71
|
+
/**
|
|
72
|
+
* The node's AudioParam map (Web Audio `AudioParamMap`). Modelled as the
|
|
73
|
+
* minimal `get(name)` surface this library uses to drive worklet params
|
|
74
|
+
* (e.g. the phase-vocoder `pitchFactor`). Optional because test/mock
|
|
75
|
+
* contexts may not synthesise the param map.
|
|
76
|
+
*/
|
|
77
|
+
readonly parameters?: {
|
|
78
|
+
get(name: string): AudioParam | undefined;
|
|
79
|
+
};
|
|
67
80
|
}
|
|
68
81
|
export interface AudioBufferSourceNode extends AudioNode {
|
|
69
82
|
buffer: AudioBuffer | null;
|
|
@@ -125,6 +138,8 @@ export interface BaseContext {
|
|
|
125
138
|
createStereoPanner(): StereoPannerNode;
|
|
126
139
|
createChannelSplitter?(numberOfOutputs?: number): ChannelSplitterNode;
|
|
127
140
|
createChannelMerger?(numberOfInputs?: number): ChannelMergerNode;
|
|
141
|
+
createConvolver?(): ConvolverNode;
|
|
142
|
+
createBuffer?(numberOfChannels: number, length: number, sampleRate: number): AudioBuffer;
|
|
128
143
|
createOscillator(): OscillatorNode;
|
|
129
144
|
decodeAudioData(audioData: ArrayBuffer): Promise<AudioBuffer>;
|
|
130
145
|
decodeAudioData(audioData: ArrayBuffer, successCallback: (buffer: AudioBuffer) => void, errorCallback?: (error: DOMException) => void): Promise<AudioBuffer>;
|