Skip to content

Performance

pschatzmann edited this page Oct 29, 2026 · 3 revisions

The speed of the modulators and demodulators, as multiples of real time: everything above 1 is fast enough, the rest is CPU time which is left for your application. The memory is documented in Memory usage.

Measurements

Measured with the benchmark example at 8000 Hz: the values are multiples of real time, so everything above 1 is fast enough. All modes decoded all characters on all boards and the PC, except one additional (wrong) character of qpsk125 on the RP2350.

Demodulation

Mode ESP32-S3 ESP32-P4 RP2040 RP2350 PC
FSK 1200 40 120 9.1 20 4700
mfsk16 27 70 3.6 16 1600
mfsk64 10 27 1.2 6.2 490
psk125 58 127 7.6 62 6900
qpsk125 52 114 7.3 53 5100
8psk250 40 85 6.2 44 5000
ofdm32 10 27 2.0 7.0 1800
aprs 24 57 4.8 23 1600
fx25 28 98 6.3 41 2900
il2p 21 56 4.8 22 1600
olivia-8-250 4.0 8.2 0.7 3.2 390
olivia-32-1000 2.6 5.1 0.5 2.0 230
contestia-8-250 5.8 12 0.9 4.5 610
css7 5.5 7.2 1.0 5.2 900
css10 5.4 7.4 1.0 5.1 880
morse 131 317 14 95 11000
morse-american 127 304 14 93 10000
dtmf 42 87 2.6 27 7500

Modulation

Mode ESP32-S3 ESP32-P4 RP2040 RP2350 PC
FSK 1200 72 142 20 75 4000
mfsk16 82 174 20 74 5700
mfsk64 84 183 21 87 6100
psk125 74 190 9.4 69 4600
qpsk125 73 190 9.4 69 3900
8psk250 70 176 9.1 63 3900
ofdm32 6.6 14 3.3 1.5 390
aprs 63 115 17 62 3900
fx25 33 110 16 57 3600
il2p 48 114 17 60 4500
olivia-8-250 5.6 10 5.4 23 2400
olivia-32-1000 5.8 11 5.8 24 2400
contestia-8-250 6.0 11 6.0 26 2800
css7 5.5 8.6 4.3 17 2300
css10 5.5 8.6 4.1 17 2300
morse 200 456 33 104 16000
morse-american 199 442 36 99 16000
dtmf 17 34 18 83 7200
  • ESP32-S3 at 240 MHz with 8 MB octal PSRAM (FQBN esp32:esp32:esp32s3:PSRAM=opi), arduino-esp32 3.3.12.
  • ESP32-P4 (Waveshare ESP32-P4-WIFI6, FQBN esp32:esp32:esp32p4:ChipVariant=postv3), arduino-esp32 3.3.12.
  • RP2040 (Raspberry Pi Pico, 133 MHz, no floating point unit, FQBN rp2040:rp2040:rpipico), Arduino-Pico 6.3.0.
  • RP2350 (Raspberry Pi Pico 2 W with PSRAM, 150 MHz, single precision floating point unit, FQBN rp2040:rp2040:rpipico2w), Arduino-Pico 6.3.0. The benchmark doesn't use the PSRAM.
  • PC: Intel Core i7-4650U (1.7 GHz, 2013), Linux, GCC 13 with -O3, the benchmark sketch compiled for the desktop. The median of three runs, rounded to two digits: a run only takes a few milliseconds, so the values vary by about ±20%.
  • The RP2040 is too slow for the Olivia and Contestia decoders (values below 1, in bold): they can only decode recorded audio, not in real time. CSS (1.0) has no headroom left: use the ESP32 for CSS. mfsk64 (1.2) and ofdm32 (2.0) leave little time for the application. All other modes run fine. The RP2350 is fast enough for all modes: thanks to its floating point unit it decodes 2 to 6 times faster than the RP2040. Only the OFDM encoder is slow on it (1.5).
  • Olivia needs the most CPU: olivia-32-1000 has the least headroom. CSS needs about the same for all spreading factors, because the FFT size grows with the symbol length. The CSS encoder calculates the chirp phase with double precision, which is slow on these chips (no double precision FPU). At higher sample rates the decoder also converts the input to 8000 Hz, which costs additional time.
  • The benchmark passes the generated audio directly to the decoder, so it doesn't need memory for the audio and also runs on boards without PSRAM. On an ESP32-S3 with octal PSRAM, select PSRAM=opi: with quad PSRAM the PSRAM isn't found.

Use a recent version of the arduino-audio-tools: older versions compute double precision sin()/cos() in the Goertzel filter for each block, which is slow on MCUs without a double precision FPU (FSK, MFSK), and their Vector::push_back() grows the buffer by one element at a time (the modulation in the benchmark was then slower than real time).

To measure your board, run the benchmark example: it needs no audio hardware and prints the real time factor of each mode. The decoding speed depends mostly on the sample rate, so use the lowest sample rate your hardware supports (see the comment on Olivia and CSS above).

PC

The PC values are in the tables above. ggwave isn't part of the benchmark: it is much slower, ggwave-fast decodes 79 times faster than real time at 24000 Hz on the PC.

The tinymodem --benchmarks option measures the FSK and MFSK modems on the desktop.

Clone this wiki locally