docs: add README
This commit is contained in:
103
README.md
Normal file
103
README.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# 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 | 50000–50100 |
|
||||
| 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
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
To check mixer logs:
|
||||
```bash
|
||||
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` |
|
||||
Reference in New Issue
Block a user