4.9 KiB
4.9 KiB
Audio Architecture Update Proposal
Date: 2026-02-25
Goals
- Fix correctness issues first (sound origin for carried items).
- Improve runtime stability without increasing server/upstream load.
- Reduce duplicate work in audio runtime (shared streams, cached effects).
- Keep server-first boundaries clear and avoid client/server drift.
Proposed Implementation Sequence
Phase 1: Correctness + low-risk fixes
- Carried-item
useSoundsource position (server)
- Problem:
item_use_soundcurrently usesitem.x/y, which can be stale while carried. - Change: resolve source position via carrier when
carrierIdis set, same pattern as piano. - Files:
server/app/server.py
- Acceptance:
- Using a carried item emits sound from carrier’s current square for all listeners.
- Stream retry policy hardening (client)
- Status: partially done (throttled retry + cap + cooldown).
- Follow-up:
- Add small inline debug counters in runtime (non-user-facing unless debug enabled).
- Ensure cooldown reset after successful play and cleanup path reset are covered by tests.
- Files:
client/src/audio/radioStationRuntime.tsclient/src/audio/itemEmitRuntime.ts
- Acceptance:
- No retry spam under repeated failures.
- Retry state recovers automatically when playback succeeds.
Phase 2: Performance and scaling improvements
-
Emit source strategy removed
-
Reverb impulse cache (client)
- Problem: effect chain rebuilds can recreate impulse buffers frequently.
- Change: cache impulse responses by
(sampleRate, effectValueBucket)ineffects.ts. - Files:
client/src/audio/effects.ts
- Acceptance:
- Effect toggling no longer repeatedly regenerates same impulse buffers.
- No audible regressions in reverb behavior.
Phase 3: Consistency and maintainability
- Centralize sound URL normalization policy
- Problem: normalization logic exists in multiple places (server validator + client resolver + proxy behavior).
- Change:
- Define one policy doc and align implementation points:
- server validation/normalization
- client runtime resolution
- proxy Dropbox/http normalization behavior
- Move server normalization logic to shared item-sound helper(s), not tied to a specific item type module.
- Define one policy doc and align implementation points:
- Files:
server/app/items/...shared validator/normalizer helper module- per-item validators (
widget,radio_station, and future sound-accepting items) call shared helper client/src/main.ts(resolveIncomingSoundUrl)deploy/php/media_proxy.phpdocs/protocol-notes.mdor new dedicated audio policy section
- Acceptance:
- Same input URL/path yields predictable behavior across use/emit/radio.
- Fewer edge mismatches (
none/off,sounds/, full URLs, Dropbox links).
Phase 4: Output routing + observability (defer)
- Output-device routing behavior
- Problem:
setSinkIdon muted element may not map to all WebAudio-rendered domains. - Change options:
- A: Explicitly document browser limitation + current behavior.
- B: Investigate alternate routing architecture and apply if robust in target browsers.
- Recommendation:
- Ship A first (fast, clear UX), then evaluate B separately.
- Files:
docs/controls.mdand/ordocs/runtime-flow.md- optional runtime status text in settings UI
- Acceptance:
- Users get accurate expectation of output-device behavior.
- Audio runtime debug observability
- Change:
- Add optional debug object/report for:
- active radio shared sources
- active emit outputs/shared sources
- retry failures and cooldown state
- Keep disabled by default.
- Add optional debug object/report for:
- Files:
client/src/audio/radioStationRuntime.tsclient/src/audio/itemEmitRuntime.ts- optional small hook in
main.tsfor debug dump command
- Acceptance:
- Runtime state can be inspected quickly during field troubleshooting.
Risks and Mitigation
- Shared emit pooling could accidentally couple per-item controls.
- Mitigation: maintain per-item gain/effect nodes after shared source split.
- Output routing changes can be browser-fragile.
- Mitigation: document-first rollout, then narrow-scope prototype for alternate routing.
- Normalization centralization can break legacy links.
- Mitigation: add targeted tests for representative URL/path cases before refactor.
Suggested PR/Commit Breakdown
- Carried-item sound origin fix (server).
- Emit shared source pooling.
- Reverb impulse cache.
- Sound normalization alignment (server/client/proxy + docs).
- Output routing docs/UX clarification.
- Optional debug observability layer.
Definition of Done
- Carried item sounds always originate from current carrier position.
- No unbounded retry loops for stream failures.
- Emit runtime reuses identical stream URLs.
- Reverb buffer creation is cached and stable under effect churn.
- Sound URL/path behavior is documented and consistent across server/client/proxy.
- Audio runtime state is inspectable when debugging is enabled.