cacophony 0.18.3 → 0.19.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/README.md +50 -38
- package/dist/basePlayback.d.ts +15 -15
- package/dist/cache.d.ts +3 -3
- package/dist/cacophony.d.ts +67 -12
- package/dist/container.d.ts +1 -0
- package/dist/context.d.ts +129 -12
- package/dist/events.d.ts +19 -19
- package/dist/filters.d.ts +1 -0
- package/dist/group.d.ts +2 -2
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.mjs +942 -854
- package/dist/index.mjs.map +1 -1
- package/dist/microphone.d.ts +5 -4
- package/dist/oscillatorMixin.d.ts +8 -8
- package/dist/pannerMixin.d.ts +27 -28
- package/dist/playback.d.ts +6 -2
- package/dist/sound.d.ts +8 -5
- package/dist/stream.d.ts +2 -2
- package/dist/synth.d.ts +9 -6
- package/dist/synthGroup.d.ts +24 -3
- package/dist/synthPlayback.d.ts +15 -10
- package/dist/volumeMixin.d.ts +11 -11
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/AudioCache.html +61 -0
- package/docs/classes/Cacophony.html +35 -15
- package/docs/classes/Group.html +13 -14
- package/docs/classes/MicrophonePlayback.html +3 -3
- package/docs/classes/Playback.html +41 -46
- package/docs/classes/Sound.html +24 -21
- package/docs/classes/Synth.html +21 -26
- package/docs/classes/SynthGroup.html +17 -5
- package/docs/enums/SoundType.html +2 -2
- package/docs/hierarchy.html +1 -1
- package/docs/index.html +12 -11
- package/docs/interfaces/AudioBuffer.html +8 -0
- package/docs/interfaces/AudioBufferSourceNode.html +32 -0
- package/docs/interfaces/AudioEventCallbacks.html +2 -2
- package/docs/interfaces/AudioListener.html +10 -0
- package/docs/interfaces/AudioNode.html +24 -0
- package/docs/interfaces/AudioParam.html +10 -0
- package/docs/interfaces/BaseAudioEvents.html +2 -2
- package/docs/interfaces/BaseContext.html +20 -0
- package/docs/interfaces/BaseSound.html +2 -2
- package/docs/interfaces/BiquadFilterNode.html +30 -0
- package/docs/interfaces/CacheErrorEvent.html +2 -2
- package/docs/interfaces/CacheHitEvent.html +2 -2
- package/docs/interfaces/CacheMissEvent.html +2 -2
- package/docs/interfaces/CacophonyEvents.html +2 -2
- package/docs/interfaces/FadeStartEvent.html +2 -2
- package/docs/interfaces/GainNode.html +25 -0
- 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/MediaElementSourceNode.html +25 -0
- package/docs/interfaces/MediaStreamAudioSourceNode.html +25 -0
- package/docs/interfaces/OfflineOptions.html +6 -0
- package/docs/interfaces/OscillatorNode.html +30 -0
- package/docs/interfaces/PannerNode.html +38 -0
- package/docs/interfaces/PlayOptions.html +2 -2
- package/docs/interfaces/PlaybackErrorEvent.html +2 -2
- package/docs/interfaces/PlaybackEvents.html +2 -2
- package/docs/interfaces/RuntimeOptions.html +2 -0
- package/docs/interfaces/SoundCleanupHoldings.html +9 -0
- package/docs/interfaces/SoundErrorEvent.html +2 -2
- package/docs/interfaces/SoundEvents.html +2 -2
- package/docs/interfaces/StereoPannerNode.html +25 -0
- package/docs/interfaces/SynthEvents.html +2 -2
- package/docs/modules.html +20 -2
- package/docs/types/CacheEventCallback.html +1 -1
- package/docs/types/ErrorEventCallback.html +1 -1
- package/docs/types/FadeType.html +1 -1
- package/docs/types/LoadingEventCallback.html +1 -1
- package/docs/types/LoopCount.html +1 -1
- package/docs/types/Orientation.html +1 -1
- package/docs/types/PanType.html +1 -1
- package/docs/types/Position.html +1 -1
- package/docs/types/SourceNode.html +1 -0
- package/package.json +83 -70
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ Cacophony is a powerful and intuitive audio library designed for modern web appl
|
|
|
13
13
|
- **Synthesizer Integration**: Create and manipulate synthesized sounds with customizable oscillator options
|
|
14
14
|
- **Efficient Group Management**: Organize and control multiple sounds or synthesizers as groups for streamlined audio management
|
|
15
15
|
- **Live Microphone Input**: Capture and process real-time audio input from the user's microphone
|
|
16
|
-
- **
|
|
16
|
+
- **Network-Backed Playback**: Play audio directly from URLs using media-element-backed sounds
|
|
17
17
|
- **Flexible Caching**: Implement efficient audio caching strategies for improved performance
|
|
18
18
|
|
|
19
19
|
## Installation
|
|
@@ -92,13 +92,13 @@ sound.stop(); // Stops all three playbacks
|
|
|
92
92
|
|
|
93
93
|
## Sound Types
|
|
94
94
|
|
|
95
|
-
Cacophony supports three sound types
|
|
95
|
+
Cacophony supports three sound types:
|
|
96
96
|
|
|
97
|
-
| Type | Memory | Latency | Seeking | Multiple Instances | Best For |
|
|
98
|
-
|------|--------|---------|---------|-------------------|----------|
|
|
99
|
-
| **Buffer** (default) | High | None | Full | Yes | Sound effects, UI sounds, short music clips |
|
|
100
|
-
| **HTML** | Medium | Low | Full |
|
|
101
|
-
| **Streaming** |
|
|
97
|
+
| Type | Memory | Latency | Seeking | Multiple Instances | Best For |
|
|
98
|
+
|------|--------|---------|---------|-------------------|----------|
|
|
99
|
+
| **Buffer** (default) | High | None | Full | Yes | Sound effects, UI sounds, short music clips |
|
|
100
|
+
| **HTML** | Medium | Low | Full | Yes | Background music, large audio files, podcasts |
|
|
101
|
+
| **Streaming** | Medium | Low | Full | Yes | Network-backed playback created via `createStream()` |
|
|
102
102
|
|
|
103
103
|
```typescript
|
|
104
104
|
// Buffer - entire file loaded into memory
|
|
@@ -107,8 +107,8 @@ const sfx = await cacophony.createSound('explosion.mp3', SoundType.Buffer);
|
|
|
107
107
|
// HTML - streams from network, good for large files
|
|
108
108
|
const music = await cacophony.createSound('bgm.mp3', SoundType.HTML);
|
|
109
109
|
|
|
110
|
-
// Streaming - for
|
|
111
|
-
const radio = await cacophony.createStream('https://example.com/stream.m3u8');
|
|
110
|
+
// Streaming - convenience helper for network-backed playback
|
|
111
|
+
const radio = await cacophony.createStream('https://example.com/stream.m3u8');
|
|
112
112
|
```
|
|
113
113
|
|
|
114
114
|
## Playback Control
|
|
@@ -441,22 +441,28 @@ const footsteps = await cacophony.createGroupFromUrls([
|
|
|
441
441
|
|
|
442
442
|
footsteps.playRandom(); // Picks one at random
|
|
443
443
|
|
|
444
|
-
//
|
|
445
|
-
const dialog = await cacophony.createGroupFromUrls(['line1.mp3', 'line2.mp3', 'line3.mp3']);
|
|
446
|
-
dialog.playOrdered(true);
|
|
447
|
-
|
|
448
|
-
//
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
synthGroup
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
synthGroup.
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
synthGroup.
|
|
459
|
-
|
|
444
|
+
// Advance through sounds in sequence, one call at a time
|
|
445
|
+
const dialog = await cacophony.createGroupFromUrls(['line1.mp3', 'line2.mp3', 'line3.mp3']);
|
|
446
|
+
dialog.playOrdered(true); // Plays line1, then advances internal order
|
|
447
|
+
dialog.playOrdered(true); // Plays line2
|
|
448
|
+
dialog.playOrdered(true); // Plays line3
|
|
449
|
+
dialog.playOrdered(true); // Plays line1 again because looping is enabled
|
|
450
|
+
|
|
451
|
+
// SynthGroup for synthesizers
|
|
452
|
+
const synthGroup = new SynthGroup();
|
|
453
|
+
const synth1 = cacophony.createOscillator({ frequency: 440, type: 'sine' });
|
|
454
|
+
const synth2 = cacophony.createOscillator({ frequency: 660, type: 'square' });
|
|
455
|
+
synthGroup.addSynth(synth1);
|
|
456
|
+
synthGroup.addSynth(synth2);
|
|
457
|
+
synthGroup.play();
|
|
458
|
+
synthGroup.volume = 0.5;
|
|
459
|
+
synthGroup.type = 'triangle';
|
|
460
|
+
synthGroup.pause();
|
|
461
|
+
synthGroup.resume();
|
|
462
|
+
|
|
463
|
+
// Remove a synth from the group
|
|
464
|
+
synthGroup.removeSynth(synth1);
|
|
465
|
+
```
|
|
460
466
|
|
|
461
467
|
## Synthesizer Functionality
|
|
462
468
|
|
|
@@ -483,16 +489,22 @@ bass.addFilter(cacophony.createBiquadFilter({ type: 'lowpass', frequency: 1000 }
|
|
|
483
489
|
bass.play();
|
|
484
490
|
lead.play();
|
|
485
491
|
|
|
486
|
-
// Modulate frequency over time
|
|
487
|
-
let time = 0;
|
|
488
|
-
setInterval(() => {
|
|
489
|
-
const frequency = 440 + Math.sin(time) * 100;
|
|
490
|
-
sineOsc.frequency = frequency;
|
|
491
|
-
time += 0.1;
|
|
492
|
-
}, 50);
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
492
|
+
// Modulate frequency over time
|
|
493
|
+
let time = 0;
|
|
494
|
+
setInterval(() => {
|
|
495
|
+
const frequency = 440 + Math.sin(time) * 100;
|
|
496
|
+
sineOsc.frequency = frequency;
|
|
497
|
+
time += 0.1;
|
|
498
|
+
}, 50);
|
|
499
|
+
|
|
500
|
+
// Pause and resume the active synth playback without losing its settings
|
|
501
|
+
sineOsc.pause();
|
|
502
|
+
sineOsc.resume();
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
`synth.pause()` keeps the existing synth playback object so `synth.resume()` can restart it with the current frequency, detune, type, volume, pan, and filter settings. `synth.play()` still creates a fresh playback instance, just like `Sound.play()`.
|
|
506
|
+
|
|
507
|
+
## 3D Audio Positioning
|
|
496
508
|
|
|
497
509
|
Create immersive soundscapes with precise spatial audio control using HRTF (Head-Related Transfer Function) or stereo panning.
|
|
498
510
|
|
|
@@ -857,9 +869,9 @@ const group = await cacophony.createGroupFromUrls(
|
|
|
857
869
|
Call `cleanup()` when done with sounds to free resources:
|
|
858
870
|
|
|
859
871
|
```typescript
|
|
860
|
-
const sound = await cacophony.createSound('temp.mp3');
|
|
861
|
-
sound.play();
|
|
862
|
-
sound.cleanup(); //
|
|
872
|
+
const sound = await cacophony.createSound('temp.mp3');
|
|
873
|
+
sound.play();
|
|
874
|
+
sound.cleanup(); // Tears down playbacks, including pausing and resetting active HTML/streaming media
|
|
863
875
|
|
|
864
876
|
// Clear memory cache
|
|
865
877
|
cacophony.clearMemoryCache();
|
package/dist/basePlayback.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { FadeType } from './cacophony';
|
|
2
2
|
import { IPlaybackContainer } from './container';
|
|
3
3
|
import { AudioNode } from './context';
|
|
4
|
-
import { FilterManager } from './filters';
|
|
5
4
|
import { TypedEventEmitter } from './eventEmitter';
|
|
6
5
|
import { PlaybackEvents } from './events';
|
|
6
|
+
import { FilterManager } from './filters';
|
|
7
7
|
declare const BasePlayback_base: (abstract new (...args: any[]) => {
|
|
8
8
|
panner?: import('./context').PannerNode | import('./context').StereoPannerNode | undefined;
|
|
9
9
|
_panType: import('./cacophony').PanType;
|
|
10
10
|
readonly panType: import('./cacophony').PanType;
|
|
11
|
-
setPanType(panType: import('./cacophony').PanType, audioContext: import('
|
|
11
|
+
setPanType(panType: import('./cacophony').PanType, audioContext: import('./context').BaseContext): void;
|
|
12
12
|
setPannerNode(pannerNode: import('./context').PannerNode): void;
|
|
13
13
|
get stereoPan(): number | null;
|
|
14
14
|
set stereoPan(value: number);
|
|
@@ -16,13 +16,13 @@ declare const BasePlayback_base: (abstract new (...args: any[]) => {
|
|
|
16
16
|
set threeDOptions(options: Partial<PannerOptions>);
|
|
17
17
|
position: import('./cacophony').Position;
|
|
18
18
|
cleanup(): void;
|
|
19
|
-
_filters: BiquadFilterNode[];
|
|
20
|
-
addFilter(filter: BiquadFilterNode): void;
|
|
21
|
-
removeFilter(filter: BiquadFilterNode): void;
|
|
19
|
+
_filters: import('./context').BiquadFilterNode[];
|
|
20
|
+
addFilter(filter: import('./context').BiquadFilterNode): void;
|
|
21
|
+
removeFilter(filter: import('./context').BiquadFilterNode): void;
|
|
22
22
|
applyFilters(connection: any): any;
|
|
23
|
-
readonly filters: BiquadFilterNode[];
|
|
24
|
-
addFilters(filters: BiquadFilterNode[]): void;
|
|
25
|
-
removeFilters(filters: BiquadFilterNode[]): void;
|
|
23
|
+
readonly filters: import('./context').BiquadFilterNode[];
|
|
24
|
+
addFilters(filters: import('./context').BiquadFilterNode[]): void;
|
|
25
|
+
removeFilters(filters: import('./context').BiquadFilterNode[]): void;
|
|
26
26
|
}) & (abstract new (...args: any[]) => {
|
|
27
27
|
gainNode?: import('./context').GainNode | undefined;
|
|
28
28
|
_fadeTimeout?: NodeJS.Timeout | undefined;
|
|
@@ -35,13 +35,13 @@ declare const BasePlayback_base: (abstract new (...args: any[]) => {
|
|
|
35
35
|
cancelFade(): void;
|
|
36
36
|
fadeIn(duration: number, type?: FadeType | undefined): Promise<void>;
|
|
37
37
|
fadeOut(duration: number, type?: FadeType | undefined): Promise<void>;
|
|
38
|
-
_filters: BiquadFilterNode[];
|
|
39
|
-
addFilter(filter: BiquadFilterNode): void;
|
|
40
|
-
removeFilter(filter: BiquadFilterNode): void;
|
|
38
|
+
_filters: import('./context').BiquadFilterNode[];
|
|
39
|
+
addFilter(filter: import('./context').BiquadFilterNode): void;
|
|
40
|
+
removeFilter(filter: import('./context').BiquadFilterNode): void;
|
|
41
41
|
applyFilters(connection: any): any;
|
|
42
|
-
readonly filters: BiquadFilterNode[];
|
|
43
|
-
addFilters(filters: BiquadFilterNode[]): void;
|
|
44
|
-
removeFilters(filters: BiquadFilterNode[]): void;
|
|
42
|
+
readonly filters: import('./context').BiquadFilterNode[];
|
|
43
|
+
addFilters(filters: import('./context').BiquadFilterNode[]): void;
|
|
44
|
+
removeFilters(filters: import('./context').BiquadFilterNode[]): void;
|
|
45
45
|
}) & typeof FilterManager;
|
|
46
46
|
export declare abstract class BasePlayback extends BasePlayback_base {
|
|
47
47
|
source?: AudioNode;
|
|
@@ -61,7 +61,7 @@ export declare abstract class BasePlayback extends BasePlayback_base {
|
|
|
61
61
|
* Register event listener.
|
|
62
62
|
* @returns Cleanup function
|
|
63
63
|
*/
|
|
64
|
-
on<K extends keyof PlaybackEvents>(event: K, listener: (data: PlaybackEvents[K]) => void): void;
|
|
64
|
+
on<K extends keyof PlaybackEvents>(event: K, listener: (data: PlaybackEvents[K]) => void): () => void;
|
|
65
65
|
/**
|
|
66
66
|
* Remove event listener.
|
|
67
67
|
*/
|
package/dist/cache.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseContext } from './context';
|
|
2
2
|
export interface ICache {
|
|
3
|
-
getAudioBuffer(context:
|
|
3
|
+
getAudioBuffer(context: BaseContext, url: string, signal?: AbortSignal, callbacks?: {
|
|
4
4
|
onLoadingStart?: (event: any) => void;
|
|
5
5
|
onLoadingProgress?: (event: any) => void;
|
|
6
6
|
onLoadingComplete?: (event: any) => void;
|
|
@@ -85,7 +85,7 @@ export declare class AudioCache implements ICache {
|
|
|
85
85
|
* @returns Promise that resolves to decoded AudioBuffer
|
|
86
86
|
* @throws Error if audio cannot be fetched or decoded
|
|
87
87
|
*/
|
|
88
|
-
getAudioBuffer(context:
|
|
88
|
+
getAudioBuffer(context: BaseContext, url: string, signal?: AbortSignal, callbacks?: {
|
|
89
89
|
onLoadingStart?: (event: any) => void;
|
|
90
90
|
onLoadingProgress?: (event: any) => void;
|
|
91
91
|
onLoadingComplete?: (event: any) => void;
|
package/dist/cacophony.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { AudioContext, IAudioListener, IPannerNode, IPannerOptions } from 'standardized-audio-context';
|
|
2
1
|
import { ICache } from './cache';
|
|
3
|
-
import { AudioBuffer, GainNode } from './context';
|
|
2
|
+
import { AudioBuffer, AudioListener, BaseContext, BiquadFilterNode, GainNode, PannerNode } from './context';
|
|
4
3
|
import { CacophonyEvents } from './events';
|
|
5
4
|
import { Group } from './group';
|
|
6
5
|
import { MicrophoneStream } from './microphone';
|
|
@@ -12,7 +11,6 @@ export declare enum SoundType {
|
|
|
12
11
|
Buffer = "Buffer",
|
|
13
12
|
Oscillator = "oscillator"
|
|
14
13
|
}
|
|
15
|
-
type PannerNode = IPannerNode<AudioContext>;
|
|
16
14
|
/**
|
|
17
15
|
* Represents a 3D position in space.
|
|
18
16
|
* @typedef {Array<number>} Position - An array of three numbers representing the x, y, and z coordinates.
|
|
@@ -73,20 +71,76 @@ export interface BaseSound {
|
|
|
73
71
|
fadeOut?(duration: number, type?: FadeType): Promise<void>;
|
|
74
72
|
stopWithFade?(duration: number, type?: FadeType): Promise<void>;
|
|
75
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* Options for creating an offline audio context.
|
|
76
|
+
*/
|
|
77
|
+
export interface OfflineOptions {
|
|
78
|
+
numberOfChannels: number;
|
|
79
|
+
length: number;
|
|
80
|
+
sampleRate: number;
|
|
81
|
+
context?: BaseContext & {
|
|
82
|
+
startRendering(): Promise<AudioBuffer>;
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
export interface RuntimeOptions {
|
|
86
|
+
createAudioWorkletNode?: (context: BaseContext, name: string) => any;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Resources belonging to a Sound that must be released when the Sound is
|
|
90
|
+
* garbage collected without an explicit cleanup() call. The record is a plain
|
|
91
|
+
* data bag with no back-references to the Sound or its Playbacks — a
|
|
92
|
+
* FinalizationRegistry strongly retains its held value, so holding the Sound
|
|
93
|
+
* itself would prevent the target from ever becoming collectable.
|
|
94
|
+
*/
|
|
95
|
+
export interface SoundCleanupHoldings {
|
|
96
|
+
sources: Array<{
|
|
97
|
+
disconnect(): void;
|
|
98
|
+
}>;
|
|
99
|
+
gainNodes: GainNode[];
|
|
100
|
+
mediaElements: HTMLMediaElement[];
|
|
101
|
+
}
|
|
76
102
|
export declare class Cacophony {
|
|
77
|
-
context:
|
|
103
|
+
context: BaseContext;
|
|
78
104
|
globalGainNode: GainNode;
|
|
79
|
-
listener:
|
|
105
|
+
listener: AudioListener;
|
|
80
106
|
private prevVolume;
|
|
81
107
|
private finalizationRegistry;
|
|
82
108
|
private eventEmitter;
|
|
83
109
|
private cache;
|
|
84
|
-
|
|
110
|
+
private createAudioWorkletNode;
|
|
111
|
+
constructor(context?: BaseContext, cache?: ICache, runtimeOptions?: RuntimeOptions);
|
|
112
|
+
/** @internal */
|
|
113
|
+
registerSoundForCleanup(sound: object, holdings: SoundCleanupHoldings, unregisterToken: object): void;
|
|
114
|
+
/** @internal */
|
|
115
|
+
unregisterSoundCleanup(unregisterToken: object): void;
|
|
116
|
+
/**
|
|
117
|
+
* Creates a Cacophony instance backed by an OfflineAudioContext.
|
|
118
|
+
* Use this for rendering, bouncing, precomputing processed output,
|
|
119
|
+
* or non-realtime scenarios.
|
|
120
|
+
*
|
|
121
|
+
* @param options - Offline context configuration (channels, length, sampleRate)
|
|
122
|
+
* @param cache - Optional cache implementation
|
|
123
|
+
* @returns A Cacophony instance backed by OfflineAudioContext
|
|
124
|
+
*/
|
|
125
|
+
static createOffline(options: OfflineOptions, cache?: ICache): Cacophony;
|
|
126
|
+
/**
|
|
127
|
+
* Returns true if this instance is backed by an offline audio context
|
|
128
|
+
* (i.e., the context has a startRendering method).
|
|
129
|
+
*/
|
|
130
|
+
get isOffline(): boolean;
|
|
131
|
+
/**
|
|
132
|
+
* Renders the offline audio graph to a buffer.
|
|
133
|
+
* Only available when the context has a startRendering method.
|
|
134
|
+
*
|
|
135
|
+
* @returns Promise that resolves to the rendered AudioBuffer
|
|
136
|
+
* @throws Error if the context does not support offline rendering
|
|
137
|
+
*/
|
|
138
|
+
startRendering(): Promise<AudioBuffer>;
|
|
85
139
|
/**
|
|
86
140
|
* Register event listener.
|
|
87
141
|
* @returns Cleanup function
|
|
88
142
|
*/
|
|
89
|
-
on<K extends keyof CacophonyEvents>(event: K, listener: (data: CacophonyEvents[K]) => void): void;
|
|
143
|
+
on<K extends keyof CacophonyEvents>(event: K, listener: (data: CacophonyEvents[K]) => void): () => void;
|
|
90
144
|
/**
|
|
91
145
|
* Remove event listener.
|
|
92
146
|
*/
|
|
@@ -94,7 +148,9 @@ export declare class Cacophony {
|
|
|
94
148
|
emit<K extends keyof CacophonyEvents>(event: K, data: CacophonyEvents[K]): void;
|
|
95
149
|
emitAsync<K extends keyof CacophonyEvents>(event: K, data: CacophonyEvents[K]): Promise<void>;
|
|
96
150
|
loadWorklets(signal?: AbortSignal): Promise<void>;
|
|
97
|
-
createWorkletNode(name: string, url: string, signal?: AbortSignal): Promise<
|
|
151
|
+
createWorkletNode(name: string, url: string, signal?: AbortSignal): Promise<any>;
|
|
152
|
+
private createAbortError;
|
|
153
|
+
private createMediaSound;
|
|
98
154
|
clearMemoryCache(): void;
|
|
99
155
|
createOscillator(options: OscillatorOptions, panType?: PanType): Synth;
|
|
100
156
|
/**
|
|
@@ -127,10 +183,10 @@ export declare class Cacophony {
|
|
|
127
183
|
* @returns Promise that resolves to a Sound instance for streaming
|
|
128
184
|
*/
|
|
129
185
|
createStream(url: string, signal?: AbortSignal): Promise<Sound>;
|
|
130
|
-
createBiquadFilter: ({ type, frequency, gain, Q
|
|
186
|
+
createBiquadFilter: ({ type, frequency, gain, Q }: BiquadFilterOptions) => BiquadFilterNode;
|
|
131
187
|
/**
|
|
132
188
|
* Creates a PannerNode with the specified options.
|
|
133
|
-
* @param {
|
|
189
|
+
* @param {PannerOptions} options - An object containing the options to use when creating the PannerNode.
|
|
134
190
|
* @returns {PannerNode} A new PannerNode instance with the specified options.
|
|
135
191
|
* @example
|
|
136
192
|
* const panner = audio.createPanner({
|
|
@@ -142,7 +198,7 @@ export declare class Cacophony {
|
|
|
142
198
|
* orientationZ: 0,
|
|
143
199
|
* });
|
|
144
200
|
*/
|
|
145
|
-
createPanner({ coneInnerAngle, coneOuterAngle, coneOuterGain, distanceModel, maxDistance, channelCount, channelCountMode, channelInterpretation, panningModel, refDistance, rolloffFactor, positionX, positionY, positionZ, orientationX, orientationY, orientationZ, }: Partial<
|
|
201
|
+
createPanner({ coneInnerAngle, coneOuterAngle, coneOuterGain, distanceModel, maxDistance, channelCount, channelCountMode, channelInterpretation, panningModel, refDistance, rolloffFactor, positionX, positionY, positionZ, orientationX, orientationY, orientationZ, }: Partial<PannerOptions>): PannerNode;
|
|
146
202
|
/**
|
|
147
203
|
* Suspends the audio context.
|
|
148
204
|
*/
|
|
@@ -170,4 +226,3 @@ export declare class Cacophony {
|
|
|
170
226
|
get listenerPosition(): Position;
|
|
171
227
|
set listenerPosition(position: Position);
|
|
172
228
|
}
|
|
173
|
-
export {};
|
package/dist/container.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { BasePlayback } from 'basePlayback';
|
|
2
2
|
import { FadeType, Position } from './cacophony';
|
|
3
|
+
import { BiquadFilterNode } from './context';
|
|
3
4
|
import { FilterManager } from './filters';
|
|
4
5
|
type Constructor<T = FilterManager> = abstract new (...args: any[]) => T;
|
|
5
6
|
export interface IPlaybackContainer {
|
package/dist/context.d.ts
CHANGED
|
@@ -1,13 +1,130 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Cacophony's own audio type interfaces.
|
|
3
|
+
*
|
|
4
|
+
* These are minimal structural interfaces covering only what Cacophony
|
|
5
|
+
* actually uses. Both the native Web Audio API and standardized-audio-context
|
|
6
|
+
* satisfy these structurally, so users can pass either.
|
|
7
|
+
*/
|
|
8
|
+
export interface AudioParam {
|
|
9
|
+
value: number;
|
|
10
|
+
setValueAtTime(value: number, startTime: number): AudioParam;
|
|
11
|
+
linearRampToValueAtTime(value: number, endTime: number): AudioParam;
|
|
12
|
+
exponentialRampToValueAtTime(value: number, endTime: number): AudioParam;
|
|
13
|
+
cancelScheduledValues(cancelTime: number): AudioParam;
|
|
14
|
+
}
|
|
15
|
+
export interface AudioNode extends EventTarget {
|
|
16
|
+
connect(destination: AudioNode, output?: number, input?: number): AudioNode;
|
|
17
|
+
connect(destination: AudioParam, output?: number): void;
|
|
18
|
+
disconnect(): void;
|
|
19
|
+
disconnect(output: number): void;
|
|
20
|
+
disconnect(destination: AudioNode): void;
|
|
21
|
+
disconnect(destination: AudioParam): void;
|
|
22
|
+
channelCount: number;
|
|
23
|
+
channelCountMode: ChannelCountMode;
|
|
24
|
+
channelInterpretation: ChannelInterpretation;
|
|
25
|
+
readonly context: {
|
|
26
|
+
readonly currentTime: number;
|
|
27
|
+
};
|
|
28
|
+
readonly numberOfInputs: number;
|
|
29
|
+
readonly numberOfOutputs: number;
|
|
30
|
+
}
|
|
31
|
+
export interface GainNode extends AudioNode {
|
|
32
|
+
readonly gain: AudioParam;
|
|
33
|
+
}
|
|
34
|
+
export interface BiquadFilterNode extends AudioNode {
|
|
35
|
+
type: BiquadFilterType;
|
|
36
|
+
readonly frequency: AudioParam;
|
|
37
|
+
readonly detune: AudioParam;
|
|
38
|
+
readonly Q: AudioParam;
|
|
39
|
+
readonly gain: AudioParam;
|
|
40
|
+
getFrequencyResponse(frequencyHz: Float32Array, magResponse: Float32Array, phaseResponse: Float32Array): void;
|
|
41
|
+
}
|
|
42
|
+
export interface PannerNode extends AudioNode {
|
|
43
|
+
coneInnerAngle: number;
|
|
44
|
+
coneOuterAngle: number;
|
|
45
|
+
coneOuterGain: number;
|
|
46
|
+
distanceModel: DistanceModelType;
|
|
47
|
+
maxDistance: number;
|
|
48
|
+
panningModel: PanningModelType;
|
|
49
|
+
refDistance: number;
|
|
50
|
+
rolloffFactor: number;
|
|
51
|
+
readonly positionX: AudioParam;
|
|
52
|
+
readonly positionY: AudioParam;
|
|
53
|
+
readonly positionZ: AudioParam;
|
|
54
|
+
readonly orientationX: AudioParam;
|
|
55
|
+
readonly orientationY: AudioParam;
|
|
56
|
+
readonly orientationZ: AudioParam;
|
|
57
|
+
}
|
|
58
|
+
export interface StereoPannerNode extends AudioNode {
|
|
59
|
+
readonly pan: AudioParam;
|
|
60
|
+
}
|
|
61
|
+
export interface AudioBufferSourceNode extends AudioNode {
|
|
62
|
+
buffer: AudioBuffer | null;
|
|
63
|
+
loop: boolean;
|
|
64
|
+
loopStart: number;
|
|
65
|
+
loopEnd: number;
|
|
66
|
+
readonly playbackRate: AudioParam;
|
|
67
|
+
onended: ((ev: Event) => any) | null;
|
|
68
|
+
start(when?: number, offset?: number, duration?: number): void;
|
|
69
|
+
stop(when?: number): void;
|
|
70
|
+
}
|
|
71
|
+
export interface OscillatorNode extends AudioNode {
|
|
72
|
+
type: OscillatorType;
|
|
73
|
+
readonly frequency: AudioParam;
|
|
74
|
+
readonly detune: AudioParam;
|
|
75
|
+
onended: ((ev: Event) => any) | null;
|
|
76
|
+
start(when?: number): void;
|
|
77
|
+
stop(when?: number): void;
|
|
78
|
+
}
|
|
79
|
+
export interface MediaElementSourceNode extends AudioNode {
|
|
80
|
+
readonly mediaElement: HTMLMediaElement;
|
|
81
|
+
}
|
|
82
|
+
export interface MediaStreamAudioSourceNode extends AudioNode {
|
|
83
|
+
readonly mediaStream: MediaStream;
|
|
84
|
+
}
|
|
85
|
+
export interface AudioBuffer {
|
|
86
|
+
readonly duration: number;
|
|
87
|
+
readonly length: number;
|
|
88
|
+
readonly sampleRate: number;
|
|
89
|
+
readonly numberOfChannels: number;
|
|
90
|
+
getChannelData(channel: number): Float32Array;
|
|
91
|
+
copyFromChannel(destination: Float32Array, channelNumber: number, bufferOffset?: number): void;
|
|
92
|
+
copyToChannel(source: Float32Array, channelNumber: number, bufferOffset?: number): void;
|
|
93
|
+
}
|
|
94
|
+
export interface AudioListener {
|
|
95
|
+
readonly positionX: AudioParam;
|
|
96
|
+
readonly positionY: AudioParam;
|
|
97
|
+
readonly positionZ: AudioParam;
|
|
98
|
+
readonly forwardX: AudioParam;
|
|
99
|
+
readonly forwardY: AudioParam;
|
|
100
|
+
readonly forwardZ: AudioParam;
|
|
101
|
+
readonly upX: AudioParam;
|
|
102
|
+
readonly upY: AudioParam;
|
|
103
|
+
readonly upZ: AudioParam;
|
|
104
|
+
}
|
|
105
|
+
export interface AudioWorklet {
|
|
106
|
+
addModule(moduleURL: string, options?: WorkletOptions): Promise<void>;
|
|
107
|
+
}
|
|
108
|
+
export interface BaseContext {
|
|
109
|
+
readonly currentTime: number;
|
|
110
|
+
readonly sampleRate: number;
|
|
111
|
+
readonly destination: AudioNode;
|
|
112
|
+
readonly listener: AudioListener;
|
|
113
|
+
readonly audioWorklet?: AudioWorklet;
|
|
114
|
+
createGain(): GainNode;
|
|
115
|
+
createBufferSource(): AudioBufferSourceNode;
|
|
116
|
+
createBiquadFilter(): BiquadFilterNode;
|
|
117
|
+
createPanner(): PannerNode;
|
|
118
|
+
createStereoPanner(): StereoPannerNode;
|
|
119
|
+
createOscillator(): OscillatorNode;
|
|
120
|
+
decodeAudioData(audioData: ArrayBuffer): Promise<AudioBuffer>;
|
|
121
|
+
decodeAudioData(audioData: ArrayBuffer, successCallback: (buffer: AudioBuffer) => void, errorCallback?: (error: DOMException) => void): Promise<AudioBuffer>;
|
|
122
|
+
createMediaElementSource?(mediaElement: HTMLMediaElement): MediaElementSourceNode;
|
|
123
|
+
createMediaStreamSource?(stream: MediaStream): MediaStreamAudioSourceNode;
|
|
124
|
+
suspend?(suspendTime?: number): Promise<void>;
|
|
125
|
+
resume?(): Promise<void>;
|
|
126
|
+
close?(): Promise<void>;
|
|
127
|
+
startRendering?(): Promise<AudioBuffer>;
|
|
128
|
+
readonly length?: number;
|
|
129
|
+
}
|
|
8
130
|
export type SourceNode = AudioBufferSourceNode | MediaElementSourceNode | OscillatorNode;
|
|
9
|
-
export type MediaStreamAudioSourceNode = IMediaStreamAudioSourceNode<AudioContext>;
|
|
10
|
-
export type GainNode = IGainNode<AudioContext>;
|
|
11
|
-
export type PannerNode = IPannerNode<AudioContext>;
|
|
12
|
-
export type StereoPannerNode = IStereoPannerNode<AudioContext>;
|
|
13
|
-
export { AudioContext };
|
package/dist/events.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BasePlayback } from './basePlayback';
|
|
2
|
-
import { SynthPlayback } from './synthPlayback';
|
|
3
2
|
import { Sound } from './sound';
|
|
4
3
|
import { Synth } from './synth';
|
|
4
|
+
import { SynthPlayback } from './synthPlayback';
|
|
5
5
|
/**
|
|
6
6
|
* Base events for all audio objects.
|
|
7
7
|
*/
|
|
@@ -12,21 +12,21 @@ export interface FadeStartEvent {
|
|
|
12
12
|
}
|
|
13
13
|
export interface BaseAudioEvents {
|
|
14
14
|
play: BasePlayback;
|
|
15
|
-
stop:
|
|
16
|
-
pause:
|
|
17
|
-
resume:
|
|
18
|
-
ended:
|
|
15
|
+
stop: undefined;
|
|
16
|
+
pause: undefined;
|
|
17
|
+
resume: undefined;
|
|
18
|
+
ended: undefined;
|
|
19
19
|
volumeChange: number;
|
|
20
20
|
error: PlaybackErrorEvent;
|
|
21
21
|
fadeStart: FadeStartEvent;
|
|
22
|
-
fadeEnd:
|
|
23
|
-
fadeCancel:
|
|
22
|
+
fadeEnd: undefined;
|
|
23
|
+
fadeCancel: undefined;
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
26
|
* Sound-specific events.
|
|
27
27
|
*/
|
|
28
28
|
export interface SoundEvents extends BaseAudioEvents {
|
|
29
|
-
loopEnd:
|
|
29
|
+
loopEnd: undefined;
|
|
30
30
|
rateChange: number;
|
|
31
31
|
soundError: SoundErrorEvent;
|
|
32
32
|
}
|
|
@@ -39,7 +39,7 @@ export interface PlaybackEvents extends BaseAudioEvents {
|
|
|
39
39
|
/**
|
|
40
40
|
* Synthesizer-specific events.
|
|
41
41
|
*/
|
|
42
|
-
export interface SynthEvents extends Omit<BaseAudioEvents,
|
|
42
|
+
export interface SynthEvents extends Omit<BaseAudioEvents, "play"> {
|
|
43
43
|
play: SynthPlayback;
|
|
44
44
|
frequencyChange: number;
|
|
45
45
|
typeChange: OscillatorType;
|
|
@@ -57,10 +57,10 @@ export interface GlobalPlaybackEvent {
|
|
|
57
57
|
*/
|
|
58
58
|
export interface CacophonyEvents {
|
|
59
59
|
volumeChange: number;
|
|
60
|
-
mute:
|
|
61
|
-
unmute:
|
|
62
|
-
suspend:
|
|
63
|
-
resume:
|
|
60
|
+
mute: undefined;
|
|
61
|
+
unmute: undefined;
|
|
62
|
+
suspend: undefined;
|
|
63
|
+
resume: undefined;
|
|
64
64
|
loadingStart: LoadingStartEvent;
|
|
65
65
|
loadingProgress: LoadingProgressEvent;
|
|
66
66
|
loadingComplete: LoadingCompleteEvent;
|
|
@@ -105,7 +105,7 @@ export interface LoadingCompleteEvent {
|
|
|
105
105
|
export interface LoadingErrorEvent {
|
|
106
106
|
url: string;
|
|
107
107
|
error: Error;
|
|
108
|
-
errorType:
|
|
108
|
+
errorType: "network" | "decode" | "abort" | "unknown";
|
|
109
109
|
timestamp: number;
|
|
110
110
|
}
|
|
111
111
|
/**
|
|
@@ -113,7 +113,7 @@ export interface LoadingErrorEvent {
|
|
|
113
113
|
*/
|
|
114
114
|
export interface PlaybackErrorEvent {
|
|
115
115
|
error: Error;
|
|
116
|
-
errorType:
|
|
116
|
+
errorType: "context" | "source" | "decode" | "unknown";
|
|
117
117
|
timestamp: number;
|
|
118
118
|
recoverable: boolean;
|
|
119
119
|
}
|
|
@@ -123,7 +123,7 @@ export interface PlaybackErrorEvent {
|
|
|
123
123
|
export interface SoundErrorEvent {
|
|
124
124
|
url?: string;
|
|
125
125
|
error: Error;
|
|
126
|
-
errorType:
|
|
126
|
+
errorType: "load" | "playback" | "context" | "unknown";
|
|
127
127
|
timestamp: number;
|
|
128
128
|
recoverable: boolean;
|
|
129
129
|
}
|
|
@@ -132,7 +132,7 @@ export interface SoundErrorEvent {
|
|
|
132
132
|
*/
|
|
133
133
|
export interface CacheHitEvent {
|
|
134
134
|
url: string;
|
|
135
|
-
cacheType:
|
|
135
|
+
cacheType: "memory" | "browser" | "conditional";
|
|
136
136
|
timestamp: number;
|
|
137
137
|
}
|
|
138
138
|
/**
|
|
@@ -140,7 +140,7 @@ export interface CacheHitEvent {
|
|
|
140
140
|
*/
|
|
141
141
|
export interface CacheMissEvent {
|
|
142
142
|
url: string;
|
|
143
|
-
reason:
|
|
143
|
+
reason: "not-found" | "expired" | "invalid";
|
|
144
144
|
timestamp: number;
|
|
145
145
|
}
|
|
146
146
|
/**
|
|
@@ -149,7 +149,7 @@ export interface CacheMissEvent {
|
|
|
149
149
|
export interface CacheErrorEvent {
|
|
150
150
|
url: string;
|
|
151
151
|
error: Error;
|
|
152
|
-
operation:
|
|
152
|
+
operation: "get" | "set" | "delete" | "validate";
|
|
153
153
|
timestamp: number;
|
|
154
154
|
}
|
|
155
155
|
/**
|
package/dist/filters.d.ts
CHANGED
package/dist/group.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BaseSound, FadeType, LoopCount } from './cacophony';
|
|
2
|
+
import { BiquadFilterNode } from './context';
|
|
2
3
|
import { Playback } from './playback';
|
|
3
4
|
import { Sound } from './sound';
|
|
4
5
|
export declare class Group implements BaseSound {
|
|
@@ -9,8 +10,7 @@ export declare class Group implements BaseSound {
|
|
|
9
10
|
constructor(sounds?: Sound[]);
|
|
10
11
|
/**
|
|
11
12
|
* Prepares a random sound from the group for playback.
|
|
12
|
-
* @returns The playback object representing the prepared sound.
|
|
13
|
-
* @throws Error if the group is empty and there are no sounds to prepare.
|
|
13
|
+
* @returns The playback object representing the prepared sound, or undefined if the group is empty.
|
|
14
14
|
*/
|
|
15
15
|
preplayRandom(): Playback | undefined;
|
|
16
16
|
/**
|