Files
unisonus-livekit/README.md
2026-03-29 22:08:39 -04:00

3.1 KiB
Raw Permalink Blame History

unisonus-livekit

WebRTC audio infrastructure for Unisonus — a choir/music streaming application. Provides a LiveKit server and a custom choir audio mixer agent that subscribes to participant audio streams, mixes them, and publishes the combined output back to the room.

Architecture

Participants (up to 6)
        │  audio tracks
        ▼
  choir-mixer agent
  ├── subscribes to all participant audio
  ├── normalises RMS per stream (target: -20 dBFS)
  ├── noise-gates signals below -40 dBFS
  ├── sums all streams
  ├── soft-limits via tanh (no hard clipping)
  └── publishes mixed audio track back to room
        │
        ▼
  All room participants receive the mix

Services

Service Image Ports Description
livekit livekit/livekit-server:latest 7880 (HTTP/WS), 7881 (RTC TCP), 50000-50100/udp LiveKit WebRTC media server
choir-mixer Built from ./choir-mixer/Dockerfile Python agent: subscribes, mixes, publishes

Audio Mixer Details

File: choir-mixer/main.py + choir-mixer/mixer.py

Parameter Value
Sample rate 48 kHz
Channels Mono (1)
Frame duration 20 ms (960 samples/frame)
Max simultaneous streams 6
Target loudness -20 dBFS (RMS)
Noise gate -40 dBFS (silence below this threshold)
Limiter tanh soft-limit (smooth saturation, no hard clipping)
Stale frame timeout 60 ms (frames older than this are discarded from mix)

The mixer runs at ~50 Hz (every 20 ms). Each cycle it:

  1. Collects the most recent frame from each active participant (discarding stale frames)
  2. Normalises each stream to -20 dBFS
  3. Noise-gates signals below -40 dBFS (suppresses background noise and keyboard clicks)
  4. Sums all streams into one
  5. Applies tanh soft limiting to prevent clipping
  6. Publishes the result as a mono 48kHz audio track

LiveKit Server Config

File: livekit.yaml

Setting Value
HTTP/WS port 7880
RTC TCP port 7881
RTC UDP range 5000050100
Node IP 192.168.0.241
External IP Disabled (LAN only)
Room empty timeout 300 s
Max participants 50
Log level info

Environment Variables

Variable Required Description
LIVEKIT_API_KEY Yes LiveKit API key (from livekit.yaml keys:)
LIVEKIT_API_SECRET Yes LiveKit API secret

Copy .env.example to .env and fill in the values. The API key/secret pair must match what is configured in livekit.yaml.

Running

docker compose up -d

To check mixer logs:

docker compose logs -f choir-mixer

Dependencies

Python (choir-mixer):

  • livekit — LiveKit Agents SDK
  • livekit-rtc — RTC bindings
  • numpy — audio processing

Deployment

Runs on 192.168.0.241 (albert-MacBookPro Linux server).

Endpoint URL
LiveKit signaling ws://192.168.0.241:7880
LiveKit RTC TCP 192.168.0.241:7881
LiveKit RTC UDP 192.168.0.241:50000-50100