Linrad Notes
Source Issues

Architecture: threads and buffers

Each stage of the DSP chain, plus I/O and the UI, runs in its own thread; stages exchange data through power-of-two circular buffers.

Threads and circular buffers

Threads

Thread identities and states are in thrdef.h. The DSP-path threads:

Thread Purpose
THREAD_RX_ADINPUT / THREAD_*_INPUT device / network / file input → fills timf1
THREAD_DO_FFT1C, THREAD_FFT1B1..6 first FFT, spread over up to 6 workers
THREAD_TIMF2 do_fft1_c()make_timf2()first_noise_blanker()
THREAD_SECOND_FFT recombine the two timf2 parts → fft2; AFC / spur removal
THREAD_NARROWBAND_DSP first mixer / AFC, timing
THREAD_MIX2 second mixer + baseband (do_mix2fft3_mix2)
THREAD_FFT3 third FFT feeding the second mixer
THREAD_RX_OUTPUT, THREAD_BLOCKING_RXOUT resample + demodulate → D/A
THREAD_SCREEN, THREAD_USER_COMMAND display and UI

Synchronization uses atomic status/command flags, an event set (lir_await_event / lir_set_event), and a small set of mutexes.

In the source

Thread IDs from thrdef.h:47; thread states (THRFLAG_*) thrdef.h:6; atomic flag helpers (lir_interlocked_*) thrdef.h:184; events (EVENT_*) thrdef.h:125; mutexes thrdef.h:162. The narrow-band trio is created together at menu.c:702. OS-specific thread bodies are in lxsys.c (Linux) and wsys.c (Windows); they call the portable DSP entry points (e.g. lxsys.c:1397 do_mix2()). Per-thread CPU/wall time (thread_tottim*, thread_cputim*) is shown when T is pressed (z_TIMING.txt).

Circular buffers

The conventions (z_BUFFERS.txt):

The main DSP buffers, in order:

timf1 → fft1 → (split) → timf2 → fft2 → timf3/fft3 → baseb → daout

The T display lists the same buffers as delay times: Raw(timf1) → fft1timf2fft2timf3fft3basebbuf(daout) → D/A.

In the source

Buffer naming/conventions: z_BUFFERS.txt. Delay-time readout: z_TIMING.txt. The timf2 buffer and its pointers (timf2_pa, timf2_px, timf2p_fit, timf2_mask, …) are declared in fft1def.h:273.