Real-Time Audio Spectrum Analyzer
Visualizes microphone input in the frequency domain in real time, rendered as a bar chart in the terminal.
Real-Time Audio Spectrum Analyzer window: Hann range: -80 to +0 dBFS
0┤████ ██
-4┤████ █ ███
-8┤█████ ████
-12┤██████ ██████
-16┤███████ ████████
-20┤████████ ██████████
| | | | | | | | | | |
20 50 100 200 500 1k 2k 5k 10k 20k
RealTimeAudioSpectrumAnalyzer/
├── CMakeLists.txt # Root — FetchContent: KissFFT, PortAudio
├── build.bat # Build + run script
├── cmake/
│ └── spectrum_analyzer/
│ └── CMakeLists.txt # Executable target, link rules
├── src/
│ ├── main.cpp # Entry point, render loop, CLI args
│ ├── audio/
│ │ └── AudioCapture.cpp # PortAudio ring-buffer capture
│ ├── dsp/
│ │ ├── WindowFunction.cpp # Hann / Hamming / Rectangular
│ │ └── FFTProcessor.cpp # KissFFT wrapper → dBFS magnitude
│ └── display/
│ └── SpectrumDisplay.cpp # ANSI terminal bar chart
└── include/
├── audio/
│ └── AudioCapture.h
├── dsp/
│ ├── WindowFunction.h
│ └── FFTProcessor.h
└── display/
└── SpectrumDisplay.h
Library
Method
Purpose
PortAudio
FetchContent
Microphone input capture
KissFFT
FetchContent
Real-valued FFT (kiss_fftr)
No external installation required — cmake downloads the sources automatically on the first build.
CMake ≥ 3.22
MSVC 2019/2022 (x64) or MinGW
Internet access (for FetchContent on first build)
build.bat # Release
build.bat Debug # Debug
build.bat Release clean # Clean and rebuild
build.bat run # default settings
build.bat run -- --window hamming # Hamming window
build.bat run -- --fft 2048 --rows 30 # 2048-point FFT, 30 rows height
build.bat run -- --min-db -60 --max-db 0 # narrow the dB range
Option
Default
Description
--window
hann
hann / hamming / rect
--fft <N>
4096
FFT size (even number, power of 2 recommended)
--rate <Hz>
44100
Sample rate
--cols <N>
80
Number of frequency columns
--rows <N>
20
Display height (terminal rows)
--min-db <dB>
-80
Lower bound of the dB axis
--max-db <dB>
0
Upper bound of the dB axis
Microphone
│ (float32 PCM, 44.1 kHz)
▼
AudioCapture ──ring-buffer──▶ readLatestFrame(N)
│
▼
WindowFunction::apply()
(Hann / Hamming / Rect)
│
▼
FFTProcessor::process()
kiss_fftr → |X[k]| → dBFS
│
▼
SpectrumDisplay::render()
log-scale bar chart @ 30 fps
Parameter
Value
Effect
FFT size N
4096 @ 44.1 kHz
Frequency resolution ≈ 10.8 Hz/bin
Window length
Same as N
Larger N → finer frequency, slower time response
Hann window
w[n] = 0.5(1−cos(2πn/(N−1)))
Sidelobe ≈ −31 dB
Hamming
w[n] = 0.54−0.46·cos(2πn/(N−1))
Sidelobe ≈ −41 dB
dBFS
20·log₁₀(
X[k]