AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
翻译准备中
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗Live demo: https://justgoscha.github.io/omg-audio/web/ — headphones on. Desktop: WASD + mouse, Space throws a whistling, exploding ball. Android Chrome: on-screen joystick, turn your body to look around (device orientation drives the binaural rendering).
The engine today is v5.5 — rays from the listener, every connection reaching each source where it was when it emitted, the traced response rendered as traced: ENGINE_V3.md (the tracer), ENGINE_V4.md (the response rendered as traced), ENGINE_V5_5.md (what v5.5 changed), measured in docs/runs/, tested per TESTS.md, open items in OPEN.md. Parts of the overview below describe the earlier engine (portals, image sources) that the offline renderer still uses.
A real-time path-traced sound propagation engine in Rust, compiled to both native (reference build) and wasm (Web Worker + AudioWorklet). One scene — a small city square with a house playing music, a great hall with a narrator, a club with four synchronized speakers behind an entrance vestibule, a two-storey old house, a colonnade and a kiosk — and the sound field is computed, not authored:
muffled N% while it holds.Every engine version re-renders the same scripted 98 s walk (living room → corridor → great hall → outside → entrance → club) as a top-down schematic video with binaural audio — the whole history is on the walkthroughs release, headphones on:
| version | what it demonstrates |
|---|---|
| v12 – huygens-doorways | apertures re-radiate as Huygens sources; doorway wet pays Lambert obliquity — a real on-axis peak walking past an open door |
| v11 – mesh-dome-cathedral | ambient dome, mesh-emergent knife-edge occlusion, cathedral + bunker |
| v10 – club-transmission | mass-law wall transmission — oomp-oomp from the street |
| v8 – point-hrtf | per-path nearest-HRIR convolution for the strongest paths |
| v7 – hrtf-binaural | measured KEMAR HRIR binaural decode |
| v6 / v5 – coupled reverb | coupled rooms carry their own reverb through doorways |
| two-sources / voice / music | the earliest renders |
New versions join with
gh release upload walkthroughs walkthrough-vN-<name>.mp4 after the
render recipe below.
Web (what the live demo runs):
sh tools/build_web.sh # cargo build wasm (+simd128) + stage into web/
python3 tools/serve.py # http://localhost:8000/web/
node tools/web_smoke.mjs # headless pipeline test
node tools/env_probe.mjs # ambience/rain continuity through doors + swings
node tools/bench_web.mjs # realtime-factor benchmark (point budgets)
Native:
cargo run --release # live playback, Ctrl+C to quit
cargo run --release -- --render demo.wav --secs 12 # offline render + level report
cargo run --release -- --input assets/aria48.wav --render out.wav
# scripted walkthrough with fixed sources + 2D schematic video
cargo run --release -- --walkthrough --render walk.wav --json walk.json \
[--music m.wav --voice v.wav --club c.wav]
python3 tools/render_viz.py walk.json frames 30
ffmpeg -framerate 30 -i frames/%05d.png -i walk.wav \
-c:v libx264 -pix_fmt yuv420p -c:a aac -shortest walkthrough.mp4
Env knobs (native): OMG_POINT_TAPS=n point-render budget,
OMG_MUTE_TAPS / OMG_MUTE_OWN / OMG_MUTE_REMOTE isolate signal paths.
Godot 4 (GDExtension, tested against 4.7):
sh tools/build_godot.sh # cargo build the extension + stage into godot/bin/
/Applications/Godot.app/Contents/MacOS/Godot --headless --path godot -s test.gd # smoke test
/Applications/Godot.app/Contents/MacOS/Godot --path godot # playable demo
The extension is omg-audio (crates/omg-audio) as Godot nodes — nothing
demo-specific:
OmgWorld — the engine: omg-audio's threaded::Engine (simulation
thread; v3 on the GPU with use_gpu, CPU otherwise). rebuild_geometry()
collects the level's triangles (MeshInstance3D surfaces) into an
omg-audio Geometry; an output thread renders binaural audio ahead
into a ring that Godot's audio thread pulls through OmgOutputStream —
the game thread never runs DSP or waits on the engine. Also:
load_clip(path, options) (Ogg Vorbis/FLAC/Opus, FLAC, WAV decoded in
Rust in the background, with the web demo's shaping options),
whisper() (near field at one ear), ambience bed + rain routed by the
frame's sky (ambience_file, rain_bank_file, rain_intensity),
ground_plane, quality, stats(), and the web worklet's load
governor over omg-audio's mix-wide budgets.OmgGeometry — tags everything below it with an acoustic material
(material = "brick", see OmgWorld.material_presets(); "none" opts
out); as_boxes makes its meshes solid boxes. Simplest of all: give a
visual Material an omg_material meta once and every mesh using it is
acoustic — the texture brings its sound.OmgSource — a looping file and/or one-shots (play_clip), at a real
SPL (level_db at 1 m).OmgListener — the ears (falls back to the current camera).OmgDoor — a leaf or pane filling an opening (an omg-audio object box),
priced by openness.godot/demo.gd + godot/demo/ is the web demo's town at night, generated
in GDScript (same rooms, doors, windows and landmarks as web/main.js /
the walkthrough scene; furniture from assets/demo/layout.json when
present), dressed with CC0 textures (assets/textures, Poly Haven) whose
materials declare their acoustics (--audit prints every
texture → acoustic pairing), and the web demo's sound design (room loops,
footsteps, owls, bells, whispers, cars, balls, rain). It renders a cheap
pixel look by default (3D at 360 px high, width from the window's aspect,
nearest upscale, no anti-aliasing); G switches to the fine look (full
resolution, SSAO/SSIL, volumetric fog), [ and ] change the height. Controls: click to
capture / throw, WASD, Shift run, Space jump, C crouch, F fly, E door,
B bells, V whisper, R rain, L labels, Q sound quality, H hud.
-- --print-fps measures ~10 s of frame rate, -- --shots=<dir> renders
a tour of viewpoints to PNGs, -- --gpu traces on the GPU.
The load-bearing decision: the simulation clock and the audio clock
never share state except through ParamBlock.
┌─────────────────────────────────┐ ParamBlock ┌──────────────────────────────────┐
│ SIMULATION (20 Hz) │ ───────────▶ │ AUDIO (per-sample) │
│ Web Worker / native thread │ │ AudioWorklet / cpal callback │
│ │ taps: key, │ │
│ omg-core + omg-scene │ delay, dir, │ omg-dsp │
│ · image sources (ISM ≤3) │ band gains │ · fractional delays (Doppler) │
│ · stochastic tracer → RT60 │ │ · per-tap shelf EQ + wall LP │
│ · portals, transmission, │ reverb: │ · point HRIR convolution │
│ apertures, diffraction │ rt60[3], │ · order-2 ambisonic bus │
│ · EMA temporal accumulation │ level[3], │ · 8-line FDN (traced RT60) ×2 │
│ (kills MC flutter) │ remote wet │ · 20-speaker KEMAR decode + AGC │
└─────────────────────────────────┘ └──────────────────────────────────┘
ParamBlocks over postMessage (~4 KB @ 20 Hz) —
no SharedArrayBuffer, no COOP/COEP headers, so it hosts on GitHub Pages.recenter
re-zeros on your current sitting pose.Two tiers, chosen per tap by measured loudness:
N is not hardcoded: the AudioWorklet measures its own render load and walks
the budget between 8 and 32 with hysteresis — a throttled CPU (Low Power
Mode, phones) settles low, a desktop climbs to the cap. The HUD shows the
current value (hrtf ×N). Measured on an M1 at the worst-case scene
position (club/entrance doorway blend, ~446 live taps, SIMD kernel):
| point budget / source | realtime factor |
|---|---|
| 0 (bus only) | 3.0× |
| 8 | 2.5× |
| 24 | 2.1× |
| 32 | 1.9× |
| 64 | 1.3× |
Rendering every tap this way (up to 160/source × 6 sources) would be ~10× over budget — that, and only that, is why the bus tier exists. The convolution kernel is written to vectorize (NEON / wasm simd128): pre-reversed HRIRs turn the ring convolution into contiguous dot products with explicit 4-lane accumulation.
| crate | role | wasm? |
|---|---|---|
omg-core | vec/rng, materials, shoebox + triangle-mesh geometry (binned-SAH BVH, budgeted diffraction-edge extraction), ISM, path tracer, ParamBlock. Zero deps. | yes |
omg-dsp | delays, smoothers, EQ, FDN, ambisonics, HRTF (bus + point), renderer, output stage. Alloc-free hot path. | yes |
omg-scene | the world: rooms, doors, windows, materials/thickness, portal graph, transmission/aperture/diffraction routing, WorldSim | yes |
omg-web | wasm C-ABI exports (sim_* for the Worker, eng_* for the Worklet), no wasm-bindgen | is the wasm |
omg-app | native binary: cpal live output, offline render, walkthrough scripting, JSON export for the video tool | native |
omg-godot | GDExtension (godot-rust): omg-audio as Godot 4 nodes (OmgWorld, OmgGeometry, OmgSource, OmgListener, OmgDoor), KEMAR HRIRs baked in | native |
Everything here is a measured trade against the real-time budget, not a
guess — tools/bench_web.mjs is the receipt:
omg_core::mesh is an arbitrary triangle mesh with a
binned-SAH BVH — the same stochastic tracer runs over it (unit-tested
to match the analytic shoebox on a box), segments query per-surface
transmission crossings, and diffraction edges are auto-extracted with
an explicit importance budget (dense meshes degrade by dropping short/
shallow creases first, never by breaking). Measured on M1
(mesh_bench, 2 520-tri city block): BVH build 2 ms, 2 M rays/s,
full trace 79 ms at the 4096-ray desktop tier / 19 ms at the 1024-ray
mobile tier — variance, not bias, is what degrades on cheaper tiers
(EMA accumulation smooths it). On top of it, omg_core::paths finds
propagation paths on a raw mesh with ZERO authoring — no rooms, no
doors, no portals: wall thickness is emergent (entry/exit crossings
paired for the mass law), and door jambs, building corners and roof
lines are all just auto-extracted edges searched for single- and
double-bend paths (166 µs per source-listener query at the default
budget). The demo's OCCLUSION now runs on this: the old hand-built
corner list, corner-visibility matrix and multi-roof rubber band are
deleted — occlusion floors come from AutoPaths over the same world
mesh the ambient dome traces (bound-ranked single bends, branch-and-
bound double bends, an over-the-silhouette hull path for any number
of buildings, bent energy averaged over each aperture's real extent,
and per-cell caching with a fixed refresh budget). In-room acoustics
remain per-room shoeboxes (which these rooms are); the directional
late field and the wgpu compute port are the remaining milestone.Code: Apache-2.0. Acoustic data and demo media:
tools/make_motors.py.tools/make_drops.py).assets/*.wav are gitignored; regenerate via tools/ or use the shipped
.ogg versions (what the web demo loads).
tools/env_probe.mjs renders a walk through a doorway and
a full door swing and asserts the level trajectory has no step.debug button): what is actually playing
right now, and why — per-source level, live/point tap slots, own- and
remote-reverb sends, distance, ambience inlet occupancy, plus ~45 s
scrolling graphs of per-source levels, total tap count, sim tick time
and render load. Slot leaks, level pile-ups and perf spikes are
measurable on sight instead of reconstructed from ear-memory.