1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
# CONTEXT
Glossary of terms used in this codebase. This file is a glossary only — it
holds no implementation decisions or specs (those live in `docs/adr/`).
## Voice
- **Voice activity** — per-user join / leave / AFK *timing metadata*, persisted
in the `voice_activity` table and updated by `events::handle_voice_state_update`.
Despite the name, it contains **no audio** — only timestamps and durations.
- **Recording** — capturing the *audio* of a voice channel into a rolling
in-memory buffer while the bot is connected. Distinct from *voice activity*
(metadata). A bot "records" continuously while in a VC (unless opted out) and
"flushes" on `/record`.
- **Window** — the retention horizon of the recording buffer: how many seconds
of the recent past are kept. Older audio is discarded as new audio arrives.
Configured via `RECORDING_WINDOW_SECONDS` (default 900 = 15 minutes).
- **Flush** — the `/record` action: snapshot the current recording buffer to an
mp3 and upload it to Copyparty. Non-destructive — the buffer keeps recording
after a flush, so successive calls may overlap.
## Stats & Leaderboard
- **User stats** — cumulative per-user counters (message count, total voice
active time, total voice AFK time) stored in the `user_stats` table. Persists
across restarts. Distinct from *voice activity* which is session-scoped.
- **Voice activity** (session) — per-session timing metadata (join time, current
active/AFK durations, is_afk flag). Resets when user joins VC. Used for
real-time status, not leaderboard rankings.
- **Leaderboard** — `/leaderboard` command group showing ranked user stats.
Metrics: `messages`, `active` (voice), `afk` (voice), `total` (voice active +
afk). Paged at 10 entries, descending by default.
- **Tracked guild** — the guild containing `status_channel_id`. Message counts
are only tracked in this guild.
## TTS
- **Synthesize** — convert text to audio via local Piper TTS (ONNX model
loaded in-process via `piper-rs`). No external fallback. Output is f32 PCM
at the model's native sample rate (typically 22050 Hz mono), resampled to
48 kHz stereo via inline linear interpolation before playback. Songbird does
not resample — playing un-resampled audio results in wrong playback speed.
- **TtsState** — struct held in poise `Data`: `OnceCell<Mutex<Piper>>` for the
model instance, `DashMap<String, (Vec<u8>, Instant)>` for the text→audio cache.
Piper loaded lazily on first TTS call. Cache keyed by full phrase string,
evicted by TTL. No Google TTS fallback.
- **Pre-generation** — on first voice event for a user, synthesize all 6 event
phrases (join/leave/deafen/undeafen/mute/unmute) with their display name and
cache them. ~120ms first time, instant after. Lazy — no startup cost.
## Music Playback
- **Compressed playback** — `/grajcuj \w compressed`: downloads audio, runs
through the /compress pipeline (Opus 500bps, 12 kHz, mono → OGG), then
decodes the compressed file via symphonia for playback. Produces properly
destroyed audio via Opus codec, not just raw low-sample-rate PCM.
|