audiobits 0.1.2 → 0.1.4
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/CHANGELOG.md +13 -0
- package/README.md +32 -295
- package/dist/capabilities.json +1 -1
- package/package.json +10 -1
- package/skill/SKILL.md +10 -4
- package/skill/references/controls.md +4 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# audiobits
|
|
2
2
|
|
|
3
|
+
## 0.1.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 5340645: Simplify the package README to a tested quick start and direct detailed guidance to the website docs. Clarify installed-version authority in the shipped integration Skill.
|
|
8
|
+
|
|
9
|
+
## 0.1.3
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 7aa39bd: Align the package README with published capabilities and add the public website
|
|
14
|
+
and relevant npm keywords to package metadata. Runtime behavior is unchanged.
|
|
15
|
+
|
|
3
16
|
## 0.1.2
|
|
4
17
|
|
|
5
18
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
# AudioBits
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
Browser-native procedural sound for games and interactive applications. Play
|
|
4
|
+
bundled sounds or build editable JSON recipes without downloaded audio assets
|
|
5
|
+
or runtime dependencies.
|
|
6
|
+
|
|
7
|
+
[Live gallery](https://audiobits.joacod.com/sounds) ·
|
|
8
|
+
[Documentation](https://audiobits.joacod.com/docs)
|
|
9
9
|
|
|
10
10
|
## Quick start
|
|
11
11
|
|
|
12
|
+
Install in a browser application with a bundler:
|
|
13
|
+
|
|
12
14
|
```sh
|
|
13
15
|
npm install audiobits
|
|
14
16
|
```
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
directly in that handler and await it before playback.
|
|
18
|
+
Create the engine and sound once. Construction is silent; call `play()` directly
|
|
19
|
+
from a user gesture, such as a button click. It awaits activation before playback.
|
|
19
20
|
|
|
20
21
|
```ts
|
|
21
22
|
import { createAudio } from "audiobits";
|
|
@@ -24,305 +25,41 @@ import { confirmation } from "audiobits/recipes";
|
|
|
24
25
|
const audio = createAudio();
|
|
25
26
|
const sound = audio.sound(confirmation);
|
|
26
27
|
|
|
27
|
-
await audio.start();
|
|
28
|
-
sound.play();
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
Surface activation failures and retry from a fresh gesture. Use
|
|
32
|
-
`audio.stopAll({ tails: "cut" })` to stop playback and `await audio.dispose()`
|
|
33
|
-
when the host is removed. See the production lifecycle example below for
|
|
34
|
-
hiding and navigation.
|
|
35
|
-
|
|
36
|
-
## Production lifecycle
|
|
37
|
-
|
|
38
|
-
For an SPA, invalidate pending activation when hiding or unmounting; suspend on
|
|
39
|
-
hide and dispose on navigation. Returning requires a fresh Play gesture.
|
|
40
|
-
|
|
41
|
-
```ts
|
|
42
|
-
import { createAudio } from "audiobits";
|
|
43
|
-
import { confirmation } from "audiobits/recipes";
|
|
44
|
-
const audio = createAudio();
|
|
45
|
-
const sound = audio.sound(confirmation);
|
|
46
|
-
let request = 0;
|
|
47
28
|
export async function play() {
|
|
48
|
-
const token = ++request;
|
|
49
29
|
await audio.start();
|
|
50
|
-
|
|
30
|
+
sound.play();
|
|
51
31
|
}
|
|
52
32
|
export function stop() {
|
|
53
|
-
request++;
|
|
54
33
|
audio.stopAll({ tails: "cut" });
|
|
55
34
|
}
|
|
56
|
-
function hide() {
|
|
57
|
-
if (document.hidden) {
|
|
58
|
-
stop();
|
|
59
|
-
void audio.suspend().catch(console.error);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
document.addEventListener("visibilitychange", hide);
|
|
63
35
|
export async function dispose() {
|
|
64
|
-
stop();
|
|
65
|
-
document.removeEventListener("visibilitychange", hide);
|
|
66
36
|
await audio.dispose();
|
|
67
37
|
}
|
|
68
38
|
```
|
|
69
39
|
|
|
70
|
-
`
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
The archive exports `audiobits/schema.json` and `audiobits/capabilities.json`.
|
|
76
|
-
The latter identifies package version, shipped primitives, initial Chromium gate and verification browser matrix;
|
|
77
|
-
the schema is structural, while `validateRecipe` enforces additional semantic
|
|
78
|
-
limits. Agent guidance is included in [the AudioBits Skill](skill/SKILL.md).
|
|
79
|
-
|
|
80
|
-
## Supported data
|
|
81
|
-
|
|
82
|
-
`defineSound(recipe)` accepts typed authored data, preserves recipe structure, literal parameter names and modes, validates and returns a deeply frozen `Recipe` snapshot.
|
|
83
|
-
Runtime validation remains authoritative for exact schema validity.
|
|
84
|
-
For external JSON, `validateRecipe(unknown)` returns `{ ok: true, recipe }` or
|
|
85
|
-
`{ ok: false, issues }`; every issue has `code`, `path`, and `message`.
|
|
86
|
-
Paths use JSON bracket notation, such as `$["layers"][0]["id"]`.
|
|
87
|
-
`AudioBitsError` carries `code` and `issues`; errors during validation use
|
|
88
|
-
`invalid-recipe`. The input must be plain JSON data without accessors or cycles.
|
|
89
|
-
Unknown fields and versions are rejected. Validation is browser-independent.
|
|
90
|
-
|
|
91
|
-
Schema version 1 supports:
|
|
92
|
-
|
|
93
|
-
- One-shot gates in `(0, 60]` seconds or sustained playback until Stop, with
|
|
94
|
-
1–16 uniquely identified layers. Sustained recipes forbid `duration`.
|
|
95
|
-
- Sine, triangle, sawtooth, and square oscillators; numeric Hz or linear/
|
|
96
|
-
exponential frequency automation beginning at zero and ending by gate close
|
|
97
|
-
(at most 60 seconds of onset automation for sustained voices). White noise
|
|
98
|
-
uses bounded generated buffers; there is no audio-file fetch.
|
|
99
|
-
- Layer gain from -60 to 0 dB and fixed ADSR envelopes. Attack/decay are 0–10 s,
|
|
100
|
-
sustain is 0–1, release is 0.005–10 s. Effective attack is at least 0.002 s;
|
|
101
|
-
effective attack plus decay must fit within the gate. A zero decay ramps
|
|
102
|
-
directly to sustain rather than introducing an instantaneous peak.
|
|
103
|
-
- Lowpass/highpass/bandpass filters with frequency 20–20000 Hz and numeric
|
|
104
|
-
Q 0.1–20. At most eight filters and 128 frequency points across the recipe.
|
|
105
|
-
- Source/filter frequencies accept numeric values, mappings, variation, or
|
|
106
|
-
automation. Layer gain accepts numeric values, mappings, or variation;
|
|
107
|
-
gain automation and variable envelope times are not supported.
|
|
108
|
-
- Up to 16 named parameters with `min < max`, an in-range `default`, and `mode`
|
|
109
|
-
of `play` or `live`. Live parameters require `smoothing` in 0.005–1 seconds.
|
|
110
|
-
Names begin with an ASCII letter and contain letters, digits or underscores,
|
|
111
|
-
up to 64 characters. Declaration numbers are bounded to -60000–60000.
|
|
112
|
-
|
|
113
|
-
Depth is limited to 16, visited values to 10000, and diagnostics to 100.
|
|
114
|
-
Source/filter frequencies must be below the owning context's Nyquist frequency
|
|
115
|
-
at playback, including all mapping/variation extrema. Other effects,
|
|
116
|
-
expression strings, sequencing, and continuous random modulation are rejected. These are the capabilities shipped in 0.1.0.
|
|
117
|
-
The generated schema is available as `recipeSchema` or `audiobits/schema.json`.
|
|
118
|
-
|
|
119
|
-
## Runtime ownership
|
|
120
|
-
|
|
121
|
-
`createAudio({ maxVoices, maxVoicesPerSound, masterGainDb })` defaults to
|
|
122
|
-
32 active voices per engine, eight per sound, and -12 dB master gain. Limits
|
|
123
|
-
must be integers from 1–128; master gain must be -60–0 dB. `setMuted(boolean)`
|
|
124
|
-
uses a separate mute setting and a 5 ms gain ramp.
|
|
125
|
-
|
|
126
|
-
`sound.play({ at, gainDb, pan, parameters, seed, bus })` creates fresh sources synchronously. `at` is
|
|
127
|
-
absolute audio-context time, obtained by the host's own scheduling logic;
|
|
128
|
-
available after startup as `audio.native.context.currentTime`. Omit it for
|
|
129
|
-
immediate playback. Past timestamps are rejected. Playback gain is -60–0 dB
|
|
130
|
-
(default 0), pan is -1–1 (default 0). Future voices reserve capacity.
|
|
131
|
-
|
|
132
|
-
`voice.stop()` cancels before onset or releases from the current envelope value.
|
|
133
|
-
Repeated stops cannot extend lifetime. `voice.ended` resolves after owned nodes
|
|
134
|
-
are disconnected; `voice.state` is `active`, `stopping`, `retiring`, or `ended`.
|
|
135
|
-
Stopping voices keep their capacity reservation until cleanup. Oldest-voice
|
|
136
|
-
stealing uses a 5 ms output fade. There is at most one retiring voice beyond
|
|
137
|
-
engine/per-sound limits; another steal finalizes the previous retiree first.
|
|
138
|
-
`audio.counts` distinguishes reserved active/stopping voices from retirees.
|
|
139
|
-
|
|
140
|
-
Gate duration excludes release. Filters receive a bounded 50 ms tail allowance;
|
|
141
|
-
output fades to zero over the final 5 ms. Layer filters precede their envelopes.
|
|
142
|
-
`stopAll()` releases managed voices according to their recipe envelopes.
|
|
143
|
-
`stopAll({ tails: "cut" })` uses a 5 ms source/output fade. `sound.dispose()` immediately finalizes
|
|
144
|
-
that sound's voices and noise buffers. `audio.suspend()` invalidates pending starts and finalizes all voices before suspending.
|
|
145
|
-
Native suspension/interruption also finalizes voices when its state event arrives.
|
|
146
|
-
`audio.dispose()` invalidates pending startup, finalizes voices immediately,
|
|
147
|
-
disconnects master output, and closes the context once, even while suspended.
|
|
148
|
-
Disposal is terminal and idempotent; no audio-clock progress is needed.
|
|
149
|
-
|
|
150
|
-
`audio.state` reports `idle`, `starting`, `running`, `suspended`, `interrupted`,
|
|
151
|
-
`closed`, or `disposed`. `subscribe(listener)` returns an unsubscribe function.
|
|
152
|
-
Concurrent starts share one promise. A host controls visibility/navigation policy;
|
|
153
|
-
the engine does not replay sounds or automatically resume them.
|
|
154
|
-
|
|
155
|
-
Recipes contain no native nodes, callbacks, framework imports, or runtime
|
|
156
|
-
dependencies. Only `audiobits/recipes` imports curated sound data.
|
|
157
|
-
Default headroom checks do not guarantee safe peaks for arbitrary recipes,
|
|
158
|
-
filter resonance, gains, or concurrency.
|
|
159
|
-
|
|
160
|
-
## Dynamic controls and replay
|
|
161
|
-
|
|
162
|
-
```ts
|
|
163
|
-
import { createAudio } from "audiobits";
|
|
164
|
-
import { impact, thruster } from "audiobits/recipes";
|
|
165
|
-
|
|
166
|
-
const audio = createAudio();
|
|
167
|
-
const hit = audio.sound(impact);
|
|
168
|
-
const engine = audio.sound(thruster);
|
|
169
|
-
|
|
170
|
-
// In a user gesture, await activation before creating voices.
|
|
171
|
-
await audio.start();
|
|
172
|
-
hit.play({ parameters: { intensity: 0.8 }, seed: 42 });
|
|
173
|
-
const voice = engine.play({ parameters: { throttle: 0.2 }, seed: 42 });
|
|
174
|
-
voice.set({ throttle: 1 }); // Update this voice without retriggering.
|
|
175
|
-
console.log(voice.seed, voice.parameters);
|
|
176
|
-
voice.stop();
|
|
177
|
-
await voice.ended;
|
|
178
|
-
await audio.dispose();
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
Omitted parameters use recipe defaults. Invalid names, non-finite values,
|
|
182
|
-
out-of-range controls, and invalid seeds fail before graph allocation or voice
|
|
183
|
-
stealing. Updates validate every supplied key before changing any parameter;
|
|
184
|
-
play-only controls cannot be updated. `voice.parameters` is a frozen snapshot of
|
|
185
|
-
requested values, not a readback of the current smoothed native parameters.
|
|
186
|
-
`voice.set()` after Stop, retirement, completion, or disposal throws
|
|
187
|
-
`ended-voice`; other control errors use `invalid-control`.
|
|
188
|
-
|
|
189
|
-
Mappings use `{ control, range: [low, high], scale }`, where scale is `linear`
|
|
190
|
-
or `exponential`. Exponential mapping endpoints must be positive. Mapping ranges
|
|
191
|
-
may descend; random ranges `{ random: [low, high] }` must be ordered. All extrema
|
|
192
|
-
must satisfy the target range. Automation points can reference only play-only
|
|
193
|
-
controls. Direct live mappings support source frequency, layer gain, and filter
|
|
194
|
-
frequency. Native targets ramp linearly over the parameter's smoothing time,
|
|
195
|
-
from their current value on every retarget. For gain, that ramp is in linear
|
|
196
|
-
amplitude after dB conversion; mapping scale describes the control-to-target
|
|
197
|
-
conversion, not the ramp curve. Envelopes remain fixed and independent of live
|
|
198
|
-
level controls, so release remains continuous.
|
|
199
|
-
|
|
200
|
-
Seeds are unsigned 32-bit integers, including zero. Without one, playback chooses
|
|
201
|
-
a seed and exposes it on `voice.seed`. xorshift32 uses shifts 13/17/5 and divides
|
|
202
|
-
its unsigned state by 2^32; seed zero maps internally to `0x6d2b79f5`. Resolution
|
|
203
|
-
traverses root effects, then layers in array order. Each layer resolves gain,
|
|
204
|
-
layer filters, source frequency, and a noise seed, in that order; automation
|
|
205
|
-
points follow time order. Each variation consumes one draw, and each noise layer
|
|
206
|
-
consumes one draw for its own xorshift32 stream. Object property insertion order
|
|
207
|
-
does not change this traversal. This algorithm reproduces choices and
|
|
208
|
-
noise for the same normalized recipe, controls, seed and sample rate; it does not
|
|
209
|
-
promise identical oscillator/filter samples across browsers or sample rates.
|
|
210
|
-
|
|
211
|
-
## Noise ownership and bounds
|
|
212
|
-
|
|
213
|
-
Each noise layer owns one mono, one-second buffer at context sample rate. The
|
|
214
|
-
last 20 ms crossfades into the first 20 ms; looping resumes after that prefix,
|
|
215
|
-
so the wrap follows an ordinary adjacent sample pair. The loop period is about
|
|
216
|
-
0.98 seconds. Both finite and sustained noise loop this bounded resource.
|
|
217
|
-
This treatment has signal evidence and maintainer listening acceptance;
|
|
218
|
-
individual listening observations were not recorded. There is no shared noise cache or rendered-output cache.
|
|
219
|
-
|
|
220
|
-
Noise supports integer sample rates from 8000 through 192000 Hz. Unsupported
|
|
221
|
-
rates fail with `noise-rate` before voice allocation. A layer retains at most
|
|
222
|
-
768000 sample bytes (192000 at 48 kHz); generation temporarily uses one extra
|
|
223
|
-
buffer of that size. A recipe has at most 16 layers, and existing voice limits
|
|
224
|
-
bound concurrent buffers. The thruster owns ten nodes and one buffer per voice;
|
|
225
|
-
with its default eight-voice limit plus one retiree, sample storage is at most
|
|
226
|
-
1728000 bytes at 48 kHz. The engine master owns two additional nodes for independent gain and mute. These are
|
|
227
|
-
owned sample-storage bounds, not measurements of all browser memory.
|
|
228
|
-
|
|
229
|
-
Control updates allocate no new audio nodes or buffers. Finishing a voice clears
|
|
230
|
-
its buffer-source references and disconnects owned nodes, including cancellation
|
|
231
|
-
before onset, stealing, sound disposal, and engine teardown. Browser-internal
|
|
232
|
-
reclamation timing remains outside the library's control.
|
|
233
|
-
|
|
234
|
-
## Buses and routing
|
|
235
|
-
|
|
236
|
-
After `await audio.start()`, `audio.master` is the root bus. `audio.bus(name,
|
|
237
|
-
parent = audio.master)` creates a named bus or reuses the live bus with that
|
|
238
|
-
name; use `setParent()` to move an existing bus. Names contain 1–64 characters
|
|
239
|
-
and cannot be blank. At most 32 buses, including master, may be live. Routes
|
|
240
|
-
form a single-parent tree; invalid, disposed, foreign-engine, and cyclic
|
|
241
|
-
parents fail before changing the previous connection. Reassigning the same
|
|
242
|
-
parent does not create another route. `sound.play({ bus })` defaults to master
|
|
243
|
-
and rejects foreign/disposed buses before voice allocation or stealing.
|
|
244
|
-
|
|
245
|
-
`bus.setGainDb(value, rampSeconds = 0.005)` accepts -60–0 dB and 0–10 seconds.
|
|
246
|
-
It holds the current native value before ramping. `bus.setMuted(boolean)` uses
|
|
247
|
-
an independent 5 ms stage, preserving volume automation. `audio.setMuted()`
|
|
248
|
-
controls master mute, including a setting made before startup.
|
|
249
|
-
|
|
250
|
-
```ts
|
|
251
|
-
import { createAudio } from "audiobits";
|
|
252
|
-
import { confirmation } from "audiobits/recipes";
|
|
253
|
-
const audio = createAudio();
|
|
254
|
-
const sound = audio.sound(confirmation);
|
|
255
|
-
// In a gesture handler, after activating this engine:
|
|
256
|
-
await audio.start();
|
|
257
|
-
const effects = audio.bus("effects");
|
|
258
|
-
effects.setGainDb(-6, 0.1);
|
|
259
|
-
const voice = sound.play({ bus: effects });
|
|
260
|
-
voice.stop(); // Release this voice.
|
|
261
|
-
audio.stopAll({ tails: "cut" }); // Fade managed voices over 5 ms.
|
|
262
|
-
effects.dispose(); // Finalize routed voices and descendant buses.
|
|
263
|
-
await audio.dispose();
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
Each bus owns two gain nodes. Suspension and disposal finalize voices
|
|
267
|
-
without waiting for audio-clock progress.
|
|
268
|
-
|
|
269
|
-
Non-master bus disposal is idempotent and stops routed voices recursively.
|
|
270
|
-
A later lookup of that name creates a fresh bus. `master.dispose()` fails;
|
|
271
|
-
dispose the engine to release master. Engine disposal removes all owned
|
|
272
|
-
output and closes its context, even while suspended or starting.
|
|
273
|
-
|
|
274
|
-
## Native analyser and caller ownership
|
|
275
|
-
|
|
276
|
-
`audio.native` is available after startup and exposes the owned `context`,
|
|
277
|
-
master `output`, and `connect(node)` tap helper. The helper rejects foreign
|
|
278
|
-
contexts, duplicate taps, the output itself, and the context destination.
|
|
279
|
-
It returns an idempotent detach function. Master already connects to the
|
|
280
|
-
speaker destination. Leave an analyser's output unconnected to avoid a second
|
|
281
|
-
audible path. The vanilla example reads peak levels with a host animation
|
|
282
|
-
frame, cancels that frame, detaches the tap, and disconnects its analyser
|
|
283
|
-
before engine teardown.
|
|
284
|
-
|
|
285
|
-
```ts
|
|
286
|
-
import { createAudio } from "audiobits";
|
|
287
|
-
const audio = createAudio();
|
|
288
|
-
// Execute in a gesture handler.
|
|
289
|
-
await audio.start();
|
|
290
|
-
const native = audio.native;
|
|
291
|
-
const analyser = native.context.createAnalyser();
|
|
292
|
-
const detach = native.connect(analyser);
|
|
293
|
-
const samples = new Float32Array(analyser.fftSize);
|
|
294
|
-
analyser.getFloatTimeDomainData(samples);
|
|
295
|
-
// Host teardown:
|
|
296
|
-
detach();
|
|
297
|
-
analyser.disconnect();
|
|
298
|
-
await audio.dispose();
|
|
299
|
-
```
|
|
40
|
+
Surface rejected activation, for example `void play().catch(console.error)`, and
|
|
41
|
+
retry from a fresh gesture. Bind `stop()` to Stop and await `dispose()` when the
|
|
42
|
+
host is removed. For pending activation, page hiding, and navigation, follow the
|
|
43
|
+
[lifecycle guide](https://audiobits.joacod.com/docs/lifecycle).
|
|
300
44
|
|
|
301
|
-
|
|
302
|
-
caller-owned. Stop unmanaged sources explicitly: `stopAll()` cannot stop them.
|
|
303
|
-
Direct native graph operations remain the caller's responsibility and cannot
|
|
304
|
-
be serialized as recipes. Closing the engine context invalidates these native
|
|
305
|
-
nodes; retained native handles do not transfer ownership back to the engine.
|
|
45
|
+
## Sounds and controls
|
|
306
46
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
native recovery is suspended until a fresh `start()` request. Physical OS
|
|
312
|
-
interruption still requires manual evidence. Step 04 passed maintainer manual
|
|
313
|
-
verification on 2026-10-06. Browser/device details and individual observations
|
|
314
|
-
were not supplied; automated checks remain separate from that acceptance.
|
|
47
|
+
Eight bundled sounds are available from `audiobits/recipes`: confirmation, impact,
|
|
48
|
+
thruster, tactile click, gentle rejection, glass notification, whoosh, and power-up.
|
|
49
|
+
Use [custom JSON recipes](https://audiobits.joacod.com/docs/recipes) with
|
|
50
|
+
`defineSound()` for typed authoring or `validateRecipe()` for external data.
|
|
315
51
|
|
|
316
|
-
|
|
317
|
-
|
|
52
|
+
[Parameters and seeds](https://audiobits.joacod.com/docs/parameters) vary playback
|
|
53
|
+
and update live controls. [Buses](https://audiobits.joacod.com/docs/buses) provide
|
|
54
|
+
gain, mute, and routing; [native taps](https://audiobits.joacod.com/docs/native)
|
|
55
|
+
connect caller-owned analysers and nodes.
|
|
318
56
|
|
|
319
|
-
|
|
57
|
+
The [API reference](https://audiobits.joacod.com/docs/api) explains public options
|
|
58
|
+
and limits. Exported types, `audiobits/schema.json`, and
|
|
59
|
+
`audiobits/capabilities.json` describe the installed package; semantic validation
|
|
60
|
+
still requires `validateRecipe()`. Integration guidance also ships in the
|
|
61
|
+
[AudioBits Skill](skill/SKILL.md).
|
|
320
62
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
controls whoosh; throttle is live on thruster. Other sounds have no parameters.
|
|
325
|
-
New sound definitions use only schema-1 sources, filters and envelopes. Their
|
|
326
|
-
signal and resource properties are tested; the current eight curated sounds have
|
|
327
|
-
passed the maintainer listening gate in Chrome. Output devices and detailed
|
|
328
|
-
listening coverage were not specified.
|
|
63
|
+
Current Chromium is the only automated browser verification target. Other
|
|
64
|
+
browsers and operating systems are unverified. Automated checks do not establish
|
|
65
|
+
subjective listening quality or physical-device compatibility.
|
package/dist/capabilities.json
CHANGED
package/package.json
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "audiobits",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Procedural browser audio: versioned recipes, live controls, managed voices and buses.",
|
|
5
5
|
"license": "MIT",
|
|
6
|
+
"homepage": "https://audiobits.joacod.com/",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"web-audio",
|
|
9
|
+
"procedural-audio",
|
|
10
|
+
"sound-effects",
|
|
11
|
+
"sfx",
|
|
12
|
+
"game-audio",
|
|
13
|
+
"typescript"
|
|
14
|
+
],
|
|
6
15
|
"repository": {
|
|
7
16
|
"type": "git",
|
|
8
17
|
"url": "https://github.com/joacod/audiobits.git",
|
package/skill/SKILL.md
CHANGED
|
@@ -8,8 +8,9 @@ description: Integrate AudioBits procedural sounds into a browser application, i
|
|
|
8
8
|
This guide ships with the `audiobits` npm package. Confirm the installed
|
|
9
9
|
package version and read `audiobits/capabilities.json` and
|
|
10
10
|
`audiobits/schema.json` before choosing primitives. Package metadata describes
|
|
11
|
-
shipped behavior, not registry availability.
|
|
12
|
-
|
|
11
|
+
shipped behavior, not registry availability. Current Chromium is the only
|
|
12
|
+
automated browser verification target. Other browsers and operating systems are
|
|
13
|
+
unverified and deliberately deferred.
|
|
13
14
|
|
|
14
15
|
Install with `npm install audiobits` and use a browser bundler. Follow the
|
|
15
16
|
[package quick start](../README.md#quick-start) to play the bundled `confirmation`
|
|
@@ -18,8 +19,13 @@ sounds without browser activation, then invoke `start()` synchronously inside
|
|
|
18
19
|
a user gesture and await it before `play()`. Surface failures and allow a fresh
|
|
19
20
|
gesture retry. Never queue playback across Stop, hiding, or disposal.
|
|
20
21
|
|
|
21
|
-
Use the
|
|
22
|
-
|
|
22
|
+
Use the installed package's exported types, schema, capabilities, and actual
|
|
23
|
+
version to determine supported options and limits. The current website may
|
|
24
|
+
postdate an older installed package. Consult the [API guide](https://audiobits.joacod.com/docs/api),
|
|
25
|
+
[lifecycle](https://audiobits.joacod.com/docs/lifecycle),
|
|
26
|
+
[seeded replay](https://audiobits.joacod.com/docs/parameters), and
|
|
27
|
+
[native interop](https://audiobits.joacod.com/docs/native) for human-readable guidance,
|
|
28
|
+
checking it against the installed contracts. Read the
|
|
23
29
|
[controlled sound example](references/controls.md) for live thruster and bus setup.
|
|
24
30
|
|
|
25
31
|
Keep recipe data JSON-only. Run `validateRecipe` for semantic validation;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# Controlled sound and routing
|
|
2
2
|
|
|
3
3
|
Call `play()` directly from a gesture. Surface rejected promises, bind Stop,
|
|
4
|
-
and call `dispose()` when the host unmounts. See the
|
|
5
|
-
bus
|
|
4
|
+
and call `dispose()` when the host unmounts. See the
|
|
5
|
+
[bus guide](https://audiobits.joacod.com/docs/buses) and
|
|
6
|
+
[native ownership guide](https://audiobits.joacod.com/docs/native), checking options
|
|
7
|
+
against the installed package's exported types and capabilities.
|
|
6
8
|
|
|
7
9
|
```ts
|
|
8
10
|
import { createAudio } from "audiobits";
|