FT8 support and demod: added unpacking of DXpedition mesages. Added message type in FT8Message

This commit is contained in:
f4exb 2023-01-28 11:39:44 +01:00
parent a86cc53945
commit e265ddf887
5 changed files with 113 additions and 21 deletions

View File

@ -211,6 +211,7 @@ void Packing::remember_call(std::string call)
{
hashes22[ihashcall(call, 22)] = call;
hashes12[ihashcall(call, 12)] = call;
hashes10[ihashcall(call, 10)] = call;
}
hashes_mu.unlock();
@ -344,6 +345,7 @@ std::string Packing::unpack_1(int a77[], std::string& call1str, std::string& cal
// details from wsjt-x's packjt77.f90
std::string Packing::unpack_0_0(int a77[], std::string& call1str, std::string& call2str, std::string& locstr)
{
// bit fields: f71
(void) call2str;
(void) locstr;
// the 42 possible characters.
@ -361,6 +363,53 @@ std::string Packing::unpack_0_0(int a77[], std::string& call1str, std::string& c
return msg;
}
std::string Packing::unpack_0_1(int a77[], std::string& call1str, std::string& call2str, std::string& locstr)
{
// bit fields: c28 c28 h10 r5
int i = 0;
int tu = a77[i];
i += 1;
int call1 = un64(a77, i, 28); // c28
i += 28;
int call2 = un64(a77, i, 28); // c28
call1str = trim(unpackcall(call1)) + ";" + trim(unpackcall(call2));
i += 28;
int x10 = un64(a77, i, 10);
// 10-bit hash
hashes_mu.lock();
std::string ocall;
if (hashes10.count(x10) > 0)
{
call2str = hashes10[x10];
ocall = "<" + call2str + ">";
}
else
{
call2str = "<...10>";
ocall = call2str;
}
hashes_mu.unlock();
i += 10;
int i5 = un64(a77, i, 5); // decode r5
int r = 2*i5 - 30;
char tmp[32];
if (r >= 0) {
sprintf(tmp, "+%02d", r);
} else {
sprintf(tmp, "-%02d", -r);
}
locstr = std::string(tmp);
std::string msg;
msg = trim(unpackcall(call1)) + " RR73;" + trim(unpackcall(call2)) + " " + ocall;
return msg;
}
// ARRL RTTY Round-Up states/provinces
const char *Packing::ru_states[] = {
"AL", "AK", "AZ", "AR", "CA", "CO", "CT", "DE", "FL", "GA",
@ -510,10 +559,19 @@ std::string Packing::unpack_0_3(int a77[], int n3, std::string& call1str, std::s
// CRC and LDPC have already been checked.
// details from wsjt-x's packjt77.f90 and 77bit.txt.
//
std::string Packing::unpack(int a77[], std::string& call1, std::string& call2, std::string& loc)
std::string Packing::unpack(int a77[], std::string& call1, std::string& call2, std::string& loc, std::string& type)
{
int i3 = un64(a77, 74, 3);
int n3 = un64(a77, 71, 3);
char tmp[64];
if (i3 == 0) {
sprintf(tmp, "%d.%d", i3, n3);
} else {
sprintf(tmp, "%d", i3);
}
type = std::string(tmp);
if (i3 == 0 && n3 == 0)
{
@ -521,6 +579,12 @@ std::string Packing::unpack(int a77[], std::string& call1, std::string& call2, s
return unpack_0_0(a77, call1, call2, loc);
}
if (i3 == 0 && n3 == 1)
{
// DXpedition
return unpack_0_1(a77, call1, call2, loc);
}
if (i3 == 0 && (n3 == 3 || n3 == 4))
{
// ARRL Field Day
@ -529,7 +593,7 @@ std::string Packing::unpack(int a77[], std::string& call1, std::string& call2, s
if (i3 == 1 || i3 == 2)
{
// ordinary message
// ordinary message or EU VHF
return unpack_1(a77, call1, call2, loc);
}
@ -541,11 +605,12 @@ std::string Packing::unpack(int a77[], std::string& call1, std::string& call2, s
if (i3 == 4)
{
// call that doesn't fit in 28 bits
// call that doesn't fit in 28 bits (non standard call)
return unpack_4(a77, call1, call2, loc);
}
char tmp[64];
// TODO: i3 == 5 EU VHF missing
call1 = "UNK";
sprintf(tmp, "UNK i3=%d n3=%d", i3, n3);
return std::string(tmp);

View File

@ -33,7 +33,7 @@ namespace FT8 {
class FT8_API Packing
{
public:
std::string unpack(int a91[], std::string& call1str, std::string& call2str, std::string& locstr);
std::string unpack(int a91[], std::string& call1str, std::string& call2str, std::string& locstr, std::string& type);
private:
static int ihashcall(std::string call, int m);
@ -43,10 +43,12 @@ private:
std::string unpack_4(int a77[], std::string& call1str, std::string& call2str, std::string& locstr);
std::string unpack_1(int a77[], std::string& call1str, std::string& call2str, std::string& locstr);
std::string unpack_0_0(int a77[], std::string& call1str, std::string& call2str, std::string& locstr);
std::string unpack_0_1(int a77[], std::string& call1str, std::string& call2str, std::string& locstr);
std::string unpack_3(int a77[], std::string& call1str, std::string& call2str, std::string& locstr);
std::string unpack_0_3(int a77[], int n3, std::string& call1str, std::string& call2str, std::string& locstr);
QRecursiveMutex hashes_mu;
std::map<int, std::string> hashes10;
std::map<int, std::string> hashes12;
std::map<int, std::string> hashes22;

View File

@ -58,7 +58,8 @@ int FT8DemodWorker::FT8Callback::hcb(
std::string call1;
std::string call2;
std::string loc;
std::string msg = m_packing.unpack(a91, call1, call2, loc);
std::string type;
std::string msg = m_packing.unpack(a91, call1, call2, loc, type);
cycle_mu.lock();
@ -70,21 +71,42 @@ int FT8DemodWorker::FT8Callback::hcb(
}
cycle_already[msg] = true;
QList<FT8Message>& ft8Messages = m_msgReportFT8Messages->getFT8Messages();
ft8Messages.push_back(FT8Message());
FT8Message& ft8Message = ft8Messages.back();
FT8Message baseMessage{
m_periodTS,
QString(type.c_str()),
pass,
(int) snr,
correct_bits,
off - 0.5,
hz0,
QString(call1.c_str()).simplified(),
QString(call2.c_str()).simplified(),
QString(loc.c_str()).simplified(),
QString(comment)
};
// DXpedition packs two messages in one with the two callees in the first call area separated by a semicolon
if (type == "0.1")
{
QStringList callees = QString(call1.c_str()).simplified().split(";");
for (int i = 0; i < 2; i++)
{
baseMessage.call1 = callees[i];
if (i == 0) { // first is with RR73 greetings in locator area
baseMessage.loc = "RR73";
}
ft8Messages.push_back(baseMessage);
}
}
else
{
ft8Messages.push_back(baseMessage);
}
ft8Message.ts = m_periodTS;
ft8Message.pass = pass;
ft8Message.snr = (int) snr;
ft8Message.nbCorrectBits = correct_bits;
ft8Message.dt = off - 0.5;
ft8Message.df = hz0;
ft8Message.call1 = QString(call1.c_str()).simplified();
ft8Message.call2 = QString(call2.c_str()).simplified();
ft8Message.loc = QString(loc.c_str()).simplified();
ft8Message.decoderInfo = QString(comment);
cycle_mu.unlock();
// qDebug("FT8DemodWorker::FT8Callback::hcb: %6.3f %d %3d %3d %5.2f %6.1f %s (%s)",

View File

@ -27,6 +27,7 @@
struct SDRBASE_API FT8Message
{
QDateTime ts;
QString type;
int pass;
int snr;
int nbCorrectBits;

View File

@ -71,7 +71,8 @@ int TestFT8Callback::hcb(
std::string call1;
std::string call2;
std::string loc;
std::string msg = packing.unpack(a91, call1, call2, loc);
std::string type;
std::string msg = packing.unpack(a91, call1, call2, loc, type);
cycle_mu.lock();
@ -86,7 +87,8 @@ int TestFT8Callback::hcb(
cycle_mu.unlock();
qDebug("TestFT8Callback::hcb: %d %3d %3d %5.2f %6.1f %s [%s:%s:%s] (%s)",
qDebug("TestFT8Callback::hcb: %3s %d %3d %3d %5.2f %6.1f %s [%s:%s:%s] (%s)",
type.c_str(),
pass,
(int)snr,
correct_bits,