From bcd3255ad7abebd030a5b32f2a2d2b2e48814be9 Mon Sep 17 00:00:00 2001 From: Stanislaw Grams Date: Tue, 17 Mar 2026 21:48:06 +0100 Subject: [PATCH] [fix](trx-wspr): fix reversed deinterleaving that prevented all decodes The deinterleave function had its indices swapped: it wrote out[j] = symbols[p] instead of out[p] = symbols[j]. This fed completely scrambled data to the Fano decoder, making convergence impossible. Matched against the reference implementation in raptor/lib/wsprd/wsprd_utils.c which does tmp[p] = sym[j]. Co-Authored-By: Claude Opus 4.6 Signed-off-by: Stanislaw Grams --- src/decoders/trx-wspr/src/protocol.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/decoders/trx-wspr/src/protocol.rs b/src/decoders/trx-wspr/src/protocol.rs index da3f81b..39b482f 100644 --- a/src/decoders/trx-wspr/src/protocol.rs +++ b/src/decoders/trx-wspr/src/protocol.rs @@ -27,13 +27,17 @@ fn rev8(mut b: u8) -> u8 { /// /// In WSPR: symbol = sync_bit + 2*data_bit, so data_bit = symbol >> 1. /// The 162 data bits are reordered via bit-reversal of 8-bit indices. +/// +/// The interleaving places coded bit p at transmitted position j = rev8(i) +/// (for each i in 0..255 where rev8(i) < 162). Deinterleaving reverses +/// this: coded[p] = transmitted[j] >> 1. fn deinterleave(symbols: &[u8]) -> [u8; NSYMS] { let mut out = [0u8; NSYMS]; let mut p = 0usize; for i in 0u8..=255 { let j = rev8(i) as usize; if j < NSYMS { - out[j] = symbols[p] >> 1; + out[p] = symbols[j] >> 1; p += 1; } }