open-standards/wai/wai-web/demo/audio.html
Transaction Science df20c392d8 wai: interactive + temporal cargo classes, provenance, telepresence
Adds the "carries whatever it can reconstruct, verifies whatever it
carries" surface on top of the existing neural/codec WAI. All builds
green against this base (wai-rs all-features tests + clippy, wai-web
wasm, wai-spz-gen, wai-relay).

Reconstruct half — each a spec + conformance corpus + in-tab browser
sink that re-derives the corpus hash, over one wai.det.fixed64 floor:
  - interactive worlds      replay-equivalence   (3 sim registrants,
    relay multiplayer, session receipts, glTF + real-SPZ assets)
  - spatial audio           mixdown-equivalence
  - haptics                 sample-equivalence
  - state-feeds             replay-equivalence  (non-physics sim)
  - avatars / digital humans  pose-equivalence  (+ telepresence)
  - volumetric / 4D splats  frame-state-equivalence (WebGPU EWA render)

Verify half (lever 4):
  - asset provenance — signed, energy-accounted lineage for opaque
    captured content WAI does not reconstruct; tamper-evident in-tab.

Cross-cutting: per-class JWP receipt profiles; a native energy meter
(IOReport via macmon, no sudo) emitting receipts with real measured
joules. Codecs gated behind a `codecs` feature (default on) so the
world/wasm sinks build without the C codec chain.

Excludes the separately-evolving neural subsystem (semantic path, GLC
rANS, ONNX tooling) to avoid reverting newer origin work.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-13 23:16:42 -04:00

61 lines
3.6 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WAI — spatial audio sink</title>
<style>
:root { --bg:#06080c; --bg2:#0d1117; --border:#1e2736; --text:#e6edf5; --text2:#8b99ad; --text3:#4a5568; --g:#00e5a0; --w:#f0b429; --mono:'JetBrains Mono','SF Mono',Menlo,monospace; }
* { box-sizing:border-box; margin:0; padding:0; }
body { background:var(--bg); color:var(--text); font-family:var(--mono); padding:24px; }
h1 { font-size:15px; letter-spacing:.04em; margin-bottom:4px; } h1 em { font-style:normal; color:var(--g); }
.sub { font-size:11px; color:var(--text2); margin-bottom:14px; max-width:880px; line-height:1.5; }
.bar { display:flex; gap:10px; align-items:center; margin-bottom:10px; flex-wrap:wrap; }
select,button { background:var(--bg2); color:var(--text); border:1px solid var(--border); border-radius:6px; padding:6px 12px; font-family:var(--mono); font-size:12px; cursor:pointer; }
select:hover,button:hover { border-color:var(--g); }
canvas { background:#04060a; border:1px solid var(--border); border-radius:10px; display:block; }
.hud { display:flex; gap:22px; margin-top:10px; font-size:11px; color:var(--text2); flex-wrap:wrap; }
.hud b { color:var(--text); } .hash { color:var(--g); }
#badge { font-size:12px; padding:4px 12px; border-radius:99px; display:none; }
#badge.ok { display:inline-block; background:rgba(0,229,160,.12); color:var(--g); border:1px solid rgba(0,229,160,.5); }
#badge.bad { display:inline-block; background:rgba(255,107,107,.12); color:#ff6b6b; border:1px solid rgba(255,107,107,.5); }
.note { margin-top:14px; font-size:10.5px; color:var(--text3); max-width:880px; line-height:1.55; }
.note b { color:var(--text2); }
</style>
</head>
<body>
<h1>WAI <em>spatial audio</em> — object-based sink</h1>
<p class="sub">
A <code>wai.audio.scene</code> arrived: sound <b>objects</b> (each a content-addressed source + a
position trajectory), not a baked stereo mix. This tab renders them to a stereo mix with the same
deterministic Rust mixer that generated the conformance corpus, then checks the BLAKE3 of its PCM
against the corpus's expected <code>mixdown_hash</code> — <b>mixdown-equivalence</b>, the audio
counterpart of replay-equivalence. The radar shows each object's position; press play to hear it pan.
</p>
<div class="bar">
<select id="scene">
<option value="moving">moving — one source sweeping left → right</option>
<option value="stereo_pair">stereo_pair — two static sources, hard L + hard R</option>
<option value="distance">distance — one source near vs. far</option>
</select>
<button id="play">▶ play</button>
<span id="badge"></span>
</div>
<canvas id="c" width="640" height="420"></canvas>
<div class="hud">
<span>objects <b id="objs">—</b></span>
<span>rate <b id="rate">—</b> Hz</span>
<span>dur <b id="dur">—</b></span>
<span>scene hash <b class="hash" id="scenehash">—</b></span>
<span>mixdown hash <b class="hash" id="mixhash">—</b></span>
</div>
<p class="note">
<b>What you are hearing:</b> not a recording — a render. The wire carried objects + trajectories;
your device made the mix. The mixdown is bit-exact (`wai.det.fixed64` floor, sqrt-only constant-power
pan), so the hash above equals the one in <code>audio-conformance/expected_hashes.json</code> — the
same number on any machine. A real sink can also render to its own layout (5.1, binaural/HRTF); the
bit-exact stereo floor is the conformance contract.
</p>
<script type="module" src="audio.js"></script>
</body>
</html>