@litlab/audx 0.0.1 → 0.5.5

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.
Files changed (81) hide show
  1. package/README.md +96 -53
  2. package/dist/bin.js +1212 -0
  3. package/dist/cc-DgCkkqq8.js +13 -0
  4. package/dist/cc-he3fHS3P.js +12 -0
  5. package/dist/index.d.ts +723 -3
  6. package/dist/index.js +1534 -126
  7. package/dist/react.d.ts +583 -0
  8. package/dist/react.js +1556 -0
  9. package/package.json +64 -39
  10. package/schemas/pack.schema.json +4 -0
  11. package/schemas/patch.schema.json +857 -0
  12. package/dist/codegen/theme-codegen.d.ts +0 -12
  13. package/dist/codegen/theme-codegen.d.ts.map +0 -1
  14. package/dist/codegen/theme-codegen.js +0 -153
  15. package/dist/codegen/theme-codegen.js.map +0 -1
  16. package/dist/commands/add.d.ts +0 -2
  17. package/dist/commands/add.d.ts.map +0 -1
  18. package/dist/commands/add.js +0 -120
  19. package/dist/commands/add.js.map +0 -1
  20. package/dist/commands/diff.d.ts +0 -2
  21. package/dist/commands/diff.d.ts.map +0 -1
  22. package/dist/commands/diff.js +0 -103
  23. package/dist/commands/diff.js.map +0 -1
  24. package/dist/commands/generate.d.ts +0 -12
  25. package/dist/commands/generate.d.ts.map +0 -1
  26. package/dist/commands/generate.js +0 -96
  27. package/dist/commands/generate.js.map +0 -1
  28. package/dist/commands/init.d.ts +0 -2
  29. package/dist/commands/init.d.ts.map +0 -1
  30. package/dist/commands/init.js +0 -79
  31. package/dist/commands/init.js.map +0 -1
  32. package/dist/commands/list.d.ts +0 -14
  33. package/dist/commands/list.d.ts.map +0 -1
  34. package/dist/commands/list.js +0 -93
  35. package/dist/commands/list.js.map +0 -1
  36. package/dist/commands/remove.d.ts +0 -2
  37. package/dist/commands/remove.d.ts.map +0 -1
  38. package/dist/commands/remove.js +0 -71
  39. package/dist/commands/remove.js.map +0 -1
  40. package/dist/commands/theme.d.ts +0 -31
  41. package/dist/commands/theme.d.ts.map +0 -1
  42. package/dist/commands/theme.js +0 -142
  43. package/dist/commands/theme.js.map +0 -1
  44. package/dist/commands/update.d.ts +0 -2
  45. package/dist/commands/update.d.ts.map +0 -1
  46. package/dist/commands/update.js +0 -123
  47. package/dist/commands/update.js.map +0 -1
  48. package/dist/core/alias-resolver.d.ts +0 -24
  49. package/dist/core/alias-resolver.d.ts.map +0 -1
  50. package/dist/core/alias-resolver.js +0 -87
  51. package/dist/core/alias-resolver.js.map +0 -1
  52. package/dist/core/config.d.ts +0 -21
  53. package/dist/core/config.d.ts.map +0 -1
  54. package/dist/core/config.js +0 -43
  55. package/dist/core/config.js.map +0 -1
  56. package/dist/core/file-writer.d.ts +0 -14
  57. package/dist/core/file-writer.d.ts.map +0 -1
  58. package/dist/core/file-writer.js +0 -90
  59. package/dist/core/file-writer.js.map +0 -1
  60. package/dist/core/package-manager.d.ts +0 -3
  61. package/dist/core/package-manager.d.ts.map +0 -1
  62. package/dist/core/package-manager.js +0 -17
  63. package/dist/core/package-manager.js.map +0 -1
  64. package/dist/core/registry.d.ts +0 -18
  65. package/dist/core/registry.d.ts.map +0 -1
  66. package/dist/core/registry.js +0 -69
  67. package/dist/core/registry.js.map +0 -1
  68. package/dist/core/theme-manager.d.ts +0 -35
  69. package/dist/core/theme-manager.d.ts.map +0 -1
  70. package/dist/core/theme-manager.js +0 -94
  71. package/dist/core/theme-manager.js.map +0 -1
  72. package/dist/core/utils.d.ts +0 -22
  73. package/dist/core/utils.d.ts.map +0 -1
  74. package/dist/core/utils.js +0 -44
  75. package/dist/core/utils.js.map +0 -1
  76. package/dist/index.d.ts.map +0 -1
  77. package/dist/index.js.map +0 -1
  78. package/dist/types.d.ts +0 -116
  79. package/dist/types.d.ts.map +0 -1
  80. package/dist/types.js +0 -43
  81. package/dist/types.js.map +0 -1
@@ -0,0 +1,583 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ /** Standard oscillator waveform source with optional FM synthesis. */
4
+ type OscillatorSource = {
5
+ type: "sine" | "triangle" | "square" | "sawtooth";
6
+ /** Fixed frequency in Hz, or a `{ start, end }` range for a pitch sweep. */
7
+ frequency: number | {
8
+ start: number;
9
+ end: number;
10
+ };
11
+ /** Detune in cents. */
12
+ detune?: number;
13
+ /** Frequency modulation: `ratio` is the modulator-to-carrier ratio, `depth` is the modulation index. */
14
+ fm?: {
15
+ ratio: number;
16
+ depth: number;
17
+ };
18
+ };
19
+ /** Procedural noise source (white, pink, or brown). */
20
+ type NoiseSource = {
21
+ type: "noise";
22
+ /** @defaultValue `"white"` */
23
+ color?: "white" | "pink" | "brown";
24
+ };
25
+ /** Custom waveform built from a harmonic series via `createPeriodicWave`. */
26
+ type WavetableSource = {
27
+ type: "wavetable";
28
+ /** Amplitude of each harmonic (index 0 = fundamental). */
29
+ harmonics: number[];
30
+ /** Fixed frequency in Hz, or a `{ start, end }` range for a pitch sweep. */
31
+ frequency: number | {
32
+ start: number;
33
+ end: number;
34
+ };
35
+ };
36
+ /** Plays a pre-recorded audio sample from a URL or an existing `AudioBuffer`. */
37
+ type SampleSource = {
38
+ type: "sample";
39
+ /** URL of the audio file to fetch and decode. Cached after first load. */
40
+ url?: string;
41
+ /** Pre-decoded buffer to use directly. */
42
+ buffer?: AudioBuffer;
43
+ /** Playback speed multiplier. @defaultValue `1` */
44
+ playbackRate?: number;
45
+ /** Detune in cents. */
46
+ detune?: number;
47
+ /** Whether the sample loops. */
48
+ loop?: boolean;
49
+ /** Loop region start in seconds. */
50
+ loopStart?: number;
51
+ /** Loop region end in seconds. */
52
+ loopEnd?: number;
53
+ };
54
+ /** Live audio input from a `MediaStream` (e.g. microphone). Requires a real-time `AudioContext`. */
55
+ type StreamSource = {
56
+ type: "stream";
57
+ stream: MediaStream;
58
+ };
59
+ /** DC offset source, useful for control signals and modulation. */
60
+ type ConstantSource = {
61
+ type: "constant";
62
+ /** @defaultValue `1` */
63
+ offset?: number;
64
+ };
65
+ /** Union of all audio source types that can drive a {@link Layer}. */
66
+ type Source = OscillatorSource | NoiseSource | WavetableSource | SampleSource | StreamSource | ConstantSource;
67
+ /** Biquad filter type identifiers matching the Web Audio API `BiquadFilterNode.type`. */
68
+ type BiquadFilterType = "lowpass" | "highpass" | "bandpass" | "notch" | "allpass" | "peaking" | "lowshelf" | "highshelf";
69
+ /** Time-varying envelope applied to a filter's cutoff frequency. */
70
+ type FilterEnvelope = {
71
+ /** Time in seconds to ramp from the base frequency to `peak`. @defaultValue `0` */
72
+ attack?: number;
73
+ /** Target frequency in Hz at the peak of the envelope. */
74
+ peak: number;
75
+ /** Time in seconds to decay from `peak` back to the base frequency. */
76
+ decay: number;
77
+ };
78
+ /** Standard biquad filter with optional frequency envelope. */
79
+ type BiquadFilter = {
80
+ type: BiquadFilterType;
81
+ /** Cutoff or center frequency in Hz. */
82
+ frequency: number;
83
+ /** Q factor (resonance). @defaultValue `1` */
84
+ resonance?: number;
85
+ /** Gain in dB (only applies to peaking / shelf types). */
86
+ gain?: number;
87
+ /** Optional frequency envelope that sweeps the cutoff over time. */
88
+ envelope?: FilterEnvelope;
89
+ };
90
+ /** Arbitrary IIR filter defined by feedforward and feedback coefficients. */
91
+ type IIRFilter = {
92
+ type: "iir";
93
+ feedforward: number[];
94
+ feedback: number[];
95
+ };
96
+ /** Union of supported filter types. */
97
+ type Filter = BiquadFilter | IIRFilter;
98
+ /**
99
+ * Amplitude envelope (ADSR).
100
+ *
101
+ * Only `decay` is required. Omitting `attack` makes the sound start at full
102
+ * volume; omitting `sustain` lets it fade to silence after the decay phase.
103
+ */
104
+ type Envelope = {
105
+ /** Time in seconds to ramp from silence to peak volume. @defaultValue `0` */
106
+ attack?: number;
107
+ /** Time in seconds for the decay phase. */
108
+ decay: number;
109
+ /** Sustain level as a fraction of peak volume (0 – 1). @defaultValue `0` */
110
+ sustain?: number;
111
+ /** Time in seconds for the release phase after sustain. @defaultValue `0` */
112
+ release?: number;
113
+ };
114
+ /** Parameter that an {@link LFO} can modulate. */
115
+ type LFOTarget = "frequency" | "detune" | "gain" | "pan" | "filter.frequency" | "filter.detune" | "filter.Q" | "filter.gain" | "playbackRate";
116
+ /** Low-frequency oscillator for periodic modulation of a target parameter. */
117
+ type LFO = {
118
+ /** Waveform shape of the modulator. */
119
+ type: "sine" | "triangle" | "square" | "sawtooth";
120
+ /** Modulation rate in Hz. */
121
+ frequency: number;
122
+ /** Modulation depth (units depend on the target parameter). */
123
+ depth: number;
124
+ /** Which parameter this LFO modulates. */
125
+ target: LFOTarget;
126
+ };
127
+ /** 3D spatial panner configuration using the Web Audio `PannerNode`. */
128
+ type Panner3D = {
129
+ positionX: number;
130
+ positionY: number;
131
+ positionZ: number;
132
+ orientationX?: number;
133
+ orientationY?: number;
134
+ orientationZ?: number;
135
+ /** @defaultValue `"HRTF"` */
136
+ panningModel?: "equalpower" | "HRTF";
137
+ /** @defaultValue `"inverse"` */
138
+ distanceModel?: "linear" | "inverse" | "exponential";
139
+ maxDistance?: number;
140
+ refDistance?: number;
141
+ rolloffFactor?: number;
142
+ coneInnerAngle?: number;
143
+ coneOuterAngle?: number;
144
+ coneOuterGain?: number;
145
+ };
146
+ /** Position and orientation of the audio listener for 3D spatialization. */
147
+ type Listener = {
148
+ positionX: number;
149
+ positionY: number;
150
+ positionZ: number;
151
+ forwardX?: number;
152
+ forwardY?: number;
153
+ forwardZ?: number;
154
+ upX?: number;
155
+ upY?: number;
156
+ upZ?: number;
157
+ };
158
+ /** Algorithmic reverb generated from an exponentially-decaying noise impulse. */
159
+ type ReverbEffect = {
160
+ type: "reverb";
161
+ /** Tail length in seconds. @defaultValue `0.5` */
162
+ decay?: number;
163
+ /** Delay in seconds before the reverb onset. @defaultValue `0` */
164
+ preDelay?: number;
165
+ /** High-frequency damping (0 – 1). @defaultValue `0` */
166
+ damping?: number;
167
+ /** Multiplier on the decay length. @defaultValue `1` */
168
+ roomSize?: number;
169
+ /** Dry/wet mix (0 = fully dry, 1 = fully wet). @defaultValue `0.3` */
170
+ mix?: number;
171
+ };
172
+ /** Convolution reverb using a provided impulse response buffer or URL. */
173
+ type ConvolverEffect = {
174
+ type: "convolver";
175
+ /** URL of the impulse response audio file. */
176
+ url?: string;
177
+ /** Pre-decoded impulse response buffer. */
178
+ buffer?: AudioBuffer;
179
+ /** @defaultValue `0.5` */
180
+ mix?: number;
181
+ };
182
+ /** Feedback delay with optional filter in the feedback path. */
183
+ type DelayEffect = {
184
+ type: "delay";
185
+ /** Delay time in seconds. @defaultValue `0.25` */
186
+ time?: number;
187
+ /** Feedback gain (0 – 1). @defaultValue `0.3` */
188
+ feedback?: number;
189
+ /** Optional filter applied in the feedback loop. */
190
+ feedbackFilter?: {
191
+ type: BiquadFilterType;
192
+ frequency: number;
193
+ Q?: number;
194
+ };
195
+ /** @defaultValue `0.3` */
196
+ mix?: number;
197
+ };
198
+ /** Waveshaper-based distortion using a `tanh` transfer curve. */
199
+ type DistortionEffect = {
200
+ type: "distortion";
201
+ /** Drive amount (higher = more distortion). @defaultValue `50` */
202
+ amount?: number;
203
+ /** @defaultValue `0.5` */
204
+ mix?: number;
205
+ };
206
+ /** Stereo chorus using two LFO-modulated delay lines. */
207
+ type ChorusEffect = {
208
+ type: "chorus";
209
+ /** LFO rate in Hz. @defaultValue `1.5` */
210
+ rate?: number;
211
+ /** LFO depth in seconds. @defaultValue `0.003` */
212
+ depth?: number;
213
+ /** @defaultValue `0.3` */
214
+ mix?: number;
215
+ };
216
+ /** Flanging effect via a short LFO-modulated delay with feedback. */
217
+ type FlangerEffect = {
218
+ type: "flanger";
219
+ /** LFO rate in Hz. @defaultValue `0.5` */
220
+ rate?: number;
221
+ /** LFO depth in seconds. @defaultValue `0.002` */
222
+ depth?: number;
223
+ /** Feedback gain (0 – 1). @defaultValue `0.5` */
224
+ feedback?: number;
225
+ /** @defaultValue `0.5` */
226
+ mix?: number;
227
+ };
228
+ /** Multi-stage allpass phaser with LFO sweep. */
229
+ type PhaserEffect = {
230
+ type: "phaser";
231
+ /** LFO rate in Hz. @defaultValue `0.5` */
232
+ rate?: number;
233
+ /** LFO depth in Hz. @defaultValue `1000` */
234
+ depth?: number;
235
+ /** Number of allpass stages. @defaultValue `4` */
236
+ stages?: number;
237
+ /** Feedback gain (0 – 1). @defaultValue `0.5` */
238
+ feedback?: number;
239
+ /** @defaultValue `0.5` */
240
+ mix?: number;
241
+ };
242
+ /** Amplitude modulation (volume tremolo). */
243
+ type TremoloEffect = {
244
+ type: "tremolo";
245
+ /** LFO rate in Hz. @defaultValue `4` */
246
+ rate?: number;
247
+ /** Modulation depth (0 – 1). @defaultValue `0.5` */
248
+ depth?: number;
249
+ };
250
+ /** Pitch vibrato via a short modulated delay line. */
251
+ type VibratoEffect = {
252
+ type: "vibrato";
253
+ /** LFO rate in Hz. @defaultValue `5` */
254
+ rate?: number;
255
+ /** LFO depth in seconds. @defaultValue `0.002` */
256
+ depth?: number;
257
+ };
258
+ /** Bit-depth reduction and optional sample-rate decimation. */
259
+ type BitcrusherEffect = {
260
+ type: "bitcrusher";
261
+ /** Bit depth. @defaultValue `8` */
262
+ bits?: number;
263
+ /** Sample rate reduction factor. @defaultValue `1` */
264
+ sampleRateReduction?: number;
265
+ /** @defaultValue `1` */
266
+ mix?: number;
267
+ };
268
+ /** Dynamics compressor wrapping the native `DynamicsCompressorNode`. */
269
+ type CompressorEffect = {
270
+ type: "compressor";
271
+ /** Threshold in dB. @defaultValue `-24` */
272
+ threshold?: number;
273
+ /** Knee width in dB. @defaultValue `30` */
274
+ knee?: number;
275
+ /** Compression ratio. @defaultValue `4` */
276
+ ratio?: number;
277
+ /** Attack time in seconds. @defaultValue `0.003` */
278
+ attack?: number;
279
+ /** Release time in seconds. @defaultValue `0.25` */
280
+ release?: number;
281
+ };
282
+ /** A single band in a parametric EQ. */
283
+ type EQBand = {
284
+ type: "lowshelf" | "highshelf" | "peaking";
285
+ /** Center or corner frequency in Hz. */
286
+ frequency: number;
287
+ /** Gain in dB. */
288
+ gain: number;
289
+ /** Q factor. @defaultValue `1` */
290
+ Q?: number;
291
+ };
292
+ /** Multi-band parametric equalizer built from chained `BiquadFilterNode`s. */
293
+ type EQEffect = {
294
+ type: "eq";
295
+ bands: EQBand[];
296
+ };
297
+ /** Simple gain stage. */
298
+ type GainEffect = {
299
+ type: "gain";
300
+ /** Linear gain value. */
301
+ value: number;
302
+ };
303
+ /** Stereo panner effect. */
304
+ type StereoPanEffect = {
305
+ type: "pan";
306
+ /** Pan position from -1 (full left) to 1 (full right). */
307
+ value: number;
308
+ };
309
+ /** Union of all effect types that can be applied to a {@link Layer} or globally. */
310
+ type Effect = ReverbEffect | ConvolverEffect | DelayEffect | DistortionEffect | ChorusEffect | FlangerEffect | PhaserEffect | TremoloEffect | VibratoEffect | BitcrusherEffect | CompressorEffect | EQEffect | GainEffect | StereoPanEffect;
311
+ /**
312
+ * A single audio layer combining a source, envelope, filter chain, effects,
313
+ * LFO modulation, and spatial positioning.
314
+ */
315
+ type Layer = {
316
+ /** The audio source that generates the signal. */
317
+ source: Source;
318
+ /** One or more filters applied before the envelope. */
319
+ filter?: Filter | Filter[];
320
+ /** Amplitude envelope (ADSR). Defaults to a short 0.5 s fade if omitted. */
321
+ envelope?: Envelope;
322
+ /** Output gain (0 – 1). @defaultValue `0.5` */
323
+ gain?: number;
324
+ /** Stereo pan (-1 left, 0 center, 1 right). */
325
+ pan?: number;
326
+ /** 3D spatialization config. Mutually exclusive with `pan`. */
327
+ panner?: Panner3D;
328
+ /** Start delay in seconds relative to the sound's trigger time. */
329
+ delay?: number;
330
+ /** One or more LFOs for periodic modulation. */
331
+ lfo?: LFO | LFO[];
332
+ /** Per-layer effects chain applied after the envelope. */
333
+ effects?: Effect[];
334
+ };
335
+ /** A sound built from multiple parallel {@link Layer}s with an optional global effects chain. */
336
+ type MultiLayerSound = {
337
+ layers: Layer[];
338
+ /** Effects applied to the summed output of all layers. */
339
+ effects?: Effect[];
340
+ };
341
+ /**
342
+ * Top-level sound definition: either a single {@link Layer} or a
343
+ * {@link MultiLayerSound} with multiple layers.
344
+ */
345
+ type SoundDefinition = Layer | MultiLayerSound;
346
+ /** Handle returned by the engine for stopping an in-flight voice. */
347
+ type VoiceHandle = {
348
+ /**
349
+ * Stops the voice with an optional fade-out.
350
+ *
351
+ * @param releaseTime - Fade-out duration in seconds. @defaultValue `0.015`
352
+ */
353
+ stop: (releaseTime?: number) => void;
354
+ };
355
+ /** Runtime overrides passed when triggering a sound. */
356
+ type PlayOptions = {
357
+ /** Volume multiplier (0 – 1). */
358
+ volume?: number;
359
+ /** Stereo pan override (-1 left, 0 center, 1 right). */
360
+ pan?: number;
361
+ /** Detune in cents, added to the source's existing detune. */
362
+ detune?: number;
363
+ /** Playback rate multiplier. */
364
+ playbackRate?: number;
365
+ /** Velocity sensitivity (0 – 1). Scales gain and can dim filter cutoffs. */
366
+ velocity?: number;
367
+ /**
368
+ * Per-voice random variation applied once on every trigger, so repeated
369
+ * plays of the same sound don't feel identical. Each field is the maximum
370
+ * symmetric offset (`±value`). Omitted fields are not jittered.
371
+ *
372
+ * @example
373
+ * ```ts
374
+ * // ±60 cents of pitch and ±10% volume on every click
375
+ * click({ jitter: { detune: 60, volume: 0.1 } });
376
+ * ```
377
+ */
378
+ jitter?: {
379
+ /** Random detune in cents, applied as ±value. E.g. `50` = ±50 cents. */
380
+ detune?: number;
381
+ /** Random volume multiplier, applied as ±value (0 – 1). E.g. `0.1` = ±10%. */
382
+ volume?: number;
383
+ /** Random playback rate offset, applied as ±value. E.g. `0.05` = ±5%. */
384
+ playbackRate?: number;
385
+ };
386
+ };
387
+ /** A single step in a {@link playSequence} timeline. */
388
+ type SequenceStep = {
389
+ /** A sound definition to render, or a pre-bound play function. */
390
+ sound: SoundDefinition | ((opts?: PlayOptions) => VoiceHandle | undefined);
391
+ /** Absolute time in seconds within the sequence. */
392
+ at?: number;
393
+ /** Relative offset in seconds from the previous step. */
394
+ wait?: number;
395
+ /** Per-step volume override. */
396
+ volume?: number;
397
+ };
398
+ /** Options for sequence playback. */
399
+ type SequenceOptions = {
400
+ /** Whether the sequence loops indefinitely. */
401
+ loop?: boolean;
402
+ /** Total loop duration in seconds (used when `loop` is true). */
403
+ duration?: number;
404
+ };
405
+ /** JSON-serializable patch containing named sound definitions. */
406
+ type SoundPatch = {
407
+ /** Optional JSON Schema reference for validation. */
408
+ $schema?: string;
409
+ /** Display name of the patch. */
410
+ name: string;
411
+ author?: string;
412
+ version?: string;
413
+ description?: string;
414
+ tags?: string[];
415
+ /** Map of sound names to their definitions. */
416
+ sounds: Record<string, SoundDefinition>;
417
+ };
418
+ /** Configuration for creating an {@link AudioAnalyser}. */
419
+ type AnalyserOptions = {
420
+ /** FFT window size (must be a power of 2). @defaultValue `2048` */
421
+ fftSize?: number;
422
+ /** Smoothing between consecutive frames (0 – 1). @defaultValue `0.8` */
423
+ smoothingTimeConstant?: number;
424
+ /** Minimum dB range for frequency data. */
425
+ minDecibels?: number;
426
+ /** Maximum dB range for frequency data. */
427
+ maxDecibels?: number;
428
+ };
429
+
430
+ /**
431
+ * Wrapper around the native `AnalyserNode` with pre-allocated typed arrays
432
+ * for zero-allocation reads in animation loops.
433
+ */
434
+ type AudioAnalyser = {
435
+ /** The underlying Web Audio `AnalyserNode`. */
436
+ node: AnalyserNode;
437
+ /** Returns byte-scaled frequency magnitudes (0 – 255). */
438
+ getFrequencyData: () => Uint8Array;
439
+ /** Returns byte-scaled time-domain waveform (0 – 255). */
440
+ getTimeDomainData: () => Uint8Array;
441
+ /** Returns frequency magnitudes in dB. */
442
+ getFloatFrequencyData: () => Float32Array;
443
+ /** Returns time-domain waveform as floats (-1 to 1). */
444
+ getFloatTimeDomainData: () => Float32Array;
445
+ /** Number of frequency bins (half of `fftSize`). */
446
+ frequencyBinCount: number;
447
+ /** Disconnects the analyser and releases resources. */
448
+ dispose: () => void;
449
+ };
450
+
451
+ /**
452
+ * A loaded sound patch with methods to play individual sounds by name.
453
+ *
454
+ * @example
455
+ * ```typescript
456
+ * const patch = await loadPatch("https://example.com/ui-sounds.json");
457
+ * patch.play("click");
458
+ * ```
459
+ */
460
+ type AudioPatch = {
461
+ /** `true` once the patch data has been loaded and parsed. */
462
+ ready: boolean;
463
+ name: string;
464
+ author?: string;
465
+ version?: string;
466
+ description?: string;
467
+ tags?: string[];
468
+ /** Names of all sounds contained in this patch. */
469
+ sounds: string[];
470
+ /**
471
+ * Plays a named sound from the patch.
472
+ *
473
+ * @param name - Sound name (must exist in {@link sounds})
474
+ * @param opts - Runtime overrides
475
+ * @throws {Error} If the sound name is not found in the patch
476
+ */
477
+ play: (name: string, opts?: PlayOptions) => VoiceHandle;
478
+ /** Returns the raw {@link SoundDefinition} for a named sound, or `undefined`. */
479
+ get: (name: string) => SoundDefinition | undefined;
480
+ /** Returns a deep-cloned copy of the underlying {@link SoundPatch} data. */
481
+ toJSON: () => SoundPatch;
482
+ };
483
+
484
+ /**
485
+ * Context provider that controls global sound state for all descendant hooks.
486
+ *
487
+ * Wrap your app (or a subtree) with `<SoundProvider>` to enable
488
+ * {@link useSound}, {@link useSequence}, and {@link usePatch} to respect
489
+ * a shared enabled/volume state.
490
+ *
491
+ * @param props.enabled - Whether sounds are allowed to play. @defaultValue `true`
492
+ * @param props.volume - Master volume multiplier (0 – 1). @defaultValue `1`
493
+ * @param props.onEnabledChange - Called when a child requests an enabled change
494
+ * @param props.onVolumeChange - Called when a child requests a volume change
495
+ *
496
+ * @example
497
+ * ```tsx
498
+ * <SoundProvider enabled={soundsOn} volume={0.8}>
499
+ * <App />
500
+ * </SoundProvider>
501
+ * ```
502
+ */
503
+ declare function SoundProvider({ children, enabled, volume, onEnabledChange, onVolumeChange, }: {
504
+ children: React.ReactNode;
505
+ enabled?: boolean;
506
+ volume?: number;
507
+ onEnabledChange?: (enabled: boolean) => void;
508
+ onVolumeChange?: (volume: number) => void;
509
+ }): react_jsx_runtime.JSX.Element;
510
+ /**
511
+ * Returns a stable callback that plays the given sound definition.
512
+ *
513
+ * Respects the nearest {@link SoundProvider}'s enabled/volume state and
514
+ * the user's `prefers-reduced-motion` preference. The callback reference
515
+ * never changes between renders (values are read from refs).
516
+ *
517
+ * @param definition - The sound to play
518
+ * @param opts - Default play options (can be overridden at call time)
519
+ * @returns A function that triggers the sound and returns a {@link VoiceHandle}, or `undefined` if muted
520
+ *
521
+ * @example
522
+ * ```tsx
523
+ * const play = useSound({
524
+ * source: { type: "sine", frequency: 440 },
525
+ * envelope: { decay: 0.1 },
526
+ * });
527
+ *
528
+ * <button onClick={play}>Beep</button>
529
+ * ```
530
+ */
531
+ declare function useSound(definition: SoundDefinition, opts?: PlayOptions): () => VoiceHandle | undefined;
532
+ /**
533
+ * Returns stable `play` and `stop` callbacks for a sound sequence.
534
+ *
535
+ * Calling `play()` starts the sequence; calling `stop()` halts it.
536
+ * Both callbacks are referentially stable across renders.
537
+ *
538
+ * @param steps - Ordered list of {@link SequenceStep}s
539
+ * @param options - Loop and duration settings
540
+ * @returns An object with `play` and `stop` functions
541
+ */
542
+ declare function useSequence(steps: SequenceStep[], options?: SequenceOptions): {
543
+ play: () => void;
544
+ stop: () => void;
545
+ };
546
+ /**
547
+ * Creates and returns an {@link AudioAnalyser} connected to the master bus.
548
+ *
549
+ * The analyser is initialized once (lazy state) and automatically disposed
550
+ * when the component unmounts.
551
+ *
552
+ * @param opts - FFT size, smoothing, and dB range overrides
553
+ */
554
+ declare function useAnalyser(opts?: AnalyserOptions): AudioAnalyser;
555
+ /**
556
+ * Loads a sound patch and returns a context-aware {@link AudioPatch}.
557
+ *
558
+ * The returned patch's `play()` method automatically respects the nearest
559
+ * {@link SoundProvider}'s enabled/volume state and reduced-motion preference.
560
+ * While the patch is loading, an empty no-op patch is returned (`ready: false`).
561
+ *
562
+ * @param source - URL string or in-memory {@link SoundPatch} object
563
+ * @returns An `AudioPatch` (initially empty until loaded)
564
+ *
565
+ * @example
566
+ * ```tsx
567
+ * const patch = usePatch("https://example.com/ui.json");
568
+ *
569
+ * <button onClick={() => patch.play("click")}>Click</button>
570
+ * ```
571
+ */
572
+ declare function usePatch(source: string | SoundPatch): AudioPatch;
573
+ /**
574
+ * Synchronizes the 3D audio listener with the given position and orientation.
575
+ *
576
+ * The effect only re-runs when individual primitive values change, not when
577
+ * the `listener` object reference changes.
578
+ *
579
+ * @param listener - Listener position and orientation
580
+ */
581
+ declare function useListener(listener: Listener): void;
582
+
583
+ export { SoundProvider, useAnalyser, useListener, usePatch, useSequence, useSound };