cacophony 0.17.1 → 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 +31 -15
- package/dist/cache.d.ts +3 -3
- package/dist/cacophony.d.ts +81 -12
- package/dist/container.d.ts +31 -1
- package/dist/context.d.ts +129 -12
- package/dist/events.d.ts +25 -17
- package/dist/filters.d.ts +1 -0
- package/dist/group.d.ts +7 -3
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.mjs +1232 -973
- package/dist/index.mjs.map +1 -1
- package/dist/microphone.d.ts +5 -4
- package/dist/oscillatorMixin.d.ts +15 -8
- package/dist/pannerMixin.d.ts +27 -28
- package/dist/playback.d.ts +41 -3
- package/dist/sound.d.ts +13 -6
- package/dist/stream.d.ts +2 -2
- package/dist/synth.d.ts +13 -9
- package/dist/synthGroup.d.ts +24 -3
- package/dist/synthPlayback.d.ts +22 -10
- package/dist/volumeMixin.d.ts +43 -10
- 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 +17 -14
- package/docs/classes/MicrophonePlayback.html +3 -3
- package/docs/classes/Playback.html +67 -41
- package/docs/classes/Sound.html +41 -17
- package/docs/classes/Synth.html +38 -22
- 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 +11 -0
- 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 +11 -0
- package/docs/interfaces/BaseContext.html +20 -0
- package/docs/interfaces/BaseSound.html +6 -2
- package/docs/interfaces/BiquadFilterNode.html +30 -0
- package/docs/interfaces/CacheErrorEvent.html +6 -0
- package/docs/interfaces/CacheHitEvent.html +5 -0
- package/docs/interfaces/CacheMissEvent.html +5 -0
- package/docs/interfaces/CacophonyEvents.html +17 -0
- package/docs/interfaces/FadeStartEvent.html +5 -0
- package/docs/interfaces/GainNode.html +25 -0
- package/docs/interfaces/GlobalPlaybackEvent.html +4 -0
- package/docs/interfaces/LoadingCompleteEvent.html +6 -0
- package/docs/interfaces/LoadingErrorEvent.html +6 -0
- package/docs/interfaces/LoadingProgressEvent.html +8 -0
- package/docs/interfaces/LoadingStartEvent.html +4 -0
- 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 +7 -0
- package/docs/interfaces/PlaybackErrorEvent.html +6 -0
- package/docs/interfaces/PlaybackEvents.html +13 -0
- package/docs/interfaces/RuntimeOptions.html +2 -0
- package/docs/interfaces/SoundCleanupHoldings.html +9 -0
- package/docs/interfaces/SoundErrorEvent.html +7 -0
- package/docs/interfaces/SoundEvents.html +15 -0
- package/docs/interfaces/StereoPannerNode.html +25 -0
- package/docs/interfaces/SynthEvents.html +15 -0
- package/docs/modules.html +42 -3
- package/docs/types/CacheEventCallback.html +2 -0
- package/docs/types/ErrorEventCallback.html +2 -0
- package/docs/types/FadeType.html +1 -1
- package/docs/types/LoadingEventCallback.html +2 -0
- 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,13 +1,14 @@
|
|
|
1
|
+
import { FadeType } from './cacophony';
|
|
1
2
|
import { IPlaybackContainer } from './container';
|
|
2
3
|
import { AudioNode } from './context';
|
|
3
|
-
import { FilterManager } from './filters';
|
|
4
4
|
import { TypedEventEmitter } from './eventEmitter';
|
|
5
5
|
import { PlaybackEvents } from './events';
|
|
6
|
+
import { FilterManager } from './filters';
|
|
6
7
|
declare const BasePlayback_base: (abstract new (...args: any[]) => {
|
|
7
8
|
panner?: import('./context').PannerNode | import('./context').StereoPannerNode | undefined;
|
|
8
9
|
_panType: import('./cacophony').PanType;
|
|
9
10
|
readonly panType: import('./cacophony').PanType;
|
|
10
|
-
setPanType(panType: import('./cacophony').PanType, audioContext: import('
|
|
11
|
+
setPanType(panType: import('./cacophony').PanType, audioContext: import('./context').BaseContext): void;
|
|
11
12
|
setPannerNode(pannerNode: import('./context').PannerNode): void;
|
|
12
13
|
get stereoPan(): number | null;
|
|
13
14
|
set stereoPan(value: number);
|
|
@@ -15,25 +16,32 @@ declare const BasePlayback_base: (abstract new (...args: any[]) => {
|
|
|
15
16
|
set threeDOptions(options: Partial<PannerOptions>);
|
|
16
17
|
position: import('./cacophony').Position;
|
|
17
18
|
cleanup(): void;
|
|
18
|
-
_filters: BiquadFilterNode[];
|
|
19
|
-
addFilter(filter: BiquadFilterNode): void;
|
|
20
|
-
removeFilter(filter: BiquadFilterNode): void;
|
|
19
|
+
_filters: import('./context').BiquadFilterNode[];
|
|
20
|
+
addFilter(filter: import('./context').BiquadFilterNode): void;
|
|
21
|
+
removeFilter(filter: import('./context').BiquadFilterNode): void;
|
|
21
22
|
applyFilters(connection: any): any;
|
|
22
|
-
readonly filters: BiquadFilterNode[];
|
|
23
|
-
addFilters(filters: BiquadFilterNode[]): void;
|
|
24
|
-
removeFilters(filters: BiquadFilterNode[]): void;
|
|
23
|
+
readonly filters: import('./context').BiquadFilterNode[];
|
|
24
|
+
addFilters(filters: import('./context').BiquadFilterNode[]): void;
|
|
25
|
+
removeFilters(filters: import('./context').BiquadFilterNode[]): void;
|
|
25
26
|
}) & (abstract new (...args: any[]) => {
|
|
26
27
|
gainNode?: import('./context').GainNode | undefined;
|
|
28
|
+
_fadeTimeout?: NodeJS.Timeout | undefined;
|
|
29
|
+
_isFading: boolean;
|
|
27
30
|
setGainNode(gainNode: import('./context').GainNode): void;
|
|
28
31
|
cleanup(): void;
|
|
29
32
|
volume: number;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
readonly isFading: boolean;
|
|
34
|
+
fadeTo(value: number, duration: number, type?: FadeType): Promise<void>;
|
|
35
|
+
cancelFade(): void;
|
|
36
|
+
fadeIn(duration: number, type?: FadeType | undefined): Promise<void>;
|
|
37
|
+
fadeOut(duration: number, type?: FadeType | undefined): Promise<void>;
|
|
38
|
+
_filters: import('./context').BiquadFilterNode[];
|
|
39
|
+
addFilter(filter: import('./context').BiquadFilterNode): void;
|
|
40
|
+
removeFilter(filter: import('./context').BiquadFilterNode): void;
|
|
33
41
|
applyFilters(connection: any): any;
|
|
34
|
-
readonly filters: BiquadFilterNode[];
|
|
35
|
-
addFilters(filters: BiquadFilterNode[]): void;
|
|
36
|
-
removeFilters(filters: BiquadFilterNode[]): void;
|
|
42
|
+
readonly filters: import('./context').BiquadFilterNode[];
|
|
43
|
+
addFilters(filters: import('./context').BiquadFilterNode[]): void;
|
|
44
|
+
removeFilters(filters: import('./context').BiquadFilterNode[]): void;
|
|
37
45
|
}) & typeof FilterManager;
|
|
38
46
|
export declare abstract class BasePlayback extends BasePlayback_base {
|
|
39
47
|
source?: AudioNode;
|
|
@@ -53,13 +61,21 @@ export declare abstract class BasePlayback extends BasePlayback_base {
|
|
|
53
61
|
* Register event listener.
|
|
54
62
|
* @returns Cleanup function
|
|
55
63
|
*/
|
|
56
|
-
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;
|
|
57
65
|
/**
|
|
58
66
|
* Remove event listener.
|
|
59
67
|
*/
|
|
60
68
|
off<K extends keyof PlaybackEvents>(event: K, listener: (data: PlaybackEvents[K]) => void): void;
|
|
61
69
|
emit<K extends keyof PlaybackEvents>(event: K, data: PlaybackEvents[K]): void;
|
|
62
70
|
emitAsync<K extends keyof PlaybackEvents>(event: K, data: PlaybackEvents[K]): Promise<void>;
|
|
71
|
+
/**
|
|
72
|
+
* Fades the volume to a target value, emitting fadeStart and fadeEnd events.
|
|
73
|
+
*/
|
|
74
|
+
fadeTo(value: number, duration: number, type?: FadeType): Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Cancels any in-progress fade, emitting fadeCancel if a fade was active.
|
|
77
|
+
*/
|
|
78
|
+
cancelFade(): void;
|
|
63
79
|
cleanup(): void;
|
|
64
80
|
}
|
|
65
81
|
export {};
|
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.
|
|
@@ -43,6 +41,16 @@ export type FadeType = "linear" | "exponential";
|
|
|
43
41
|
* @typedef {'HRTF' | 'stereo'} PanType - The pan type, either 'HRTF' for 3D audio or 'stereo' for traditional stereo panning.
|
|
44
42
|
*/
|
|
45
43
|
export type PanType = "HRTF" | "stereo";
|
|
44
|
+
/**
|
|
45
|
+
* Options for configuring fade behavior when starting playback via Sound.play().
|
|
46
|
+
* @interface PlayOptions
|
|
47
|
+
*/
|
|
48
|
+
export interface PlayOptions {
|
|
49
|
+
fadeIn?: number;
|
|
50
|
+
fadeOut?: number;
|
|
51
|
+
fadeType?: FadeType;
|
|
52
|
+
fadeInPerLoop?: boolean;
|
|
53
|
+
}
|
|
46
54
|
/**
|
|
47
55
|
* The base interface for any sound-producing entity, including individual sounds, groups, and playbacks.
|
|
48
56
|
* @interface BaseSound
|
|
@@ -58,21 +66,81 @@ export interface BaseSound {
|
|
|
58
66
|
volume: number;
|
|
59
67
|
position?: Position;
|
|
60
68
|
threeDOptions?: any;
|
|
69
|
+
fadeTo?(value: number, duration: number, type?: FadeType): Promise<void>;
|
|
70
|
+
fadeIn?(duration: number, type?: FadeType): Promise<void>;
|
|
71
|
+
fadeOut?(duration: number, type?: FadeType): Promise<void>;
|
|
72
|
+
stopWithFade?(duration: number, type?: FadeType): Promise<void>;
|
|
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[];
|
|
61
101
|
}
|
|
62
102
|
export declare class Cacophony {
|
|
63
|
-
context:
|
|
103
|
+
context: BaseContext;
|
|
64
104
|
globalGainNode: GainNode;
|
|
65
|
-
listener:
|
|
105
|
+
listener: AudioListener;
|
|
66
106
|
private prevVolume;
|
|
67
107
|
private finalizationRegistry;
|
|
68
108
|
private eventEmitter;
|
|
69
109
|
private cache;
|
|
70
|
-
|
|
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>;
|
|
71
139
|
/**
|
|
72
140
|
* Register event listener.
|
|
73
141
|
* @returns Cleanup function
|
|
74
142
|
*/
|
|
75
|
-
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;
|
|
76
144
|
/**
|
|
77
145
|
* Remove event listener.
|
|
78
146
|
*/
|
|
@@ -80,7 +148,9 @@ export declare class Cacophony {
|
|
|
80
148
|
emit<K extends keyof CacophonyEvents>(event: K, data: CacophonyEvents[K]): void;
|
|
81
149
|
emitAsync<K extends keyof CacophonyEvents>(event: K, data: CacophonyEvents[K]): Promise<void>;
|
|
82
150
|
loadWorklets(signal?: AbortSignal): Promise<void>;
|
|
83
|
-
createWorkletNode(name: string, url: string, signal?: AbortSignal): Promise<
|
|
151
|
+
createWorkletNode(name: string, url: string, signal?: AbortSignal): Promise<any>;
|
|
152
|
+
private createAbortError;
|
|
153
|
+
private createMediaSound;
|
|
84
154
|
clearMemoryCache(): void;
|
|
85
155
|
createOscillator(options: OscillatorOptions, panType?: PanType): Synth;
|
|
86
156
|
/**
|
|
@@ -113,10 +183,10 @@ export declare class Cacophony {
|
|
|
113
183
|
* @returns Promise that resolves to a Sound instance for streaming
|
|
114
184
|
*/
|
|
115
185
|
createStream(url: string, signal?: AbortSignal): Promise<Sound>;
|
|
116
|
-
createBiquadFilter: ({ type, frequency, gain, Q
|
|
186
|
+
createBiquadFilter: ({ type, frequency, gain, Q }: BiquadFilterOptions) => BiquadFilterNode;
|
|
117
187
|
/**
|
|
118
188
|
* Creates a PannerNode with the specified options.
|
|
119
|
-
* @param {
|
|
189
|
+
* @param {PannerOptions} options - An object containing the options to use when creating the PannerNode.
|
|
120
190
|
* @returns {PannerNode} A new PannerNode instance with the specified options.
|
|
121
191
|
* @example
|
|
122
192
|
* const panner = audio.createPanner({
|
|
@@ -128,7 +198,7 @@ export declare class Cacophony {
|
|
|
128
198
|
* orientationZ: 0,
|
|
129
199
|
* });
|
|
130
200
|
*/
|
|
131
|
-
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;
|
|
132
202
|
/**
|
|
133
203
|
* Suspends the audio context.
|
|
134
204
|
*/
|
|
@@ -156,4 +226,3 @@ export declare class Cacophony {
|
|
|
156
226
|
get listenerPosition(): Position;
|
|
157
227
|
set listenerPosition(position: Position);
|
|
158
228
|
}
|
|
159
|
-
export {};
|
package/dist/container.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { BasePlayback } from 'basePlayback';
|
|
2
|
-
import { Position } from './cacophony';
|
|
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 {
|
|
@@ -73,6 +74,35 @@ export declare function PlaybackContainer<TBase extends Constructor>(Base: TBase
|
|
|
73
74
|
* @returns {number} The current volume of the sound.
|
|
74
75
|
*/
|
|
75
76
|
volume: number;
|
|
77
|
+
/**
|
|
78
|
+
* Fades the volume of all playbacks to a target value over a duration.
|
|
79
|
+
* @param {number} value - The target volume (0 to 1).
|
|
80
|
+
* @param {number} duration - The fade duration in milliseconds.
|
|
81
|
+
* @param {FadeType} type - The fade curve type. Defaults to "linear".
|
|
82
|
+
* @returns {Promise<void>} Resolves when all fades complete.
|
|
83
|
+
*/
|
|
84
|
+
fadeTo(value: number, duration: number, type?: FadeType): Promise<void>;
|
|
85
|
+
/**
|
|
86
|
+
* Fades in all playbacks from silence to their current volume.
|
|
87
|
+
* @param {number} duration - The fade duration in milliseconds.
|
|
88
|
+
* @param {FadeType} type - The fade curve type. Defaults to "linear".
|
|
89
|
+
* @returns {Promise<void>} Resolves when all fades complete.
|
|
90
|
+
*/
|
|
91
|
+
fadeIn(duration: number, type?: FadeType): Promise<void>;
|
|
92
|
+
/**
|
|
93
|
+
* Fades out all playbacks from their current volume to silence.
|
|
94
|
+
* @param {number} duration - The fade duration in milliseconds.
|
|
95
|
+
* @param {FadeType} type - The fade curve type. Defaults to "linear".
|
|
96
|
+
* @returns {Promise<void>} Resolves when all fades complete.
|
|
97
|
+
*/
|
|
98
|
+
fadeOut(duration: number, type?: FadeType): Promise<void>;
|
|
99
|
+
/**
|
|
100
|
+
* Fades out all playbacks then stops them.
|
|
101
|
+
* @param {number} duration - The fade-out duration in milliseconds.
|
|
102
|
+
* @param {FadeType} type - The fade curve type. Defaults to "linear".
|
|
103
|
+
* @returns {Promise<void>} Resolves when the fade completes and all playbacks are stopped.
|
|
104
|
+
*/
|
|
105
|
+
stopWithFade(duration: number, type?: FadeType): Promise<void>;
|
|
76
106
|
_filters: BiquadFilterNode[];
|
|
77
107
|
applyFilters(connection: any): any;
|
|
78
108
|
readonly filters: BiquadFilterNode[];
|
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 };
|