Oto: Real-Time Terminal Audio Visualizer in C

Oto is a small terminal audio visualizer I built in C. It captures live PCM from PipeWire, runs a real-time FFT with FFTW, and draws a scrolling single-band spectrum in ncurses.
Oto terminal audio visualizer demo showing frequency band bars.
Demo capture of Oto running in the terminal.
Language + UI C + ncurses
Audio In PipeWire stream (F32_LE, negotiated rate/channels)
DSP Hann window + FFTW r2c transform on 3072 frames

Technical Flow

PipeWire process callback -> dequeue input buffer -> copy one channel into time ring buffer (3072 samples) -> apply Hann window -> fftw_execute(plan_dft_r2c_1d) -> magnitude per bin -> average energy in one band: Bass 20-250 Hz (-B, default) Mid 250-2000 Hz (-M) Treble 2000-8000 Hz (-T) -> smooth with previous sample + peak decay -> render Unicode bars via ncurses -> queue buffer back to PipeWire

PipeWire integration uses pw_stream_new_simple with PW_STREAM_FLAG_AUTOCONNECT, PW_STREAM_FLAG_MAP_BUFFERS, and PW_STREAM_FLAG_RT_PROCESS. The code subscribes to param_changed to lock format details and process for per-buffer sample handling.

Build is straightforward with gcc, pkgconf, libpipewire-0.3, fftw3, and ncurses. One thing I still want to improve is moving FFT/rendering work off the real-time callback to keep audio processing minimal.