Skip to content

Repository files navigation

mesh-tap-symphony

Live Version License No backend

Peer-to-peer mesh: each phone is one drum; 30 seconds of taps records a synced loop that replays on every phone.

Live: https://baditaflorin.github.io/mesh-tap-symphony/

Each phone is one drum sound — kick, snare, hi-hat, clap, cowbell, rim. Tap the screen to play your sound. Every tap, from every phone, is appended to a shared 30-second loop. The loop runs on every phone simultaneously, so the group accidentally composes a beat together.

Try it: open the link in two browser tabs, pick a different drum in each, hit Join the band, and tap. Each tab hears both drums replay together every 30 seconds.

How it works

  1. Yjs over y-webrtc, clock-synced (median offset, ~10–30 ms).
  2. The 30-second loop is anchored to mesh time: loopT = meshNow() % 30000.
  3. Each tap is appended to a shared Y.Array<{ slot, dt, id }>, where dt is the position inside the 30-second loop in milliseconds.
  4. Every phone, every frame, looks at incoming tap events whose dt is about to be crossed and schedules them through Web Audio at currentTime + (dt - loopT)/1000. Sample-accurate playback locally; mesh-time-synchronized across phones.

The loop is rolling — your taps replay every 30 seconds until someone hits Clear loop for everyone (it wipes the shared loop on all phones). The track view at the top shows everyone's marks; your own slot's marks are highlighted in your accent color.

Drums

Slot Synthesis
kick sine, 140→40 Hz exponential drop, 0.4 s decay
snare high-passed white noise, 0.18 s
hi-hat high-passed noise, 0.05 s
clap 4 short noise bursts spaced 10 ms
cowbell dual square wave at 800/540 Hz
rim very short hi-hat

All synthesized in Web Audio — no samples, no network, no licensing.

Privacy threat model

See docs/privacy.md. What's on the wire: per-tap { slot, dt: ms-into-loop, id: uuid }. Plus the usual clock-sync timestamps. No audio is transmitted; every phone synthesizes from the tap metadata.

Architecture

  • Mode A — pure GitHub Pages.
  • WebRTC — Yjs + y-webrtc with self-hosted signaling and TURN.

Run it locally

git clone https://github.com/baditaflorin/mesh-tap-symphony.git
cd mesh-tap-symphony
npm install
npm run dev

Self-hosted infrastructure

Repo Endpoint Role
signaling-server wss://turn.0docker.com/ws y-webrtc protocol fan-out
turn-token-server https://turn.0docker.com/credentials HMAC TURN creds
coturn-hetzner turn:turn.0docker.com:3479 TURN relay

ADRs

License

MIT © 2026 Florin Badita

About

Peer-to-peer mesh: each phone is one drum; 30 seconds of taps records a synced loop that replays on every phone.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages