@league-of-foundry-developers/foundry-vtt-types 13.346.0-beta.20250825015921 → 13.346.0-beta.20250825020008
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/package.json +1 -1
- package/src/configuration/configuration.d.mts +3 -3
- package/src/foundry/client/audio/_types.d.mts +11 -0
- package/src/foundry/client/audio/biquad.d.mts +7 -9
- package/src/foundry/client/audio/cache.d.mts +3 -2
- package/src/foundry/client/audio/convolver.d.mts +2 -6
- package/src/foundry/client/audio/helper.d.mts +263 -87
- package/src/foundry/client/audio/sound.d.mts +172 -70
- package/src/foundry/client/audio/timeout.d.mts +9 -3
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
3
3
|
"name": "@league-of-foundry-developers/foundry-vtt-types",
|
4
|
-
"version": "13.346.0-beta.
|
4
|
+
"version": "13.346.0-beta.20250825020008",
|
5
5
|
"description": "TypeScript type definitions for Foundry VTT",
|
6
6
|
"type": "module",
|
7
7
|
"types": "./src/index.d.mts",
|
@@ -295,9 +295,9 @@ export interface SettingConfig {
|
|
295
295
|
"core.disableResolutionScaling": boolean;
|
296
296
|
"core.fontSize": number;
|
297
297
|
"core.fpsMeter": boolean;
|
298
|
-
"core.globalAmbientVolume":
|
299
|
-
"core.globalInterfaceVolume":
|
300
|
-
"core.globalPlaylistVolume":
|
298
|
+
"core.globalAmbientVolume": fields.AlphaField<{ required: true; initial: 0.5 }>;
|
299
|
+
"core.globalInterfaceVolume": fields.AlphaField<{ required: true; initial: 0.5 }>;
|
300
|
+
"core.globalPlaylistVolume": fields.AlphaField<{ required: true; initial: 0.5 }>;
|
301
301
|
"core.keybindings": Record<string, foundry.helpers.interaction.ClientKeybindings.KeybindingActionBinding[]>;
|
302
302
|
"core.language": fields.StringField<{
|
303
303
|
required: true;
|
@@ -16,3 +16,14 @@ type SoundCreationOptions = foundry.audio.AudioHelper.SoundCreationOptions;
|
|
16
16
|
type SoundPlaybackOptions = foundry.audio.Sound.PlaybackOptions;
|
17
17
|
|
18
18
|
type SoundScheduleCallback = foundry.audio.Sound.ScheduleCallback;
|
19
|
+
|
20
|
+
type AnalysisDataValue = foundry.audio.AudioHelper.AnalysisDataValue;
|
21
|
+
|
22
|
+
type AnalysisData = foundry.audio.AudioHelper.AnalysisData;
|
23
|
+
|
24
|
+
type ContextName = foundry.audio.AudioHelper.ContextName;
|
25
|
+
|
26
|
+
type BandName = foundry.audio.AudioHelper.BandName;
|
27
|
+
|
28
|
+
/** @privateRemarks We have no implementation of this type to point to because it is completely unused by core as of 13.347 */
|
29
|
+
type AnalysisNodes = unknown;
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import type { Identity, InexactPartial
|
1
|
+
import type { Identity, InexactPartial } from "#utils";
|
2
2
|
|
3
3
|
/**
|
4
4
|
* A sound effect which applies a biquad filter.
|
@@ -9,7 +9,6 @@ declare class BiquadFilterEffect extends BiquadFilterNode {
|
|
9
9
|
* @param context - The audio context required by the BiquadFilterNode
|
10
10
|
* @param options - Additional options which modify the BiquadFilterEffect behavior
|
11
11
|
*/
|
12
|
-
// options: not null (destructured)
|
13
12
|
constructor(context: AudioContext, options?: BiquadFilterEffect.ConstructorOptions);
|
14
13
|
|
15
14
|
/**
|
@@ -22,10 +21,12 @@ declare class BiquadFilterEffect extends BiquadFilterNode {
|
|
22
21
|
/**
|
23
22
|
* Update the state of the effect node given the active flag and numeric intensity.
|
24
23
|
* @param options - Options which are updated
|
25
|
-
* @
|
24
|
+
* @remarks
|
25
|
+
* @throws If `type` is set to any value in {@linkcode BiquadFilterEffect.AllowedFilterType} other than `"highpass"` or `"lowpass"`
|
26
26
|
*/
|
27
|
-
// options: not null (destructured)
|
28
27
|
update(options?: BiquadFilterEffect.UpdateOptions): void;
|
28
|
+
|
29
|
+
#BiquadFilterEffect: true;
|
29
30
|
}
|
30
31
|
|
31
32
|
declare namespace BiquadFilterEffect {
|
@@ -56,16 +57,13 @@ declare namespace BiquadFilterEffect {
|
|
56
57
|
/**
|
57
58
|
* The initial intensity of the effect
|
58
59
|
* @defaultValue `5`
|
59
|
-
* @remarks Can't be `null` as it only has a parameter default
|
60
60
|
*/
|
61
61
|
intensity: number;
|
62
62
|
|
63
63
|
/**
|
64
64
|
* The filter type to apply
|
65
65
|
* @defaultValue `"lowpass"`
|
66
|
-
* @remarks
|
67
|
-
*
|
68
|
-
* Only allows a subset of {@linkcode BiquadFilterType}s
|
66
|
+
* @remarks Only allows a subset of {@linkcode BiquadFilterType}s
|
69
67
|
*/
|
70
68
|
type: AllowedFilterType;
|
71
69
|
}>;
|
@@ -77,7 +75,7 @@ declare namespace BiquadFilterEffect {
|
|
77
75
|
*/
|
78
76
|
interface ConstructorOptions extends _ConstructorOptions, Omit<BiquadFilterOptions, "type"> {}
|
79
77
|
|
80
|
-
type _UpdateOptions =
|
78
|
+
type _UpdateOptions = InexactPartial<{
|
81
79
|
/**
|
82
80
|
* A new effect intensity
|
83
81
|
* @remarks This is ignored if it fails a `Number.isFinite` check
|
@@ -4,7 +4,7 @@ import type { Identity } from "#utils";
|
|
4
4
|
* A specialized cache used for audio buffers.
|
5
5
|
* This is an LRU cache which expires buffers from the cache once the maximum cache size is exceeded.
|
6
6
|
*/
|
7
|
-
declare class AudioBufferCache extends Map {
|
7
|
+
declare class AudioBufferCache extends Map<string, AudioBufferCache.Entry> {
|
8
8
|
/**
|
9
9
|
* Construct an AudioBufferCache providing a maximum disk size beyond which entries are expired.
|
10
10
|
* @param cacheSize - The maximum cache size in bytes. 1GB by default.
|
@@ -42,10 +42,11 @@ declare class AudioBufferCache extends Map {
|
|
42
42
|
* @param src - The audio buffer source path
|
43
43
|
* @param locked - Lock the buffer, preventing its expiration?
|
44
44
|
*/
|
45
|
-
// locked: not null (put directly into an Entry)
|
46
45
|
lock(src: string, locked?: boolean): void;
|
47
46
|
|
48
47
|
override toString(): string;
|
48
|
+
|
49
|
+
#AudioBufferCache: true;
|
49
50
|
}
|
50
51
|
|
51
52
|
declare namespace AudioBufferCache {
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import type { Identity, InexactPartial
|
1
|
+
import type { Identity, InexactPartial } from "#utils";
|
2
2
|
|
3
3
|
declare namespace ConvolverEffect {}
|
4
4
|
|
@@ -16,7 +16,6 @@ declare class ConvolverEffect extends ConvolverNode {
|
|
16
16
|
* @param context - The audio context required by the ConvolverNode
|
17
17
|
* @param options - Additional options which modify the ConvolverEffect behavior
|
18
18
|
*/
|
19
|
-
// options: not null (destructured)
|
20
19
|
constructor(context: AudioContext, options?: ConvolverEffect.ConstructorOptions);
|
21
20
|
|
22
21
|
/**
|
@@ -30,7 +29,6 @@ declare class ConvolverEffect extends ConvolverNode {
|
|
30
29
|
* Update the state of the effect node given the active flag and numeric intensity.
|
31
30
|
* @param options - Options which are updated
|
32
31
|
*/
|
33
|
-
// options: not null (destructured)
|
34
32
|
update(options?: ConvolverEffect.UpdateOptions): void;
|
35
33
|
|
36
34
|
/** @privateRemarks This override only does side effects then forwards args to super, no type changes */
|
@@ -61,14 +59,12 @@ declare namespace ConvolverEffect {
|
|
61
59
|
/**
|
62
60
|
* The file path to the impulse response buffer to use
|
63
61
|
* @defaultValue `"sounds/impulse-responses/ir-full.wav"`
|
64
|
-
* @remarks Can't be `null` as it only has a parameter default
|
65
62
|
*/
|
66
63
|
impulseResponsePath: string;
|
67
64
|
|
68
65
|
/**
|
69
66
|
* The initial intensity of the effect
|
70
67
|
* @defaultValue `5`
|
71
|
-
* @remarks Can't be `null` as it only has a parameter default
|
72
68
|
*/
|
73
69
|
intensity: number;
|
74
70
|
}>;
|
@@ -76,7 +72,7 @@ declare namespace ConvolverEffect {
|
|
76
72
|
interface ConstructorOptions extends _ConstructorOptions, ConvolverOptions {}
|
77
73
|
|
78
74
|
/** @internal */
|
79
|
-
type _UpdateOptions =
|
75
|
+
type _UpdateOptions = InexactPartial<{
|
80
76
|
/**
|
81
77
|
* A new effect intensity
|
82
78
|
* @remarks This is ignored if it fails a `Number.isFinite` check
|
@@ -1,16 +1,37 @@
|
|
1
1
|
import type Sound from "./sound.d.mts";
|
2
2
|
import type AudioBufferCache from "./cache.d.mts";
|
3
|
-
import type { Identity, InexactPartial,
|
3
|
+
import type { Identity, InexactPartial, ValueOf } from "#utils";
|
4
4
|
|
5
5
|
/**
|
6
6
|
* A helper class to provide common functionality for working with the Web Audio API.
|
7
7
|
* https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API
|
8
8
|
* A singleton instance of this class is available as game#audio.
|
9
|
-
* @see {@
|
9
|
+
* @see {@linkcode Game.audio | Game#audio}
|
10
10
|
*/
|
11
11
|
declare class AudioHelper {
|
12
|
+
/** @remarks Construction will throw if {@linkcode Game.audio | game.audio} is already instantiated */
|
12
13
|
constructor();
|
13
14
|
|
15
|
+
/**
|
16
|
+
* Analyzers for each context, plus an internal ticker. Each context key holds data about its {@linkcode AnalyserNode},
|
17
|
+
* a {@linkcode Float32Array} for FFT data, and so on.
|
18
|
+
* @defaultValue
|
19
|
+
* ```js
|
20
|
+
* Object.seal({
|
21
|
+
* music: {active: false, node: null, dataArray: null, lastUsed: 0, db: {}, bands: {}},
|
22
|
+
* environment: {active: false, node: null, dataArray: null, lastUsed: 0, db: {}, bands: {}},
|
23
|
+
* interface: {active: false, node: null, dataArray: null, lastUsed: 0, db: {}, bands: {}},
|
24
|
+
* analysisLoopActive: false
|
25
|
+
* });
|
26
|
+
* ```
|
27
|
+
*/
|
28
|
+
analyzer: AudioHelper.AnalysisData;
|
29
|
+
|
30
|
+
/**
|
31
|
+
* An array containing all possible audio context names.
|
32
|
+
*/
|
33
|
+
static AUDIO_CONTEXTS: ReadonlyArray<AudioHelper.ContextName>;
|
34
|
+
|
14
35
|
/**
|
15
36
|
* The Native interval for the AudioHelper to analyse audio levels from streams
|
16
37
|
* Any interval passed to startLevelReports() would need to be a multiple of this value.
|
@@ -41,7 +62,7 @@ declare class AudioHelper {
|
|
41
62
|
* Once a gesture is observed, we begin playing all elements of this Array.
|
42
63
|
* @see {@linkcode Sound}
|
43
64
|
* @defaultValue `[]`
|
44
|
-
* @remarks Foundry only populates this in one place, {@
|
65
|
+
* @remarks Foundry only populates this in one place, {@linkcode SoundsLayer.refresh | SoundsLayer#refresh}
|
45
66
|
*/
|
46
67
|
pending: (() => void)[];
|
47
68
|
|
@@ -59,29 +80,36 @@ declare class AudioHelper {
|
|
59
80
|
|
60
81
|
/**
|
61
82
|
* A singleton audio context used for playback of music
|
62
|
-
* @remarks Not initialized to a value, set in
|
63
|
-
*
|
83
|
+
* @remarks Not initialized to a value, set in `AudioHelper##onFirstGesture`. In practice, this is `undefined` until
|
84
|
+
* the first audio is played after page load.
|
64
85
|
*/
|
65
86
|
music: AudioContext | undefined;
|
66
87
|
|
67
88
|
/**
|
68
89
|
* A singleton audio context used for playback of environmental audio.
|
69
|
-
* @remarks Not initialized to a value, set in
|
70
|
-
*
|
90
|
+
* @remarks Not initialized to a value, set in `AudioHelper##onFirstGesture`. In practice, this is `undefined` until
|
91
|
+
* the first audio is played after page load.
|
71
92
|
*/
|
72
93
|
environment: AudioContext | undefined;
|
73
94
|
|
74
95
|
/**
|
75
96
|
* A singleton audio context used for playback of interface sounds and effects.
|
76
|
-
* @remarks Not initialized to a value, set in
|
77
|
-
*
|
97
|
+
* @remarks Not initialized to a value, set in `AudioHelper##onFirstGesture`. In practice, this is `undefined` until
|
98
|
+
* the first audio is played after page load.
|
78
99
|
*/
|
79
100
|
interface: AudioContext | undefined;
|
80
101
|
|
81
102
|
/**
|
82
103
|
* For backwards compatibility, AudioHelper#context refers to the context used for music playback.
|
83
104
|
*/
|
84
|
-
get context():
|
105
|
+
get context(): this["music"];
|
106
|
+
|
107
|
+
/**
|
108
|
+
* A global mute which suppresses all 3 audio channels.
|
109
|
+
*/
|
110
|
+
get globalMute(): boolean;
|
111
|
+
|
112
|
+
set globalMute(muted);
|
85
113
|
|
86
114
|
/**
|
87
115
|
* A singleton cache used for audio buffers.
|
@@ -115,7 +143,6 @@ declare class AudioHelper {
|
|
115
143
|
* @param options - Additional options which configure playback
|
116
144
|
* @returns The created Sound which is now playing
|
117
145
|
*/
|
118
|
-
// options: not null (destructured)
|
119
146
|
play(src: string, options?: AudioHelper.PlayOptions): Promise<Sound>;
|
120
147
|
|
121
148
|
/**
|
@@ -146,18 +173,18 @@ declare class AudioHelper {
|
|
146
173
|
/**
|
147
174
|
* Play a one-off sound effect which is not part of a Playlist
|
148
175
|
*
|
149
|
-
* @param data
|
150
|
-
* @param socketOptions - Options which only apply when emitting playback over websocket.
|
151
|
-
*
|
152
|
-
*
|
153
|
-
* @returns A Sound instance which controls audio playback.
|
176
|
+
* @param data - An object configuring the audio data to play
|
177
|
+
* @param socketOptions - Options which only apply when emitting playback over websocket. As a boolean, emits (true)
|
178
|
+
* or does not emit (false) playback to all other clients. As an object, can configure which recipients (an array of
|
179
|
+
* User IDs) should receive the event (all clients by default). Default: `false`.
|
180
|
+
* @returns A Sound instance which controls audio playback, or nothing if `data.autoplay` is false.
|
154
181
|
*
|
155
182
|
* @example Play the sound of a locked door for all players
|
156
|
-
* ```
|
183
|
+
* ```js
|
157
184
|
* AudioHelper.play({src: "sounds/lock.wav", volume: 0.8, loop: false}, true);
|
158
185
|
* ```
|
159
186
|
*/
|
160
|
-
static play(data: AudioHelper.PlayData, socketOptions?: boolean | AudioHelper.SocketOptions
|
187
|
+
static play(data: AudioHelper.PlayData, socketOptions?: boolean | AudioHelper.SocketOptions): Promise<Sound | void>;
|
161
188
|
|
162
189
|
/**
|
163
190
|
* Begin loading the sound for a provided source URL adding its
|
@@ -183,6 +210,12 @@ declare class AudioHelper {
|
|
183
210
|
*/
|
184
211
|
static volumeToInput(volume: number, order?: number): number;
|
185
212
|
|
213
|
+
/**
|
214
|
+
* Converts a volume level to a human-readable percentage value.
|
215
|
+
* @param volume - Value in the interval [0, 1] of the volume level.
|
216
|
+
*/
|
217
|
+
static volumeToPercentage(volume: number, options?: AudioHelper.VolumeToPercentageOptions): string;
|
218
|
+
|
186
219
|
/**
|
187
220
|
* Returns a singleton AudioContext if one can be created.
|
188
221
|
* An audio context may not be available due to limited resources or browser compatibility
|
@@ -207,7 +240,6 @@ declare class AudioHelper {
|
|
207
240
|
* @param smoothing - The smoothingTimeConstant to set on the audio analyser. (default: `0.1`)
|
208
241
|
* @returns Returns whether listening to the stream was successful
|
209
242
|
*/
|
210
|
-
// interval, smoothing: not null (parameter default only)
|
211
243
|
startLevelReports(
|
212
244
|
id: string,
|
213
245
|
stream: MediaStream,
|
@@ -224,13 +256,8 @@ declare class AudioHelper {
|
|
224
256
|
*/
|
225
257
|
stopLevelReports(id: string): void;
|
226
258
|
|
227
|
-
/**
|
228
|
-
|
229
|
-
* @param event - The mouse-move event which enables playback
|
230
|
-
* @param resolve - The Promise resolution function
|
231
|
-
* @internal
|
232
|
-
*/
|
233
|
-
protected _onFirstGesture(event: Event, resolve: () => void): void;
|
259
|
+
/** @deprecated Made hard private in v13. This warning will be removed in v14. */
|
260
|
+
protected _onFirstGesture(event: never, resolve: never): never;
|
234
261
|
|
235
262
|
/**
|
236
263
|
* Log a debugging message if the audio debugging flag is enabled.
|
@@ -239,22 +266,62 @@ declare class AudioHelper {
|
|
239
266
|
debug(message: string): void;
|
240
267
|
|
241
268
|
/**
|
242
|
-
*
|
243
|
-
*
|
269
|
+
* A static inactivity threshold for audio analysis, in milliseconds.
|
270
|
+
* If no band value is requested for a channel within this duration,
|
271
|
+
* the analyzer is disabled to conserve resources (unless the analyzer is enabled with the `keepAlive=true` option)
|
272
|
+
* @defaultValue `1000`
|
273
|
+
*/
|
274
|
+
static ANALYSIS_TIMEOUT_MS: number;
|
275
|
+
|
276
|
+
/**
|
277
|
+
* Enable the analyzer for a given context (`music`, `environment`, `interface`), attaching an {@linkcode AnalyserNode} to its gain node if not already active.
|
278
|
+
*/
|
279
|
+
enableAnalyzer(contextName: AudioHelper.ContextName, options?: AudioHelper.EnableAnalyzerOptions): void;
|
280
|
+
|
281
|
+
/**
|
282
|
+
* Disable the analyzer for a given context, disconnecting the {@linkcode AnalyserNode}.
|
283
|
+
*/
|
284
|
+
disableAnalyzer(contextName: AudioHelper.ContextName): void;
|
285
|
+
|
286
|
+
/**
|
287
|
+
* Returns a normalized band value in [0,1].
|
288
|
+
* Optionally, we can subtract the actual gainNode (global) volume from the measurement.
|
289
|
+
* - Important:
|
290
|
+
* - Local gain applied to {@linkcode foundry.audio.Sound} source can't be ignored.
|
291
|
+
* - If this method needs to activate the analyzer, the latter requires a brief warm-up.
|
292
|
+
* One or two frames may be needed before it produces meaningful values (instead of returning 0).
|
293
|
+
* @returns The normalized band value in [0,1].
|
294
|
+
*/
|
295
|
+
getBandLevel(
|
296
|
+
contextName: AudioHelper.ContextName,
|
297
|
+
bandName: AudioHelper.BandName,
|
298
|
+
options?: AudioHelper.GetBandLevelOptions,
|
299
|
+
): number;
|
300
|
+
|
301
|
+
/**
|
302
|
+
* Retrieve a single "peak" analyzer value across the three main audio contexts (music, environment, interface).
|
303
|
+
* This takes the maximum of the three normalized [0,1] values for a given frequency band.
|
304
|
+
* @param band - The frequency band for which to retrieve an analyzer value. (default: `"all"`)
|
305
|
+
* @returns A number in the [0,1] range representing the loudest band value among the three contexts.
|
306
|
+
*/
|
307
|
+
getMaxBandLevel(band?: AudioHelper.BandName, options?: AudioHelper.GetMaxBandLevelOptions): number;
|
308
|
+
|
309
|
+
/**
|
310
|
+
* @deprecated "`AudioHelper#getCache` is deprecated in favor of {@linkcode AudioBufferCache | AudioHelper#buffers#get}" (since v12, until v14)
|
244
311
|
*/
|
245
312
|
getCache(src: string): AudioBuffer | undefined;
|
246
313
|
|
247
314
|
/**
|
248
|
-
* @deprecated since v12,
|
249
|
-
* @remarks "`AudioHelper#updateCache` is deprecated without replacement"
|
315
|
+
* @deprecated "`AudioHelper#updateCache` is deprecated without replacement" (since v12, until v14)
|
250
316
|
*/
|
251
317
|
updateCache(src: string, playing: boolean): void;
|
252
318
|
|
253
319
|
/**
|
254
|
-
* @deprecated since v12,
|
255
|
-
* @remarks "`AudioHelper#setCache` is deprecated in favor of {@link AudioBufferCache | `AudioHelper#buffers#set`}"
|
320
|
+
* @deprecated "`AudioHelper#setCache` is deprecated in favor of {@linkcode AudioBufferCache |`AudioHelper#buffers#set}" (since v12, until v14)
|
256
321
|
*/
|
257
322
|
setCache(src: string, buffer: AudioBuffer): void;
|
323
|
+
|
324
|
+
#AudioHelper: true;
|
258
325
|
}
|
259
326
|
|
260
327
|
declare namespace AudioHelper {
|
@@ -263,41 +330,109 @@ declare namespace AudioHelper {
|
|
263
330
|
|
264
331
|
type AUDIO_MIME_TYPES = ValueOf<typeof CONST.AUDIO_FILE_EXTENSIONS>;
|
265
332
|
|
333
|
+
interface AnalysisDataValueDB {
|
334
|
+
/** Average dB in ~20-200 Hz */
|
335
|
+
bass: number;
|
336
|
+
|
337
|
+
/** Average dB in ~200-2000 Hz */
|
338
|
+
mid: number;
|
339
|
+
|
340
|
+
/** Average dB in ~2000-8000 Hz */
|
341
|
+
treble: number;
|
342
|
+
|
343
|
+
/** Average dB in ~20-20000 Hz */
|
344
|
+
all: number;
|
345
|
+
}
|
346
|
+
|
347
|
+
interface AnalysisDataValueBands {
|
348
|
+
/** Normalized amplitude for low frequencies. */
|
349
|
+
bass: number;
|
350
|
+
|
351
|
+
/** Normalized amplitude for midrange frequencies. */
|
352
|
+
mid: number;
|
353
|
+
|
354
|
+
/** Normalized amplitude for high frequencies. */
|
355
|
+
treble: number;
|
356
|
+
|
357
|
+
/** Normalized amplitude for the entire audible range. */
|
358
|
+
all: number;
|
359
|
+
}
|
360
|
+
|
361
|
+
interface AnalysisDataValue {
|
362
|
+
/** Whether the analyzer is currently active. */
|
363
|
+
active: boolean;
|
364
|
+
|
365
|
+
/** If true, the analyzer remains active and will not be disabled after inactivity */
|
366
|
+
keepAlive: boolean;
|
367
|
+
|
368
|
+
/** The {@linkcode AnalyserNode} for this context, or `null` if inactive. */
|
369
|
+
node: AnalyserNode | null;
|
370
|
+
|
371
|
+
/** The FFT frequency data buffer used by the {@linkcode AnalyserNode}. */
|
372
|
+
dataArray: Float32Array | null;
|
373
|
+
|
374
|
+
/** Raw average decibel values for each frequency band. */
|
375
|
+
db: AnalysisDataValueDB;
|
376
|
+
|
377
|
+
/** Normalized [0,1] values for the same bands. */
|
378
|
+
bands: AnalysisDataValueBands;
|
379
|
+
|
380
|
+
/** The timestamp when data was last requested. */
|
381
|
+
lastUsed: number;
|
382
|
+
}
|
383
|
+
|
384
|
+
interface AnalysisData {
|
385
|
+
/** Analysis data for the music context. */
|
386
|
+
music: AnalysisDataValue;
|
387
|
+
|
388
|
+
/** Analysis data for the ambient/environment context. */
|
389
|
+
environment: AnalysisDataValue;
|
390
|
+
|
391
|
+
/** Analysis data for the interface context. */
|
392
|
+
interface: AnalysisDataValue;
|
393
|
+
|
394
|
+
/** Whether the internal RAQ loop is currently running. */
|
395
|
+
analysisLoopActive: boolean;
|
396
|
+
}
|
397
|
+
|
398
|
+
/** @privateRemarks Foundry has this in a `_types` as a union of literals, but it lines up with `AUDIO_CHANNELS` so is typed thusly */
|
399
|
+
type ContextName = keyof typeof CONST.AUDIO_CHANNELS;
|
400
|
+
|
401
|
+
type BandName = keyof AnalysisDataValueBands;
|
402
|
+
|
266
403
|
/** @internal */
|
267
404
|
type _SoundCreationOptions = InexactPartial<{
|
268
405
|
/**
|
269
406
|
* Additional options passed to the play method if autoplay is true
|
270
407
|
* @defaultValue `{}`
|
271
|
-
* @remarks Can't be `null` as it only has a parameter default
|
272
408
|
*/
|
273
409
|
autoplayOptions: Sound.PlaybackOptions;
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
}>;
|
410
|
+
|
411
|
+
/**
|
412
|
+
* A specific AudioContext to attach the sound to
|
413
|
+
* @remarks Has no default, but if it's falsey, the {@linkcode Sound} constructor
|
414
|
+
* (where this is forwarded) will use {@linkcode AudioHelper.music | game.audio.music} instead
|
415
|
+
*/
|
416
|
+
context: AudioContext;
|
417
|
+
|
418
|
+
/**
|
419
|
+
* Reuse an existing Sound for this source?
|
420
|
+
* @defaultValue `true`
|
421
|
+
*/
|
422
|
+
singleton: boolean;
|
423
|
+
|
424
|
+
/**
|
425
|
+
* Begin loading the audio immediately?
|
426
|
+
* @defaultValue `false`
|
427
|
+
*/
|
428
|
+
preload: boolean;
|
429
|
+
|
430
|
+
/**
|
431
|
+
* Begin playing the audio as soon as it is ready?
|
432
|
+
* @defaultValue `false`
|
433
|
+
*/
|
434
|
+
autoplay: boolean;
|
435
|
+
}>;
|
301
436
|
|
302
437
|
interface SoundCreationOptions extends _SoundCreationOptions {
|
303
438
|
/** The source URL for the audio file */
|
@@ -305,18 +440,39 @@ declare namespace AudioHelper {
|
|
305
440
|
}
|
306
441
|
|
307
442
|
/**
|
308
|
-
* {@linkcode AudioHelper#play} pulls `context` out of this object then forwards the rest to {@
|
443
|
+
* {@linkcode AudioHelper#play} pulls `context` out of this object then forwards the rest to {@linkcode Sound.play | Sound#play}
|
309
444
|
*/
|
310
445
|
interface PlayOptions extends Pick<SoundCreationOptions, "context">, Sound.PlaybackOptions {}
|
311
446
|
|
312
447
|
/** @internal */
|
313
|
-
type _PlayData =
|
448
|
+
type _PlayData = InexactPartial<{
|
314
449
|
/**
|
315
|
-
*
|
450
|
+
* The volume level at which to play the audio, between 0 and 1.
|
451
|
+
* @defaultValue `1.0`
|
452
|
+
* @privateRemarks Despite the initial default being via `mergeObject`, there's a second `??` default so it's allowed to be nullish
|
453
|
+
*/
|
454
|
+
volume: number;
|
455
|
+
|
456
|
+
/**
|
457
|
+
* Loop the audio effect and continue playing it until it is manually stopped.
|
458
|
+
* @defaultValue `false`
|
459
|
+
* @privateRemarks Despite the default being via `mergeObject`, {@linkcode Sound.PlaybackOptions.loop | Sound.PlaybackOptions["loop"]} can be nullish, therefor so can this
|
460
|
+
*/
|
461
|
+
loop: boolean;
|
462
|
+
}>;
|
463
|
+
|
464
|
+
interface PlayData extends _PlayData {
|
465
|
+
/**
|
466
|
+
* The audio source file path, either a public URL or a local path relative to the public directory
|
467
|
+
*/
|
468
|
+
src: string;
|
469
|
+
|
470
|
+
/**
|
471
|
+
* An audio channel in {@linkcode CONST.AUDIO_CHANNELS} where the sound should play
|
316
472
|
* @defaultValue `"interface"`
|
317
473
|
* @remarks Can't be nullish as the only default is provided by `mergeObject`
|
318
474
|
*/
|
319
|
-
channel
|
475
|
+
channel?: AudioHelper.ContextName;
|
320
476
|
|
321
477
|
/**
|
322
478
|
* Begin playback of the audio effect immediately once it is loaded.
|
@@ -329,29 +485,7 @@ declare namespace AudioHelper {
|
|
329
485
|
*
|
330
486
|
* "// Backwards compatibility, if autoplay was passed as false take no further action"
|
331
487
|
*/
|
332
|
-
autoplay
|
333
|
-
}> &
|
334
|
-
NullishProps<{
|
335
|
-
/**
|
336
|
-
* The volume level at which to play the audio, between 0 and 1.
|
337
|
-
* @defaultValue `1.0`
|
338
|
-
* @privateRemarks Despite the initial default being via `mergeObject`, there's a second `??` default so it's allowed to be nullish
|
339
|
-
*/
|
340
|
-
volume: number;
|
341
|
-
|
342
|
-
/**
|
343
|
-
* Loop the audio effect and continue playing it until it is manually stopped.
|
344
|
-
* @defaultValue `false`
|
345
|
-
* @privateRemarks Despite the default being via `mergeObject`, {@link Sound.PlaybackOptions.loop | `Sound.PlaybackOptions["loop"]`} can be nullish, therefor so can this
|
346
|
-
*/
|
347
|
-
loop: boolean;
|
348
|
-
}>;
|
349
|
-
|
350
|
-
interface PlayData extends _PlayData {
|
351
|
-
/**
|
352
|
-
* The audio source file path, either a public URL or a local path relative to the public directory
|
353
|
-
*/
|
354
|
-
src: string;
|
488
|
+
autoplay?: false;
|
355
489
|
}
|
356
490
|
|
357
491
|
interface SocketOptions {
|
@@ -362,6 +496,48 @@ declare namespace AudioHelper {
|
|
362
496
|
recipients?: string[];
|
363
497
|
}
|
364
498
|
|
499
|
+
/** @internal */
|
500
|
+
type _VolumeToPercentageOptions = InexactPartial<{
|
501
|
+
/**
|
502
|
+
* Prefix the returned tooltip with a localized 'Volume: ' label. This should be used if the returned string is intended for assistive
|
503
|
+
* technologies, such as the `aria-value` text attribute.
|
504
|
+
* @defaultValue `false`
|
505
|
+
*/
|
506
|
+
label: boolean;
|
507
|
+
|
508
|
+
/**
|
509
|
+
* The number of decimal places to round the percentage to.
|
510
|
+
* @defaultValue `0`
|
511
|
+
*/
|
512
|
+
decimalPlaces: number;
|
513
|
+
}>;
|
514
|
+
|
515
|
+
interface VolumeToPercentageOptions extends _VolumeToPercentageOptions {}
|
516
|
+
|
517
|
+
/** @internal */
|
518
|
+
type _EnableAnalyzerOptions = InexactPartial<{
|
519
|
+
/**
|
520
|
+
* If true, this analyzer will not auto-disable after inactivity.
|
521
|
+
* @defaultValue `false`
|
522
|
+
*/
|
523
|
+
keepAlive: boolean;
|
524
|
+
}>;
|
525
|
+
|
526
|
+
interface EnableAnalyzerOptions extends _EnableAnalyzerOptions {}
|
527
|
+
|
528
|
+
/** @internal */
|
529
|
+
type _GetBandLevelOptions = InexactPartial<{
|
530
|
+
/**
|
531
|
+
* If true, remove the real-time channel volume from the measurement.
|
532
|
+
* @defaultValue `false`
|
533
|
+
*/
|
534
|
+
ignoreVolume: boolean;
|
535
|
+
}>;
|
536
|
+
|
537
|
+
interface GetBandLevelOptions extends _GetBandLevelOptions {}
|
538
|
+
|
539
|
+
interface GetMaxBandLevelOptions extends _GetBandLevelOptions {}
|
540
|
+
|
365
541
|
type LevelReportCallback = (maxDecibel: number, fftArray: Float32Array) => void;
|
366
542
|
}
|
367
543
|
|
@@ -1,13 +1,16 @@
|
|
1
|
-
import type { Brand, InexactPartial, MaybePromise,
|
1
|
+
import type { Brand, InexactPartial, MaybePromise, Identity, IntentionalPartial } from "#utils";
|
2
2
|
import type EventEmitterMixin from "#common/utils/event-emitter.d.mts";
|
3
3
|
import type { AmbientSound } from "#client/canvas/placeables/_module.d.mts";
|
4
|
+
import type { Canvas } from "#client/canvas/_module.d.mts";
|
5
|
+
import type { PointSoundSource } from "#client/canvas/sources/_module.d.mts";
|
6
|
+
import type { AudioTimeout } from "./_module.d.mts";
|
4
7
|
|
5
8
|
declare namespace Sound {
|
6
9
|
interface Any extends AnySound {}
|
7
10
|
interface AnyConstructor extends Identity<typeof AnySound> {}
|
8
11
|
|
9
12
|
/** @internal */
|
10
|
-
type _ConstructorOptions =
|
13
|
+
type _ConstructorOptions = InexactPartial<{
|
11
14
|
/**
|
12
15
|
* Force use of an AudioBufferSourceNode even if the audio duration is long
|
13
16
|
* @defaultValue `false`
|
@@ -38,21 +41,19 @@ declare namespace Sound {
|
|
38
41
|
}
|
39
42
|
|
40
43
|
/** @internal */
|
41
|
-
type _LoadOptions =
|
44
|
+
type _LoadOptions = InexactPartial<{
|
42
45
|
/**
|
43
46
|
* Automatically begin playback of the sound once loaded
|
44
47
|
* @defaultValue `false`
|
45
48
|
*/
|
46
49
|
autoplay: boolean;
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
autoplayOptions: Sound.PlaybackOptions;
|
55
|
-
}>;
|
50
|
+
|
51
|
+
/**
|
52
|
+
* Playback options passed to Sound#play, if autoplay
|
53
|
+
* @defaultValue `{}`
|
54
|
+
*/
|
55
|
+
autoplayOptions: Sound.PlaybackOptions;
|
56
|
+
}>;
|
56
57
|
|
57
58
|
interface LoadOptions extends _LoadOptions {}
|
58
59
|
|
@@ -60,10 +61,9 @@ declare namespace Sound {
|
|
60
61
|
* Since `Sound##playback` isn't exposed, this interface can *just* be accurate to what's allowable to pass
|
61
62
|
* to {@link Sound.play | `Sound#play`} or {@link Sound.stop | `#stop`}, which in reality is what's allowed
|
62
63
|
* by `Sound##configurePlayback`
|
63
|
-
*
|
64
64
|
* @internal
|
65
65
|
*/
|
66
|
-
type _PlaybackOptions =
|
66
|
+
type _PlaybackOptions = InexactPartial<{
|
67
67
|
/**
|
68
68
|
* A delay in seconds by which to delay playback
|
69
69
|
* @defaultValue `0`
|
@@ -87,49 +87,54 @@ declare namespace Sound {
|
|
87
87
|
/**
|
88
88
|
* Should sound playback loop?
|
89
89
|
* @defaultValue `false`
|
90
|
-
* @remarks The above default is true for initial calls, but the actual default
|
91
|
-
*
|
90
|
+
* @remarks The above default is true for initial calls, but the actual default value, if this is passed nullish or omitted, is whatever the current value in `this##playback`
|
91
|
+
* is, unless this is part of a {@linkcode foundry.canvas.layers.SoundsLayer.playAtPosition | SoundsLayer#playAtPosition} call, as that method always creates a new sound with
|
92
|
+
* no playback history
|
92
93
|
*/
|
93
94
|
loop: boolean;
|
94
95
|
|
95
96
|
/**
|
96
97
|
* Seconds of the AudioBuffer when looped playback should start. Only works for AudioBufferSourceNode.
|
97
98
|
* @defaultValue `0`
|
98
|
-
* @remarks The above default is true for initial calls, but the actual default
|
99
|
-
*
|
99
|
+
* @remarks The above default is true for initial calls, but the actual default value, if this is passed nullish or omitted, is whatever the current value in `this##playback`
|
100
|
+
* is, unless this is part of a {@linkcode foundry.canvas.layers.SoundsLayer.playAtPosition | SoundsLayer#playAtPosition} call, as that method always creates a new sound with
|
101
|
+
* no playback history
|
100
102
|
*/
|
101
103
|
loopStart: number;
|
102
104
|
|
103
105
|
/**
|
104
106
|
* Seconds of the Audio buffer when looped playback should restart. Only works for AudioBufferSourceNode.
|
105
107
|
* @defaultValue `undefined`
|
106
|
-
* @remarks The above default is true for initial calls, but the actual default
|
107
|
-
*
|
108
|
+
* @remarks The above default is true for initial calls, but the actual default value, if this is passed nullish or omitted, is whatever the current value in `this##playback`
|
109
|
+
* is, unless this is part of a {@linkcode foundry.canvas.layers.SoundsLayer.playAtPosition | SoundsLayer#playAtPosition} call, as that method always creates a new sound with
|
110
|
+
* no playback history
|
108
111
|
*/
|
109
112
|
loopEnd: number;
|
110
113
|
|
111
114
|
/**
|
112
115
|
* An offset in seconds at which to start playback
|
113
116
|
* @defaultValue `0`
|
114
|
-
* @remarks The above default is true for initial calls, but the actual default
|
115
|
-
*
|
116
|
-
*
|
117
|
+
* @remarks The above default is true for initial calls, but the actual default value, if this is passed nullish or omitted, is whatever the current value of `loopStart` in
|
118
|
+
* `this##playback` is, unless this is part of a {@linkcode foundry.canvas.layers.SoundsLayer.playAtPosition | SoundsLayer#playAtPosition} call, as that method always creates
|
119
|
+
* a new sound with no playback history
|
117
120
|
*/
|
118
121
|
offset: number;
|
119
122
|
|
120
123
|
/**
|
121
124
|
* A callback function attached to the source node
|
122
125
|
* @defaultValue `null`
|
123
|
-
* @remarks The above default is true for initial calls, but the actual default
|
124
|
-
*
|
126
|
+
* @remarks The above default is true for initial calls, but the actual default value, if this is passed nullish or omitted, is whatever the current value in `this##playback`
|
127
|
+
* is, unless this is part of a {@linkcode foundry.canvas.layers.SoundsLayer.playAtPosition | SoundsLayer#playAtPosition} call, as that method always creates a new sound with
|
128
|
+
* no playback history
|
125
129
|
*/
|
126
130
|
onended: ScheduleCallback | null;
|
127
131
|
|
128
132
|
/**
|
129
133
|
* The volume at which to play the sound
|
130
134
|
* @defaultValue `1.0`
|
131
|
-
* @remarks The above default is true for initial calls, but the actual default
|
132
|
-
*
|
135
|
+
* @remarks The above default is true for initial calls, but the actual default value, if this is passed nullish or omitted, is whatever the current value in `this##playback`
|
136
|
+
* is, unless this is part of a {@linkcode foundry.canvas.layers.SoundsLayer.playAtPosition | SoundsLayer#playAtPosition} call, as that method always creates a new sound with
|
137
|
+
* no playback history
|
133
138
|
*/
|
134
139
|
volume: number;
|
135
140
|
}>;
|
@@ -137,29 +142,78 @@ declare namespace Sound {
|
|
137
142
|
/** @remarks Default values here are what `Sound##configurePlayback` would use if passed an empty object with no prior calls */
|
138
143
|
interface PlaybackOptions extends _PlaybackOptions {}
|
139
144
|
|
145
|
+
/** @remarks `volume` is always overwritten in {@linkcode Sound.playAtPosition | Sound#playAtPosition} */
|
146
|
+
interface PlaybackOptionsPositional extends Omit<PlaybackOptions, "volume"> {}
|
147
|
+
|
148
|
+
/** @remarks The keys omitted are generated from other data passed to {@linkcode Sound.playAtPosition | Sound#playAtPosition} */
|
149
|
+
interface PartialSourceData
|
150
|
+
extends IntentionalPartial<Omit<PointSoundSource.SourceData, "x" | "y" | "elevation" | "radius" | "walls">> {}
|
151
|
+
|
152
|
+
/** @internal */
|
153
|
+
type _PlayAtPositionOptions = InexactPartial<{
|
154
|
+
/**
|
155
|
+
* The maximum volume at which the effect should be played
|
156
|
+
* @defaultValue `1.0`
|
157
|
+
*/
|
158
|
+
volume: number;
|
159
|
+
|
160
|
+
/**
|
161
|
+
* Should volume be attenuated by distance?
|
162
|
+
* @defaultValue `true`
|
163
|
+
*/
|
164
|
+
easing: boolean;
|
165
|
+
|
166
|
+
/**
|
167
|
+
* Should the sound be constrained by walls?
|
168
|
+
* @defaultValue `true`
|
169
|
+
*/
|
170
|
+
walls: boolean;
|
171
|
+
|
172
|
+
/**
|
173
|
+
* Should the sound always be played for GM users regardless of actively controlled tokens?
|
174
|
+
* @defaultValue `true`
|
175
|
+
*/
|
176
|
+
gmAlways: boolean;
|
177
|
+
|
178
|
+
/** A base sound effect to apply to playback */
|
179
|
+
baseEffect: AmbientSoundDocument.Effect;
|
180
|
+
|
181
|
+
/** A muffled sound effect to apply to playback, a sound may only be muffled if it is not constrained by walls */
|
182
|
+
muffledEffect: AmbientSoundDocument.Effect;
|
183
|
+
|
184
|
+
/**
|
185
|
+
* Additional data passed to the SoundSource constructor
|
186
|
+
*/
|
187
|
+
sourceData: Sound.PartialSourceData;
|
188
|
+
|
189
|
+
/**
|
190
|
+
* Additional options passed to {@linkcode Sound.play | Sound#play}
|
191
|
+
*/
|
192
|
+
playbackOptions: Sound.PlaybackOptionsPositional;
|
193
|
+
}>;
|
194
|
+
|
195
|
+
interface PlayAtPositionOptions extends _PlayAtPositionOptions {}
|
196
|
+
|
140
197
|
/** @internal */
|
141
198
|
type _FadeOptions = InexactPartial<{
|
142
199
|
/**
|
143
200
|
* The duration of the fade effect in milliseconds
|
144
201
|
* @defaultValue `1000`
|
145
|
-
* @remarks Can't be `null` as it only has a parameter default
|
146
202
|
*/
|
147
203
|
duration: number;
|
148
204
|
|
149
205
|
/**
|
150
206
|
* The type of fade easing, "linear" or "exponential"
|
151
207
|
* @defaultValue `"linear"`
|
152
|
-
* @remarks Can't be `null` as it only has a parameter default
|
153
208
|
*/
|
154
209
|
type: "linear" | "exponential";
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
}>;
|
210
|
+
|
211
|
+
/**
|
212
|
+
* A volume level to start from, the current volume by default
|
213
|
+
* @defaultValue `this.gain.value`
|
214
|
+
*/
|
215
|
+
from: number;
|
216
|
+
}>;
|
163
217
|
|
164
218
|
interface FadeOptions extends _FadeOptions {}
|
165
219
|
|
@@ -177,7 +231,6 @@ declare class Sound extends EventEmitterMixin() {
|
|
177
231
|
* @param src - The audio source path, either a relative path or a remote URL
|
178
232
|
* @param options - Additional options which configure the Sound
|
179
233
|
*/
|
180
|
-
// options: not null (destructured)
|
181
234
|
constructor(src: string, options?: Sound.ConstructorOptions);
|
182
235
|
|
183
236
|
/**
|
@@ -241,7 +294,7 @@ declare class Sound extends EventEmitterMixin() {
|
|
241
294
|
|
242
295
|
/**
|
243
296
|
* The life-cycle state of the sound.
|
244
|
-
* @defaultValue
|
297
|
+
* @defaultValue {@linkcode Sound.STATES.NONE}
|
245
298
|
*/
|
246
299
|
protected _state: Sound.STATES;
|
247
300
|
|
@@ -268,7 +321,7 @@ declare class Sound extends EventEmitterMixin() {
|
|
268
321
|
|
269
322
|
/**
|
270
323
|
* A convenience reference to the GainNode gain audio parameter.
|
271
|
-
* @remarks `undefined` if {@
|
324
|
+
* @remarks `undefined` if {@linkcode Sound.gainNode | Sound#gainNode} is.
|
272
325
|
*/
|
273
326
|
get gain(): AudioParam | undefined;
|
274
327
|
|
@@ -325,11 +378,8 @@ declare class Sound extends EventEmitterMixin() {
|
|
325
378
|
/**
|
326
379
|
* An internal reference to some object which is managing this Sound instance.
|
327
380
|
* @defaultValue `null`
|
328
|
-
* @
|
329
|
-
*
|
330
|
-
* Only ever set *or* read externally by core, so not protected
|
331
|
-
*
|
332
|
-
* @privateRemarks Foundry types this as `Object|null` but the only place in Core this gets set is in `AmbientSound`, to `this`
|
381
|
+
* @internal
|
382
|
+
* @remarks Only ever set *or* read externally by core, so not protected
|
333
383
|
*/
|
334
384
|
_manager: AmbientSound.Implementation | null;
|
335
385
|
|
@@ -338,14 +388,12 @@ declare class Sound extends EventEmitterMixin() {
|
|
338
388
|
* @param options - Additional options which affect resource loading
|
339
389
|
* @returns A Promise which resolves to the Sound once it is loaded
|
340
390
|
*/
|
341
|
-
// options: not null (destructured)
|
342
391
|
load(options?: Sound.LoadOptions): Promise<this>;
|
343
392
|
|
344
393
|
/**
|
345
394
|
* An inner method which handles loading so that it can be de-duplicated under a single shared Promise resolution.
|
346
395
|
* This method is factored out to allow for subclasses to override loading behavior.
|
347
396
|
* @returns A Promise which resolves once the sound is loaded
|
348
|
-
* @throws An error if loading failed for any reason
|
349
397
|
*/
|
350
398
|
protected _load(): Promise<void>;
|
351
399
|
|
@@ -359,11 +407,60 @@ declare class Sound extends EventEmitterMixin() {
|
|
359
407
|
play(options?: Sound.PlaybackOptions): Promise<this>;
|
360
408
|
|
361
409
|
/**
|
362
|
-
* @deprecated since v12, until v14
|
363
|
-
* @remarks "`Sound#play` now takes an object of playback options instead of positional arguments."
|
410
|
+
* @deprecated "`Sound#play` now takes an object of playback options instead of positional arguments." (since v12, until v14)
|
364
411
|
*/
|
365
412
|
play(offset: number, onended?: Sound.ScheduleCallback | null): Promise<this>;
|
366
413
|
|
414
|
+
/**
|
415
|
+
* Play a one-shot Sound originating from a predefined point on the canvas.
|
416
|
+
* The sound plays locally for the current client only.
|
417
|
+
* To play a sound for all connected clients use {@linkcode foundry.canvas.layers.SoundsLayer.emitAtPosition | SoundsLayer#emitAtPosition}.
|
418
|
+
* A helper which does not depend on a pre-existing Sound instance is available at
|
419
|
+
* {@linkcode foundry.canvas.layers.SoundsLayer.playAtPosition | SoundsLayer#playAtPosition}.
|
420
|
+
*
|
421
|
+
* @param origin - The canvas coordinates from which the sound originates
|
422
|
+
* @param radius - The radius of effect in distance units
|
423
|
+
* @param options - Additional options which configure playback
|
424
|
+
* @returns A Promise which resolves to the played Sound, or null
|
425
|
+
*
|
426
|
+
* Play the sound of a trap springing
|
427
|
+
* @example
|
428
|
+
* ```js
|
429
|
+
* const sound = new Sound("modules/my-module/sounds/spring-trap.ogg", {context: game.audio.environment});
|
430
|
+
* await sound.load();
|
431
|
+
* const origin = {x: 5200, y: 3700}; // The origin point for the sound
|
432
|
+
* const radius = 30; // Audible in a 30-foot radius
|
433
|
+
* await sound.playAtPosition(origin, radius);
|
434
|
+
* ```
|
435
|
+
*
|
436
|
+
* A Token casts a spell
|
437
|
+
* @example
|
438
|
+
* ```js
|
439
|
+
* const sound = new Sound("modules/my-module/sounds/spells-sprite.ogg", {context: game.audio.environment});
|
440
|
+
* const origin = token.center; // The origin point for the sound
|
441
|
+
* const radius = 60; // Audible in a 60-foot radius
|
442
|
+
* await sound.playAtPosition(origin, radius, {
|
443
|
+
* walls: false, // Not constrained by walls with a lowpass muffled effect
|
444
|
+
* muffledEffect: {type: "lowpass", intensity: 6},
|
445
|
+
* sourceData: {
|
446
|
+
* angle: 120, // Sound emitted at a limited angle
|
447
|
+
* rotation: 270 // Configure the direction of sound emission
|
448
|
+
* }
|
449
|
+
* playbackOptions: {
|
450
|
+
* loopStart: 12, // Audio sprite timing
|
451
|
+
* loopEnd: 16,
|
452
|
+
* fade: 300, // Fade-in 300ms
|
453
|
+
* onended: () => console.log("Do something after the spell sound has played")
|
454
|
+
* }
|
455
|
+
* });
|
456
|
+
* ```
|
457
|
+
*/
|
458
|
+
playAtPosition(
|
459
|
+
origin: Canvas.PossiblyElevatedPoint,
|
460
|
+
radius: number,
|
461
|
+
options?: Sound.PlayAtPositionOptions,
|
462
|
+
): Promise<this | null>;
|
463
|
+
|
367
464
|
/**
|
368
465
|
* Begin playback for the configured pipeline and playback options.
|
369
466
|
* This method is factored out so that subclass implementations of Sound can implement alternative behavior.
|
@@ -372,9 +469,10 @@ declare class Sound extends EventEmitterMixin() {
|
|
372
469
|
|
373
470
|
/**
|
374
471
|
* Pause playback of the Sound.
|
375
|
-
* For AudioBufferSourceNode this stops playback after recording the current time.
|
376
|
-
* Calling Sound#play will resume playback from the pausedTime unless some other offset is passed.
|
377
|
-
* For a MediaElementAudioSourceNode this simply calls the HTMLAudioElement#pause method directly.
|
472
|
+
* For {@linkcode AudioBufferSourceNode} this stops playback after recording the current time.
|
473
|
+
* Calling {@linkcode Sound.play | Sound#play} will resume playback from the {@linkcode Sound.pauseTime | #pausedTime} unless some other offset is passed.
|
474
|
+
* For a {@linkcode MediaElementAudioSourceNode} this simply calls the {@linkcode HTMLAudioElement.pause | HTMLAudioElement#pause} method directly.
|
475
|
+
* @remarks
|
378
476
|
* @throws If called while the Sound isn't playing
|
379
477
|
*/
|
380
478
|
pause(): void;
|
@@ -392,7 +490,6 @@ declare class Sound extends EventEmitterMixin() {
|
|
392
490
|
* @param options - Options which configure the stopping of sound playback
|
393
491
|
* @returns A Promise which resolves once playback is fully stopped (including fade)
|
394
492
|
*/
|
395
|
-
// options: not null (parameter default only, destructured where forwarded)
|
396
493
|
stop(options?: Sound.PlaybackOptions): Promise<this>;
|
397
494
|
|
398
495
|
/**
|
@@ -407,7 +504,6 @@ declare class Sound extends EventEmitterMixin() {
|
|
407
504
|
* @param options - Additional options that configure the fade operation
|
408
505
|
* @returns A Promise that resolves after the requested fade duration
|
409
506
|
*/
|
410
|
-
// options: not null (destructured)
|
411
507
|
fade(volume: number, options?: Sound.FadeOptions): Promise<void>;
|
412
508
|
|
413
509
|
/**
|
@@ -432,6 +528,18 @@ declare class Sound extends EventEmitterMixin() {
|
|
432
528
|
*/
|
433
529
|
schedule<R extends Sound.ScheduleCallback>(fn: R, playbackTime: number): Promise<Awaited<ReturnType<R>>>;
|
434
530
|
|
531
|
+
/**
|
532
|
+
* Cancel one scheduled event created with {@linkcode Sound.schedule | Sound#schedule}.
|
533
|
+
* You may pass either the {@linkcode AudioTimeout} returned internally or the Promise returned by `Sound#schedule`.
|
534
|
+
* @param handle - The handle to cancel.
|
535
|
+
*/
|
536
|
+
unschedule(handle: AudioTimeout | { timeout: AudioTimeout }): void;
|
537
|
+
|
538
|
+
/**
|
539
|
+
* Cancel all events that are still scheduled for this sound.
|
540
|
+
*/
|
541
|
+
unscheduleAll(): void;
|
542
|
+
|
435
543
|
/**
|
436
544
|
* Update the array of effects applied to a Sound instance.
|
437
545
|
* Optionally a new array of effects can be assigned. If no effects are passed, the current effects are re-applied.
|
@@ -458,48 +566,42 @@ declare class Sound extends EventEmitterMixin() {
|
|
458
566
|
protected _disconnectPipeline(): void;
|
459
567
|
|
460
568
|
/**
|
461
|
-
* @deprecated since v12,
|
462
|
-
* @remarks "`AudioContainer.LOAD_STATES` is deprecated in favor of {@linkcode Sound.STATES}"
|
569
|
+
* @deprecated "`AudioContainer.LOAD_STATES` is deprecated in favor of {@linkcode Sound.STATES}" (since v12, until v14)
|
463
570
|
*/
|
464
571
|
static get LOAD_STATES(): Sound.States;
|
465
572
|
|
466
573
|
/**
|
467
|
-
* @deprecated since v12,
|
468
|
-
* @remarks "`AudioContainer#loadState` is deprecated in favor of {@link Sound._state | `Sound#_state`}"
|
574
|
+
* @deprecated "`AudioContainer#loadState` is deprecated in favor of {@linkcode Sound._state | Sound#_state}" (since v12, until v14)
|
469
575
|
*/
|
470
576
|
get loadState(): Sound.STATES;
|
471
577
|
|
472
578
|
/**
|
473
|
-
* @deprecated since v12,
|
474
|
-
* @remarks "`Sound#container` is deprecated without replacement because the `Sound` and `AudioContainer` classes are now merged"
|
579
|
+
* @deprecated "`Sound#container` is deprecated without replacement because the `Sound` and `AudioContainer` classes are now merged" (since v12, until v14)
|
475
580
|
*/
|
476
581
|
get container(): this;
|
477
582
|
|
478
583
|
/**
|
479
|
-
* @deprecated since v12,
|
480
|
-
* @remarks "`Sound#node` is renamed {@link Sound.sourceNode | `Sound#sourceNode`}"
|
584
|
+
* @deprecated "`Sound#node` is renamed {@linkcode Sound.sourceNode | Sound#sourceNode}" (since v12, until v14)
|
481
585
|
*/
|
482
586
|
get node(): this["sourceNode"];
|
483
587
|
|
484
588
|
/**
|
485
|
-
* @deprecated since v12,
|
486
|
-
* @remarks "`Sound#on` is deprecated in favor of {@link Sound.addEventListener | `Sound#addEventListener`}"
|
589
|
+
* @deprecated "`Sound#on` is deprecated in favor of {@linkcode Sound.addEventListener | Sound#addEventListener}" (since v12, until v14)
|
487
590
|
*/
|
488
591
|
on(eventName: string, fn: EventEmitterMixin.EventListener, options?: EventEmitterMixin.AddListenerOptions): void;
|
489
592
|
|
490
593
|
/**
|
491
|
-
* @deprecated since v12,
|
492
|
-
* @remarks "`Sound#off` is deprecated in favor of {@link Sound.removeEventListener | `Sound#removeEventListener`}"
|
594
|
+
* @deprecated "`Sound#off` is deprecated in favor of {@linkcode Sound.removeEventListener | Sound#removeEventListener}" (since v12, until v14)
|
493
595
|
*/
|
494
596
|
off(eventName: string, fn: EventEmitterMixin.EventListener): void;
|
495
597
|
|
496
598
|
/**
|
497
|
-
* @deprecated since v12,
|
498
|
-
* @remarks
|
499
|
-
*
|
500
|
-
* This method still takes a string, then creates an `Event` with it and passes that along to `dispatchEvent`
|
599
|
+
* @deprecated "`Sound#emit` is deprecated in favor of {@linkcode Sound.dispatchEvent | Sound#dispatchEvent}" (since v12, until v14)
|
600
|
+
* @remarks This method still takes a string, then creates an `Event` with it and passes that along to `dispatchEvent`
|
501
601
|
*/
|
502
602
|
emit(eventName: string): void;
|
603
|
+
|
604
|
+
#Sound: true;
|
503
605
|
}
|
504
606
|
|
505
607
|
export default Sound;
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import type { Identity,
|
1
|
+
import type { Identity, InexactPartial } from "#utils";
|
2
2
|
|
3
3
|
/**
|
4
4
|
* A special error class used for cancellation.
|
@@ -56,6 +56,11 @@ declare class AudioTimeout<CallbackReturn = undefined> {
|
|
56
56
|
*/
|
57
57
|
complete: Promise<CallbackReturn> | undefined;
|
58
58
|
|
59
|
+
/**
|
60
|
+
* Is this audio timeout cancelled?
|
61
|
+
*/
|
62
|
+
get cancelled(): boolean;
|
63
|
+
|
59
64
|
/**
|
60
65
|
* Cancel an AudioTimeout by ending it early, rejecting its completion promise, and skipping any callback function.
|
61
66
|
*/
|
@@ -72,11 +77,12 @@ declare class AudioTimeout<CallbackReturn = undefined> {
|
|
72
77
|
* @param options - Additional options which modify timeout behavior
|
73
78
|
* @returns A promise which resolves as a returned value of the callback or void
|
74
79
|
*/
|
75
|
-
// options: not null (destructured where forwarded)
|
76
80
|
static wait<CallbackReturn = undefined>(
|
77
81
|
delayMS: number,
|
78
82
|
options?: AudioTimeout.ConstructorOptions<CallbackReturn>,
|
79
83
|
): Promise<CallbackReturn>;
|
84
|
+
|
85
|
+
#AudioTimeout: true;
|
80
86
|
}
|
81
87
|
|
82
88
|
declare namespace AudioTimeout {
|
@@ -84,7 +90,7 @@ declare namespace AudioTimeout {
|
|
84
90
|
interface AnyConstructor extends Identity<typeof AnyAudioTimeout> {}
|
85
91
|
|
86
92
|
/** @internal */
|
87
|
-
type _ConstructorOptions<Return = undefined> =
|
93
|
+
type _ConstructorOptions<Return = undefined> = InexactPartial<{
|
88
94
|
/** @defaultValue `game.audio.music` */
|
89
95
|
context: AudioContext;
|
90
96
|
|