star-audio 0.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/LICENSE-3RD-PARTY.md +31 -0
- package/README.md +187 -0
- package/dist/index.d.cts +144 -0
- package/dist/index.d.ts +144 -0
- package/dist/index.js +3149 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +3134 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Third-Party Software Notices and Information
|
|
2
|
+
|
|
3
|
+
This package contains third-party software components governed by the licenses indicated below.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## howler.js
|
|
8
|
+
|
|
9
|
+
- **Website:** [https://howlerjs.com/](https://howlerjs.com/)
|
|
10
|
+
- **License:** MIT License
|
|
11
|
+
|
|
12
|
+
Copyright (c) 2013-2020 James Simpson and GoldFire Studios, Inc.
|
|
13
|
+
|
|
14
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
15
|
+
a copy of this software and associated documentation files (the
|
|
16
|
+
"Software"), to deal in the Software without restriction, including
|
|
17
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
18
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
19
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
20
|
+
the following conditions:
|
|
21
|
+
|
|
22
|
+
The above copyright notice and this permission notice shall be
|
|
23
|
+
included in all copies or substantial portions of the Software.
|
|
24
|
+
|
|
25
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
26
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
27
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
28
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
29
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
30
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
31
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# Star Audio
|
|
2
|
+
|
|
3
|
+
A simple sound manager for web games that "just works" on mobile.
|
|
4
|
+
|
|
5
|
+
`star-audio` solves the 90% use case for game audio: SFX playback and BGM crossfades, with a mobile-first design that handles browser audio unlocking automatically. It's designed to be predictable, easy to use, and LLM-friendly.
|
|
6
|
+
|
|
7
|
+
**Powered by the battle-tested [Howler.js](https://howlerjs.com/) core.**
|
|
8
|
+
|
|
9
|
+
This package is part of the **Star SDK**.
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- **Bulletproof:** Missing audio files won't crash your game - errors are logged but never thrown.
|
|
14
|
+
- **Mobile-Safe by Default:** Automatically handles audio context unlocking on user interaction. Plays sound even when the device's silent/ringer switch is on.
|
|
15
|
+
- **Tiny API Surface:** A small, guessable API (`play`, `music.crossfadeTo`, `setMute`). No try/catch needed.
|
|
16
|
+
- **Two-Bus Mixer:** Simple `music` and `sfx` groups for easy volume control.
|
|
17
|
+
- **Seamless Music Crossfades:** Built-in helpers for smooth background music transitions.
|
|
18
|
+
- **SSR-Safe:** Can be imported in server-side environments without errors.
|
|
19
|
+
- **Single Dependency:** Powered by Howler.js for maximum reliability.
|
|
20
|
+
|
|
21
|
+
## Install
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
yarn add star-audio
|
|
25
|
+
# or
|
|
26
|
+
npm install star-audio
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Quick Starts
|
|
30
|
+
|
|
31
|
+
### 1. Vanilla JS (60 seconds)
|
|
32
|
+
|
|
33
|
+
This is the fastest way to get started. Serve an `index.html` file and add the following.
|
|
34
|
+
|
|
35
|
+
```html
|
|
36
|
+
<div id="root" style="height:100vh; display: grid; place-items: center;">Tap anywhere</div>
|
|
37
|
+
<script type="module">
|
|
38
|
+
import createAudio from 'star-audio';
|
|
39
|
+
|
|
40
|
+
// Create an audio manager.
|
|
41
|
+
// 'auto' unlocks audio on the first user interaction.
|
|
42
|
+
// 'autostart' will play 'music.theme' once unlocked.
|
|
43
|
+
const audio = createAudio({
|
|
44
|
+
unlockWith: 'auto',
|
|
45
|
+
autostart: { id: 'music.theme', crossfadeSec: 1 }
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// Preload your audio assets.
|
|
49
|
+
await audio.preload({
|
|
50
|
+
'music.theme': ['/audio/theme.m4a', '/audio/theme.mp3'],
|
|
51
|
+
'sfx.tap': ['/audio/tap.mp3']
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// Play a sound effect on user interaction.
|
|
55
|
+
document.getElementById('root').addEventListener('pointerdown', () => {
|
|
56
|
+
audio.play('sfx.tap', { volume: 0.9 }); // alias: audio.playSound('sfx.tap')
|
|
57
|
+
});
|
|
58
|
+
</script>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 2. Next.js / React (Client Component)
|
|
62
|
+
|
|
63
|
+
In a React component, it's best to create the audio instance once with `useMemo`.
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
/* app/game/page.tsx */
|
|
67
|
+
"use client";
|
|
68
|
+
import { useEffect, useMemo } from 'react';
|
|
69
|
+
import { createStarAudio } from 'star-audio';
|
|
70
|
+
|
|
71
|
+
export default function Game() {
|
|
72
|
+
const audio = useMemo(() => createStarAudio({
|
|
73
|
+
unlockWith: 'auto',
|
|
74
|
+
autostart: { id: 'music.theme', crossfadeSec: 1 },
|
|
75
|
+
suspendOnHidden: true, // Pauses audio when tab is not visible
|
|
76
|
+
}), []);
|
|
77
|
+
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
// Preload assets when the component mounts.
|
|
80
|
+
(async () => {
|
|
81
|
+
await audio.preload({
|
|
82
|
+
'music.theme': ['/audio/theme.m4a', '/audio/theme.mp3'],
|
|
83
|
+
'sfx.tap': ['/audio/tap.mp3']
|
|
84
|
+
});
|
|
85
|
+
})();
|
|
86
|
+
|
|
87
|
+
// Clean up the audio instance when the component unmounts.
|
|
88
|
+
return () => audio.destroy();
|
|
89
|
+
}, [audio]);
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<div
|
|
93
|
+
className="h-screen w-screen"
|
|
94
|
+
onPointerDown={() => audio.play('sfx.tap', { volume: 0.9 })}
|
|
95
|
+
>
|
|
96
|
+
Tap to play
|
|
97
|
+
</div>
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Common Recipes
|
|
103
|
+
|
|
104
|
+
### Crossfade Background Music
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
await audio.preload({ 'bgm.title': ['/music/title.m4a'] });
|
|
108
|
+
|
|
109
|
+
// Fade from the current track (or silence) to the title music over 1.5 seconds.
|
|
110
|
+
await audio.music.crossfadeTo('bgm.title', { duration: 1.5 });
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Volumes & Mute
|
|
114
|
+
|
|
115
|
+
The volume and mute state are automatically persisted to `localStorage`.
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
// Set music volume to 60% with a 300ms fade.
|
|
119
|
+
audio.setMusicVolume(0.6, { durationMs: 300 });
|
|
120
|
+
|
|
121
|
+
// Set SFX volume to 80% instantly.
|
|
122
|
+
audio.setSfxVolume(0.8);
|
|
123
|
+
|
|
124
|
+
// Toggle mute for all audio.
|
|
125
|
+
audio.toggleMute();
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Pause/Resume (e.g., for a pause menu)
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
// Suspend the audio context.
|
|
132
|
+
await audio.pause();
|
|
133
|
+
|
|
134
|
+
// Resume the audio context.
|
|
135
|
+
await audio.resume();
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Limit SFX Overlap
|
|
139
|
+
|
|
140
|
+
To prevent audio clipping from too many overlapping sounds, you can limit the number of concurrent SFX voices.
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
// Only allow a maximum of 16 sound effects to play at once.
|
|
144
|
+
const audio = createAudio({ maxSfxVoices: 16 });
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Error Handling Philosophy
|
|
148
|
+
|
|
149
|
+
Star Audio is designed to **never crash your game**. All loading methods (`preload()`, `load()`) gracefully handle missing or corrupt audio files:
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
// ✅ This never throws - even if the file doesn't exist!
|
|
153
|
+
await audio.preload({
|
|
154
|
+
'sfx.coin': '/missing.mp3', // ⚠️ Logs warning, continues
|
|
155
|
+
'sfx.jump': '/audio/jump.mp3' // ✅ Loads successfully
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// Game continues working with the sounds that did load
|
|
159
|
+
audio.play('sfx.jump'); // ✅ Works
|
|
160
|
+
audio.play('sfx.coin'); // ⚠️ Silently fails (already warned during preload)
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**No try/catch needed.** Failed audio loads are logged to the console with clear warnings, but your game keeps running.
|
|
164
|
+
|
|
165
|
+
If you need programmatic error handling, listen to the `'error'` event:
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
audio.on('error', () => {
|
|
169
|
+
console.log('An audio file failed to load, but the game is still running!');
|
|
170
|
+
});
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Known Limitations
|
|
174
|
+
|
|
175
|
+
`star-audio` is designed to solve the 90% use case for web game audio. The current implementation (v1.x) has the following limitations:
|
|
176
|
+
|
|
177
|
+
- **No SFX voice limiting**: The `maxSfxVoices` option is accepted but not enforced. In practice, browsers limit concurrent audio to ~30-50 voices.
|
|
178
|
+
- **No micro-ducking**: Background music does not automatically reduce volume when sound effects play.
|
|
179
|
+
- **No volume ramping**: The `durationMs` parameter in `setMusicVolume()` and `setSfxVolume()` is accepted but ignored. Volume changes are instant.
|
|
180
|
+
- **No scheduled playback**: The `when`, `offset`, and `duration` parameters in `PlayOptions` are not currently implemented.
|
|
181
|
+
- **Pause/Resume behavior**: Only music is automatically resumed when calling `resume()` after `pause()`. Sound effects that were playing will not resume.
|
|
182
|
+
|
|
183
|
+
These limitations reflect the current Howler.js wrapper implementation. If you need any of these features, please open an issue on GitHub to help us prioritize future development.
|
|
184
|
+
|
|
185
|
+
## Acknowledgements
|
|
186
|
+
|
|
187
|
+
The reliability and robustness of `star-audio`, especially on mobile devices, is made possible by the fantastic work of the developers behind [Howler.js](https://howlerjs.com/). We use the Howler core to handle the complexities of cross-browser audio, allowing us to provide a simpler, game-focused API on top of a battle-tested foundation.
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Star Audio SDK version
|
|
3
|
+
*/
|
|
4
|
+
declare const VERSION = "0.1.0";
|
|
5
|
+
/**
|
|
6
|
+
* The possible states of the audio context.
|
|
7
|
+
* - `locked`: The audio context is waiting for a user gesture to start.
|
|
8
|
+
* - `running`: The audio context is active and playing sound.
|
|
9
|
+
* - `suspended`: The audio context is paused.
|
|
10
|
+
*/
|
|
11
|
+
type AudioState = 'locked' | 'running' | 'suspended';
|
|
12
|
+
/**
|
|
13
|
+
* Predefined procedural sound presets.
|
|
14
|
+
*/
|
|
15
|
+
type SynthPreset = 'beep' | 'coin' | 'pickup' | 'jump' | 'hurt' | 'explosion' | 'powerup' | 'shoot' | 'laser' | 'error' | 'click' | 'success' | 'bonus' | 'select' | 'unlock' | 'swoosh' | 'hit';
|
|
16
|
+
/**
|
|
17
|
+
* Custom procedural sound definition using Web Audio API oscillators.
|
|
18
|
+
*/
|
|
19
|
+
interface SynthDefinition {
|
|
20
|
+
waveform?: 'sine' | 'square' | 'sawtooth' | 'triangle';
|
|
21
|
+
frequency?: number | number[];
|
|
22
|
+
duration?: number;
|
|
23
|
+
volume?: number;
|
|
24
|
+
envelope?: 'percussive' | 'sustained';
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* A manifest of audio assets to load.
|
|
28
|
+
* The key is the asset ID, and the value can be:
|
|
29
|
+
* - A URL string (file-based audio)
|
|
30
|
+
* - An array of URLs (multiple formats)
|
|
31
|
+
* - A SynthPreset string (procedural preset sound)
|
|
32
|
+
* - A SynthDefinition object (custom procedural sound)
|
|
33
|
+
* - An object with `src`/`url`/`synth` and optional `group` properties
|
|
34
|
+
*/
|
|
35
|
+
type Manifest = Record<string, string | string[] | SynthPreset | SynthDefinition | {
|
|
36
|
+
src?: string | string[];
|
|
37
|
+
url?: string | string[];
|
|
38
|
+
synth?: SynthPreset | SynthDefinition;
|
|
39
|
+
group?: 'music' | 'sfx';
|
|
40
|
+
volume?: number;
|
|
41
|
+
}>;
|
|
42
|
+
/**
|
|
43
|
+
* Options for playing a sound.
|
|
44
|
+
*/
|
|
45
|
+
interface PlayOptions {
|
|
46
|
+
src?: string | string[];
|
|
47
|
+
url?: string | string[];
|
|
48
|
+
volume?: number;
|
|
49
|
+
loop?: boolean;
|
|
50
|
+
rate?: number;
|
|
51
|
+
detune?: number;
|
|
52
|
+
when?: number;
|
|
53
|
+
offset?: number;
|
|
54
|
+
duration?: number;
|
|
55
|
+
group?: 'music' | 'sfx';
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* A handle to a playing sound, allowing for control over its playback.
|
|
59
|
+
*/
|
|
60
|
+
interface SoundHandle {
|
|
61
|
+
id: string;
|
|
62
|
+
stop(at?: number): void;
|
|
63
|
+
setVolume(v: number, nowPlusSec?: number): void;
|
|
64
|
+
readonly playing: boolean;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Options for creating a StarAudio instance.
|
|
68
|
+
*/
|
|
69
|
+
interface StarAudioOptions {
|
|
70
|
+
unlockWith?: 'auto' | HTMLElement | Document | Window | false;
|
|
71
|
+
autostart?: string | {
|
|
72
|
+
id: string;
|
|
73
|
+
crossfadeSec?: number;
|
|
74
|
+
loop?: boolean;
|
|
75
|
+
};
|
|
76
|
+
autoplay?: StarAudioOptions['autostart'];
|
|
77
|
+
maxSfxVoices?: number;
|
|
78
|
+
initialMute?: boolean;
|
|
79
|
+
initialVolumes?: {
|
|
80
|
+
music?: number;
|
|
81
|
+
sfx?: number;
|
|
82
|
+
};
|
|
83
|
+
suspendOnHidden?: boolean;
|
|
84
|
+
persistKey?: string;
|
|
85
|
+
ducking?: boolean | {
|
|
86
|
+
amount?: number;
|
|
87
|
+
holdMs?: number;
|
|
88
|
+
releaseMs?: number;
|
|
89
|
+
};
|
|
90
|
+
latencyHint?: 'interactive' | 'balanced' | 'playback';
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* The main interface for the Star Audio manager.
|
|
94
|
+
*/
|
|
95
|
+
interface StarAudio {
|
|
96
|
+
readonly state: AudioState;
|
|
97
|
+
readonly ready: Promise<void>;
|
|
98
|
+
preload(m: Manifest): Promise<void>;
|
|
99
|
+
load(o: {
|
|
100
|
+
id: string;
|
|
101
|
+
src?: string | string[];
|
|
102
|
+
url?: string | string[];
|
|
103
|
+
group?: 'music' | 'sfx';
|
|
104
|
+
}): Promise<void>;
|
|
105
|
+
play(id: string, opts?: PlayOptions): SoundHandle | null;
|
|
106
|
+
playSound: StarAudio['play'];
|
|
107
|
+
music: {
|
|
108
|
+
crossfadeTo(id: string, o?: {
|
|
109
|
+
duration?: number;
|
|
110
|
+
loop?: boolean;
|
|
111
|
+
}): Promise<void>;
|
|
112
|
+
stop(fadeSec?: number): void;
|
|
113
|
+
fadeTo: StarAudio['music']['crossfadeTo'];
|
|
114
|
+
switchTo: StarAudio['music']['crossfadeTo'];
|
|
115
|
+
};
|
|
116
|
+
musicFadeTo: StarAudio['music']['crossfadeTo'];
|
|
117
|
+
setMusicVolume(v: number, o?: {
|
|
118
|
+
durationMs?: number;
|
|
119
|
+
}): void;
|
|
120
|
+
setSfxVolume(v: number, o?: {
|
|
121
|
+
durationMs?: number;
|
|
122
|
+
}): void;
|
|
123
|
+
setMusic: StarAudio['setMusicVolume'];
|
|
124
|
+
setSfx: StarAudio['setSfxVolume'];
|
|
125
|
+
setMute(muted: boolean): void;
|
|
126
|
+
mute: StarAudio['setMute'];
|
|
127
|
+
toggleMute(): void;
|
|
128
|
+
isMuted(): boolean;
|
|
129
|
+
pause(): Promise<void>;
|
|
130
|
+
resume(): Promise<void>;
|
|
131
|
+
unlock(): Promise<void>;
|
|
132
|
+
attachUnlock(target?: HTMLElement | Document | Window): void;
|
|
133
|
+
on(evt: 'unlocked' | 'suspended' | 'resumed' | 'error', cb: () => void): void;
|
|
134
|
+
off(evt: 'unlocked' | 'suspended' | 'resumed' | 'error', cb: () => void): void;
|
|
135
|
+
destroy(): void;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Creates a new StarAudio instance.
|
|
139
|
+
* @param opts - A set of options for configuring the audio manager.
|
|
140
|
+
* @returns A new `StarAudio` instance.
|
|
141
|
+
*/
|
|
142
|
+
declare function createStarAudio(opts?: StarAudioOptions): StarAudio;
|
|
143
|
+
|
|
144
|
+
export { type AudioState, type Manifest, type PlayOptions, type SoundHandle, type StarAudio, type StarAudioOptions, type SynthDefinition, type SynthPreset, VERSION, createStarAudio, createStarAudio as default };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Star Audio SDK version
|
|
3
|
+
*/
|
|
4
|
+
declare const VERSION = "0.1.0";
|
|
5
|
+
/**
|
|
6
|
+
* The possible states of the audio context.
|
|
7
|
+
* - `locked`: The audio context is waiting for a user gesture to start.
|
|
8
|
+
* - `running`: The audio context is active and playing sound.
|
|
9
|
+
* - `suspended`: The audio context is paused.
|
|
10
|
+
*/
|
|
11
|
+
type AudioState = 'locked' | 'running' | 'suspended';
|
|
12
|
+
/**
|
|
13
|
+
* Predefined procedural sound presets.
|
|
14
|
+
*/
|
|
15
|
+
type SynthPreset = 'beep' | 'coin' | 'pickup' | 'jump' | 'hurt' | 'explosion' | 'powerup' | 'shoot' | 'laser' | 'error' | 'click' | 'success' | 'bonus' | 'select' | 'unlock' | 'swoosh' | 'hit';
|
|
16
|
+
/**
|
|
17
|
+
* Custom procedural sound definition using Web Audio API oscillators.
|
|
18
|
+
*/
|
|
19
|
+
interface SynthDefinition {
|
|
20
|
+
waveform?: 'sine' | 'square' | 'sawtooth' | 'triangle';
|
|
21
|
+
frequency?: number | number[];
|
|
22
|
+
duration?: number;
|
|
23
|
+
volume?: number;
|
|
24
|
+
envelope?: 'percussive' | 'sustained';
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* A manifest of audio assets to load.
|
|
28
|
+
* The key is the asset ID, and the value can be:
|
|
29
|
+
* - A URL string (file-based audio)
|
|
30
|
+
* - An array of URLs (multiple formats)
|
|
31
|
+
* - A SynthPreset string (procedural preset sound)
|
|
32
|
+
* - A SynthDefinition object (custom procedural sound)
|
|
33
|
+
* - An object with `src`/`url`/`synth` and optional `group` properties
|
|
34
|
+
*/
|
|
35
|
+
type Manifest = Record<string, string | string[] | SynthPreset | SynthDefinition | {
|
|
36
|
+
src?: string | string[];
|
|
37
|
+
url?: string | string[];
|
|
38
|
+
synth?: SynthPreset | SynthDefinition;
|
|
39
|
+
group?: 'music' | 'sfx';
|
|
40
|
+
volume?: number;
|
|
41
|
+
}>;
|
|
42
|
+
/**
|
|
43
|
+
* Options for playing a sound.
|
|
44
|
+
*/
|
|
45
|
+
interface PlayOptions {
|
|
46
|
+
src?: string | string[];
|
|
47
|
+
url?: string | string[];
|
|
48
|
+
volume?: number;
|
|
49
|
+
loop?: boolean;
|
|
50
|
+
rate?: number;
|
|
51
|
+
detune?: number;
|
|
52
|
+
when?: number;
|
|
53
|
+
offset?: number;
|
|
54
|
+
duration?: number;
|
|
55
|
+
group?: 'music' | 'sfx';
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* A handle to a playing sound, allowing for control over its playback.
|
|
59
|
+
*/
|
|
60
|
+
interface SoundHandle {
|
|
61
|
+
id: string;
|
|
62
|
+
stop(at?: number): void;
|
|
63
|
+
setVolume(v: number, nowPlusSec?: number): void;
|
|
64
|
+
readonly playing: boolean;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Options for creating a StarAudio instance.
|
|
68
|
+
*/
|
|
69
|
+
interface StarAudioOptions {
|
|
70
|
+
unlockWith?: 'auto' | HTMLElement | Document | Window | false;
|
|
71
|
+
autostart?: string | {
|
|
72
|
+
id: string;
|
|
73
|
+
crossfadeSec?: number;
|
|
74
|
+
loop?: boolean;
|
|
75
|
+
};
|
|
76
|
+
autoplay?: StarAudioOptions['autostart'];
|
|
77
|
+
maxSfxVoices?: number;
|
|
78
|
+
initialMute?: boolean;
|
|
79
|
+
initialVolumes?: {
|
|
80
|
+
music?: number;
|
|
81
|
+
sfx?: number;
|
|
82
|
+
};
|
|
83
|
+
suspendOnHidden?: boolean;
|
|
84
|
+
persistKey?: string;
|
|
85
|
+
ducking?: boolean | {
|
|
86
|
+
amount?: number;
|
|
87
|
+
holdMs?: number;
|
|
88
|
+
releaseMs?: number;
|
|
89
|
+
};
|
|
90
|
+
latencyHint?: 'interactive' | 'balanced' | 'playback';
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* The main interface for the Star Audio manager.
|
|
94
|
+
*/
|
|
95
|
+
interface StarAudio {
|
|
96
|
+
readonly state: AudioState;
|
|
97
|
+
readonly ready: Promise<void>;
|
|
98
|
+
preload(m: Manifest): Promise<void>;
|
|
99
|
+
load(o: {
|
|
100
|
+
id: string;
|
|
101
|
+
src?: string | string[];
|
|
102
|
+
url?: string | string[];
|
|
103
|
+
group?: 'music' | 'sfx';
|
|
104
|
+
}): Promise<void>;
|
|
105
|
+
play(id: string, opts?: PlayOptions): SoundHandle | null;
|
|
106
|
+
playSound: StarAudio['play'];
|
|
107
|
+
music: {
|
|
108
|
+
crossfadeTo(id: string, o?: {
|
|
109
|
+
duration?: number;
|
|
110
|
+
loop?: boolean;
|
|
111
|
+
}): Promise<void>;
|
|
112
|
+
stop(fadeSec?: number): void;
|
|
113
|
+
fadeTo: StarAudio['music']['crossfadeTo'];
|
|
114
|
+
switchTo: StarAudio['music']['crossfadeTo'];
|
|
115
|
+
};
|
|
116
|
+
musicFadeTo: StarAudio['music']['crossfadeTo'];
|
|
117
|
+
setMusicVolume(v: number, o?: {
|
|
118
|
+
durationMs?: number;
|
|
119
|
+
}): void;
|
|
120
|
+
setSfxVolume(v: number, o?: {
|
|
121
|
+
durationMs?: number;
|
|
122
|
+
}): void;
|
|
123
|
+
setMusic: StarAudio['setMusicVolume'];
|
|
124
|
+
setSfx: StarAudio['setSfxVolume'];
|
|
125
|
+
setMute(muted: boolean): void;
|
|
126
|
+
mute: StarAudio['setMute'];
|
|
127
|
+
toggleMute(): void;
|
|
128
|
+
isMuted(): boolean;
|
|
129
|
+
pause(): Promise<void>;
|
|
130
|
+
resume(): Promise<void>;
|
|
131
|
+
unlock(): Promise<void>;
|
|
132
|
+
attachUnlock(target?: HTMLElement | Document | Window): void;
|
|
133
|
+
on(evt: 'unlocked' | 'suspended' | 'resumed' | 'error', cb: () => void): void;
|
|
134
|
+
off(evt: 'unlocked' | 'suspended' | 'resumed' | 'error', cb: () => void): void;
|
|
135
|
+
destroy(): void;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Creates a new StarAudio instance.
|
|
139
|
+
* @param opts - A set of options for configuring the audio manager.
|
|
140
|
+
* @returns A new `StarAudio` instance.
|
|
141
|
+
*/
|
|
142
|
+
declare function createStarAudio(opts?: StarAudioOptions): StarAudio;
|
|
143
|
+
|
|
144
|
+
export { type AudioState, type Manifest, type PlayOptions, type SoundHandle, type StarAudio, type StarAudioOptions, type SynthDefinition, type SynthPreset, VERSION, createStarAudio, createStarAudio as default };
|