JTDX_CONTEST · CE3TSKTested during WW Digi 2026 · 1 / 12
v3.0.0-rc05 · derivative work of JTDX by UA3DJY/ES1JA and WSJT-X by K1JT

JTDX
Contest Edition

New decoding approaches. More decodes. Decided on time. Built for WW Digi.

+27.5 % more messages than stock JTDX and +20 % over WSJT-X 3.0.2 on one hour of real air — with the reply still decided at 1.1 seconds into the period, and the contest exchange, points and log built in. The GUI has been repaired throughout and the dark style now works.

165815 -24  0.3 1061 ~ CQ CT7AUT IM67      *
165815 -21  0.1 2180 ~ RI1FJL W6EU CM99    |
165815 -19  0.2 1793 ~ KC3MSE K7MK DN13
Measured on 240 consecutive 15 s periods, 2026-08-27 16:57–17:57 UTC, 20 m, 100–3100 Hz, 12 threads on an AMD Ryzen 7 5800H (8 cores / 16 threads)ce3tsk.com · github.com/ce3tsk/jtdx_contest · How the decoder works · Benchmark WAV files
The headline2 / 12

One hour of air, every decoder, same audio

The same 240 recorded FT8 periods, decoded by each engine with its own best settings. Unique messages found:

JTDX Contest Edition · Pipeline ensemble fullSWL-4 + member at reply time, every unit in the TX background
6 208
JTDX Contest Edition · recommended presetPipeline max decodes light, 5.3 s of CPU per period
6 091
JTDX_CONTEST at JTDX’s own recipe9 cycles, sensitivity 2 — what the fork does with stock’s settings
5 249
WSJT-X 3.0.2multi-thread FT8 decoder, 9 passes, sensitivity 3, AP
5 171
WSJT-X improved 3.2.0same settings
5 163
Stock JTDX v2.2.159 without ALLCALL7.TXTits known-call lookup switched off — 67 real decodes back — the baseline
4 869
Stock JTDX v2.2.159 as shipped9 cycles, sensitivity 2, ALLCALL7.TXT, 12 threads
4 802
WSJT-X 3.0.2 standard decoderdepth 3, AP
4 782
+27.5 %
vs stock JTDX without ALLCALL7.TXT
6 208 against 4 869, its known-call lookup switched off
+29.3 %
vs stock JTDX v2.2.159
6 208 against 4 802 messages, as shipped
+20.1 %
vs WSJT-X 3.0.2
its best mode, its own ini settings
+16.8 %
live, side by side
two receivers on one antenna, 56 minutes on air
Union of all engines: 6 450 messages · Pipeline ensemble reaches 96.2 % of everything anyone decodedmeasured by CE3TSK
The innovation — in no other FT8 program3 / 12

Decide at 1.1 s. Keep decoding while you transmit.

No other FT8 program does this. WSJT-X, JTDX and MSHV all decode once per period and then wait. A contest reply must be decided before the transmitter keys. So the decoder is split in two: a fast RX phase that decides the answer, and a TX background that keeps working on the same audio through your own transmission — where the CPU used to sit idle.

051015202530 seconds RX audio, 12.64 s your transmission decode trigger 14.1 s RX phase 1.1 s → reply decided TX background light preset ~6 s (green), pipeline ensemble up to ~11 s (blue) — stops before the next decode next decode 29.1 s one period = 15 s the classic decoder does everything in the cyan slot; the pipeline uses the idle time behind it
Times measured on the 240-period benchmark, 12 threads of an AMD Ryzen 7 5800H. The background aborts cleanly on a band change and never carries over.

The RX phase

5 cycles, sensitivity 2, one ensemble member: 87 of 100 reference messages on the benchmark, 1.1 s per period on the air. AutoSeq answers on time, every period.

The TX background

The plain classic pass on pristine audio, two ensemble members, then the residual pass — fixed, measured lists, no guesswork. Their decodes arrive while you transmit and are ready for the next reply.

Pipeline units abort cleanly at a band change and never carry over between periods
Two new ways to decode4 / 12

New approaches, and where the extra messages come from

New approach 1: the alternate pass

After the normal passes have decoded and subtracted what they can, the residual audio is decoded again with the opposite recipe — SWL after plain, plain after SWL. Each recipe has its own blind spots; the alternate pass covers them.

New approach 2: the ensemble

Re-decodes of the same audio through fixed perturbations — delay, dither, tone shift — each member finding messages the others miss, the union kept. Deterministic: the same set on any machine with 2 threads or more.

Four-period hint memory

The hint decoder used to forget a station after one missed period. It now remembers four: +6 % messages on the hour, at no measurable CPU cost; cleared on a band change.

Where the gains are

Share of the extra messages by signal level — the recommended preset more than doubles the decodes at the weakest end, 152 → 346 in the hour.

≤ −24 dB~1/5
−23 … −21 dB~1/2
−20 … −18 dB~1/4
> −18 dBrest

100–3100 Hz done right

The decode range no longer follows the waterfall: the sync baseline and slice grid are anchored to the full band, so a narrower range decodes exactly as the full band does inside it.

Every approach is a fixed, measured unit — the same audio gives the same messages on any machine
One menu, six measured choices5 / 12

Pick a preset. The lamp tells you which one is on.

Every tier is a measured recipe on the same hour of air — decodes gained over stock JTDX (its ALLCALL7 lookup off), and the CPU it costs per 15 s period. Applying one also sets the environment it was measured in. Everything else lives under an expert submenu.

Best power

+11.3 %0.4 s

Maximum efficiency — the most decodes per second of CPU. Laptops on battery.

Best value

+16.6 %1.1 s

Maximum decodes — 5 cycles, sensitivity 2, one member. Four-core machines.

Recommended

Best medium effort

+25.1 %5.3 s

Pipeline max decodes light — the reply decided at 1.1 s, a ~6 s background through TX.

Best results

+27.2 %12.7 s

Pipeline ensemble — for S&P and monitoring on 8 threads or more.

Max effort

+27.5 %14.0 s

Pipeline ensemble full — every member sample.

Most results

+28.0 %13.3 s

Pipeline run — 5 cycles in the period, the whole ensemble behind it.

+0 %+5 %+10 %+15 %+20 %+25 %+30 % 0 s2 s4 s6 s8 s10 s12 s14 s Stock JTDX, ALLCALL7 off 4 869 Best power +11.3 %Best value +16.6 %Best medium effort (recommended) +25.1 %Best results +27.2 %Max effort +27.5 %Most results +28.0 %Ensemble (RX only) +23.1 % CPU seconds per 15 s period messages gained over stock JTDX (ALLCALL7 off), 240 periods
The knee is the recommended preset: 90 % of the maximum gain for 40 % of the CPU — and the reply still decided at 1.1 s.

The preset lamp

Under the Contest lamp, above Tune: Preset R in the tier's colour, Custom the moment a control drifts, greyed outside FT8.

Contest
Preset R

Budget auto

Optionally, the RX phase adds ensemble members while the next one's learned cost still fits the 2.7 s reply budget — a quiet band gets depth at reply time, a crowded one stays fast.

Presets set early start off and wideband DX Call search on — the environment every table was measured in
Cleaner output, honest numbers6 / 12

Fewer phantoms, more real stations

The stale callsign list retired

Stock JTDX discards any message whose callsigns are both missing from a 2024 callsign file — every QSO between two recently licensed stations, whatever the SNR. Measured: ~45 real decodes an hour thrown away for one or two false ones. Switched off.

Phantom reports rejected

CE3TSK JW1GPY/R 216 — a random codeword behind an a-priori callsign. Reports no transmitter can encode are now refused at unpack time; RTTY Roundup exchanges and telemetry, never used in FT8 on HF and only ever seen as false decodes, are switched off in the source.

Deterministic and thread-safe

Six data races found and fixed in the stock decoder (shared audio buffer, FFT plan caches, OSD init, message store). The same audio now gives the same messages on 1, 3 or 12 threads — which is what makes every number here reproducible.

Faster core

OSD bit-packing rewritten into 64-bit words, the sync window sums tabulated, the candidate cap raised from 450 to 2000 so a crowded band no longer silently drops real signals.

Tested like software

43-row deterministic decode regression, 14 background/abort cases, Fortran unit checks, a C++ harness for presets, contest logic and the sequencer — all green before every deployment.

False-decode classRateNow
Real QSOs discarded by the 2024 callsign list−45 / hlookup off — the decodes are back
Telemetry (18 hex digits)~50 / monthswitched off
RTTY Roundup exchanges~10 / monthswitched off
Phantom reports (/R 216)2 / monthrejected at unpack
A-priori phantoms with a plausible call~10 / monthno safe filter — left, ≤ 1 every 3 days
False-decode rate in production, as seen with classic JTDX: ~5 lines a day out of ~26 000, 0.02 %IMPROVEMENTS_WW_DIGI_2026.pdf items 8–36
Are the extra decodes real?7 / 12

The extra messages, checked one callsign at a time

Every message a preset found that stock JTDX (ALLCALL7 off) did not, on the same hour of air — each callsign checked against 14 months of production ALL.TXT (95 801 callsigns, the experiment hour excluded), the ALLCALL7 database, and what stock JTDX and WSJT-X decoded elsewhere in the hour.

PresetExtra messagesAll callsigns knownUnknown
Maximum efficiency624623 (99.8 %)1
Maximum decodes860856 (99.5 %)4
Pipeline max decodes light — recommended12291218 (99.1 %)11
Pipeline ensemble13391313 (98.1 %)26
Pipeline run13711350 (98.5 %)21
Known = decoded by production on another day, listed in ALLCALL7, or decoded by stock JTDX / WSJT-X in the same hour.
Engine, whole hourMessages with an unknown callsign
Stock JTDX, ALLCALL7 off24 / 4 869 (0.49 %)
WSJT-X 3.0.226 / 5 171 (0.50 %)
WSJT-X improved 3.2.026 / 5 163 (0.50 %)
Pipeline max decodes light26 / 6 091 (0.43 %)
Pipeline ensemble36 / 6 208 (0.58 %)

Where the doubtful ones sit

At the −23 dB floor: 25 of the 38 doubtful messages, 2 below it — where 211 extras from known stations live. 29 of them come from the TX background, 9 from the reply-time decode.

Already removed

The RTTY Roundup serials and telemetry strings that made 17 of the August run’s 52 doubtful messages are switched off in the source — none in this run.

the extra-calls check of the measurement harness · 240 periods, 2026-09-05 · audio at ce3tsk.com/download/wavmeasured by CE3TSK
FT4, not only FT88 / 12

FT4: the same decoder, rebuilt around a 1.36 s deadline

FT4 gives the decoder 1360 ms of its 7.5 s period. The contest edition carries every FT8 approach across — slice threading, the ensemble, the alternate pass, a four-period hint memory, a TX background with its own settings and a budget that fits the effort to the band — each measured on 240 consecutive on-air periods.

+24 %
more messages than stock JTDX
1 525 → 1 888, max effort, stock without its ALLCALL7.TXT
+8.7 %
over the default recipe
1 737 → 1 888; recommended 1 881 for nothing at reply time
0.59 s
reply time at max effort
the deadline is 1.36 s; recommended answers in 0.10 s
PresetMessagesAt reply timeReply sBackground s
Stock JTDX v2.2.159 without ALLCALL7.TXT1 5251 525
WSJT-X 3.0.21 5611 561
Default1 7371 7370.10
Best power1 8221 7610.100.3
Recommended1 8811 7630.102.1
Most at reply time1 8781 8370.480.5
Max effort1 8881 8550.590.6
240 periods, 14.080 MHz, 100–3100 Hz, 12 threads. “At reply time” = decoded before the transmitter keys; the rest arrive in the TX background.

Threaded, deterministic, whole at the seams

The band is fanned out over an anchored grid of 417 Hz cells, each slice subtracting into its own copy of the audio: 295 ms down to 95. Four data races inherited from stock were fixed, so the same audio gives the same message set at any thread count of 2 or more, byte for byte, and a second slicing with every edge shifted half a cell closes the boundaries.

A TX background of its own

While you transmit, the decoder re-works the retained period: the members the reply phase did not run, deep OSD, the alternate pass, the residual pass, lower thresholds — switched on exactly as FT8’s, with its own effort, sensitivity and clock, until 0.5 s before the window ends. That is where +8 % comes from for nothing at reply time.

Six presets and a budget

Fast, default, best power, recommended, most at reply time, max effort — every label carries its measured cost. Max effort’s member count is budget auto: the decoder learns what a member costs on this band and admits as many as fit inside 1.3 s. The Preset lamp names the tier; an X after a background the next period cut short says the load wants a look.

What FT8 has, FT4 has

The hint memory four periods deep (+12 %), the virtual candidate at the QSO frequency (+1 dB on the reply you are waiting for), four subtraction passes, the second DT peak, the false-decode gate and the best-SNR merge across slices — one design, two modes.

240 consecutive periods, 14.080 MHz, WW Digi 2026 · 12 threads · FT4 deadline 1360 ms of a 7.5 s periodIMPROVEMENTS_WW_DIGI_2026.pdf items 51–81
FT4, the same test9 / 12

Half an hour of air, every FT4 decoder, same audio

The same 240 recorded FT4 periods of 7.5 s (14.080 MHz, WW Digi 2026), decoded by each engine with its own best settings, 100–3100 Hz. Unique messages found:

JTDX Contest Edition · max effortbudget-auto members + low thresholds at reply time, everything in the TX background
1 888
JTDX Contest Edition · recommendedbackground 6 + deep OSD + alternate pass + residual, nothing at reply time
1 881
WSJT-X improved 3.2.0FT4 decoder, depth 3, AP
1 688
WSJT-X 3.0.2FT4 decoder, depth 3, AP
1 561
JTDX_CONTEST without its hint memoryJTDX’s FT4 recipe on the fork’s code
1 552
Stock JTDX v2.2.159 without ALLCALL7.TXTits known-call lookup switched off — 169 real decodes back — the baseline
1 525
Stock JTDX v2.2.159 as shippedits FT4 decoder, ALLCALL7.TXT present
1 356
+23.8 %
vs stock JTDX without ALLCALL7.TXT
1 888 against 1 525, its known-call lookup switched off
+39.2 %
vs stock JTDX v2.2.159
1 888 against 1 356 messages, as shipped
+20.9 %
vs WSJT-X 3.0.2
its FT4 decoder at depth 3, AP
+11.8 %
vs WSJT-X improved 3.2.0
its FT4 decoder at depth 3, AP
+10.5 %
on the day hour too
73 busier periods: 507 → 560
Union of all engines: 2 008 messages · max effort reaches 94.0 % of everything anyone decodedmeasured by CE3TSK
WW Digi, built in10 / 12

The exchange, the points and the log — automatic

One switch on the Contest tab

Selecting WW Digi parks 28 settings and eight main-window controls in their contest state, names the contest in the window title and lights the Contest lamp. Nothing to remember at 03:00am during a contest.

The exchange that works

HISCALL MYCALL R FF46 — received and transmitted correctly, the grid as the exchange, the SNR in the log's RST fields where it belongs. No grid, no transmission.

Points and multipliers live

1 + km/3000 per QSO from 4-character grid centres, shown next to every decode (CQ XQ3SK FF46 * 1p Chile) and in the score bar as M × P = S. Multipliers are the 2-character fields, tracked per band.

Autoselect that knows the rules

Contest points rank above every other tier, a new field outranks a new DXCC, and rule XI.12 is respected: the sequencer answers stations calling you and never initiates. Several callers? The most valuable one first, then the strongest.

A separate contest log

Every contest QSO goes to its own ADIF; worked-before, multipliers, highlighting and the score all come from it, so a rare field worked in 2025 is new again this year.

Contest frequencies

The contest keeps its own frequency list, separate from the everyday band plan, and restores yours when it ends.

DistancePoints
< 3 000 km1
3 000 – 5 999 km2
6 000 – 8 999 km3
9 000 – 11 999 km4
12 000 – 14 999 km5
15 000 – 17 999 km6
≥ 18 000 km7
1 + km/3000 from 4-character grid centres; 20 400 km (antipodes) = 7, nothing on Earth is further.
ContestWW-Digi271 QSOs58M × 213P = 12 354
Settings interlock: the parked controls come back exactly as they were when the contest is switched offIMPROVEMENTS_WW_DIGI_2026.pdf
Before you judge the numbers11 / 12

These recipes are tuned for this machine, or a faster one

Every figure in this deck was measured on one computer: an AMD Ryzen 7 5800H (8 cores / 16 threads), otherwise idle, with the decoder on 12 threads. The shipped presets are calibrated for that class of CPU or better. On a slower one they can miss the deadline.

The deadline is real

FT8 decides the reply 1.1 s into the period; FT4 must finish inside 1360 ms of 7.5 s. Past that a decode is not merely slow — the reply is gone. A preset that fits here need not fit on a slower CPU.

Eight threads is the useful ceiling

The band is cut into a fixed grid of 417 Hz cells — 8 slices over 100–3300 Hz — so a ninth thread has no slice to take: 12 threads measured no faster than 8. Fewer than 8 costs proportionally more time.

FT4 has a budget too

Since v3.0.0-rc02 FT4’s max effort preset uses budget auto: the decoder learns what a member costs on this band and this machine, and admits as many as fit inside 1.3 s. The other tiers follow the thread count. On a slower CPU the budget trims by itself; a fixed ladder does not.

What to do on a slower machine

Pick a lower tier for FT8. For FT4 pick max effort, which fits itself, or a lower tier; the members can still be set by hand under Decode → FT4 decoding → expert → RX → ensemble effort. Every menu label carries the measured cost of that step, and the Preset lamp shows an X when a background was cut short by the next decode.

One thread is the exception

At a single thread both modes decode the band as one piece and skip the second slicing, so the set differs from every multi-threaded run — 6 lost and 3 gained on 60 FT4 periods. From two threads up the set is identical at every count.

This is a release candidate

v3.0.0-rc05, in its first round of beta testing. The recipes will be re-measured across machines before anything is called final, — the recordings and a benchmark script are already published at ce3tsk.com/download/wav, so anyone can repeat them on their own CPU. Thanks to the operators who put those first candidates on the air: Willy XQ3SK, Eduardo CA3EAP, Miguel CA7FKZ and Cristian CA8CEU.

Measured on an idle AMD Ryzen 7 5800H (8 cores / 16 threads), 12 decoder threads · scaling the recipes for weaker machines is future worksrc/decodepreset.h
Measured, reproducible, deployed12 / 12

Every claim has a wav file behind it

No number on these slides is an estimate. Each comes from recorded audio, a file-mode decoder run and a script anyone can rerun — the recordings and the replay script are at ce3tsk.com/download/wav.

The benchmark

240 consecutive on-air periods plus a 100-message reference capture, run on an AMD Ryzen 7 5800H laptop; run_presets.sh re-runs every preset and every WSJT-X engine and rewrites the tables in the documents.

The comparisons

Side-by-side ALL.TXT analysis of two receivers, gain distribution by SNR, hint-memory depth 1–8, with and without the callsign file — all archived with their outputs.

The documents

FT8_DECODER.pdf explains the decoder; IMPROVEMENTS_WW_DIGI_2026.pdf lists every change with its measurement.

Get started

Decode → FT8 decoding → Presets → recommended: best medium effort. Settings → Contest → WW Digi. Watch the lamps: Contest green, Preset R green. Go.

CE3TSK

Tihomir Sokcevic, Santiago de Chile — author of every change on these slides: the decoder work, the contest support, the measurements and the documents.Questions, reports from the air and QSOs welcome: CE3TSK on the bands, on the WW Digi weekend and after. · ce3tsk.com · github.com/ce3tsk/jtdx_contest · How the decoder works · Benchmark WAV filesBuy Me a Coffee at ko-fi.com

CE3TSK · Tihomir Sokcevic · August 202673
JTDX Contest Edition · Tihomir Sokcevic · CE3TSK · ce3tsk.com · github · How the decoder works · Benchmark WAV files
↑ ↓ or PgUp / PgDn to move between slides