@zakkster/lite-audio 1.0.0 → 1.1.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/Audio.d.ts +107 -9
- package/Audio.js +551 -10
- package/CHANGELOG.md +198 -88
- package/README.md +91 -15
- package/llms.txt +55 -44
- package/package.json +3 -4
package/Audio.d.ts
CHANGED
|
@@ -31,14 +31,49 @@ export interface SoundConfig {
|
|
|
31
31
|
pitchVar?: number;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
export interface TrackConfig {
|
|
35
|
+
/** Source URL list, ordered by preference. First supported extension wins. */
|
|
36
|
+
src: string[];
|
|
37
|
+
/** Bus to route this track to. Defaults to 'music'. Must exist in `opts.buses`. */
|
|
38
|
+
bus?: string;
|
|
39
|
+
/** Baseline volume for this track (0..1). Independent of the crossfade knob. */
|
|
40
|
+
volume?: number;
|
|
41
|
+
/** Loop this track when it ends (or when loopEnd is reached, if set). */
|
|
42
|
+
loop?: boolean;
|
|
43
|
+
/** Custom loop start (seconds). Requires loopEnd; the native element.loop is disabled. */
|
|
44
|
+
loopStart?: number;
|
|
45
|
+
/** Custom loop end (seconds). When currentTime crosses this, seeks to loopStart. */
|
|
46
|
+
loopEnd?: number;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface PlayTrackOptions {
|
|
50
|
+
/** Fade-in duration in ms. Default 0 (snap to full). */
|
|
51
|
+
fadeIn?: number;
|
|
52
|
+
/** Seek to this position (seconds) before playback. */
|
|
53
|
+
position?: number;
|
|
54
|
+
/** If the track is already playing, seek to 0 and continue. Default false (no-op). */
|
|
55
|
+
restart?: boolean;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface StopTrackOptions {
|
|
59
|
+
/** Fade-out duration in ms. Default 200. */
|
|
60
|
+
fade?: number;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface PlayExclusiveOptions extends PlayTrackOptions {
|
|
64
|
+
/** Fade-out duration for siblings on the same bus, ms. Default 200. */
|
|
65
|
+
fade?: number;
|
|
66
|
+
}
|
|
67
|
+
|
|
34
68
|
export interface LiteAudioOptions {
|
|
35
69
|
/**
|
|
36
70
|
* User-facing bus names. Do not include 'master' - it is always the top
|
|
37
71
|
* of the graph and is controlled via setMuted() / muted().
|
|
72
|
+
* Defaults to ['sfx', 'ui', 'voice', 'music'].
|
|
38
73
|
*/
|
|
39
74
|
buses?: string[];
|
|
40
75
|
|
|
41
|
-
/** Voices per bus pool. Defaults to 32. */
|
|
76
|
+
/** Voices per bus pool (SFX). Defaults to 32. */
|
|
42
77
|
poolCapacity?: number;
|
|
43
78
|
|
|
44
79
|
/**
|
|
@@ -59,6 +94,10 @@ export interface LiteAudioOptions {
|
|
|
59
94
|
|
|
60
95
|
/** Injectable for tests. Defaults to globalThis.document. */
|
|
61
96
|
document?: any;
|
|
97
|
+
|
|
98
|
+
/** Injectable for tests. Defaults to globalThis.setTimeout / clearTimeout. */
|
|
99
|
+
setTimeout?: (cb: () => void, ms: number) => any;
|
|
100
|
+
clearTimeout?: (id: any) => void;
|
|
62
101
|
}
|
|
63
102
|
|
|
64
103
|
export class LiteAudio {
|
|
@@ -80,9 +119,9 @@ export class LiteAudio {
|
|
|
80
119
|
* Locked-context plays are queued and flushed on the first user gesture (D3).
|
|
81
120
|
*
|
|
82
121
|
* The handle is `busIndex * 2^32 + poolHandle`: a plain number, exact well
|
|
83
|
-
* inside 2^53, opaque to callers.
|
|
84
|
-
*
|
|
85
|
-
*
|
|
122
|
+
* inside 2^53, opaque to callers. Every bus's pool counts channels and
|
|
123
|
+
* generations from zero on its own, so the raw pool handles collide across
|
|
124
|
+
* buses by construction - the bus tag is what makes a handle name one voice.
|
|
86
125
|
*/
|
|
87
126
|
play(soundId: string, volume?: number, pan?: number, pitch?: number): number;
|
|
88
127
|
|
|
@@ -106,14 +145,73 @@ export class LiteAudio {
|
|
|
106
145
|
/** Name of the bus that issued this handle, or null. */
|
|
107
146
|
busOf(handle: number): string | null;
|
|
108
147
|
|
|
109
|
-
/**
|
|
148
|
+
/**
|
|
149
|
+
* SFX voices sounding on a bus, or across every bus with no argument.
|
|
150
|
+
* Tracks are not voices and are not counted - ask trackPlaying(name).
|
|
151
|
+
*/
|
|
110
152
|
activeCount(busName?: string): number;
|
|
111
153
|
|
|
112
|
-
/** Stop every voice on a named bus. */
|
|
113
|
-
stopBus(busName: string): void;
|
|
154
|
+
/** Stop every voice on a named bus, and fade out any track routed there. */
|
|
155
|
+
stopBus(busName: string, opts?: { fade?: number }): void;
|
|
156
|
+
|
|
157
|
+
/** Stop every voice on every bus, and fade out every playing track. */
|
|
158
|
+
stopAll(opts?: { fade?: number }): void;
|
|
159
|
+
|
|
160
|
+
// ---------- Music layer (v1.1.0) ---------------------------------------
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Register music tracks. Streaming via MediaElementAudioSourceNode.
|
|
164
|
+
* Same async loader shape as defineSounds; per-track loadState signal
|
|
165
|
+
* transitions idle -> loading -> ready | error.
|
|
166
|
+
*/
|
|
167
|
+
defineTracks(config: Record<string, TrackConfig>): Promise<void>;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Start (or resume) a track. Idempotent per name unless `restart: true`.
|
|
171
|
+
* Silent no-op if the context is locked or the track is not ready.
|
|
172
|
+
*/
|
|
173
|
+
playTrack(name: string, opts?: PlayTrackOptions): void;
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Fade a track out. The playing signal flips false immediately; the
|
|
177
|
+
* <audio> element is paused after the fade completes.
|
|
178
|
+
*/
|
|
179
|
+
stopTrack(name: string, opts?: StopTrackOptions): void;
|
|
180
|
+
|
|
181
|
+
/** Pause without losing position. */
|
|
182
|
+
pauseTrack(name: string): void;
|
|
183
|
+
|
|
184
|
+
/** Resume from paused state. Position (element.currentTime) preserved. */
|
|
185
|
+
resumeTrack(name: string): void;
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Equal-power crossfade between two tracks. Either side may be null.
|
|
189
|
+
* Case (c) interruption semantics: only tracks named in this call are
|
|
190
|
+
* touched. A track fading out from a previous crossfade keeps its
|
|
191
|
+
* schedule; a track being retargeted reads its current xfadeGain value
|
|
192
|
+
* and scales the equal-power curve from there.
|
|
193
|
+
*/
|
|
194
|
+
crossfade(fromName: string | null, toName: string | null, durationMs?: number): void;
|
|
195
|
+
|
|
196
|
+
/** Start `name` and fade every other playing track on its bus. */
|
|
197
|
+
playExclusive(name: string, opts?: PlayExclusiveOptions): void;
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Play `name` (sound OR track) only if the last play attempt for the
|
|
201
|
+
* same name was more than `thresholdMs` ago. Ported from the manager.
|
|
202
|
+
*
|
|
203
|
+
* Returns a voice handle for a sound, `-2` for a track (music is a singleton,
|
|
204
|
+
* addressed by name), and `-1` on threshold rejection or unknown name. It never
|
|
205
|
+
* returns 0 for a track: 0 is a real handle (bus 0, channel 0, generation 0), and
|
|
206
|
+
* passing it to stop() would kill an unrelated SFX voice.
|
|
207
|
+
*/
|
|
208
|
+
playUnique(name: string, thresholdMs?: number): number;
|
|
114
209
|
|
|
115
|
-
/**
|
|
116
|
-
|
|
210
|
+
/** Per-track signals. Undefined for unknown track name. */
|
|
211
|
+
trackLoadState(name: string): ReadSignal<LoadState> | undefined;
|
|
212
|
+
trackPlaying(name: string): ReadSignal<boolean> | undefined;
|
|
213
|
+
trackPosition(name: string): ReadSignal<number> | undefined;
|
|
214
|
+
trackDuration(name: string): ReadSignal<number> | undefined;
|
|
117
215
|
|
|
118
216
|
// ---------- Bus + master controls --------------------------------------
|
|
119
217
|
setBusVolume(busName: string, volume: number): void;
|