mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-10 14:23:31 -05:00
Use the low confidence decode quality marker to elide spots and pass info via UDP
The UDP decode and reply message have been augmented with a boolean flag denoting a low confidence decode when set. Existing clients can safely use the reply message without passing the flag as the default value will still action messages that have high confidence. If low confidence decodes are to be passed back via the reply message then the low confidence flag must be included and correctly set to match the original decode. See NetworkMessage.hpp for message fields and meanings. git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@7957 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
parent
8fe7d5c5de
commit
ee2badb86f
@ -151,11 +151,13 @@ void MessageClient::impl::parse_message (QByteArray const& msg)
|
||||
quint32 delta_frequency;
|
||||
QByteArray mode;
|
||||
QByteArray message;
|
||||
in >> time >> snr >> delta_time >> delta_frequency >> mode >> message;
|
||||
bool low_confidence {false};
|
||||
in >> time >> snr >> delta_time >> delta_frequency >> mode >> message >> low_confidence;
|
||||
if (check_status (in) != Fail)
|
||||
{
|
||||
Q_EMIT self_->reply (time, snr, delta_time, delta_frequency
|
||||
, QString::fromUtf8 (mode), QString::fromUtf8 (message));
|
||||
, QString::fromUtf8 (mode), QString::fromUtf8 (message)
|
||||
, low_confidence);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -366,13 +368,14 @@ void MessageClient::status_update (Frequency f, QString const& mode, QString con
|
||||
}
|
||||
|
||||
void MessageClient::decode (bool is_new, QTime time, qint32 snr, float delta_time, quint32 delta_frequency
|
||||
, QString const& mode, QString const& message_text)
|
||||
, QString const& mode, QString const& message_text, bool low_confidence)
|
||||
{
|
||||
if (m_->server_port_ && !m_->server_string_.isEmpty ())
|
||||
{
|
||||
QByteArray message;
|
||||
NetworkMessage::Builder out {&message, NetworkMessage::Decode, m_->id_, m_->schema_};
|
||||
out << is_new << time << snr << delta_time << delta_frequency << mode.toUtf8 () << message_text.toUtf8 ();
|
||||
out << is_new << time << snr << delta_time << delta_frequency << mode.toUtf8 ()
|
||||
<< message_text.toUtf8 () << low_confidence;
|
||||
m_->send_message (out, message);
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ public:
|
||||
, QString const& dx_grid, bool watchdog_timeout, QString const& sub_mode
|
||||
, bool fast_mode);
|
||||
Q_SLOT void decode (bool is_new, QTime time, qint32 snr, float delta_time, quint32 delta_frequency
|
||||
, QString const& mode, QString const& message);
|
||||
, QString const& mode, QString const& message, bool low_confidence);
|
||||
Q_SLOT void WSPR_decode (bool is_new, QTime time, qint32 snr, float delta_time, Frequency
|
||||
, qint32 drift, QString const& callsign, QString const& grid, qint32 power);
|
||||
Q_SLOT void clear_decodes ();
|
||||
@ -70,7 +70,7 @@ public:
|
||||
// this signal is emitted if the server sends us a reply, the only
|
||||
// reply supported is reply to a prior CQ or QRZ message
|
||||
Q_SIGNAL void reply (QTime, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode
|
||||
, QString const& message_text);
|
||||
, QString const& message_text, bool low_confidence);
|
||||
|
||||
// this signal is emitted if the server has requested a replay of
|
||||
// all decodes
|
||||
|
@ -241,11 +241,14 @@ void MessageServer::impl::parse_message (QHostAddress const& sender, port_type s
|
||||
quint32 delta_frequency;
|
||||
QByteArray mode;
|
||||
QByteArray message;
|
||||
in >> is_new >> time >> snr >> delta_time >> delta_frequency >> mode >> message;
|
||||
bool low_confidence;
|
||||
in >> is_new >> time >> snr >> delta_time >> delta_frequency >> mode
|
||||
>> message >> low_confidence;
|
||||
if (check_status (in) != Fail)
|
||||
{
|
||||
Q_EMIT self_->decode (is_new, id, time, snr, delta_time, delta_frequency
|
||||
, QString::fromUtf8 (mode), QString::fromUtf8 (message));
|
||||
, QString::fromUtf8 (mode), QString::fromUtf8 (message)
|
||||
, low_confidence);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -396,14 +399,15 @@ void MessageServer::start (port_type port, QHostAddress const& multicast_group_a
|
||||
}
|
||||
}
|
||||
|
||||
void MessageServer::reply (QString const& id, QTime time, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode, QString const& message_text)
|
||||
void MessageServer::reply (QString const& id, QTime time, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode, QString const& message_text, bool low_confidence)
|
||||
{
|
||||
auto iter = m_->clients_.find (id);
|
||||
if (iter != std::end (m_->clients_))
|
||||
{
|
||||
QByteArray message;
|
||||
NetworkMessage::Builder out {&message, NetworkMessage::Reply, id, (*iter).negotiated_schema_number_};
|
||||
out << time << snr << delta_time << delta_frequency << mode.toUtf8 () << message_text.toUtf8 ();
|
||||
out << time << snr << delta_time << delta_frequency << mode.toUtf8 ()
|
||||
<< message_text.toUtf8 () << low_confidence;
|
||||
m_->send_message (out, message, iter.value ().sender_address_, (*iter).sender_port_);
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ public:
|
||||
// note that the client is not obliged to take any action and only
|
||||
// takes any action if the decode is present and is a CQ or QRZ message
|
||||
Q_SLOT void reply (QString const& id, QTime time, qint32 snr, float delta_time, quint32 delta_frequency
|
||||
, QString const& mode, QString const& message);
|
||||
, QString const& mode, QString const& message, bool low_confidence);
|
||||
|
||||
// ask the client with identification 'id' to replay all decodes
|
||||
Q_SLOT void replay (QString const& id);
|
||||
@ -69,7 +69,8 @@ public:
|
||||
, bool watchdog_timeout, QString const& sub_mode, bool fast_mode);
|
||||
Q_SIGNAL void client_closed (QString const& id);
|
||||
Q_SIGNAL void decode (bool is_new, QString const& id, QTime time, qint32 snr, float delta_time
|
||||
, quint32 delta_frequency, QString const& mode, QString const& message);
|
||||
, quint32 delta_frequency, QString const& mode, QString const& message
|
||||
, bool low_confidence);
|
||||
Q_SIGNAL void WSPR_decode (bool is_new, QString const& id, QTime time, qint32 snr, float delta_time, Frequency
|
||||
, qint32 drift, QString const& callsign, QString const& grid, qint32 power);
|
||||
Q_SIGNAL void qso_logged (QString const& id, QDateTime timeOff, QString const& dx_call, QString const& dx_grid
|
||||
|
@ -156,13 +156,19 @@
|
||||
* Delta frequency (Hz) quint32
|
||||
* Mode utf8
|
||||
* Message utf8
|
||||
* Low confidence bool
|
||||
*
|
||||
* The decode message is sent when a new decode is completed, in
|
||||
* this case the 'New' field is true. It is also used in response
|
||||
* to a "Replay" message where each old decode in the "Band
|
||||
* activity" window, that has not been erased, is sent in order
|
||||
* as a one of these messages with the 'New' field set to
|
||||
* false. See the "Replay" message below for details of usage.
|
||||
* as a one of these messages with the 'New' field set to false.
|
||||
* See the "Replay" message below for details of usage. Low
|
||||
* confidence decodes are flagged in protocols where the decoder
|
||||
* has knows that a decode has a higher than normal probability
|
||||
* of being false, they should not be reported on publicly
|
||||
* accessible services without some attached warning or further
|
||||
* validation.
|
||||
*
|
||||
*
|
||||
* Clear Out 3 quint32
|
||||
@ -184,6 +190,7 @@
|
||||
* Delta frequency (Hz) quint32
|
||||
* Mode utf8
|
||||
* Message utf8
|
||||
* Low confidence bool
|
||||
*
|
||||
* In order for a server to provide a useful cooperative service
|
||||
* to WSJT-X it is possible for it to initiate a QSO by sending
|
||||
|
@ -244,7 +244,7 @@ void ClientWidget::update_status (QString const& id, Frequency f, QString const&
|
||||
|
||||
void ClientWidget::decode_added (bool /*is_new*/, QString const& client_id, QTime /*time*/, qint32 /*snr*/
|
||||
, float /*delta_time*/, quint32 /*delta_frequency*/, QString const& /*mode*/
|
||||
, QString const& /*message*/)
|
||||
, QString const& /*message*/, bool /*low_confidence*/)
|
||||
{
|
||||
if (client_id == id_)
|
||||
{
|
||||
|
@ -33,7 +33,7 @@ public:
|
||||
, bool watchdog_timeout, QString const& sub_mode, bool fast_mode);
|
||||
Q_SLOT void decode_added (bool is_new, QString const& client_id, QTime, qint32 snr
|
||||
, float delta_time, quint32 delta_frequency, QString const& mode
|
||||
, QString const& message);
|
||||
, QString const& message, bool low_confidence);
|
||||
Q_SLOT void beacon_spot_added (bool is_new, QString const& client_id, QTime, qint32 snr
|
||||
, float delta_time, Frequency delta_frequency, qint32 drift
|
||||
, QString const& callsign, QString const& grid, qint32 power);
|
||||
|
@ -17,13 +17,19 @@ namespace
|
||||
QT_TRANSLATE_NOOP ("DecodesModel", "DF"),
|
||||
QT_TRANSLATE_NOOP ("DecodesModel", "Md"),
|
||||
QT_TRANSLATE_NOOP ("DecodesModel", "Message"),
|
||||
QT_TRANSLATE_NOOP ("DecodesModel", "Confidence"),
|
||||
};
|
||||
|
||||
QString confidence_string (bool low_confidence)
|
||||
{
|
||||
return low_confidence ? QT_TRANSLATE_NOOP ("DecodesModel", "low") : QT_TRANSLATE_NOOP ("DecodesModel", "high");
|
||||
}
|
||||
|
||||
QFont text_font {"Courier", 10};
|
||||
|
||||
QList<QStandardItem *> make_row (QString const& client_id, QTime time, qint32 snr, float delta_time
|
||||
, quint32 delta_frequency, QString const& mode, QString const& message
|
||||
, bool is_fast)
|
||||
, bool low_confidence, bool is_fast)
|
||||
{
|
||||
auto time_item = new QStandardItem {time.toString (is_fast || "~" == mode ? "hh:mm:ss" : "hh:mm")};
|
||||
time_item->setData (time);
|
||||
@ -44,8 +50,11 @@ namespace
|
||||
auto md = new QStandardItem {mode};
|
||||
md->setTextAlignment (Qt::AlignHCenter);
|
||||
|
||||
auto confidence = new QStandardItem {confidence_string (low_confidence)};
|
||||
confidence->setTextAlignment (Qt::AlignHCenter);
|
||||
|
||||
QList<QStandardItem *> row {
|
||||
new QStandardItem {client_id}, time_item, snr_item, dt, df, md, new QStandardItem {message}};
|
||||
new QStandardItem {client_id}, time_item, snr_item, dt, df, md, new QStandardItem {message}, confidence};
|
||||
Q_FOREACH (auto& item, row)
|
||||
{
|
||||
item->setEditable (false);
|
||||
@ -57,7 +66,7 @@ namespace
|
||||
}
|
||||
|
||||
DecodesModel::DecodesModel (QObject * parent)
|
||||
: QStandardItemModel {0, 7, parent}
|
||||
: QStandardItemModel {0, sizeof (headings) / sizeof (headings[0]), parent}
|
||||
{
|
||||
int column {0};
|
||||
for (auto const& heading : headings)
|
||||
@ -68,7 +77,7 @@ DecodesModel::DecodesModel (QObject * parent)
|
||||
|
||||
void DecodesModel::add_decode (bool is_new, QString const& client_id, QTime time, qint32 snr, float delta_time
|
||||
, quint32 delta_frequency, QString const& mode, QString const& message
|
||||
, bool is_fast)
|
||||
, bool low_confidence, bool is_fast)
|
||||
{
|
||||
if (!is_new)
|
||||
{
|
||||
@ -83,7 +92,8 @@ void DecodesModel::add_decode (bool is_new, QString const& client_id, QTime time
|
||||
&& item (row, 3)->data ().toFloat () == delta_time
|
||||
&& item (row, 4)->data ().toUInt () == delta_frequency
|
||||
&& data (index (row, 5)).toString () == mode
|
||||
&& data (index (row, 6)).toString () == message)
|
||||
&& data (index (row, 6)).toString () == message
|
||||
&& data (index (row, 7)).toString () == confidence_string (low_confidence))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -96,12 +106,12 @@ void DecodesModel::add_decode (bool is_new, QString const& client_id, QTime time
|
||||
if (target_row >= 0)
|
||||
{
|
||||
insertRow (target_row + 1, make_row (client_id, time, snr, delta_time, delta_frequency, mode
|
||||
, message, is_fast));
|
||||
, message, low_confidence, is_fast));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
appendRow (make_row (client_id, time, snr, delta_time, delta_frequency, mode, message, is_fast));
|
||||
appendRow (make_row (client_id, time, snr, delta_time, delta_frequency, mode, message, low_confidence, is_fast));
|
||||
}
|
||||
|
||||
void DecodesModel::clear_decodes (QString const& client_id)
|
||||
@ -124,7 +134,8 @@ void DecodesModel::do_reply (QModelIndex const& source)
|
||||
, item (row, 3)->data ().toFloat ()
|
||||
, item (row, 4)->data ().toInt ()
|
||||
, data (index (row, 5)).toString ()
|
||||
, data (index (row, 6)).toString ());
|
||||
, data (index (row, 6)).toString ()
|
||||
, confidence_string (true) == data (index (row, 7)).toString ());
|
||||
}
|
||||
|
||||
#include "moc_DecodesModel.cpp"
|
||||
|
@ -32,12 +32,13 @@ public:
|
||||
explicit DecodesModel (QObject * parent = nullptr);
|
||||
|
||||
Q_SLOT void add_decode (bool is_new, QString const& client_id, QTime time, qint32 snr, float delta_time
|
||||
, quint32 delta_frequency, QString const& mode, QString const& message, bool is_fast);
|
||||
, quint32 delta_frequency, QString const& mode, QString const& message
|
||||
, bool low_confidence, bool is_fast);
|
||||
Q_SLOT void clear_decodes (QString const& client_id);
|
||||
Q_SLOT void do_reply (QModelIndex const& source);
|
||||
|
||||
Q_SIGNAL void reply (QString const& id, QTime time, qint32 snr, float delta_time, quint32 delta_frequency
|
||||
, QString const& mode, QString const& message);
|
||||
, QString const& mode, QString const& message, bool low_confidence);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -91,9 +91,9 @@ MessageAggregatorMainWindow::MessageAggregatorMainWindow ()
|
||||
connect (server_, &MessageServer::decode, [this] (bool is_new, QString const& id, QTime time
|
||||
, qint32 snr, float delta_time
|
||||
, quint32 delta_frequency, QString const& mode
|
||||
, QString const& message) {
|
||||
, QString const& message, bool low_confidence) {
|
||||
decodes_model_->add_decode (is_new, id, time, snr, delta_time, delta_frequency, mode, message
|
||||
, dock_widgets_[id]->fast_mode ());});
|
||||
, low_confidence, dock_widgets_[id]->fast_mode ());});
|
||||
connect (server_, &MessageServer::WSPR_decode, beacons_model_, &BeaconsModel::add_beacon_spot);
|
||||
connect (server_, &MessageServer::clear_decodes, decodes_model_, &DecodesModel::clear_decodes);
|
||||
connect (server_, &MessageServer::clear_decodes, beacons_model_, &BeaconsModel::clear_decodes);
|
||||
|
@ -69,13 +69,13 @@ public:
|
||||
|
||||
Q_SLOT void decode_added (bool is_new, QString const& client_id, QTime time, qint32 snr
|
||||
, float delta_time, quint32 delta_frequency, QString const& mode
|
||||
, QString const& message)
|
||||
, QString const& message, bool low_confidence)
|
||||
{
|
||||
if (client_id == id_)
|
||||
{
|
||||
qDebug () << "new:" << is_new << "t:" << time << "snr:" << snr
|
||||
<< "Dt:" << delta_time << "Df:" << delta_frequency
|
||||
<< "mode:" << mode;
|
||||
<< "mode:" << mode << "Confidence:" << (low_confidence ? "low" : "high");
|
||||
std::cout << tr ("%1: Decoded %2").arg (id_).arg (message).toStdString () << std::endl;
|
||||
}
|
||||
}
|
||||
|
@ -56,6 +56,11 @@ bool DecodedText::isTX()
|
||||
return (i >= 0 && i < 15); // TODO guessing those numbers. Does Tx ever move?
|
||||
}
|
||||
|
||||
bool DecodedText::isLowConfidence ()
|
||||
{
|
||||
return QChar {'?'} == _string.mid (padding_ + column_qsoText + 21, 1);
|
||||
}
|
||||
|
||||
int DecodedText::frequencyOffset()
|
||||
{
|
||||
return _string.mid(column_freq + padding_,4).toInt();
|
||||
|
@ -57,6 +57,7 @@ public:
|
||||
bool isJT65();
|
||||
bool isJT9();
|
||||
bool isTX();
|
||||
bool isLowConfidence ();
|
||||
int frequencyOffset(); // hertz offset from the tuned dial or rx frequency, aka audio frequency
|
||||
int snr();
|
||||
float dt();
|
||||
|
@ -1440,7 +1440,7 @@ void MainWindow::fastSink(qint64 frames)
|
||||
bool stdMsg = decodedtext.report(m_baseCall,
|
||||
Radio::base_callsign(ui->dxCallEntry->text()),m_rptRcvd);
|
||||
decodedtext=message.mid(0,4) + message.mid(6,-1);
|
||||
if(m_config.spot_to_psk_reporter() and stdMsg and !m_diskData) pskPost(decodedtext);
|
||||
if (stdMsg) pskPost (decodedtext);
|
||||
}
|
||||
|
||||
float fracTR=float(k)/(12000.0*m_TRperiod);
|
||||
@ -2593,9 +2593,7 @@ void::MainWindow::fast_decode_done()
|
||||
Radio::base_callsign(ui->dxCallEntry->text()), m_rptRcvd);
|
||||
|
||||
// extract details and send to PSKreporter
|
||||
if(m_config.spot_to_psk_reporter() and stdMsg and !m_diskData) {
|
||||
pskPost(decodedtext);
|
||||
}
|
||||
if (stdMsg) pskPost(decodedtext);
|
||||
}
|
||||
}
|
||||
m_startAnother=m_loopall;
|
||||
@ -2774,9 +2772,7 @@ void MainWindow::readFromStdout() //readFromStdout
|
||||
// extract details and send to PSKreporter
|
||||
int nsec=QDateTime::currentMSecsSinceEpoch()/1000-m_secBandChanged;
|
||||
bool okToPost=(nsec>(4*m_TRperiod)/5);
|
||||
if(m_config.spot_to_psk_reporter () and stdMsg and !m_diskData and okToPost) {
|
||||
pskPost(decodedtext);
|
||||
}
|
||||
if (stdMsg && okToPost) pskPost(decodedtext);
|
||||
|
||||
if((m_mode=="JT4" or m_mode=="JT65" or m_mode=="QRA64") and m_msgAvgWidget!=NULL) {
|
||||
if(m_msgAvgWidget->isVisible()) {
|
||||
@ -2832,6 +2828,8 @@ void MainWindow::auto_sequence (QString const& message, unsigned tolerance)
|
||||
|
||||
void MainWindow::pskPost (DecodedText decodedtext)
|
||||
{
|
||||
if (m_diskData || !m_config.spot_to_psk_reporter() || decodedtext.isLowConfidence ()) return;
|
||||
|
||||
QString msgmode=m_mode;
|
||||
if(m_mode=="JT9+JT65") {
|
||||
msgmode="JT9";
|
||||
@ -6157,14 +6155,15 @@ void MainWindow::postDecode (bool is_new, QString const& message)
|
||||
{
|
||||
auto const& decode = message.trimmed ();
|
||||
auto const& parts = decode.left (22).split (' ', QString::SkipEmptyParts);
|
||||
if (parts.size () >= 5)
|
||||
if (!m_diskData && parts.size () >= 5)
|
||||
{
|
||||
auto has_seconds = parts[0].size () > 4;
|
||||
m_messageClient->decode (is_new
|
||||
, QTime::fromString (parts[0], has_seconds ? "hhmmss" : "hhmm")
|
||||
, parts[1].toInt ()
|
||||
, parts[2].toFloat (), parts[3].toUInt (), parts[4][0]
|
||||
, decode.mid (has_seconds ? 24 : 22));
|
||||
, decode.mid (has_seconds ? 24 : 22, 21)
|
||||
, QChar {'?'} == decode.mid (has_seconds ? 24 + 21 : 22 + 21, 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user