@nodetool-ai/game-renderer 0.8.1 → 0.8.2
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/README.md +46 -0
- package/dist/.nodetool-build-stamp +1 -1
- package/dist/audio/mixer.d.ts +75 -0
- package/dist/audio/mixer.d.ts.map +1 -0
- package/dist/audio/mixer.js +345 -0
- package/dist/audio/mixer.js.map +1 -0
- package/dist/audio/player.d.ts +67 -0
- package/dist/audio/player.d.ts.map +1 -0
- package/dist/audio/player.js +337 -0
- package/dist/audio/player.js.map +1 -0
- package/dist/audio/spatial.d.ts +50 -0
- package/dist/audio/spatial.d.ts.map +1 -0
- package/dist/audio/spatial.js +166 -0
- package/dist/audio/spatial.js.map +1 -0
- package/dist/audio/voices.d.ts +11 -0
- package/dist/audio/voices.d.ts.map +1 -0
- package/dist/audio/voices.js +22 -0
- package/dist/audio/voices.js.map +1 -0
- package/dist/audio.d.ts +6 -38
- package/dist/audio.d.ts.map +1 -1
- package/dist/audio.js +3 -226
- package/dist/audio.js.map +1 -1
- package/dist/browser.d.ts +2 -1
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +5 -5
- package/dist/browser.js.map +1 -1
- package/dist/browser3d.d.ts +2 -0
- package/dist/browser3d.d.ts.map +1 -0
- package/dist/browser3d.js +2 -0
- package/dist/browser3d.js.map +1 -0
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +29 -19
- package/dist/build.js.map +1 -1
- package/dist/build3d.d.ts +11 -0
- package/dist/build3d.d.ts.map +1 -0
- package/dist/build3d.js +126 -0
- package/dist/build3d.js.map +1 -0
- package/dist/canvas2d.d.ts +12 -3
- package/dist/canvas2d.d.ts.map +1 -1
- package/dist/canvas2d.js +59 -12
- package/dist/canvas2d.js.map +1 -1
- package/dist/fixed-tick-host.d.ts +10 -0
- package/dist/fixed-tick-host.d.ts.map +1 -0
- package/dist/fixed-tick-host.js +29 -0
- package/dist/fixed-tick-host.js.map +1 -0
- package/dist/frame-budget.d.ts +34 -0
- package/dist/frame-budget.d.ts.map +1 -0
- package/dist/frame-budget.js +52 -0
- package/dist/frame-budget.js.map +1 -0
- package/dist/frame.d.ts +20 -1
- package/dist/frame.d.ts.map +1 -1
- package/dist/frame.js +69 -1
- package/dist/frame.js.map +1 -1
- package/dist/game3d-capture-page.js +5834 -0
- package/dist/game3d-player.js +6001 -0
- package/dist/imageDiff.d.ts +9 -0
- package/dist/imageDiff.d.ts.map +1 -0
- package/dist/imageDiff.js +30 -0
- package/dist/imageDiff.js.map +1 -0
- package/dist/index.d.ts +12 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/dist/input-bindings.d.ts +76 -0
- package/dist/input-bindings.d.ts.map +1 -0
- package/dist/input-bindings.js +377 -0
- package/dist/input-bindings.js.map +1 -0
- package/dist/input.d.ts +1 -1
- package/dist/input.d.ts.map +1 -1
- package/dist/input.js +1 -14
- package/dist/input.js.map +1 -1
- package/dist/input3d.d.ts +3 -0
- package/dist/input3d.d.ts.map +1 -0
- package/dist/input3d.js +3 -0
- package/dist/input3d.js.map +1 -0
- package/dist/node.d.ts +5 -0
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +28 -11
- package/dist/node.js.map +1 -1
- package/dist/node3d.d.ts +29 -0
- package/dist/node3d.d.ts.map +1 -0
- package/dist/node3d.js +160 -0
- package/dist/node3d.js.map +1 -0
- package/dist/particles/curves.d.ts +16 -0
- package/dist/particles/curves.d.ts.map +1 -0
- package/dist/particles/curves.js +49 -0
- package/dist/particles/curves.js.map +1 -0
- package/dist/particles/index.d.ts +6 -0
- package/dist/particles/index.d.ts.map +1 -0
- package/dist/particles/index.js +6 -0
- package/dist/particles/index.js.map +1 -0
- package/dist/particles/random.d.ts +10 -0
- package/dist/particles/random.d.ts.map +1 -0
- package/dist/particles/random.js +26 -0
- package/dist/particles/random.js.map +1 -0
- package/dist/particles/render2d.d.ts +40 -0
- package/dist/particles/render2d.d.ts.map +1 -0
- package/dist/particles/render2d.js +70 -0
- package/dist/particles/render2d.js.map +1 -0
- package/dist/particles/shapes.d.ts +18 -0
- package/dist/particles/shapes.d.ts.map +1 -0
- package/dist/particles/shapes.js +92 -0
- package/dist/particles/shapes.js.map +1 -0
- package/dist/particles/simulator.d.ts +88 -0
- package/dist/particles/simulator.d.ts.map +1 -0
- package/dist/particles/simulator.js +371 -0
- package/dist/particles/simulator.js.map +1 -0
- package/dist/player-v1.js +2502 -0
- package/dist/preparation3d.d.ts +3 -0
- package/dist/preparation3d.d.ts.map +1 -0
- package/dist/preparation3d.js +3 -0
- package/dist/preparation3d.js.map +1 -0
- package/dist/renderPipeline.d.ts +12 -0
- package/dist/renderPipeline.d.ts.map +1 -0
- package/dist/renderPipeline.js +17 -0
- package/dist/renderPipeline.js.map +1 -0
- package/dist/renderer3d/animation/index.d.ts +11 -0
- package/dist/renderer3d/animation/index.d.ts.map +1 -0
- package/dist/renderer3d/animation/index.js +212 -0
- package/dist/renderer3d/animation/index.js.map +1 -0
- package/dist/renderer3d/assets/cache.d.ts +14 -0
- package/dist/renderer3d/assets/cache.d.ts.map +1 -0
- package/dist/renderer3d/assets/cache.js +74 -0
- package/dist/renderer3d/assets/cache.js.map +1 -0
- package/dist/renderer3d/assets/dispose.d.ts +4 -0
- package/dist/renderer3d/assets/dispose.d.ts.map +1 -0
- package/dist/renderer3d/assets/dispose.js +41 -0
- package/dist/renderer3d/assets/dispose.js.map +1 -0
- package/dist/renderer3d/assets/hdri-contract.d.ts +23 -0
- package/dist/renderer3d/assets/hdri-contract.d.ts.map +1 -0
- package/dist/renderer3d/assets/hdri-contract.js +2 -0
- package/dist/renderer3d/assets/hdri-contract.js.map +1 -0
- package/dist/renderer3d/assets/instances.d.ts +5 -0
- package/dist/renderer3d/assets/instances.d.ts.map +1 -0
- package/dist/renderer3d/assets/instances.js +86 -0
- package/dist/renderer3d/assets/instances.js.map +1 -0
- package/dist/renderer3d/capture-driver-types.d.ts +42 -0
- package/dist/renderer3d/capture-driver-types.d.ts.map +1 -0
- package/dist/renderer3d/capture-driver-types.js +2 -0
- package/dist/renderer3d/capture-driver-types.js.map +1 -0
- package/dist/renderer3d/capture-page.d.ts +36 -0
- package/dist/renderer3d/capture-page.d.ts.map +1 -0
- package/dist/renderer3d/capture-page.js +68 -0
- package/dist/renderer3d/capture-page.js.map +1 -0
- package/dist/renderer3d/culling.d.ts +10 -0
- package/dist/renderer3d/culling.d.ts.map +1 -0
- package/dist/renderer3d/culling.js +27 -0
- package/dist/renderer3d/culling.js.map +1 -0
- package/dist/renderer3d/environment/index.d.ts +4 -0
- package/dist/renderer3d/environment/index.d.ts.map +1 -0
- package/dist/renderer3d/environment/index.js +9 -0
- package/dist/renderer3d/environment/index.js.map +1 -0
- package/dist/renderer3d/environment/sky.d.ts +45 -0
- package/dist/renderer3d/environment/sky.d.ts.map +1 -0
- package/dist/renderer3d/environment/sky.js +221 -0
- package/dist/renderer3d/environment/sky.js.map +1 -0
- package/dist/renderer3d/hud/fonts.d.ts +13 -0
- package/dist/renderer3d/hud/fonts.d.ts.map +1 -0
- package/dist/renderer3d/hud/fonts.js +69 -0
- package/dist/renderer3d/hud/fonts.js.map +1 -0
- package/dist/renderer3d/hud/paint.d.ts +4 -0
- package/dist/renderer3d/hud/paint.d.ts.map +1 -0
- package/dist/renderer3d/hud/paint.js +22 -0
- package/dist/renderer3d/hud/paint.js.map +1 -0
- package/dist/renderer3d/import.d.ts +34 -0
- package/dist/renderer3d/import.d.ts.map +1 -0
- package/dist/renderer3d/import.js +408 -0
- package/dist/renderer3d/import.js.map +1 -0
- package/dist/renderer3d/index.d.ts +74 -0
- package/dist/renderer3d/index.d.ts.map +1 -0
- package/dist/renderer3d/index.js +338 -0
- package/dist/renderer3d/index.js.map +1 -0
- package/dist/renderer3d/lights/index.d.ts +7 -0
- package/dist/renderer3d/lights/index.d.ts.map +1 -0
- package/dist/renderer3d/lights/index.js +67 -0
- package/dist/renderer3d/lights/index.js.map +1 -0
- package/dist/renderer3d/materials/index.d.ts +4 -0
- package/dist/renderer3d/materials/index.d.ts.map +1 -0
- package/dist/renderer3d/materials/index.js +8 -0
- package/dist/renderer3d/materials/index.js.map +1 -0
- package/dist/renderer3d/passes/post-processing.d.ts +44 -0
- package/dist/renderer3d/passes/post-processing.d.ts.map +1 -0
- package/dist/renderer3d/passes/post-processing.js +213 -0
- package/dist/renderer3d/passes/post-processing.js.map +1 -0
- package/dist/renderer3d/pipeline.d.ts +15 -0
- package/dist/renderer3d/pipeline.d.ts.map +1 -0
- package/dist/renderer3d/pipeline.js +10 -0
- package/dist/renderer3d/pipeline.js.map +1 -0
- package/dist/renderer3d/playwright-contract.d.ts +3 -0
- package/dist/renderer3d/playwright-contract.d.ts.map +1 -0
- package/dist/renderer3d/playwright-contract.js +4 -0
- package/dist/renderer3d/playwright-contract.js.map +1 -0
- package/dist/renderer3d/preparation.d.ts +79 -0
- package/dist/renderer3d/preparation.d.ts.map +1 -0
- package/dist/renderer3d/preparation.js +458 -0
- package/dist/renderer3d/preparation.js.map +1 -0
- package/dist/renderer3d/scene-sync.d.ts +8 -0
- package/dist/renderer3d/scene-sync.d.ts.map +1 -0
- package/dist/renderer3d/scene-sync.js +96 -0
- package/dist/renderer3d/scene-sync.js.map +1 -0
- package/dist/renderer3d/shadows/cascades.d.ts +40 -0
- package/dist/renderer3d/shadows/cascades.d.ts.map +1 -0
- package/dist/renderer3d/shadows/cascades.js +244 -0
- package/dist/renderer3d/shadows/cascades.js.map +1 -0
- package/dist/renderer3d/shadows/index.d.ts +44 -0
- package/dist/renderer3d/shadows/index.d.ts.map +1 -0
- package/dist/renderer3d/shadows/index.js +129 -0
- package/dist/renderer3d/shadows/index.js.map +1 -0
- package/dist/renderer3d/types.d.ts +18 -0
- package/dist/renderer3d/types.d.ts.map +1 -0
- package/dist/renderer3d/types.js +2 -0
- package/dist/renderer3d/types.js.map +1 -0
- package/dist/smoke.d.ts +15 -0
- package/dist/smoke.d.ts.map +1 -0
- package/dist/smoke.js +138 -0
- package/dist/smoke.js.map +1 -0
- package/dist/standalone-player.d.ts +11 -1
- package/dist/standalone-player.d.ts.map +1 -1
- package/dist/standalone-player.js +67 -41
- package/dist/standalone-player.js.map +1 -1
- package/dist/standalone-player3d.d.ts +14 -0
- package/dist/standalone-player3d.d.ts.map +1 -0
- package/dist/standalone-player3d.js +255 -0
- package/dist/standalone-player3d.js.map +1 -0
- package/dist/touch-controls.d.ts +22 -8
- package/dist/touch-controls.d.ts.map +1 -1
- package/dist/touch-controls.js +88 -21
- package/dist/touch-controls.js.map +1 -1
- package/dist/ui/controller.d.ts +59 -0
- package/dist/ui/controller.d.ts.map +1 -0
- package/dist/ui/controller.js +201 -0
- package/dist/ui/controller.js.map +1 -0
- package/dist/ui/hud2d.d.ts +11 -0
- package/dist/ui/hud2d.d.ts.map +1 -0
- package/dist/ui/hud2d.js +25 -0
- package/dist/ui/hud2d.js.map +1 -0
- package/dist/ui/layout.d.ts +42 -0
- package/dist/ui/layout.d.ts.map +1 -0
- package/dist/ui/layout.js +182 -0
- package/dist/ui/layout.js.map +1 -0
- package/dist/ui/paint.d.ts +45 -0
- package/dist/ui/paint.d.ts.map +1 -0
- package/dist/ui/paint.js +121 -0
- package/dist/ui/paint.js.map +1 -0
- package/dist/webgpu/effects.d.ts +22 -0
- package/dist/webgpu/effects.d.ts.map +1 -0
- package/dist/webgpu/effects.js +69 -0
- package/dist/webgpu/effects.js.map +1 -0
- package/dist/webgpu/hud.d.ts +4 -0
- package/dist/webgpu/hud.d.ts.map +1 -0
- package/dist/webgpu/hud.js +27 -0
- package/dist/webgpu/hud.js.map +1 -0
- package/dist/webgpu/lighting.d.ts +4 -0
- package/dist/webgpu/lighting.d.ts.map +1 -0
- package/dist/webgpu/lighting.js +47 -0
- package/dist/webgpu/lighting.js.map +1 -0
- package/dist/webgpu/pipeline.d.ts +11 -0
- package/dist/webgpu/pipeline.d.ts.map +1 -0
- package/dist/webgpu/pipeline.js +11 -0
- package/dist/webgpu/pipeline.js.map +1 -0
- package/dist/webgpu/sprites.d.ts +6 -0
- package/dist/webgpu/sprites.d.ts.map +1 -0
- package/dist/webgpu/sprites.js +74 -0
- package/dist/webgpu/sprites.js.map +1 -0
- package/dist/webgpu/types.d.ts +14 -0
- package/dist/webgpu/types.d.ts.map +1 -0
- package/dist/webgpu/types.js +2 -0
- package/dist/webgpu/types.js.map +1 -0
- package/dist/webgpu.d.ts +4 -3
- package/dist/webgpu.d.ts.map +1 -1
- package/dist/webgpu.js +119 -279
- package/dist/webgpu.js.map +1 -1
- package/package.json +47 -10
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
import { gameAudioMixer } from "@nodetool-ai/protocol";
|
|
2
|
+
import { GameAudioMixer } from "./mixer.js";
|
|
3
|
+
import { createGameAudioPanner, gameAudioDopplerRate, gameAudioVelocity, placeGameAudioListener, placeGameAudioPanner, setGameAudioDopplerRate } from "./spatial.js";
|
|
4
|
+
import { playBuiltinGameVoice, stopGameVoice } from "./voices.js";
|
|
5
|
+
const MAX_VOICES = 32;
|
|
6
|
+
/** Shares Web Audio voice, decoding, and lifecycle behavior across browser players. */
|
|
7
|
+
export class GameAudioPlayer {
|
|
8
|
+
options;
|
|
9
|
+
context;
|
|
10
|
+
mixer;
|
|
11
|
+
buffers = new Map();
|
|
12
|
+
voices = new Map();
|
|
13
|
+
fading = new Set();
|
|
14
|
+
pending = new Map();
|
|
15
|
+
voiceAssets = new WeakMap();
|
|
16
|
+
spatialVoices = new Set();
|
|
17
|
+
view = null;
|
|
18
|
+
listenerSample;
|
|
19
|
+
listenerVelocity = { x: 0, y: 0, z: 0 };
|
|
20
|
+
desiredMusic = null;
|
|
21
|
+
sceneId = null;
|
|
22
|
+
tick = 0;
|
|
23
|
+
generation = 0;
|
|
24
|
+
legacySequence = 0;
|
|
25
|
+
disposed = false;
|
|
26
|
+
paused = false;
|
|
27
|
+
constructor(options) {
|
|
28
|
+
this.options = options;
|
|
29
|
+
this.context = options.context ?? new AudioContext();
|
|
30
|
+
this.mixer = new GameAudioMixer(this.context, this.mixerSettings(options.mixer), options.tickRate);
|
|
31
|
+
}
|
|
32
|
+
mixerSettings(settings) {
|
|
33
|
+
const parsed = gameAudioMixer.safeParse(settings ?? {});
|
|
34
|
+
if (parsed.success) {
|
|
35
|
+
return settings;
|
|
36
|
+
}
|
|
37
|
+
this.options.status(`Audio mixer settings are invalid, so the default mix is used: ${parsed.error.issues[0]?.message ?? "unknown issue"}`);
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
/** Applies edited mixer settings. Playing voices keep playing on their buses. */
|
|
41
|
+
updateMixer(settings) {
|
|
42
|
+
if (this.disposed)
|
|
43
|
+
return;
|
|
44
|
+
this.mixer.update(this.mixerSettings(settings));
|
|
45
|
+
}
|
|
46
|
+
/** Player-facing bus volume, for example from a settings screen. */
|
|
47
|
+
setBusVolume(busId, volume) {
|
|
48
|
+
if (!this.disposed)
|
|
49
|
+
this.mixer.setUserVolume(busId, volume);
|
|
50
|
+
}
|
|
51
|
+
setBusMuted(busId, muted) {
|
|
52
|
+
if (!this.disposed)
|
|
53
|
+
this.mixer.setUserMuted(busId, muted);
|
|
54
|
+
}
|
|
55
|
+
mixerState() {
|
|
56
|
+
return this.mixer.state();
|
|
57
|
+
}
|
|
58
|
+
buffer(assetId) {
|
|
59
|
+
const cached = this.buffers.get(assetId);
|
|
60
|
+
if (cached)
|
|
61
|
+
return cached;
|
|
62
|
+
const binding = this.options.assets[assetId];
|
|
63
|
+
if (!binding) {
|
|
64
|
+
this.options.status(`Audio asset ${assetId} is missing`);
|
|
65
|
+
return Promise.resolve(null);
|
|
66
|
+
}
|
|
67
|
+
const pending = this.options.resolveAsset(binding).then(async (url) => {
|
|
68
|
+
if (!url)
|
|
69
|
+
throw new Error("asset URL is unavailable");
|
|
70
|
+
const response = await fetch(url, { cache: "force-cache" });
|
|
71
|
+
if (!response.ok)
|
|
72
|
+
throw new Error(`HTTP ${response.status}`);
|
|
73
|
+
return this.context.decodeAudioData(await response.arrayBuffer());
|
|
74
|
+
}).catch((error) => {
|
|
75
|
+
this.options.status(`Audio ${assetId} could not be decoded: ${error instanceof Error ? error.message : String(error)}`);
|
|
76
|
+
return null;
|
|
77
|
+
});
|
|
78
|
+
this.buffers.set(assetId, pending);
|
|
79
|
+
return pending;
|
|
80
|
+
}
|
|
81
|
+
/** Keeps decoded audio for unchanged bindings when the editor document changes. */
|
|
82
|
+
updateAssets(assets) {
|
|
83
|
+
if (this.disposed)
|
|
84
|
+
return;
|
|
85
|
+
const changed = new Set();
|
|
86
|
+
for (const slot of new Set([...Object.keys(this.options.assets), ...Object.keys(assets)])) {
|
|
87
|
+
if (JSON.stringify(this.options.assets[slot]) !== JSON.stringify(assets[slot])) {
|
|
88
|
+
this.buffers.delete(slot);
|
|
89
|
+
changed.add(slot);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
for (const [id, pending] of this.pending) {
|
|
93
|
+
if (changed.has(pending.assetId))
|
|
94
|
+
this.pending.delete(id);
|
|
95
|
+
}
|
|
96
|
+
for (const [id, voice] of this.voices) {
|
|
97
|
+
if (changed.has(this.voiceAssets.get(voice) ?? ""))
|
|
98
|
+
this.stop(id, 0);
|
|
99
|
+
}
|
|
100
|
+
for (const voice of this.fading) {
|
|
101
|
+
if (changed.has(this.voiceAssets.get(voice) ?? "")) {
|
|
102
|
+
voice.source.stop();
|
|
103
|
+
this.fading.delete(voice);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
this.options = { ...this.options, assets };
|
|
107
|
+
this.preload();
|
|
108
|
+
this.startDesiredMusic();
|
|
109
|
+
}
|
|
110
|
+
preload() {
|
|
111
|
+
for (const [id, binding] of Object.entries(this.options.assets)) {
|
|
112
|
+
if (binding.mediaKind === "audio" && !binding.assetId.startsWith("builtin:"))
|
|
113
|
+
void this.buffer(id);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
async unlock() {
|
|
117
|
+
if (this.disposed || this.paused)
|
|
118
|
+
return;
|
|
119
|
+
try {
|
|
120
|
+
await this.context.resume();
|
|
121
|
+
this.startDesiredMusic();
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
this.options.status("Audio is blocked. Tap Play to enable sound in this browser.");
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
pause() {
|
|
128
|
+
if (this.disposed || this.paused)
|
|
129
|
+
return;
|
|
130
|
+
this.paused = true;
|
|
131
|
+
void this.context.suspend().catch(() => this.options.status("Audio could not pause"));
|
|
132
|
+
}
|
|
133
|
+
resume() {
|
|
134
|
+
this.paused = false;
|
|
135
|
+
void this.unlock();
|
|
136
|
+
}
|
|
137
|
+
sync(snapshot) {
|
|
138
|
+
if (this.disposed)
|
|
139
|
+
return;
|
|
140
|
+
this.tick = snapshot.tick;
|
|
141
|
+
if (this.sceneId && this.sceneId !== snapshot.sceneId) {
|
|
142
|
+
for (const id of this.pending.keys()) {
|
|
143
|
+
if (!id.startsWith(`effect:${snapshot.sceneId}:`))
|
|
144
|
+
this.pending.delete(id);
|
|
145
|
+
}
|
|
146
|
+
for (const id of this.voices.keys()) {
|
|
147
|
+
if (id.startsWith(`effect:${this.sceneId}:`))
|
|
148
|
+
this.stop(id, 0);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
this.sceneId = snapshot.sceneId;
|
|
152
|
+
this.mixer.enterScene(snapshot.sceneId);
|
|
153
|
+
const next = snapshot.music;
|
|
154
|
+
if (this.desiredMusic?.voiceId !== next?.voiceId || this.desiredMusic?.startTick !== next?.startTick ||
|
|
155
|
+
this.desiredMusic?.assetId !== next?.assetId || this.desiredMusic?.volume !== next?.volume ||
|
|
156
|
+
this.desiredMusic?.fadeInTicks !== next?.fadeInTicks || this.desiredMusic?.fadeOutTicks !== next?.fadeOutTicks) {
|
|
157
|
+
if (this.desiredMusic)
|
|
158
|
+
this.stop(this.desiredMusic.voiceId, this.desiredMusic.fadeOutTicks);
|
|
159
|
+
this.desiredMusic = next;
|
|
160
|
+
}
|
|
161
|
+
this.startDesiredMusic();
|
|
162
|
+
}
|
|
163
|
+
startDesiredMusic() {
|
|
164
|
+
const music = this.desiredMusic;
|
|
165
|
+
if (!music || !this.options.assets[music.assetId] || this.paused || this.context.state !== "running" || this.voices.has(music.voiceId) || this.pending.has(music.voiceId))
|
|
166
|
+
return;
|
|
167
|
+
const token = Symbol();
|
|
168
|
+
this.pending.set(music.voiceId, { token, assetId: music.assetId });
|
|
169
|
+
void this.start(music.voiceId, music.assetId, true, music.volume, music.fadeInTicks, music.fadeOutTicks, token, music.startTick)
|
|
170
|
+
.catch((error) => this.options.status(`Music could not start: ${error instanceof Error ? error.message : String(error)}`))
|
|
171
|
+
.finally(() => { if (this.pending.get(music.voiceId)?.token === token)
|
|
172
|
+
this.pending.delete(music.voiceId); });
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Moves the listener and every spatial voice to a rendered frame. Players call it once per rendered frame with the view
|
|
176
|
+
* built from the interpolated frame, so positions follow what is on screen. Emitters missing from the view keep their last position.
|
|
177
|
+
*/
|
|
178
|
+
updateSpatial(view) {
|
|
179
|
+
if (this.disposed)
|
|
180
|
+
return;
|
|
181
|
+
this.view = view;
|
|
182
|
+
const now = this.context.currentTime;
|
|
183
|
+
const listenerSample = { position: view.listener.position, time: now };
|
|
184
|
+
this.listenerVelocity = gameAudioVelocity(this.listenerSample, listenerSample) ?? this.listenerVelocity;
|
|
185
|
+
this.listenerSample = listenerSample;
|
|
186
|
+
placeGameAudioListener(this.context.listener, view.listener, now, true);
|
|
187
|
+
for (const voice of this.spatialVoices) {
|
|
188
|
+
const pose = view.emitter(voice.emitter.entityId);
|
|
189
|
+
if (!pose)
|
|
190
|
+
continue;
|
|
191
|
+
placeGameAudioPanner(voice.panner, voice.emitter, pose, now, true);
|
|
192
|
+
const sample = { position: pose.position, time: now };
|
|
193
|
+
const velocity = gameAudioVelocity(voice.sample, sample);
|
|
194
|
+
voice.sample = sample;
|
|
195
|
+
if (voice.rate && voice.emitter.doppler > 0 && velocity) {
|
|
196
|
+
setGameAudioDopplerRate(voice.rate, gameAudioDopplerRate(view.listener.position, this.listenerVelocity, pose.position, velocity, voice.emitter.doppler), now);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/** Creates the panner for a voice and connects it to the bus. The voice connects to the returned node. */
|
|
201
|
+
spatialOutput(emitter, bus, rate) {
|
|
202
|
+
const input = this.mixer.input(bus);
|
|
203
|
+
if (!emitter)
|
|
204
|
+
return { node: input, release: () => { } };
|
|
205
|
+
const now = this.context.currentTime;
|
|
206
|
+
const panner = createGameAudioPanner(this.context, emitter, this.options.spatialQuality ?? "high", now);
|
|
207
|
+
const pose = this.view?.emitter(emitter.entityId);
|
|
208
|
+
if (pose)
|
|
209
|
+
placeGameAudioPanner(panner, emitter, pose, now, false);
|
|
210
|
+
panner.connect(input);
|
|
211
|
+
const voice = { emitter, panner, rate, sample: pose ? { position: pose.position, time: now } : undefined };
|
|
212
|
+
this.spatialVoices.add(voice);
|
|
213
|
+
return { node: panner, release: () => { this.spatialVoices.delete(voice); panner.disconnect(); } };
|
|
214
|
+
}
|
|
215
|
+
/** Plays audio events and lets other simulation events drive mixer snapshot transitions. */
|
|
216
|
+
handle(event) {
|
|
217
|
+
if (this.disposed)
|
|
218
|
+
return;
|
|
219
|
+
if (event.kind !== "audio") {
|
|
220
|
+
this.mixer.observe(event);
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
if (event.action === "stop") {
|
|
224
|
+
if (event.voiceId)
|
|
225
|
+
this.stop(event.voiceId, event.fadeOutTicks);
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
if (this.paused || this.context.state !== "running")
|
|
229
|
+
return;
|
|
230
|
+
const voiceId = event.voiceId ?? `legacy:${this.tick}:${this.legacySequence++}`;
|
|
231
|
+
if (this.pending.has(voiceId))
|
|
232
|
+
return;
|
|
233
|
+
const token = Symbol();
|
|
234
|
+
this.pending.set(voiceId, { token, assetId: event.assetId });
|
|
235
|
+
void this.start(voiceId, event.assetId, event.loop, event.volume, event.fadeInTicks, event.fadeOutTicks, token, undefined, event.emitter)
|
|
236
|
+
.catch((error) => this.options.status(`Audio effect could not start: ${error instanceof Error ? error.message : String(error)}`))
|
|
237
|
+
.finally(() => { if (this.pending.get(voiceId)?.token === token)
|
|
238
|
+
this.pending.delete(voiceId); });
|
|
239
|
+
}
|
|
240
|
+
async start(id, assetId, loop, volume, fadeInTicks, fadeOutTicks, token, logicalStartTick, emitter) {
|
|
241
|
+
const generation = this.generation;
|
|
242
|
+
const binding = this.options.assets[assetId];
|
|
243
|
+
const bus = this.mixer.busFor(assetId, logicalStartTick !== undefined);
|
|
244
|
+
if (binding?.assetId.startsWith("builtin:")) {
|
|
245
|
+
if (loop)
|
|
246
|
+
this.options.status(`Audio ${assetId} cannot loop a built-in effect`);
|
|
247
|
+
else {
|
|
248
|
+
this.mixer.voiceStarted(bus);
|
|
249
|
+
const output = this.spatialOutput(emitter, bus);
|
|
250
|
+
playBuiltinGameVoice(this.context, volume, output.node, () => { output.release(); this.mixer.voiceEnded(bus); });
|
|
251
|
+
}
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
const buffer = await this.buffer(assetId);
|
|
255
|
+
if (!buffer || this.disposed || this.paused || this.context.state !== "running" || generation !== this.generation ||
|
|
256
|
+
this.pending.get(id)?.token !== token || this.voices.has(id))
|
|
257
|
+
return;
|
|
258
|
+
if (this.voices.size + this.fading.size >= MAX_VOICES && this.fading.size > 0) {
|
|
259
|
+
const fading = this.fading.values().next().value;
|
|
260
|
+
if (fading) {
|
|
261
|
+
fading.source.stop();
|
|
262
|
+
this.fading.delete(fading);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
if (this.voices.size + this.fading.size >= MAX_VOICES) {
|
|
266
|
+
const oldestEffect = [...this.voices.values()].find((voice) => !voice.loop);
|
|
267
|
+
if (!oldestEffect)
|
|
268
|
+
return;
|
|
269
|
+
this.stop(oldestEffect.id, 0);
|
|
270
|
+
}
|
|
271
|
+
const source = this.context.createBufferSource();
|
|
272
|
+
const gain = this.context.createGain();
|
|
273
|
+
source.buffer = buffer;
|
|
274
|
+
source.loop = loop;
|
|
275
|
+
const output = this.spatialOutput(emitter, bus, source.playbackRate);
|
|
276
|
+
source.connect(gain).connect(output.node);
|
|
277
|
+
const now = this.context.currentTime;
|
|
278
|
+
gain.gain.setValueAtTime(fadeInTicks > 0 ? 0 : volume, now);
|
|
279
|
+
if (fadeInTicks > 0)
|
|
280
|
+
gain.gain.linearRampToValueAtTime(volume, now + fadeInTicks / this.options.tickRate);
|
|
281
|
+
const voice = { id, source, gain, loop, fadeOutTicks, bus };
|
|
282
|
+
this.voices.set(id, voice);
|
|
283
|
+
this.voiceAssets.set(voice, assetId);
|
|
284
|
+
this.mixer.voiceStarted(bus);
|
|
285
|
+
let ended = false;
|
|
286
|
+
source.onended = () => {
|
|
287
|
+
if (!ended) {
|
|
288
|
+
ended = true;
|
|
289
|
+
this.mixer.voiceEnded(bus);
|
|
290
|
+
}
|
|
291
|
+
if (this.voices.get(id) === voice)
|
|
292
|
+
this.voices.delete(id);
|
|
293
|
+
this.fading.delete(voice);
|
|
294
|
+
source.disconnect();
|
|
295
|
+
gain.disconnect();
|
|
296
|
+
output.release();
|
|
297
|
+
};
|
|
298
|
+
const offset = logicalStartTick === undefined ? 0 : Math.max(0, this.tick - logicalStartTick) / this.options.tickRate;
|
|
299
|
+
source.start(0, loop && buffer.duration > 0 ? offset % buffer.duration : 0);
|
|
300
|
+
}
|
|
301
|
+
stop(id, fadeTicks) {
|
|
302
|
+
this.pending.delete(id);
|
|
303
|
+
const voice = this.voices.get(id);
|
|
304
|
+
if (!voice)
|
|
305
|
+
return;
|
|
306
|
+
this.voices.delete(id);
|
|
307
|
+
stopGameVoice(voice, this.context, fadeTicks, this.options.tickRate, this.fading);
|
|
308
|
+
}
|
|
309
|
+
reset(snapshot) {
|
|
310
|
+
this.generation += 1;
|
|
311
|
+
this.pending.clear();
|
|
312
|
+
for (const id of this.voices.keys())
|
|
313
|
+
this.stop(id, 0);
|
|
314
|
+
for (const voice of this.fading)
|
|
315
|
+
voice.source.stop();
|
|
316
|
+
this.fading.clear();
|
|
317
|
+
this.desiredMusic = null;
|
|
318
|
+
this.mixer.reset(snapshot.sceneId);
|
|
319
|
+
this.sync(snapshot);
|
|
320
|
+
}
|
|
321
|
+
dispose() {
|
|
322
|
+
if (this.disposed)
|
|
323
|
+
return;
|
|
324
|
+
this.disposed = true;
|
|
325
|
+
this.generation += 1;
|
|
326
|
+
this.pending.clear();
|
|
327
|
+
for (const id of this.voices.keys())
|
|
328
|
+
this.stop(id, 0);
|
|
329
|
+
for (const voice of this.fading)
|
|
330
|
+
voice.source.stop();
|
|
331
|
+
this.fading.clear();
|
|
332
|
+
this.buffers.clear();
|
|
333
|
+
this.mixer.dispose();
|
|
334
|
+
void this.context.close();
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
//# sourceMappingURL=player.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"player.js","sourceRoot":"","sources":["../../src/audio/player.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { GameAudioEmitter, GameRenderFrame, GameRenderFrame3D } from "@nodetool-ai/protocol";
|
|
2
|
+
export interface GameAudioVector {
|
|
3
|
+
readonly x: number;
|
|
4
|
+
readonly y: number;
|
|
5
|
+
readonly z: number;
|
|
6
|
+
}
|
|
7
|
+
/** A listener or emitter position. `forward` orients a directional emitter and the listener. */
|
|
8
|
+
export interface GameAudioPose {
|
|
9
|
+
readonly position: GameAudioVector;
|
|
10
|
+
readonly forward?: GameAudioVector;
|
|
11
|
+
readonly up?: GameAudioVector;
|
|
12
|
+
}
|
|
13
|
+
/** Where the listener and emitters are on one rendered frame. Emitter poses are looked up by entity id. */
|
|
14
|
+
export interface GameAudioSpatialView {
|
|
15
|
+
readonly listener: Required<GameAudioPose>;
|
|
16
|
+
emitter(entityId: string): GameAudioPose | undefined;
|
|
17
|
+
}
|
|
18
|
+
/** `high` uses HRTF panning. `low` uses equal-power panning, which costs far less CPU per voice. */
|
|
19
|
+
export type GameAudioSpatialQuality = "high" | "low";
|
|
20
|
+
/** Builds a view from a 3D frame at the renderer's interpolation `alpha`. The listener is the active camera. */
|
|
21
|
+
export declare function gameAudioSpatialView3D(frame: GameRenderFrame3D, alpha: number): GameAudioSpatialView;
|
|
22
|
+
/**
|
|
23
|
+
* Builds a view from a 2D frame. The listener sits at the camera on the z = 0 plane, facing -z with +y up,
|
|
24
|
+
* so +x is to the right. Spatial sources carry their simulation positions and have no facing.
|
|
25
|
+
*/
|
|
26
|
+
export declare function gameAudioSpatialView2D(frame: GameRenderFrame, alpha: number): GameAudioSpatialView;
|
|
27
|
+
/** Creates the panner for one spatial voice at the emitter's position when it played. */
|
|
28
|
+
export declare function createGameAudioPanner(context: BaseAudioContext, emitter: GameAudioEmitter, quality: GameAudioSpatialQuality, time: number): PannerNode;
|
|
29
|
+
/**
|
|
30
|
+
* Moves a panner to an emitter pose. The cone applies only once the pose has a facing, so 2D emitters stay omnidirectional.
|
|
31
|
+
* `smooth` glides to the new values for per-frame updates.
|
|
32
|
+
*/
|
|
33
|
+
export declare function placeGameAudioPanner(panner: PannerNode, emitter: GameAudioEmitter, pose: GameAudioPose, time: number, smooth: boolean): void;
|
|
34
|
+
/** Moves the context's listener. Falls back to the legacy setters where a browser lacks listener AudioParams. */
|
|
35
|
+
export declare function placeGameAudioListener(listener: AudioListener, pose: Required<GameAudioPose>, time: number, smooth: boolean): void;
|
|
36
|
+
/** A position at a context time, for velocity estimates. */
|
|
37
|
+
export interface GameAudioSample {
|
|
38
|
+
readonly position: GameAudioVector;
|
|
39
|
+
readonly time: number;
|
|
40
|
+
}
|
|
41
|
+
/** Velocity between two samples, or null when the gap is empty or too long to be motion. */
|
|
42
|
+
export declare function gameAudioVelocity(previous: GameAudioSample | undefined, current: GameAudioSample): GameAudioVector | null;
|
|
43
|
+
/**
|
|
44
|
+
* Playback rate for the doppler shift heard by a listener from an emitter. `factor` scales both velocities: 0 is no shift, 1 is physical.
|
|
45
|
+
* An approaching emitter or listener raises the pitch.
|
|
46
|
+
*/
|
|
47
|
+
export declare function gameAudioDopplerRate(listener: GameAudioVector, listenerVelocity: GameAudioVector, emitter: GameAudioVector, emitterVelocity: GameAudioVector, factor: number): number;
|
|
48
|
+
/** Glides a source's playback rate to the doppler rate. */
|
|
49
|
+
export declare function setGameAudioDopplerRate(param: AudioParam, rate: number, time: number): void;
|
|
50
|
+
//# sourceMappingURL=spatial.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spatial.d.ts","sourceRoot":"","sources":["../../src/audio/spatial.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,iBAAiB,EAAmB,MAAM,uBAAuB,CAAC;AAEnH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,gGAAgG;AAChG,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;IACnC,QAAQ,CAAC,OAAO,CAAC,EAAE,eAAe,CAAC;IACnC,QAAQ,CAAC,EAAE,CAAC,EAAE,eAAe,CAAC;CAC/B;AAED,2GAA2G;AAC3G,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC;IAC3C,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAAC;CACtD;AAED,oGAAoG;AACpG,MAAM,MAAM,uBAAuB,GAAG,MAAM,GAAG,KAAK,CAAC;AA4CrD,gHAAgH;AAChH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,GAAG,oBAAoB,CAWpG;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,GAAG,oBAAoB,CAuBlG;AAOD,yFAAyF;AACzF,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,uBAAuB,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,CAStJ;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAY5I;AAED,iHAAiH;AACjH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAelI;AAED,4DAA4D;AAC5D,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,4FAA4F;AAC5F,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,eAAe,GAAG,SAAS,EAAE,OAAO,EAAE,eAAe,GAAG,eAAe,GAAG,IAAI,CAMzH;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAAE,OAAO,EAAE,eAAe,EACzH,eAAe,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAU1D;AAED,2DAA2D;AAC3D,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAE3F"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/** Speed of sound in world units per second, with one world unit as one metre. */
|
|
2
|
+
const SPEED_OF_SOUND = 343;
|
|
3
|
+
/** Doppler pitch stays within one octave of the original. */
|
|
4
|
+
const MIN_DOPPLER_RATE = 0.5;
|
|
5
|
+
const MAX_DOPPLER_RATE = 2;
|
|
6
|
+
/** Time constant for per-frame position and pitch changes, so 60 Hz updates do not click. */
|
|
7
|
+
const SMOOTHING_SECONDS = 0.02;
|
|
8
|
+
/** Frame gaps longer than this, such as a paused tab, do not count as motion for doppler. */
|
|
9
|
+
const MAX_DOPPLER_GAP_SECONDS = 0.25;
|
|
10
|
+
const FORWARD = { x: 0, y: 0, z: -1 };
|
|
11
|
+
const UP = { x: 0, y: 1, z: 0 };
|
|
12
|
+
function lerp(from, to, alpha) {
|
|
13
|
+
return from + (to - from) * alpha;
|
|
14
|
+
}
|
|
15
|
+
function rotate(rotation, vector) {
|
|
16
|
+
const [qx, qy, qz, qw] = rotation;
|
|
17
|
+
const tx = 2 * (qy * vector.z - qz * vector.y);
|
|
18
|
+
const ty = 2 * (qz * vector.x - qx * vector.z);
|
|
19
|
+
const tz = 2 * (qx * vector.y - qy * vector.x);
|
|
20
|
+
return { x: vector.x + qw * tx + (qy * tz - qz * ty), y: vector.y + qw * ty + (qz * tx - qx * tz), z: vector.z + qw * tz + (qx * ty - qy * tx) };
|
|
21
|
+
}
|
|
22
|
+
/** Normalised linear interpolation. Close enough to slerp for one tick of rotation. */
|
|
23
|
+
function interpolateRotation(previous, current, alpha) {
|
|
24
|
+
const sign = previous[0] * current[0] + previous[1] * current[1] + previous[2] * current[2] + previous[3] * current[3] < 0 ? -1 : 1;
|
|
25
|
+
const mixed = [0, 1, 2, 3].map((index) => lerp(previous[index], current[index] * sign, alpha));
|
|
26
|
+
const length = Math.hypot(...mixed) || 1;
|
|
27
|
+
return [mixed[0] / length, mixed[1] / length, mixed[2] / length, mixed[3] / length];
|
|
28
|
+
}
|
|
29
|
+
function pose3D(previous, current, alpha) {
|
|
30
|
+
const rotation = interpolateRotation(previous.rotation, current.rotation, alpha);
|
|
31
|
+
return {
|
|
32
|
+
position: { x: lerp(previous.position.x, current.position.x, alpha), y: lerp(previous.position.y, current.position.y, alpha),
|
|
33
|
+
z: lerp(previous.position.z, current.position.z, alpha) },
|
|
34
|
+
forward: rotate(rotation, FORWARD), up: rotate(rotation, UP)
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/** Builds a view from a 3D frame at the renderer's interpolation `alpha`. The listener is the active camera. */
|
|
38
|
+
export function gameAudioSpatialView3D(frame, alpha) {
|
|
39
|
+
const amount = Math.max(0, Math.min(1, alpha));
|
|
40
|
+
let entities;
|
|
41
|
+
return {
|
|
42
|
+
listener: pose3D(frame.camera.previousTransform ?? frame.camera.transform, frame.camera.transform, amount),
|
|
43
|
+
emitter(entityId) {
|
|
44
|
+
entities ??= new Map(frame.entities.map((entity) => [entity.entityId, entity]));
|
|
45
|
+
const entity = entities.get(entityId);
|
|
46
|
+
return entity ? pose3D(entity.previousTransform, entity.transform, amount) : undefined;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Builds a view from a 2D frame. The listener sits at the camera on the z = 0 plane, facing -z with +y up,
|
|
52
|
+
* so +x is to the right. Spatial sources carry their simulation positions and have no facing.
|
|
53
|
+
*/
|
|
54
|
+
export function gameAudioSpatialView2D(frame, alpha) {
|
|
55
|
+
const amount = Math.max(0, Math.min(1, alpha));
|
|
56
|
+
let positions;
|
|
57
|
+
return {
|
|
58
|
+
listener: {
|
|
59
|
+
position: { x: lerp(frame.camera.previousX ?? frame.camera.x, frame.camera.x, amount), y: lerp(frame.camera.previousY ?? frame.camera.y, frame.camera.y, amount), z: 0 },
|
|
60
|
+
forward: FORWARD, up: UP
|
|
61
|
+
},
|
|
62
|
+
emitter(entityId) {
|
|
63
|
+
if (!positions) {
|
|
64
|
+
positions = new Map();
|
|
65
|
+
for (const particles of frame.particles ?? []) {
|
|
66
|
+
positions.set(particles.entityId, { x: particles.x, y: particles.y, z: 0 });
|
|
67
|
+
}
|
|
68
|
+
for (const sprite of frame.sprites) {
|
|
69
|
+
positions.set(sprite.entityId, { x: lerp(sprite.previousX, sprite.x, amount), y: lerp(sprite.previousY, sprite.y, amount), z: 0 });
|
|
70
|
+
}
|
|
71
|
+
for (const emitter of frame.audioEmitters ?? []) {
|
|
72
|
+
positions.set(emitter.entityId, { x: lerp(emitter.previousX, emitter.x, amount), y: lerp(emitter.previousY, emitter.y, amount), z: 0 });
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const position = positions.get(entityId);
|
|
76
|
+
return position ? { position } : undefined;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function setParam(param, value, time, smooth) {
|
|
81
|
+
if (smooth) {
|
|
82
|
+
param.setTargetAtTime(value, time, SMOOTHING_SECONDS);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
param.setValueAtTime(value, time);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/** Creates the panner for one spatial voice at the emitter's position when it played. */
|
|
89
|
+
export function createGameAudioPanner(context, emitter, quality, time) {
|
|
90
|
+
const panner = context.createPanner();
|
|
91
|
+
panner.panningModel = quality === "high" ? "HRTF" : "equalpower";
|
|
92
|
+
panner.distanceModel = emitter.distanceModel;
|
|
93
|
+
panner.refDistance = emitter.minDistance;
|
|
94
|
+
panner.maxDistance = emitter.maxDistance;
|
|
95
|
+
panner.rolloffFactor = emitter.distanceModel === "linear" ? Math.min(1, emitter.rolloff) : emitter.rolloff;
|
|
96
|
+
placeGameAudioPanner(panner, emitter, { position: emitter.position }, time, false);
|
|
97
|
+
return panner;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Moves a panner to an emitter pose. The cone applies only once the pose has a facing, so 2D emitters stay omnidirectional.
|
|
101
|
+
* `smooth` glides to the new values for per-frame updates.
|
|
102
|
+
*/
|
|
103
|
+
export function placeGameAudioPanner(panner, emitter, pose, time, smooth) {
|
|
104
|
+
setParam(panner.positionX, pose.position.x, time, smooth);
|
|
105
|
+
setParam(panner.positionY, pose.position.y, time, smooth);
|
|
106
|
+
setParam(panner.positionZ, pose.position.z, time, smooth);
|
|
107
|
+
if (emitter.cone && pose.forward) {
|
|
108
|
+
panner.coneInnerAngle = emitter.cone.innerAngle;
|
|
109
|
+
panner.coneOuterAngle = emitter.cone.outerAngle;
|
|
110
|
+
panner.coneOuterGain = emitter.cone.outerGain;
|
|
111
|
+
setParam(panner.orientationX, pose.forward.x, time, smooth);
|
|
112
|
+
setParam(panner.orientationY, pose.forward.y, time, smooth);
|
|
113
|
+
setParam(panner.orientationZ, pose.forward.z, time, smooth);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/** Moves the context's listener. Falls back to the legacy setters where a browser lacks listener AudioParams. */
|
|
117
|
+
export function placeGameAudioListener(listener, pose, time, smooth) {
|
|
118
|
+
if (!listener.positionX) {
|
|
119
|
+
listener.setPosition(pose.position.x, pose.position.y, pose.position.z);
|
|
120
|
+
listener.setOrientation(pose.forward.x, pose.forward.y, pose.forward.z, pose.up.x, pose.up.y, pose.up.z);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
setParam(listener.positionX, pose.position.x, time, smooth);
|
|
124
|
+
setParam(listener.positionY, pose.position.y, time, smooth);
|
|
125
|
+
setParam(listener.positionZ, pose.position.z, time, smooth);
|
|
126
|
+
setParam(listener.forwardX, pose.forward.x, time, smooth);
|
|
127
|
+
setParam(listener.forwardY, pose.forward.y, time, smooth);
|
|
128
|
+
setParam(listener.forwardZ, pose.forward.z, time, smooth);
|
|
129
|
+
setParam(listener.upX, pose.up.x, time, smooth);
|
|
130
|
+
setParam(listener.upY, pose.up.y, time, smooth);
|
|
131
|
+
setParam(listener.upZ, pose.up.z, time, smooth);
|
|
132
|
+
}
|
|
133
|
+
/** Velocity between two samples, or null when the gap is empty or too long to be motion. */
|
|
134
|
+
export function gameAudioVelocity(previous, current) {
|
|
135
|
+
if (!previous) {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
const seconds = current.time - previous.time;
|
|
139
|
+
if (seconds <= 0 || seconds > MAX_DOPPLER_GAP_SECONDS) {
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
return { x: (current.position.x - previous.position.x) / seconds, y: (current.position.y - previous.position.y) / seconds,
|
|
143
|
+
z: (current.position.z - previous.position.z) / seconds };
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Playback rate for the doppler shift heard by a listener from an emitter. `factor` scales both velocities: 0 is no shift, 1 is physical.
|
|
147
|
+
* An approaching emitter or listener raises the pitch.
|
|
148
|
+
*/
|
|
149
|
+
export function gameAudioDopplerRate(listener, listenerVelocity, emitter, emitterVelocity, factor) {
|
|
150
|
+
const dx = emitter.x - listener.x;
|
|
151
|
+
const dy = emitter.y - listener.y;
|
|
152
|
+
const dz = emitter.z - listener.z;
|
|
153
|
+
const distance = Math.hypot(dx, dy, dz);
|
|
154
|
+
if (factor <= 0 || distance === 0) {
|
|
155
|
+
return 1;
|
|
156
|
+
}
|
|
157
|
+
const listenerToward = factor * (listenerVelocity.x * dx + listenerVelocity.y * dy + listenerVelocity.z * dz) / distance;
|
|
158
|
+
const emitterAway = factor * (emitterVelocity.x * dx + emitterVelocity.y * dy + emitterVelocity.z * dz) / distance;
|
|
159
|
+
const rate = (SPEED_OF_SOUND + listenerToward) / Math.max(1, SPEED_OF_SOUND + emitterAway);
|
|
160
|
+
return Math.min(MAX_DOPPLER_RATE, Math.max(MIN_DOPPLER_RATE, rate));
|
|
161
|
+
}
|
|
162
|
+
/** Glides a source's playback rate to the doppler rate. */
|
|
163
|
+
export function setGameAudioDopplerRate(param, rate, time) {
|
|
164
|
+
param.setTargetAtTime(rate, time, SMOOTHING_SECONDS * 2.5);
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=spatial.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spatial.js","sourceRoot":"","sources":["../../src/audio/spatial.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface Voice {
|
|
2
|
+
readonly id: string;
|
|
3
|
+
readonly source: AudioBufferSourceNode;
|
|
4
|
+
readonly gain: GainNode;
|
|
5
|
+
readonly loop: boolean;
|
|
6
|
+
readonly fadeOutTicks: number;
|
|
7
|
+
readonly bus: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function playBuiltinGameVoice(context: BaseAudioContext, volume: number, destination: AudioNode, onEnded: () => void): void;
|
|
10
|
+
export declare function stopGameVoice(voice: Voice, context: AudioContext, fadeTicks: number, tickRate: number, fading: Set<Voice>): void;
|
|
11
|
+
//# sourceMappingURL=voices.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voices.d.ts","sourceRoot":"","sources":["../../src/audio/voices.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,qBAAqB,CAAC;IACvC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAUjI;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,CAShI"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export function playBuiltinGameVoice(context, volume, destination, onEnded) {
|
|
2
|
+
const oscillator = context.createOscillator();
|
|
3
|
+
const gain = context.createGain();
|
|
4
|
+
oscillator.frequency.value = 660;
|
|
5
|
+
gain.gain.setValueAtTime(volume * 0.08, context.currentTime);
|
|
6
|
+
gain.gain.exponentialRampToValueAtTime(0.001, context.currentTime + 0.12);
|
|
7
|
+
oscillator.connect(gain).connect(destination);
|
|
8
|
+
oscillator.onended = () => { oscillator.disconnect(); gain.disconnect(); onEnded(); };
|
|
9
|
+
oscillator.start();
|
|
10
|
+
oscillator.stop(context.currentTime + 0.12);
|
|
11
|
+
}
|
|
12
|
+
export function stopGameVoice(voice, context, fadeTicks, tickRate, fading) {
|
|
13
|
+
const now = context.currentTime;
|
|
14
|
+
voice.gain.gain.cancelScheduledValues(now);
|
|
15
|
+
if (fadeTicks > 0) {
|
|
16
|
+
fading.add(voice);
|
|
17
|
+
voice.gain.gain.setValueAtTime(voice.gain.gain.value, now);
|
|
18
|
+
voice.gain.gain.linearRampToValueAtTime(0, now + fadeTicks / tickRate);
|
|
19
|
+
}
|
|
20
|
+
voice.source.stop(now + fadeTicks / tickRate);
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=voices.js.map
|