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.
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.