Fluister (Dutch for "whisper"): a participatory sound piece. Phones, laptops and self-built ESP32 devices form a circle of voices (group call, whisper chain or silence) while a host whispers stereo instructions into their ears. By Joke Caimo. https://experiments.samenschool.org/fluister/
  • JavaScript 44.5%
  • HTML 30.9%
  • C++ 17%
  • CSS 4.2%
  • C 3.2%
  • Other 0.2%
Find a file
Claude ec080afb33
MANUAL: LED colour depends on the build variant
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CDye7FLH2xCAzpSU2Vq2Kx
2026-10-19 21:24:57 +02:00
docs Fluister: a circle of voices — server, web pages, ESP32 device and workshop manual 2026-10-14 23:31:11 +02:00
firmware Firmware: join the Accessphone hotspot by itself, start-up test tone 2026-10-19 21:24:48 +02:00
public Fluister: a circle of voices — server, web pages, ESP32 device and workshop manual 2026-10-14 23:31:11 +02:00
test Fluister: a circle of voices — server, web pages, ESP32 device and workshop manual 2026-10-14 23:31:11 +02:00
.dockerignore Fluister: a circle of voices — server, web pages, ESP32 device and workshop manual 2026-10-14 23:31:11 +02:00
.gitignore Fluister: a circle of voices — server, web pages, ESP32 device and workshop manual 2026-10-14 23:31:11 +02:00
docker-compose.yml Fluister: a circle of voices — server, web pages, ESP32 device and workshop manual 2026-10-14 23:31:11 +02:00
Dockerfile Fluister: a circle of voices — server, web pages, ESP32 device and workshop manual 2026-10-14 23:31:11 +02:00
ecosystem.config.js Fluister: a circle of voices — server, web pages, ESP32 device and workshop manual 2026-10-14 23:31:11 +02:00
LICENSE Fluister: a circle of voices — server, web pages, ESP32 device and workshop manual 2026-10-14 23:31:11 +02:00
MANUAL.md MANUAL: LED colour depends on the build variant 2026-10-19 21:24:57 +02:00
nginx-experiments.conf Fluister: a circle of voices — server, web pages, ESP32 device and workshop manual 2026-10-14 23:31:11 +02:00
nginx-fluister.conf Fluister: a circle of voices — server, web pages, ESP32 device and workshop manual 2026-10-14 23:31:11 +02:00
package.json Fluister: a circle of voices — server, web pages, ESP32 device and workshop manual 2026-10-14 23:31:11 +02:00
README.md Fluister: a circle of voices — server, web pages, ESP32 device and workshop manual 2026-10-14 23:31:11 +02:00
server.js Fluister: a circle of voices — server, web pages, ESP32 device and workshop manual 2026-10-14 23:31:11 +02:00

Fluister — a circle of voices

Fluister (Dutch for whisper) is a participatory sound piece for a group of people. Everyone joins with a phone, a laptop or a small self-built device with headphones. A host switches the whole circle between three states:

Together everyone hears everyone
Whispers you only hear your neighbour in the circle — a chain of whispers that is reshuffled every n seconds
Silence nobody hears each other, only the instructions

On top of that the host can whisper sound instructions into people's ears: recorded or uploaded audio, live speech, or text on the screens. Instructions can go to everyone, to one person, or to the start of the chain, so the circle passes them on. Stereo instructions can give the left and the right ear something different.

Fluister is part of the research of Joke Caimo into collective energy, intimacy and resonance.

wiring

What is in this repository

server.js                  Node.js server: circles, audio mixer, instructions, small web server
public/                    web pages: index.html (participants), host.html (host)
firmware/fluister-device/  Arduino code for the ESP32 device (+ config.h)
docs/                      wiring diagrams, Dutch notes
MANUAL.md                  workshop manual: build your own Fluister device
test/                      automated tests (node test/sim.js, test/browser.js)

How it works

All audio goes through the server (no peer-to-peer). Every participant — browser or ESP32 — sends 16 kHz mono 16-bit PCM in 20 ms frames over a WebSocket (/ws). The server mixes for each listener what they should hear and sends it back, in stereo when the client asks for it. Because everything travels over normal HTTPS, it works behind any Wi-Fi or 4G, without TURN servers.

Run the server

Requires Node.js 18+.

npm install
HOST_PIN=choose-a-pin npm start          # http://localhost:3000   host page: /host
npm test                                  # simulation test of all modes

Environment variables: PORT (3000), HOST_PIN, SHUFFLE_SEC (30), DATA_DIR (./data — uploaded instructions).

Deployment examples are included: docker-compose.yml, ecosystem.config.js (pm2), nginx-fluister.conf (own subdomain) and nginx-experiments.conf (under a sub-path such as /fluister/). The app works both on the root of a domain and under a sub-path.

Use it

  • Participants: https://your-server/?room=circle-name → name → join. Headphones recommended.
  • Host: https://your-server/host?room=circle-name → PIN. Switch modes, reshuffle the circle, upload / record instructions (mono or stereo), choose the ear (both / left / right), speak live, send text, listen in, show the QR code.

The device

An ESP32-WROOM-32 with an INMP441 I²S microphone and a PCM5102A I²S DAC with a 3.5 mm jack. About €12–15 in parts. See MANUAL.md for the full build: soldering, wiring, flashing and testing.

Fonts and images

The participant page uses BBB ReadMe by Bye Bye Binary. The font files are not included in this repository: download BBB ReadMe from the Bye Bye Binary typothèque and put BBBReadMe-Regular, -Italic, -SemiBold and -Black (.woff2 and .woff) in public/fonts/. Without them the page falls back to a system font.

The background drawings in public/img/ are by Joke Caimo and are not covered by the code licence.

Licence

Code: MIT (see LICENSE). Drawings: © Joke Caimo, all rights reserved.