Line-by-line source code analysis of lib/ft2/ directory.
Are the FT2 implementations related? Is code copied? Here are the facts.
Protocol parameters. LDPC(128,90) vs LDPC(174,91). Incompatible modulation and timing.
Message encoder. 2-FSK binary vs 4-FSK Costas. AL_PLUS has wrong comment "Encode an MSK144 message".
Decoder. Monolithic (AL_PLUS) vs modular 9-file architecture (Decodium). Different LDPC decoders.
Candidate search. int16 3-point smoothing vs float Nuttal window, baseline subtraction, parabolic fit.
Common block. Byte-for-byte identical. Contains NMAX=30000 matching AL_PLUS params.
Main program + update() + transmit(). Every line identical including comments.
PortAudio interface. SoundIn/SoundOut callbacks, device enumeration. Identical.
PTT control for Windows COM ports and Unix serial/parallel. Identical.
Waveform generation for FT2 mode. 64 lines identical.
GFSK waveform generation. 88 lines identical.
Utility functions. Date/time formatting and GFSK pulse shape. Identical.
Config file (K1JT FN20) and PortAudio header. Identical.
ft2_baseline, ft2_downsample, foxfiltft2, foxgenft2, gen_ft2wave, get_ft2_bitmetrics, getcandidates2, subtractft2, sync2d, and more.
This file defines the entire FT2 protocol architecture. The two projects are radically incompatible.
| Parameter | AL_PLUS | Decodium | Impact |
|---|---|---|---|
| LDPC Code | (128, 90) | (174, 91) | Incompatible decoders |
| KK (info bits) | 90 (77 + CRC13) | 91 (77 + CRC14) | Different CRC length |
| ND (data symbols) | 128 | 87 | Different frame length |
| NN (total symbols) | 144 | 103 (+2 ramp = 105) | Different frame structure |
| NSPS (samples/symbol) | 160 | 288 | Nearly 2x longer symbols |
| NMAX (buffer) | 30,000 | 45,000 | 50% larger buffer |
| NDOWN (downsample) | 16x | 9x | Different DSP chain |
| TX Duration | 1.92s | 2.52s | Cannot interoperate |
| Sync Type | 2x8 binary | 4x4 Costas arrays | Different sync detection |
| Modulation | 2-FSK (0,1) | 4-FSK (0,1,2,3) | Different modulation |
| Code Rate | 0.703 | 0.523 | Decodium more robust |
| Baud Rate | 75 baud | 41.67 baud | Different keying speed |
! LDPC (128,90) code parameter (KK=90) !77 + CRC13 parameter (ND=128) !Data symbols parameter (NS=16) !Sync symbols (2x8) parameter (NN=NS+ND) !Total: 144 parameter (NSPS=160) !Samples/symbol parameter (NMAX=30000) !2.5*12000 parameter (NDOWN=16) !Downsample
! LDPC(174,91), four 4x4 Costas arrays parameter (KK=91) !77 + CRC14 parameter (ND=87) !Data symbols parameter (NS=16) !Sync symbols parameter (NN2=NS+ND+2) !Total: 105 parameter (NSPS=288) !Samples/symbol parameter (NMAX=45000) !3.75*12000 parameter (NDOWN=9) !Downsample
"Encode an MSK144 message" — proving it was copied/adapted from the MSK144 mode in WSJT-X, not from Decodium.
subroutine genft2(msg0,ichk,msgsent,i4tone,itype) ! s8 + 48bits + s8 + 80 bits = 144 bits ! Encode an MSK144 message <-- WRONG! ! i4tone: values 0 or 1 <-- 2 tones integer*1 s16(16) data s16/0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0/ call encode_128_90(msgbits,codeword) ! Simple frame: sync + codeword bitseq(1:16)=s16 bitseq(17:144)=codeword ! No Grayscale mapping ! No scrambling vector ! No Costas arrays i4tone=bitseq
subroutine genft2(msg0,ichk,msgsent,msgbits,i4tone) ! Encode an FT2 message <-- CORRECT ! i4tone: values {0,1,2,3} <-- 4 tones integer icos4a(4),icos4b(4),icos4c(4),icos4d(4) data icos4a/0,1,3,2/ ! Costas array 1 data icos4b/1,0,2,3/ ! Costas array 2 data icos4c/2,3,1,0/ ! Costas array 3 data icos4d/3,2,0,1/ ! Costas array 4 msgbits=mod(msgbits+rvec,2) ! Scrambling call encode174_91(msgbits,codeword) ! Grayscale mapping: 00->0 01->1 11->2 10->3 ! Frame: r1+s4+d29+s4+d29+s4+d29+s4+r1
| Aspect | AL_PLUS | Decodium |
|---|---|---|
| Architecture | Monolithic (1 file, 298 lines) | Modular (9+ dedicated files) |
| Input type | integer*2 (int16) | real (float) |
| LDPC Decoder | bpdecode128_90 | LDPC(174,91) decoder |
| Downsample | Gaussian filter (inline) | Nuttal window (separate file) |
| Sync detection | Binary correlation (s16) | Costas array correlation (sync2d.f90) |
| Baseline correction | None | ft2_baseline.f90 |
| Signal subtraction | None | subtractft2.f90 |
| Fox/Hound support | None | foxfiltft2.f90 + foxgenft2.f90 |
| Multi-decode | Single pass only | Iterative with subtraction |
These 10+ files are byte-for-byte identical between both projects, indicating a common origin from the WSJT-X experimental FT2 framework.
gcom1.f90 contains NMAX=30000 and NTZ=23040 (=144*160), matching AL_PLUS parameters exactly. Decodium uses NMAX=45000 in its ft2_params.f90, proving that gcom1.f90 predates Decodium's evolution and comes from the original primitive FT2 base.
| File | Type | Lines | Function | Status |
|---|---|---|---|---|
| gcom1.f90 | Fortran | 35 | Common block (shared variables) | IDENTICAL |
| ft2.f90 | Fortran | 280 | Main program + update + transmit | IDENTICAL |
| ft2_iwave.f90 | Fortran | 64 | Waveform generation | IDENTICAL |
| ft2_gfsk_iwave.f90 | Fortran | 88 | GFSK waveform generation | IDENTICAL |
| cdatetime.f90 | Fortran | 6 | Date/time formatting | IDENTICAL |
| gfsk_pulse.f90 | Fortran | 6 | GFSK pulse shape function | IDENTICAL |
| ft2audio.c | C | 347 | PortAudio interface | IDENTICAL |
| ptt.c | C | 59 | PTT control (Windows) | IDENTICAL |
| ptt_unix.c | C | 342 | PTT control (Unix) | IDENTICAL |
| ft2.ini | Config | 2 | K1JT FN20 configuration | IDENTICAL |
These files exist only in Decodium and represent significant original development work:
| File | Function | Innovation |
|---|---|---|
| ft2_baseline.f90 | Spectral baseline estimation/subtraction | Improved weak signal detection |
| ft2_downsample.f90 | 9x downsample with Nuttal window | Superior filtering vs Gaussian |
| sync2d.f90 | 2D time-frequency synchronization | Advanced Costas array detection |
| get_ft2_bitmetrics.f90 | Sophisticated bit metrics | More sensitive decoder |
| subtractft2.f90 | Decoded signal subtraction | Enables multi-pass decoding |
| getcandidates2.f90 | Advanced candidate search | Parabolic fitting, nfqso priority |
| gen_ft2wave.f90 | Evolved waveform generator | 4-FSK with ramp-up/down |
| foxfiltft2.f90 | Fox/Hound filter for FT2 | Entirely new feature |
| foxgenft2.f90 | Fox generator for FT2 | Entirely new feature |
Duration: 1.92 seconds Tones: 2 (binary: 0, 1) Baud: 75 baud Symbols: 144 (16 sync + 128 data) Sync: 0000111111110000 FEC: LDPC(128,90) - rate 0.703 Decoder: bpdecode128_90
Duration: 2.52 seconds Tones: 4 (quaternary: 0, 1, 2, 3) Baud: 41.67 baud Symbols: 105 (16 sync + 87 data + 2 ramp) Sync: 4x Costas: [0132][1023][2310][3201] FEC: LDPC(174,91) - rate 0.523 Decoder: LDPC(174,91) + Grayscale
DG2YCB (AL_PLUS) did NOT copy core FT2 decoder/encoder code from Decodium. Both projects share an infrastructure base from the original WSJT-X experimental FT2 framework. The AL_PLUS version contains a primitive implementation derived from MSK144, while Decodium 3.0 represents a significantly evolved protocol with LDPC(174,91), 4-FSK, Costas arrays, and modular architecture.
Analysis performed on original source files • AL_PLUS: wsjtx-3.1.0/src/wsjtx/lib/ft2/ (local) • Decodium: github.com/IU8LMC/Decodium-3.0-Codename-Raptor/lib/ft2/ (GitHub)