Merged master 8748

This commit is contained in:
Jordan Sherer
2018-08-05 11:33:30 -04:00
parent 8f8772f1bd
commit 62899069bf
1095 changed files with 31298 additions and 367679 deletions
@@ -1,42 +0,0 @@
image::settings-advanced.png[align="center",alt="Settings Advanced"]
_JT65 decoding parameters_
- *Random erasure patterns* logarithmically scales the number of
pseudo-random trials used by the Franke-Taylor JT65 decoder. Larger
numbers give slightly better sensitivity but take longer. For most
purposes a good setting is 6 or 7.
- *Aggressive decoding level* sets the threshold for acceptable
decodes using Deep Search. Higher numbers will display results
with lower confidence levels.
- Check *Two-pass decoding* to enable a second decoding pass after
signals producing first-pass decodes have been subtracted from the
received data stream.
_Miscellaneous_
- Set a positive number in *Degrade S/N of .wav file* to add known
amounts of pseudo-random noise to data read from a .wav file. To
ensure that the resulting S/N degradation is close to the requested
number of dB, set *Receiver bandwidth* to your best estimate of the
receiver's effective noise bandwidth.
- Set *Tx delay* to a number larger than the default 0.2 s to create
a larger delay between execution of a command to enable PTT and onset
of Tx audio.
IMPORTANT: For the health of your T/R relays and external
preamplifier, we strongly recommend using a hardware sequencer and
testing to make sure that sequencing is correct.
- Check *FT8 and MSK144: NA VHF Contest Mode* to enable generation and
auto-sequencing of messages using four-character grid locators in
place of signal reports, as required for most North American VHF
contests.
- Check *x 2 Tone spacing* to generate Tx audio with twice the normal
tone spacing. This feature is intended for use with specialized LF/MF
transmitters that divide the audio waveform by 2 before further
processing.
@@ -1,54 +0,0 @@
/* RAND.H - Interface to random number generation procedures. */
/* Copyright (c) 1995-2012 by Radford M. Neal.
*
* Permission is granted for anyone to copy, use, modify, and distribute
* these programs and accompanying documents for any purpose, provided
* this copyright notice is retained and prominently displayed, and note
* is made of any changes made to these programs. These programs and
* documents are distributed without any warranty, express or implied.
* As the programs were written for research purposes only, they have not
* been tested to the degree that would be advisable in any important
* application. All use of these programs is entirely at the user's own
* risk.
*/
/* STATE OF RANDOM NUMBER GENERATOR. */
#define N_tables 5 /* Number of tables of real random numbers */
typedef struct
{ int seed; /* Seed state derives from */
int ptr[N_tables]; /* Pointers for tables of real random numbers */
unsigned short state48[3]; /* State of 'rand48' pseudo-random generator */
} rand_state;
/* BASIC PSEUDO-RANDOM GENERATION PROCEDURES. */
void rand_seed (int); /* Initialize current state structure by seed */
void rand_use_state (rand_state *); /* Start using given state structure */
rand_state *rand_get_state (void); /* Return pointer to current state */
int rand_word (void); /* Generate random 31-bit positive integer */
/* GENERATORS FOR VARIOUS DISTRIBUTIONS. */
double rand_uniform (void); /* Uniform from [0,1) */
double rand_uniopen (void); /* Uniform from (0,1) */
int rand_int (int); /* Uniform from 0, 1, ... (n-1) */
int rand_pickd (double *, int); /* From 0 ... (n-1), with given distribution */
int rand_pickf (float *, int); /* Same as above, but with floats */
void rand_permutation (int *, int); /* Random permutation */
int rand_poisson (double); /* Poisson with given mean */
double rand_gaussian (void); /* Gaussian with mean zero and unit variance */
double rand_logistic (void); /* Logistic centred at zero with unit width */
double rand_cauchy (void); /* Cauchy centred at zero with unit width */
double rand_gamma (double); /* Gamma with given shape parameter */
double rand_exp (void); /* Exponential with mean one */
double rand_beta (double, double); /* Beta with given parameters */
@@ -1,209 +0,0 @@
//
// UDPDaemon - an example console application that utilizes the WSJT-X
// messaging facility
//
// This application is only provided as a simple console application
// example to demonstrate the WSJT-X messaging facility. It allows
// the user to set the server details either as a unicast UDP server
// or, if a multicast group address is provided, as a multicast
// server. The benefit of the multicast server is that multiple
// servers can be active at once each receiving all WSJT-X broadcast
// messages and each able to respond to individual WSJT_X clients. To
// utilize the multicast group features each WSJT-X client must set
// the same multicast group address as the UDP server address for
// example 239.255.0.0 for a site local multicast group.
//
//
#include <iostream>
#include <exception>
#include <QCoreApplication>
#include <QCommandLineParser>
#include <QDateTime>
#include <QTime>
#include <QHash>
#include <QDebug>
#include "MessageServer.hpp"
#include "Radio.hpp"
#include "qt_helpers.hpp"
using port_type = MessageServer::port_type;
using Frequency = MessageServer::Frequency;
class Client
: public QObject
{
Q_OBJECT
public:
explicit Client (QString const& id, QObject * parent = nullptr)
: QObject {parent}
, id_ {id}
, dial_frequency_ {0u}
{
}
Q_SLOT void update_status (QString const& id, Frequency f, QString const& mode, QString const& /*dx_call*/
, QString const& /*report*/, QString const& /*tx_mode*/, bool /*tx_enabled*/
, bool /*transmitting*/, bool /*decoding*/, qint32 /*rx_df*/, qint32 /*tx_df*/
, QString const& /*de_call*/, QString const& /*de_grid*/, QString const& /*dx_grid*/
, bool /* watchdog_timeout */, QString const& sub_mode, bool /*fast_mode*/)
{
if (id == id_)
{
if (f != dial_frequency_)
{
std::cout << tr ("%1: Dial frequency changed to %2").arg (id_).arg (f).toStdString () << std::endl;
dial_frequency_ = f;
}
if (mode + sub_mode != mode_)
{
std::cout << tr ("%1: Mode changed to %2").arg (id_).arg (mode + sub_mode).toStdString () << std::endl;
mode_ = mode + sub_mode;
}
}
}
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)
{
if (client_id == id_)
{
qDebug () << "new:" << is_new << "t:" << time << "snr:" << snr
<< "Dt:" << delta_time << "Df:" << delta_frequency
<< "mode:" << mode;
std::cout << tr ("%1: Decoded %2").arg (id_).arg (message).toStdString () << std::endl;
}
}
Q_SLOT void beacon_spot_added (bool is_new, QString const& client_id, QTime time, qint32 snr
, float delta_time, Frequency delta_frequency, qint32 drift, QString const& callsign
, QString const& grid, qint32 power)
{
if (client_id == id_)
{
qDebug () << "new:" << is_new << "t:" << time << "snr:" << snr
<< "Dt:" << delta_time << "Df:" << delta_frequency
<< "drift:" << drift;
std::cout << tr ("%1: WSPR decode %2 grid %3 power: %4").arg (id_).arg (callsign).arg (grid).arg (power).toStdString () << std::endl;
}
}
private:
QString id_;
Frequency dial_frequency_;
QString mode_;
};
class Server
: public QObject
{
Q_OBJECT
public:
Server (port_type port, QHostAddress const& multicast_group)
: server_ {new MessageServer {this}}
{
// connect up server
connect (server_, &MessageServer::error, [this] (QString const& message) {
std::cerr << tr ("Network Error: %1").arg ( message).toStdString () << std::endl;
});
connect (server_, &MessageServer::client_opened, this, &Server::add_client);
connect (server_, &MessageServer::client_closed, this, &Server::remove_client);
server_->start (port, multicast_group);
}
private:
void add_client (QString const& id, QString const& version, QString const& revision)
{
auto client = new Client {id};
connect (server_, &MessageServer::status_update, client, &Client::update_status);
connect (server_, &MessageServer::decode, client, &Client::decode_added);
connect (server_, &MessageServer::WSPR_decode, client, &Client::beacon_spot_added);
clients_[id] = client;
server_->replay (id);
std::cout << "Discovered WSJT-X instance: " << id.toStdString ();
if (version.size ())
{
std::cout << " v" << version.toStdString ();
}
if (revision.size ())
{
std::cout << " (" << revision.toStdString () << ")";
}
std::cout << std::endl;
}
void remove_client (QString const& id)
{
auto iter = clients_.find (id);
if (iter != std::end (clients_))
{
clients_.erase (iter);
(*iter)->deleteLater ();
}
std::cout << "Removed WSJT-X instance: " << id.toStdString () << std::endl;
}
MessageServer * server_;
// maps client id to clients
QHash<QString, Client *> clients_;
};
#include "UDPDaemon.moc"
int main (int argc, char * argv[])
{
QCoreApplication app {argc, argv};
try
{
setlocale (LC_NUMERIC, "C"); // ensure number forms are in
// consistent format, do this after
// instantiating QApplication so
// that GUI has correct l18n
app.setApplicationName ("WSJT-X UDP Message Server Daemon");
app.setApplicationVersion ("1.0");
QCommandLineParser parser;
parser.setApplicationDescription ("\nWSJT-X UDP Message Server Daemon.");
auto help_option = parser.addHelpOption ();
auto version_option = parser.addVersionOption ();
QCommandLineOption port_option (QStringList {"p", "port"},
app.translate ("UDPDaemon",
"Where <PORT> is the UDP service port number to listen on.\n"
"The default service port is 2237."),
app.translate ("UDPDaemon", "PORT"),
"2237");
parser.addOption (port_option);
QCommandLineOption multicast_addr_option (QStringList {"g", "multicast-group"},
app.translate ("UDPDaemon",
"Where <GROUP> is the multicast group to join.\n"
"The default is a unicast server listening on all interfaces."),
app.translate ("UDPDaemon", "GROUP"));
parser.addOption (multicast_addr_option);
parser.process (app);
Server server {static_cast<port_type> (parser.value (port_option).toUInt ()), QHostAddress {parser.value (multicast_addr_option)}};
return app.exec ();
}
catch (std::exception const & e)
{
std::cerr << "Error: " << e.what () << '\n';
}
catch (...)
{
std::cerr << "Unexpected error\n";
}
return -1;
}
@@ -0,0 +1,526 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>WideGraph</class>
<widget class="QDialog" name="WideGraph">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>799</width>
<height>337</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>1</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="CPlotter" name="widePlot">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>400</width>
<height>100</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>1</number>
</property>
<widget class="QCheckBox" name="cbControls">
<property name="geometry">
<rect>
<x>5</x>
<y>0</y>
<width>77</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Controls</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</widget>
</item>
<item>
<widget class="QWidget" name="controls_widget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="horizontalSpacing">
<number>5</number>
</property>
<property name="verticalSpacing">
<number>0</number>
</property>
<item row="1" column="8">
<widget class="QSlider" name="gain2dSlider">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Spectrum gain</string>
</property>
<property name="minimum">
<number>-50</number>
</property>
<property name="maximum">
<number>50</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksAbove</enum>
</property>
</widget>
</item>
<item row="0" column="4">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="labPalette">
<property name="text">
<string> Palette </string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="adjust_palette_push_button">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enter definition for a new color palette.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Adjust...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="8">
<widget class="QSlider" name="gainSlider">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Waterfall gain</string>
</property>
<property name="minimum">
<number>-50</number>
</property>
<property name="maximum">
<number>50</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksAbove</enum>
</property>
</widget>
</item>
<item row="0" column="11">
<widget class="QSpinBox" name="sbPercent2dPlot">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Set fractional size of spectrum in this window.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="suffix">
<string> %</string>
</property>
<property name="prefix">
<string>Spec </string>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>5</number>
</property>
<property name="value">
<number>30</number>
</property>
</widget>
</item>
<item row="0" column="6">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QCheckBox" name="cbFlatten">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Flatten spectral baseline over the full displayed interval.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Flatten</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cbRef">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Compute and save a reference spectrum. (Not yet fully implemented.)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Ref Spec</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="11">
<widget class="QSpinBox" name="smoSpinBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Smoothing of Linear Average spectrum</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="suffix">
<string/>
</property>
<property name="prefix">
<string>Smooth </string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>7</number>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="bppSpinBox">
<property name="toolTip">
<string>Compression factor for frequency scale</string>
</property>
<property name="suffix">
<string/>
</property>
<property name="prefix">
<string>Bins/Pixel </string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="value">
<number>2</number>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QComboBox" name="paletteComboBox">
<property name="toolTip">
<string>Select waterfall palette</string>
</property>
</widget>
</item>
<item row="1" column="6">
<widget class="QComboBox" name="spec2dComboBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Select data for spectral display&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>Current</string>
</property>
</item>
<item>
<property name="text">
<string>Cumulative</string>
</property>
</item>
<item>
<property name="text">
<string>Linear Avg</string>
</property>
</item>
<item>
<property name="text">
<string>Reference</string>
</property>
</item>
</widget>
</item>
<item row="0" column="2">
<widget class="QSpinBox" name="fStartSpinBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Frequency at left edge of waterfall&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="suffix">
<string> Hz</string>
</property>
<property name="prefix">
<string>Start </string>
</property>
<property name="maximum">
<number>5000</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="fSplitSpinBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Decode JT9 only above this frequency&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="suffix">
<string> JT9</string>
</property>
<property name="prefix">
<string>JT65 </string>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>5000</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
<property name="value">
<number>3000</number>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="waterfallAvgSpinBox">
<property name="toolTip">
<string>Number of FFTs averaged (controls waterfall scrolling rate)</string>
</property>
<property name="prefix">
<string>N Avg </string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>50</number>
</property>
</widget>
</item>
<item row="0" column="10">
<widget class="QSlider" name="zeroSlider">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Waterfall zero</string>
</property>
<property name="minimum">
<number>-50</number>
</property>
<property name="maximum">
<number>50</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksAbove</enum>
</property>
</widget>
</item>
<item row="1" column="10">
<widget class="QSlider" name="zero2dSlider">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Spectrum zero</string>
</property>
<property name="minimum">
<number>-50</number>
</property>
<property name="maximum">
<number>50</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksAbove</enum>
</property>
</widget>
</item>
<item row="0" column="0" rowspan="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="12" rowspan="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="3" rowspan="2">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item row="0" column="5" rowspan="2">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>CPlotter</class>
<extends>QFrame</extends>
<header>plotter.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>