summaryrefslogtreecommitdiff
path: root/stacks/crdop/docs/AUDIO-ARCHITECTURE.md
diff options
context:
space:
mode:
Diffstat (limited to 'stacks/crdop/docs/AUDIO-ARCHITECTURE.md')
-rw-r--r--stacks/crdop/docs/AUDIO-ARCHITECTURE.md80
1 files changed, 80 insertions, 0 deletions
diff --git a/stacks/crdop/docs/AUDIO-ARCHITECTURE.md b/stacks/crdop/docs/AUDIO-ARCHITECTURE.md
new file mode 100644
index 0000000..6320253
--- /dev/null
+++ b/stacks/crdop/docs/AUDIO-ARCHITECTURE.md
@@ -0,0 +1,80 @@
+# CRDOP audio architecture — kernel ALSA only
+
+**CRDOP** = stack acronym for **MAX25-SoftModem** (device id `soft-crdop`).
+
+MAX25-SoftModem (CRDOP) talks to the radio **through the sound hardware directly**. There is **no PulseAudio**, **no PipeWire default route**, and **no desktop sound server** in the path.
+
+## Stack layers
+
+```
+┌─────────────┐ M25/1 TCP ┌──────────────┐ host TCP ┌─────────────┐
+│ max25d │ ◄────────────► │ CRDOP modem │ ◄──────────► │ max25- │
+│ (stack) │ │ (DSP/AX.25) │ │ terminal │
+└─────────────┘ └──────┬───────┘ └─────────────┘
+ │
+ MAX25 sound-proxy
+ (buffer, timing, duplex)
+ │
+ ▼
+ libasound (userspace)
+ │
+ ▼
+ Linux kernel ALSA
+ (/dev/snd/*, drivers)
+ │
+ ▼
+ Sound hardware (USB/PCI codec)
+ │
+ ▼
+ Radio interface (line / acoustic)
+```
+
+| Layer | Role | Allowed |
+|-------|------|---------|
+| **max25d** | Device lifecycle, `CrdopTcpBackend`, no audio I/O | — |
+| **CRDOP modem** | AFSK encode/decode, AX.25 framing, duplex policy | — |
+| **MAX25 sound-proxy** | **Only** audio shim between modem and ALSA — period size, xrun recovery, hw params, PTT timing hooks | MAX25-owned |
+| **ALSA userspace** | `snd_pcm_*` on **`hw:` / `plughw:`** devices | Direct libasound |
+| **Kernel ALSA** | Driver, DMA, card registry | Required |
+| **PulseAudio / PipeWire** | — | **Forbidden** in production path |
+
+The sound-proxy is **not** a second network hop — it is the in-process (or co-process) module that owns ALSA opens and keeps modem timing off the desktop audio stack.
+
+## Why no PulseAudio
+
+PulseAudio and PipeWire insert mixing, resampling, and variable latency between applications and the kernel. CRDOP must:
+
+- Reproduce **exact mark/space frequencies** on playback
+- Sample capture with **stable phase** for demodulation
+- Meet **tighter deadlines** as baud rises toward 19200
+
+A userspace mixer breaks those guarantees. Operators must bind **card and device explicitly** (`hw:Card,Device` or tested `plughw:`).
+
+## Operator setup
+
+1. Identify hardware: `arecord -l` and `aplay -l` (kernel cards, not `pulse` pseudo-devices).
+2. Set INI `[audio] capture` and `playback` to **hardware ALSA names**.
+3. Ensure no session steals the device (`pasuspender` / stop PulseAudio on dedicated hosts).
+4. Verify loopback before on-air traffic.
+
+Example INI:
+
+```ini
+[audio]
+backend = alsa-kernel
+no_pulse = yes
+capture = hw:1,0
+playback = hw:1,0
+```
+
+Dedicated packet-radio hosts: prefer **single-purpose Linux** without a desktop sound daemon, or `PULSE_SERVER=` / `PIPEWIRE_RUNTIME_DIR=` unset for the `crdop` service unit.
+
+## Development (Eigenentwicklung)
+
+Native CRDOP will implement the sound-proxy in-tree (`include/crdop/sound_proxy.h`). Legacy optional vendor builds used `ALSASound.c` with the same rule: **open ALSA devices directly**.
+
+## See also
+
+- [SOFTMODEM.md](SOFTMODEM.md) — product scope, baud, duplex
+- [CONFIG.md](CONFIG.md) — INI keys
+- [BUILD.md](BUILD.md) — `libasound2-dev` dependency
git clone -b <branch> https://cgit.mode42.com/<repo>.git
git clone -b <branch> git://cgit.mode42.com/<repo>.git

info@mode42.com