Spatial audio showcases
Three live demos on the marketing site let visitors hear positional mix features in under a minute — a looping sine tone orbiting with TTS, panned clip playback, and proximity-based room voice. All three share one Voice+Data showcase project and the spatial-showcase agent template. Visitors pick a mode with a DataChannel join message; the browser never sends clip URLs.
Use stereo headphones for every spatial demo — panning is equal-power stereo, not HRTF binaural.
Try the live demos
- Orbiting voice — continuous per-client sine tone plus TTS circle your head (
setPlayPose,setTtsPose). Drag the marker to place the speaker; orbit cycling stops until you resume. - Spatial soundboard — drop clips in space with
play({ volume, pose }). - Proximity room — mix groups, listener poses, and per-peer mute (
setClientPose,setListenerMute).
What each demo exercises
| Demo | Agent APIs | Visitor experience |
|---|---|---|
| Orbit | setPlayPose, setTtsPose, speak | Continuous sine (per-session frequency and start/stop), TTS with Say-it lock until orbit_say_status ended, drag-to-place marker; stage dot tracks speaker position. |
| Soundboard | play with volume and world pose; setPlayPose via pad_move | Tap a pad to preview near center; click the field to place the selected clip; drag stage markers to reposition; Left / Center / Right place in front and to the sides of the listener. |
| Proximity | createMixGroup, setClientPose, setListenerMute | Avatars move on a ~50 m stage (zoom to inspect nearby); voices get louder when closer. |
First-frame spatial pose (agent 0.7.11+)
In @voicethere/agent 0.7.11 and later, the spatial-showcase template emits the first orbit_pose and proximity room_state before the greeting speak(). Browsers can apply spatial pose on the first TTS chunk instead of waiting for the second pose update.
Run it yourself
- Dashboard: Create project → Template → Spatial audio showcase (
spatial-showcase). - Set runner mode to Voice+Data and enable
shared_child_per_session(required so mix-group members share one runner process). See Runner settings. - Deploy to cloud and connect a browser client with a client API key.
- Send the first DataChannel message:
{ "type": "join", "demo": "orbit" | "soundboard" | "proximity" }. OptionalassetOrigintells the agent where to resolve showcase sound files (allowlisted origins only).
Template source: templates/spatial-showcase/
DataChannel protocol
The browser sends commands only — never HTTPS clip URLs. The agent resolves clipId to ${assetOrigin}/showcase/sounds/<file> after validating assetOrigin.
| Direction | type | Purpose |
|---|---|---|
| Browser → agent | join | demo + optional assetOrigin |
| Browser → agent | orbit | action: set | say | place — radius, period, frequencyHz (110–1760), sinePlaying, text, or place x/z |
| Browser → agent | pad | clipId, x, z, optional volume (0–1) — world pose only |
| Browser → agent | pad_move | Reposition an existing play: playId, x, z |
| Browser → agent | move | Listener pose x, z, yawDeg |
| Browser → agent | mute_peer | peerId, muted |
| Agent → browser | orbit_pose | Speaker position for the stage canvas |
| Agent → browser | orbit_say_status | TTS playback playing or ended — Say it stays disabled until ended |
| Agent → browser | room_state | Peer list with poses and mute flags |
| Agent → browser | showcase_ack | Command result; pad acks include playId |
Two volume layers
- Per-clip — soundboard pads send
volume(0–1) onpad; the agent passes it toplay({ volume }). This scales that clip in the server mix. - Browser master — each showcase page has an agent volume slider backed by a Web Audio
GainNodeon the inbound track (persisted inlocalStorage["vt-showcase-volume"]). It affects TTS, clips, and remote mics equally — it does not change per-pad mix levels server-side.
Sourcing showcase sounds
The live soundboard catalog uses short WAV clips served from your site under /showcase/sounds/. When building your own project, you can source effects from:
- Kenney.nl asset packs (UI Audio, Interface, Impact, Sci-Fi) — check each pack license.
- Freesound — filter for CC0 and record attribution in your project docs.
- Procedural or in-house WAV files you generate and host on HTTPS (same pattern as the showcase procedural chimes).
Always host clips on HTTPS URLs your runner can fetch; keep files small, document license and author in your repo, and never pass raw URLs from an untrusted browser — send ids or paths your agent validates.