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 prevdecs; - for (int i = 0; i < nprevdecs; i++) - { + + for (int i = 0; i < nprevdecs; i++) { prevdecs.push_back(xprevdecs[i]); } std::vector 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 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.