From 04d965d67a7264a1c7c211494aebda1953df7603 Mon Sep 17 00:00:00 2001 From: "info@mode42.com" Date: Fri, 7 Aug 2026 18:25:13 +0000 Subject: Initial push --- stacks/crdop/docs/AUDIO-ARCHITECTURE.md | 80 +++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 stacks/crdop/docs/AUDIO-ARCHITECTURE.md (limited to 'stacks/crdop/docs/AUDIO-ARCHITECTURE.md') 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 -- cgit v1.3.1