From 23e01ea064c7b9d0f133441dfc7cf697915c0005 Mon Sep 17 00:00:00 2001
From: f4exb <f4exb06@gmail.com>
Date: Sun, 8 Jan 2023 23:15:31 +0100
Subject: [PATCH] FT8 demod: isolate call1, all2 and locator in callback

---
 ft8/ft8.cpp           | 219 ++++++------------------------------------
 ft8/unpack.cpp        | 102 +++++++++++---------
 ft8/unpack.h          |   2 +-
 sdrbench/test_ft8.cpp |  28 ++++--
 4 files changed, 108 insertions(+), 243 deletions(-)

diff --git a/ft8/ft8.cpp b/ft8/ft8.cpp
index d855ceea4..2d5952a35 100644
--- a/ft8/ft8.cpp
+++ b/ft8/ft8.cpp
@@ -406,181 +406,23 @@ public:
 // bits being one. measured from reconstructed correct
 // codewords, into ft8bits, then python bprob.py.
 // from ft8-n4
-float apriori174[] = {
-    0.47,
-    0.32,
-    0.29,
-    0.37,
-    0.52,
-    0.36,
-    0.40,
-    0.42,
-    0.42,
-    0.53,
-    0.44,
-    0.44,
-    0.39,
-    0.46,
-    0.39,
-    0.38,
-    0.42,
-    0.43,
-    0.45,
-    0.51,
-    0.42,
-    0.48,
-    0.31,
-    0.45,
-    0.47,
-    0.53,
-    0.59,
-    0.41,
-    0.03,
-    0.50,
-    0.30,
-    0.26,
-    0.40,
-    0.65,
-    0.34,
-    0.49,
-    0.46,
-    0.49,
-    0.69,
-    0.40,
-    0.45,
-    0.45,
-    0.60,
-    0.46,
-    0.43,
-    0.49,
-    0.56,
-    0.45,
-    0.55,
-    0.51,
-    0.46,
-    0.37,
-    0.55,
-    0.52,
-    0.56,
-    0.55,
-    0.50,
-    0.01,
-    0.19,
-    0.70,
-    0.88,
-    0.75,
-    0.75,
-    0.74,
-    0.73,
-    0.18,
-    0.71,
-    0.35,
-    0.60,
-    0.58,
-    0.36,
-    0.60,
-    0.38,
-    0.50,
-    0.02,
-    0.01,
-    0.98,
-    0.48,
-    0.49,
-    0.54,
-    0.50,
-    0.49,
-    0.53,
-    0.50,
-    0.49,
-    0.49,
-    0.51,
-    0.51,
-    0.51,
-    0.47,
-    0.50,
-    0.53,
-    0.51,
-    0.46,
-    0.51,
-    0.51,
-    0.48,
-    0.51,
-    0.52,
-    0.50,
-    0.52,
-    0.51,
-    0.50,
-    0.49,
-    0.53,
-    0.52,
-    0.50,
-    0.46,
-    0.47,
-    0.48,
-    0.52,
-    0.50,
-    0.49,
-    0.51,
-    0.49,
-    0.49,
-    0.50,
-    0.50,
-    0.50,
-    0.50,
-    0.51,
-    0.50,
-    0.49,
-    0.49,
-    0.55,
-    0.49,
-    0.51,
-    0.48,
-    0.55,
-    0.49,
-    0.48,
-    0.50,
-    0.51,
-    0.50,
-    0.51,
-    0.50,
-    0.51,
-    0.53,
-    0.49,
-    0.54,
-    0.50,
-    0.48,
-    0.49,
-    0.46,
-    0.51,
-    0.51,
-    0.52,
-    0.49,
-    0.51,
-    0.49,
-    0.51,
-    0.50,
-    0.49,
-    0.50,
-    0.50,
-    0.47,
-    0.49,
-    0.52,
-    0.49,
-    0.51,
-    0.49,
-    0.48,
-    0.52,
-    0.48,
-    0.49,
-    0.47,
-    0.50,
-    0.48,
-    0.50,
-    0.49,
-    0.51,
-    0.51,
-    0.51,
-    0.49,
+double apriori174[] = {
+  0.47, 0.32, 0.29, 0.37, 0.52, 0.36, 0.40, 0.42, 0.42, 0.53, 0.44,
+  0.44, 0.39, 0.46, 0.39, 0.38, 0.42, 0.43, 0.45, 0.51, 0.42, 0.48,
+  0.31, 0.45, 0.47, 0.53, 0.59, 0.41, 0.03, 0.50, 0.30, 0.26, 0.40,
+  0.65, 0.34, 0.49, 0.46, 0.49, 0.69, 0.40, 0.45, 0.45, 0.60, 0.46,
+  0.43, 0.49, 0.56, 0.45, 0.55, 0.51, 0.46, 0.37, 0.55, 0.52, 0.56,
+  0.55, 0.50, 0.01, 0.19, 0.70, 0.88, 0.75, 0.75, 0.74, 0.73, 0.18,
+  0.71, 0.35, 0.60, 0.58, 0.36, 0.60, 0.38, 0.50, 0.02, 0.01, 0.98,
+  0.48, 0.49, 0.54, 0.50, 0.49, 0.53, 0.50, 0.49, 0.49, 0.51, 0.51,
+  0.51, 0.47, 0.50, 0.53, 0.51, 0.46, 0.51, 0.51, 0.48, 0.51, 0.52,
+  0.50, 0.52, 0.51, 0.50, 0.49, 0.53, 0.52, 0.50, 0.46, 0.47, 0.48,
+  0.52, 0.50, 0.49, 0.51, 0.49, 0.49, 0.50, 0.50, 0.50, 0.50, 0.51,
+  0.50, 0.49, 0.49, 0.55, 0.49, 0.51, 0.48, 0.55, 0.49, 0.48, 0.50,
+  0.51, 0.50, 0.51, 0.50, 0.51, 0.53, 0.49, 0.54, 0.50, 0.48, 0.49,
+  0.46, 0.51, 0.51, 0.52, 0.49, 0.51, 0.49, 0.51, 0.50, 0.49, 0.50,
+  0.50, 0.47, 0.49, 0.52, 0.49, 0.51, 0.49, 0.48, 0.52, 0.48, 0.49,
+  0.47, 0.50, 0.48, 0.50, 0.49, 0.51, 0.51, 0.51, 0.49,
 };
 
 class FT8
@@ -3772,38 +3614,41 @@ void entry(
 
     // decodes from previous runs, for subtraction.
     std::vector<cdecode> prevdecs;
-    for (int i = 0; i < nprevdecs; i++)
-    {
+
+    for (int i = 0; i < nprevdecs; i++) {
         prevdecs.push_back(xprevdecs[i]);
     }
 
     std::vector<float> samples(nsamples);
-    for (int i = 0; i < nsamples; i++)
-    {
+
+    for (int i = 0; i < nsamples; i++) {
         samples[i] = xsamples[i];
     }
 
-    if (min_hz < 0)
-    {
+    if (min_hz < 0) {
         min_hz = 0;
     }
-    if (max_hz > rate / 2)
-    {
+
+    if (max_hz > rate / 2) {
         max_hz = rate / 2;
     }
-    float per = (max_hz - min_hz) / nthreads;
 
+    float per = (max_hz - min_hz) / nthreads;
     std::vector<FT8 *> thv;
 
     for (int i = 0; i < nthreads; i++)
     {
         float hz0 = min_hz + i * per;
-        if (i > 0 || overlap_edges)
+
+        if (i > 0 || overlap_edges) {
             hz0 -= overlap;
+        }
 
         float hz1 = min_hz + (i + 1) * per;
-        if (i != nthreads - 1 || overlap_edges)
+
+        if (i != nthreads - 1 || overlap_edges) {
             hz1 += overlap;
+        }
 
         hz0 = std::max(hz0, 0.0f);
         hz1 = std::min(hz1, (rate / 2.0f) - 50);
@@ -3823,9 +3668,7 @@ void entry(
         );
 
         int npasses = nprevdecs > 0 ? npasses_two : npasses_one;
-
         ft8->th_ = new std::thread([ft8, npasses] () { ft8->go(npasses); });
-
         thv.push_back(ft8);
     }
 
diff --git a/ft8/unpack.cpp b/ft8/unpack.cpp
index f30f85cf1..088ea9412 100644
--- a/ft8/unpack.cpp
+++ b/ft8/unpack.cpp
@@ -248,24 +248,25 @@ void remember_call(std::string call)
 // 1 bit: swap
 // 2 bits: 1 RRR, 2 RR73, 3 73
 // 1 bit: 1 means CQ
-std::string unpack_4(int a77[])
+std::string unpack_4(int a77[], std::string& call1str, std::string& call2str, std::string& locstr)
 {
+    (void) locstr;
     // 38 possible characters:
     const char *chars = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ/";
-
     long long n58 = un(a77, 12, 58);
     char call[16];
+
     for (int i = 0; i < 11; i++)
     {
         call[10 - i] = chars[n58 % 38];
         n58 = n58 / 38;
     }
+
     call[11] = '\0';
 
     remember_call(call);
 
-    if (un(a77, 73, 1) == 1)
-    {
+    if (un(a77, 73, 1) == 1) {
         return std::string("CQ ") + call;
     }
 
@@ -273,38 +274,38 @@ std::string unpack_4(int a77[])
     // 12-bit hash
     hashes_mu.lock();
     std::string ocall;
-    if (hashes12.count(x12) > 0)
-    {
+
+    if (hashes12.count(x12) > 0) {
         ocall = hashes12[x12];
-    }
-    else
-    {
+    } else {
         ocall = "<...12>";
     }
+
     hashes_mu.unlock();
 
     int swap = un(a77, 70, 1);
     std::string msg;
+
     if (swap)
     {
         msg = std::string(call) + " " + ocall;
+        call1str = call;
+        call2str = ocall;
     }
     else
     {
         msg = std::string(ocall) + " " + call;
+        call1str = ocall;
+        call2str = call;
     }
 
     int suffix = un(a77, 71, 2);
-    if (suffix == 1)
-    {
+
+    if (suffix == 1) {
         msg += " RRR";
-    }
-    else if (suffix == 2)
-    {
+    } else if (suffix == 2) {
         msg += " RR73";
-    }
-    else if (suffix == 3)
-    {
+    } else if (suffix == 3) {
         msg += " 73";
     }
 
@@ -314,7 +315,7 @@ std::string unpack_4(int a77[])
 //
 // i3=1
 //
-std::string unpack_1(int a77[])
+std::string unpack_1(int a77[], std::string& call1str, std::string& call2str, std::string& locstr)
 {
     // type 1:
     // 28 call1
@@ -342,24 +343,26 @@ std::string unpack_1(int a77[])
     i += 3;
     assert((i3 == 1 || i3 == 2) && i == 77);
 
-    std::string call1text = trim(unpackcall(call1));
-    std::string call2text = trim(unpackcall(call2));
-    std::string gridtext = unpackgrid(grid, ir, i3);
+    call1str = trim(unpackcall(call1));
+    call2str = trim(unpackcall(call2));
+    locstr = unpackgrid(grid, ir, i3);
 
-    remember_call(call1text);
-    remember_call(call2text);
+    remember_call(call1str);
+    remember_call(call2str);
 
     const char *pr = (i3 == 1 ? "/R" : "/P");
 
-    return call1text + (rover1 ? pr : "") + " " + call2text + (rover2 ? pr : "") + " " + gridtext;
+    return call1str + (rover1 ? pr : "") + " " + call2str + (rover2 ? pr : "") + " " + locstr;
 }
 
 // free text
 // 71 bits, 13 characters, each one of 42 choices.
 // reversed.
 // details from wsjt-x's packjt77.f90
-std::string unpack_0_0(int a77[])
+std::string unpack_0_0(int a77[], std::string& call1str, std::string& call2str, std::string& locstr)
 {
+    (void) call2str;
+    (void) locstr;
     // the 42 possible characters.
     const char *cc = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+-./?";
     __int128 x = un(a77, 0, 71);
@@ -369,6 +372,7 @@ std::string unpack_0_0(int a77[])
         msg[13 - 1 - i] = cc[x % 42];
         x = x / 42;
     }
+    call1str = msg;
     return msg;
 }
 
@@ -390,8 +394,9 @@ const char *ru_states[] = {
 //  1 R
 //  3 RST 529 to 599
 // 13 state/province/serialnumber
-std::string unpack_3(int a77[])
+std::string unpack_3(int a77[], std::string& call1str, std::string& call2str, std::string& locstr)
 {
+    (void) locstr;
     int i = 0;
     int tu = a77[i];
     i += 1;
@@ -406,8 +411,8 @@ std::string unpack_3(int a77[])
     int serial = un(a77, i, 13);
     i += 13;
 
-    std::string call1text = unpackcall(call1);
-    std::string call2text = unpackcall(call2);
+    call1str = trim(unpackcall(call1));
+    call2str = trim(unpackcall(call2));
 
     rst = 529 + 10 * rst;
 
@@ -431,7 +436,7 @@ std::string unpack_3(int a77[])
     {
         msg += "TU; ";
     }
-    msg += call1text + " " + call2text + " ";
+    msg += call1str + " " + call2str + " ";
     if (r)
     {
         msg += "R ";
@@ -443,8 +448,8 @@ std::string unpack_3(int a77[])
     }
     msg += serialstr;
 
-    remember_call(call1text);
-    remember_call(call2text);
+    remember_call(call1str);
+    remember_call(call2str);
 
     return msg;
 }
@@ -464,8 +469,9 @@ const char *sections[] = {
 // i3 = 0, n3 = 3 or 4: ARRL Field Day
 // 0.3   WA9XYZ KA1ABC R 16A EMA            28 28 1 4 3 7    71   ARRL Field Day
 // 0.4   WA9XYZ KA1ABC R 32A EMA            28 28 1 4 3 7    71   ARRL Field Day
-std::string unpack_0_3(int a77[], int n3)
+std::string unpack_0_3(int a77[], int n3, std::string& call1str, std::string& call2str, std::string& locstr)
 {
+    (void) locstr;
     int i = 0;
     int call1 = un(a77, i, 28);
     i += 28;
@@ -474,8 +480,11 @@ std::string unpack_0_3(int a77[], int n3)
     int R = un(a77, i, 1);
     i += 1;
     int n_transmitters = un(a77, i, 4);
-    if (n3 == 4)
+
+    if (n3 == 4) {
         n_transmitters += 16;
+    }
+
     i += 4;
     int clss = un(a77, i, 3); // class
     i += 3;
@@ -483,19 +492,24 @@ std::string unpack_0_3(int a77[], int n3)
     i += 7;
 
     std::string msg;
-    msg += unpackcall(call1);
+    call1str = trim(unpackcall(call1));
+    msg += call1str;
     msg += " ";
-    msg += unpackcall(call2);
+    call2str = trim(unpackcall(call2));
+    msg += call2str;
     msg += " ";
-    if (R)
+
+    if (R) {
         msg += "R ";
+    }
+
     {
         char tmp[16];
         sprintf(tmp, "%d%c ", n_transmitters + 1, clss + 'A');
         msg += tmp;
     }
-    if (section - 1 >= 0 && section - 1 < (int)(sizeof(sections) / sizeof(sections[0])))
-    {
+
+    if (section - 1 >= 0 && section - 1 < (int)(sizeof(sections) / sizeof(sections[0]))) {
         msg += sections[section - 1];
     }
 
@@ -508,7 +522,7 @@ std::string unpack_0_3(int a77[], int n3)
 // CRC and LDPC have already been checked.
 // details from wsjt-x's packjt77.f90 and 77bit.txt.
 //
-std::string unpack(int a77[])
+std::string unpack(int a77[], std::string& call1, std::string& call2, std::string& loc)
 {
     int i3 = un(a77, 74, 3);
     int n3 = un(a77, 71, 3);
@@ -516,31 +530,31 @@ std::string unpack(int a77[])
     if (i3 == 0 && n3 == 0)
     {
         // free text
-        return unpack_0_0(a77);
+        return unpack_0_0(a77, call1, call2, loc);
     }
 
     if (i3 == 0 && (n3 == 3 || n3 == 4))
     {
         // ARRL Field Day
-        return unpack_0_3(a77, n3);
+        return unpack_0_3(a77, n3, call1, call2, loc);
     }
 
     if (i3 == 1 || i3 == 2)
     {
         // ordinary message
-        return unpack_1(a77);
+        return unpack_1(a77, call1, call2, loc);
     }
 
     if (i3 == 3)
     {
         // RTTY Round-Up
-        return unpack_3(a77);
+        return unpack_3(a77, call1, call2, loc);
     }
 
     if (i3 == 4)
     {
         // call that doesn't fit in 28 bits
-        return unpack_4(a77);
+        return unpack_4(a77, call1, call2, loc);
     }
 
     char tmp[64];
diff --git a/ft8/unpack.h b/ft8/unpack.h
index ea266cd20..a8a344e77 100644
--- a/ft8/unpack.h
+++ b/ft8/unpack.h
@@ -23,7 +23,7 @@
 
 namespace FT8 {
 
-std::string unpack(int a91[]);
+std::string unpack(int a91[], std::string& call1str, std::string& call2str, std::string& locstr);
 
 } // namespace FT8
 
diff --git a/sdrbench/test_ft8.cpp b/sdrbench/test_ft8.cpp
index 5683b56a7..82ac583a7 100644
--- a/sdrbench/test_ft8.cpp
+++ b/sdrbench/test_ft8.cpp
@@ -41,9 +41,13 @@ int hcb(
     const char *comment,
     float snr,
     int pass,
-    int correct_bits)
+    int correct_bits
+)
 {
-    std::string msg = FT8::unpack(a91);
+    std::string call1;
+    std::string call2;
+    std::string loc;
+    std::string msg = FT8::unpack(a91, call1, call2, loc);
 
     cycle_mu.lock();
 
@@ -58,14 +62,18 @@ int hcb(
 
     cycle_mu.unlock();
 
-    printf("%d %3d %3d %5.2f %6.1f %s, %s\n",
-           pass,
-           (int)snr,
-           correct_bits,
-           off - 0.5,
-           hz0,
-           msg.c_str(),
-           comment);
+    printf("%d %3d %3d %5.2f %6.1f %s [%s:%s:%s] (%s)\n",
+        pass,
+        (int)snr,
+        correct_bits,
+        off - 0.5,
+        hz0,
+        msg.c_str(),
+        call1.c_str(),
+        call2.c_str(),
+        loc.c_str(),
+        comment
+    );
     fflush(stdout);
 
     return 2; // 2 => new decode, do subtract.