mirror of https://github.com/f4exb/sdrangel.git
FT8 support and demod: added unpacking of DXpedition mesages. Added message type in FT8Message
This commit is contained in:
parent
a86cc53945
commit
e265ddf887
|
@ -211,6 +211,7 @@ void Packing::remember_call(std::string call)
|
||||||
{
|
{
|
||||||
hashes22[ihashcall(call, 22)] = call;
|
hashes22[ihashcall(call, 22)] = call;
|
||||||
hashes12[ihashcall(call, 12)] = call;
|
hashes12[ihashcall(call, 12)] = call;
|
||||||
|
hashes10[ihashcall(call, 10)] = call;
|
||||||
}
|
}
|
||||||
|
|
||||||
hashes_mu.unlock();
|
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
|
// details from wsjt-x's packjt77.f90
|
||||||
std::string Packing::unpack_0_0(int a77[], std::string& call1str, std::string& call2str, std::string& locstr)
|
std::string Packing::unpack_0_0(int a77[], std::string& call1str, std::string& call2str, std::string& locstr)
|
||||||
{
|
{
|
||||||
|
// bit fields: f71
|
||||||
(void) call2str;
|
(void) call2str;
|
||||||
(void) locstr;
|
(void) locstr;
|
||||||
// the 42 possible characters.
|
// the 42 possible characters.
|
||||||
|
@ -361,6 +363,53 @@ std::string Packing::unpack_0_0(int a77[], std::string& call1str, std::string& c
|
||||||
return msg;
|
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
|
// ARRL RTTY Round-Up states/provinces
|
||||||
const char *Packing::ru_states[] = {
|
const char *Packing::ru_states[] = {
|
||||||
"AL", "AK", "AZ", "AR", "CA", "CO", "CT", "DE", "FL", "GA",
|
"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.
|
// CRC and LDPC have already been checked.
|
||||||
// details from wsjt-x's packjt77.f90 and 77bit.txt.
|
// 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 i3 = un64(a77, 74, 3);
|
||||||
int n3 = un64(a77, 71, 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)
|
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);
|
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))
|
if (i3 == 0 && (n3 == 3 || n3 == 4))
|
||||||
{
|
{
|
||||||
// ARRL Field Day
|
// 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)
|
if (i3 == 1 || i3 == 2)
|
||||||
{
|
{
|
||||||
// ordinary message
|
// ordinary message or EU VHF
|
||||||
return unpack_1(a77, call1, call2, loc);
|
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)
|
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);
|
return unpack_4(a77, call1, call2, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
char tmp[64];
|
// TODO: i3 == 5 EU VHF missing
|
||||||
|
|
||||||
call1 = "UNK";
|
call1 = "UNK";
|
||||||
sprintf(tmp, "UNK i3=%d n3=%d", i3, n3);
|
sprintf(tmp, "UNK i3=%d n3=%d", i3, n3);
|
||||||
return std::string(tmp);
|
return std::string(tmp);
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace FT8 {
|
||||||
class FT8_API Packing
|
class FT8_API Packing
|
||||||
{
|
{
|
||||||
public:
|
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:
|
private:
|
||||||
static int ihashcall(std::string call, int m);
|
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_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_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_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_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);
|
std::string unpack_0_3(int a77[], int n3, std::string& call1str, std::string& call2str, std::string& locstr);
|
||||||
|
|
||||||
QRecursiveMutex hashes_mu;
|
QRecursiveMutex hashes_mu;
|
||||||
|
std::map<int, std::string> hashes10;
|
||||||
std::map<int, std::string> hashes12;
|
std::map<int, std::string> hashes12;
|
||||||
std::map<int, std::string> hashes22;
|
std::map<int, std::string> hashes22;
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,8 @@ int FT8DemodWorker::FT8Callback::hcb(
|
||||||
std::string call1;
|
std::string call1;
|
||||||
std::string call2;
|
std::string call2;
|
||||||
std::string loc;
|
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();
|
cycle_mu.lock();
|
||||||
|
|
||||||
|
@ -70,21 +71,42 @@ int FT8DemodWorker::FT8Callback::hcb(
|
||||||
}
|
}
|
||||||
|
|
||||||
cycle_already[msg] = true;
|
cycle_already[msg] = true;
|
||||||
|
|
||||||
QList<FT8Message>& ft8Messages = m_msgReportFT8Messages->getFT8Messages();
|
QList<FT8Message>& ft8Messages = m_msgReportFT8Messages->getFT8Messages();
|
||||||
ft8Messages.push_back(FT8Message());
|
FT8Message baseMessage{
|
||||||
FT8Message& ft8Message = ft8Messages.back();
|
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();
|
cycle_mu.unlock();
|
||||||
|
|
||||||
// qDebug("FT8DemodWorker::FT8Callback::hcb: %6.3f %d %3d %3d %5.2f %6.1f %s (%s)",
|
// qDebug("FT8DemodWorker::FT8Callback::hcb: %6.3f %d %3d %3d %5.2f %6.1f %s (%s)",
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
struct SDRBASE_API FT8Message
|
struct SDRBASE_API FT8Message
|
||||||
{
|
{
|
||||||
QDateTime ts;
|
QDateTime ts;
|
||||||
|
QString type;
|
||||||
int pass;
|
int pass;
|
||||||
int snr;
|
int snr;
|
||||||
int nbCorrectBits;
|
int nbCorrectBits;
|
||||||
|
|
|
@ -71,7 +71,8 @@ int TestFT8Callback::hcb(
|
||||||
std::string call1;
|
std::string call1;
|
||||||
std::string call2;
|
std::string call2;
|
||||||
std::string loc;
|
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();
|
cycle_mu.lock();
|
||||||
|
|
||||||
|
@ -86,7 +87,8 @@ int TestFT8Callback::hcb(
|
||||||
|
|
||||||
cycle_mu.unlock();
|
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,
|
pass,
|
||||||
(int)snr,
|
(int)snr,
|
||||||
correct_bits,
|
correct_bits,
|
||||||
|
|
Loading…
Reference in New Issue