Project_Detail
All_Projects

rtl-psp

RTL-SDR receiver for the Sony PSP

View on GitHub
README.md

RTL-PSP

An RTL-SDR receiver for the Sony PSP. The PSP connects over WiFi to an rtl_tcp server on a PC, streams raw 8-bit I/Q, and renders a live spectrum + waterfall on the 480x272 screen. It also includes a mono WFM (broadcast FM) demodulator with audio out.

Tested in PPSSPP and on a PSP-2000 (ARK-5, 6.61, WPA2).

 RTL-SDR ──USB──▶ PC (rtl_tcp) ──WiFi/TCP──▶ PSP
                                              ├─ FFT ──▶ spectrum + waterfall
                                              └─ WFM demod ──▶ 44.1 kHz audio

Layout

Path What
psp/ PSP homebrew client (C, pspdev SDK) → psp/EBOOT.PBP
psp/src/net.c WiFi (sceNetApctl) bring-up and a small TCP client
psp/src/rtltcp.c rtl_tcp protocol: header, tuning commands, I/Q stream
psp/src/fft.c Float radix-2 complex FFT + Hann window
psp/src/viewer.c Spectrum/waterfall rendering (oslib) and input
psp/src/wfm.c FM discriminator, decimation, de-emphasis, resampler
psp/src/demod.c Demodulator thread fed by an I/Q ring buffer
psp/src/audio.c 44.1 kHz mono output thread (stereo duplexed)
psp/src/ui.c Settings screen and status messages
tools/ Build/install helpers

Build

The PSP client is built with the pspdev/pspdev Docker image:

tools/pspbuild.sh            # -> psp/EBOOT.PBP
tools/pspbuild.sh clean

Install to a real PSP (USB mode) or PPSSPP's memstick:

tools/install-psp.sh

Run

Start rtl_tcp on the PC (bind to all interfaces so the PSP can reach it):

rtl_tcp -a 0.0.0.0 -p 1234 -f 102500000 -s 250000

The PC firewall must allow inbound TCP 1234.

Copy EBOOT.PBP to ms0:/PSP/GAME/RTLPSP/ and launch it. On first run the settings screen asks for the server address; settings persist to ms0:/RTLPSP/config.txt.

Controls

Screen Input Action
Viewer ← / → Tune ±100 kHz
Viewer L / R Tune ±1 MHz
Viewer X Toggle gain auto/manual
Viewer Triangle Toggle WFM audio
Viewer Start Pause / resume
Viewer Select / Circle Settings
Settings ↑ / ↓ Move field
Settings ← / → , L / R Change value
Settings X Edit text / toggle
Settings Start Save and connect
Any HOME Quit

How it works

  1. Tune — the client opens TCP 1234, reads the 12-byte RTL0 header, and sends set_frequency, set_sample_rate and gain commands.
  2. Stream — rtl_tcp sends interleaved unsigned 8-bit I/Q. The client drains the socket into a ring and consumes the newest data.
  3. Spectrum/waterfall — a 1024-point FFT of a Hann-windowed frame gives 1024 bins, FFT-shifted so the tuned frequency is centred. Magnitudes are mapped to a 256-entry palette; the waterfall is a scrolling 5650 image.
  4. WFM audio — I/Q is decimated to ~256 kHz, run through a polar discriminator, low-passed by three cascaded boxcars (rejects the 19 kHz pilot and 38 kHz stereo subcarrier), de-emphasised (75 µs), and resampled to 44.1 kHz. The demodulator runs on its own thread so it never starves audio scheduling.

Status

Working

  • Live spectrum + waterfall from rtl_tcp in PPSSPP and on real hardware.
  • Mono WFM audio.
  • Settings persisted on the memory stick; live tuning while streaming.

Limitations

  • Bandwidth. The PSP's 802.11b link caps throughput at roughly 4 Mbit/s, so the sample rate must stay around 250 kSps. At 1.024 MSps rtl_tcp cannot keep up and drops samples. 250 kSps is enough for WFM but gives only a 250 kHz-wide waterfall.
  • Weak signals. Auto gain can settle low; use manual gain for weak stations.
  • Mono WFM only — no stereo decoding or RDS.

Gotchas worth remembering

  • ms0:/ maps to the memory stick root. Under PPSSPP that is ~/.config/ppsspp/ (so ms0:/RTLPSP/config.txt is ~/.config/ppsspp/RTLPSP/config.txt, not under PSP/).
  • Homebrew runs at 222 MHz unless it calls scePowerSetClockFrequency.
  • On the PSP, doubles are software-emulated and FPU divides are slow — keep the hot DSP path in single precision and avoid divides/modulo.
  • The demodulator's I/Q decimation and the audio boxcar cascade are what keep the 38 kHz stereo subcarrier from aliasing into the audio band; a single boxcar is not enough.
  • rtl_tcp serves one client at a time, and PPSSPP and a real PSP cannot share it simultaneously.
  • PPSSPP shares one emulated CPU across all threads, so a heavy DSP loop shows up as a low emulated frame rate and can overflow the audio queue.

License

MIT