End-to-end physical layer implementation — C++17 + Python 3.11
Built as a portfolio project demonstrating PHY software engineering skills relevant to 4G/5G base station development.
├── cpp/
│ ├── dsp.h # Cooley-Tukey Radix-2 FFT/IFFT from scratch
│ ├── ofdm.h # OFDM modulator/demodulator (LTE numerology)
│ ├── channel.h # AWGN + Rayleigh fading channel models
│ └── main.cpp # BER vs SNR simulation (outputs ber_results.csv)
│
├── python/
│ └── spectrum_analyzer.py # RF spectrum analysis + signal detection
│
└── docs/
└── project_writeup.docx # Full technical write-up
Full LTE baseband chain, no external libraries:
Random bits → QAM mapper → Subcarrier mapping → IFFT → Cyclic prefix → TX signal
↓
AWGN channel
↓
Decoded bits ← QAM demapper ← FFT ← CP removal ← RX signal
g++ -O2 -std=c++17 -o ofdm_ber cpp/main.cpp
./ofdm_berOutput: BER table printed to stdout + ber_results.csv for plotting.
| Parameter | Value |
|---|---|
| FFT size | 128 |
| Active subcarriers | 72 (6 RBs) |
| Subcarrier spacing | 15 kHz |
| Cyclic prefix | 9 samples (normal CP) |
| Modulation | BPSK / QPSK / 16-QAM / 64-QAM |
IFFT(FFT(x)) max error: 5.2e-16 ✓ (floating-point machine epsilon)
Zero-noise BER: 0 bit errors across all modulation orders ✓
Processes real RTL-SDR IQ captures or synthetic signals.
pip install numpy scipy matplotlib# Synthetic demo (no hardware needed)
python python/spectrum_analyzer.py --demo --fc 1800 --fs 20.0
# Real RTL-SDR capture
python python/spectrum_analyzer.py --file capture.bin --fc 1800 --fs 2.0
# Plot BER curves from C++ output
python python/spectrum_analyzer.py --ber ber_results.csvIQ samples → Hanning window → FFT (Welch PSD) → dBm conversion
→ Peak detection → 3dB BW estimation → Signal classification
→ Spectrum plot + Waterfall display
| Occupied BW | Classification |
|---|---|
| ≥ 80 MHz | 5G NR (100 MHz) |
| 18–25 MHz | LTE 20 MHz |
| 8–13 MHz | LTE 10 MHz |
| 4–8 MHz | LTE 5 MHz |
# Install drivers
sudo apt install rtl-sdr gnuradio
# Test dongle
rtl_test -t
# Capture LTE Band 3 (1800 MHz)
rtl_sdr -f 1800000000 -s 2000000 -n 2000000 capture.bin
# Analyse
python python/spectrum_analyzer.py --file capture.bin --fc 1800 --fs 2.0- 3GPP TS 36.211 — LTE Physical channels and modulation
- 3GPP TS 38.211 — NR Physical channels and modulation
- Cooley & Tukey (1965) — "An Algorithm for the Machine Calculation of Complex Fourier Series"
- Frequency-domain channel equaliser (ZF / MMSE)
- LDPC/Turbo FEC to show coding gain on BER curves
- SIMD optimisation using Intel AVX2 intrinsics
- LTE cell search (PSS/SSS detection)
- GNU Radio real-time integration