Merge branch 'release-2.4.0'

This commit is contained in:
Bill Somerville 2021-03-04 18:13:18 +00:00
commit ff87cefc5d
No known key found for this signature in database
GPG Key ID: D864B06D1E81618F
117 changed files with 1753 additions and 6090 deletions

View File

@ -71,7 +71,7 @@ message (STATUS "******************************************************")
include (set_build_type)
# RC 0 or omitted is a development build, GA is a General Availability release build
set_build_type (RC 1)
set_build_type (RC 2)
set (wsjtx_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}${BUILD_TYPE_REVISION}")
#
@ -424,7 +424,6 @@ set (wsjt_FSRCS
lib/gen4.f90
lib/gen65.f90
lib/gen9.f90
lib/geniscat.f90
lib/genwave.f90
lib/ft8/genft8.f90
lib/qra/q65/genq65.f90
@ -456,7 +455,6 @@ set (wsjt_FSRCS
lib/interleave63.f90
lib/interleave9.f90
lib/inter_wspr.f90
lib/iscat.f90
lib/jplsubs.f
lib/jt9fano.f90
lib/jtmsg.f90
@ -538,7 +536,6 @@ set (wsjt_FSRCS
lib/sync9.f90
lib/sync9f.f90
lib/sync9w.f90
lib/synciscat.f90
lib/timf2.f90
lib/tweak1.f90
lib/twkfreq.f90

View File

@ -21,7 +21,7 @@ There are two system variables that must be set manually since the M1 Macs do no
automatic parameter settings by means of the sysctl.conf file present in the download.
Type these commands - you will be asked for your password which will not be echoed:
sudo sysctl -w kern.sysv.shmmax=104857600
sudo sysctl -w kern.sysv.shmmax=52428800
sudo sysctl -w kern.sysv.shmall=25600
It is important to note that these parameter settings will not survive a reboot. If you
@ -46,7 +46,7 @@ change has been made by typing:
sysctl -a | grep sysv.shm
If shmmax is not shown as 104857600 then contact me since WSJT-X will fail to load with
If shmmax is not shown as 52428800 then contact me since WSJT-X will fail to load with
an error message: "Unable to create shared memory segment".
You can now close the Terminal window. It will not be necessary to repeat this procedure
@ -105,10 +105,23 @@ would probably be corrupted.)
It is possible to run two instances of WSJT-X simultaneously. See "Section 16.2
Frequently asked Questions" in the User Guide. If you wish to run more than two instances
simultaneously, the sysctl.conf file needs to be modified. Please email me with your
requirements and I will provide a replacement sysctl.conf to suit.
simultaneously, the shmall parameter in the sysctl.conf file needs to be modified as follows.
The shmall parameter determines the amount of shared memory which is allocated in 4096 byte pages
with 50MB (52428800) required for each instance. The shmall parameter is calculated as:
(n * 52428800)/4096 where 'n' is the number of instances required to run simultaneously. If
you are using an Intel Mac, modify the shmall parameter in the sysctl.conf file using a Mac editor
and then install in the /etc directory using the installation procedure described above for an
Intel Mac. Remember to reboot your Mac afterwards.
If you are using an M1 Mac, then simply issue the sudo sysctl -w kern.sysv.shmall=xxx command where
xxx is the new value of shmall that is required.
Note that the shmmax parameter remains unchanged. This is the maximum amount of shared memory that
any one instance is allowed to request from the total shared memory allocation and should not
be changed.
If two instances of WSJT-X are running, it is likely that you might need additional
audio devices, from two rigs for example. Visit Audio MIDI Setup and create an Aggregate Device
which will allow you to specific more than one interface. I recommend you consult Apple's guide
which will allow you to specify more than one interface. I recommend you consult Apple's guide
on combining multiple audio interfaces which is at https://support.apple.com/en-us/HT202000.

View File

@ -1,4 +1,4 @@
kern.sysv.shmmax=104857600
kern.sysv.shmmax=52428800
kern.sysv.shmmin=1
kern.sysv.shmmni=128
kern.sysv.shmseg=32

View File

@ -16,11 +16,15 @@ namespace
DecodedText::DecodedText (QString const& the_string)
: string_ {the_string.left (the_string.indexOf (QChar::Nbsp))} // discard appended info
, clean_string_ {string_}
, padding_ {string_.indexOf (" ") > 4 ? 2 : 0} // allow for
// seconds
, message_ {string_.mid (column_qsoText + padding_).trimmed ()}
, is_standard_ {false}
{
// discard appended AP info
clean_string_.replace (QRegularExpression {R"(^(.*)(?:(?:\?\s)?a[0-9].*)$)"}, "\\1");
// qDebug () << "DecodedText: the_string:" << the_string << "Nbsp pos:" << the_string.indexOf (QChar::Nbsp);
if (message_.length() >= 1)
{

View File

@ -32,6 +32,7 @@ public:
explicit DecodedText (QString const& message);
QString string() const { return string_; };
QString clean_string() const { return clean_string_; };
QStringList messageWords () const;
int indexOf(QString s) const { return string_.indexOf(s); };
int indexOf(QString s, int i) const { return string_.indexOf(s,i); };
@ -76,6 +77,7 @@ private:
column_qsoText = 22 };
QString string_;
QString clean_string_;
int padding_;
QString message_;
QString message0_;

View File

@ -576,20 +576,28 @@ void MultiSettings::impl::select_configuration (QString const& target_name)
{
if (main_window_ && target_name != current_)
{
bool changed {false};
{
auto const& current_group = settings_.group ();
if (current_group.size ()) settings_.endGroup ();
// position to the alternative settings
SettingsGroup alternatives {&settings_, multi_settings_root_group};
// save the target settings
SettingsGroup target_group {&settings_, target_name};
new_settings_ = get_settings ();
if (settings_.childGroups ().contains (target_name))
{
changed = true;
// save the target settings
SettingsGroup target_group {&settings_, target_name};
new_settings_ = get_settings ();
}
if (current_group.size ()) settings_.beginGroup (current_group);
}
// and set up the restart
current_ = target_name;
Q_EMIT parent_->configurationNameChanged (unescape_ampersands (current_));
restart (RepositionType::save_and_replace);
if (changed)
{
// and set up the restart
current_ = target_name;
Q_EMIT parent_->configurationNameChanged (unescape_ampersands (current_));
restart (RepositionType::save_and_replace);
}
}
}

88
NEWS
View File

@ -1,4 +1,3 @@
__ __ ______ _____ ________ __ __
| \ _ | \ / \ | \| \ | \ | \
| $$ / \ | $$| $$$$$$\ \$$$$$ \$$$$$$$$ | $$ | $$
@ -13,6 +12,91 @@
Copyright 2001 - 2021 by Joe Taylor, K1JT.
Release: WSJT-X 2.4.0-rc2
Mar 6, 2021
-------------------------
WSJT-X 2.4.0 Release Candidate 2 adds new Q65 mode functionality and
decoder optimizations; repairs defects and regressions discovered in
the RC1 release.
- Q65 sample .WAV files added.
- Repair a defect that caused WSJT-X to crash when launched from an
icon on macOS.
- Repair a crash when using the JT4 mode.
- Sequencing improvements to hold transmitted signal report fixed
during a QSO.
- UI translation updates tnx to Sze-to, VR2UPU, and Michael, 5P1KZX.
- Enable the "Call 1st" option for Q65.
- Improved Q65 message averaging that linearly averages the first 4
sequences and averages exponentially thereafter using a
time-constant of 4 sequences.
- Improved macOS post-install instructions, tnx to John, G4KLA.
- Enhanced Q65 simulator that generates file names compatible with
message averaging, tnx Charlie, G3WDG.
- Q65 simulator option to generate single tone waveforms, tnx to
Charlie, G3WDG.
- Better suppression of birdies in the Q65 decoder.
- Blank Q65 decode messages removed.
- Automatic low Tx audio offset for the widest Q65 modes to keep Tx
signal in transmitter passband, tnx to Charlie, G3WDG.
- Improved SNR estimates for Q65 mode.
- Decode depths Fast/Normal/Deep are now identical in Q65 mode.
- "Save decoded" is now enabled for Q65 mode.
- The obsolete ISCAT mode has been removed.
Release: WSJT-X 2.3.1
Mar 8, 2021
---------------------
WSJT-X 2.3.1 General Availability release updates the User Guide to
cover the new modes FST4 and FST4W along with sample .WAV files and
decoding tutorials. This release also repairs a number of defects and
regressions discovered since the v2.3.0 release, including those
below.
- When sending traffic to a multicast UDP server ensure that the
local loop-back interface is used if no others are selected.
- Repair a defect in instance lock file handling that causes an
infinite loop on start up.
- Invert the PTT serial port sharing default behaviour, and enable
sharing when non-Hamlib CAT control is combined with direct serial
port PTT control.
- Allow the FST4 and FST4W decoders to continue after the first
successful decode when using negative NB values to try multiple NB
values.
- Repair defects in auto-sequencing, particularly with responding to
a repeated final message. In general a double-click of the repeated
message now does the right thing.
- Repair a regression that had inadvertently disabled EU VHF Contest
mode when using the MSK144 mode.
- Repair a defect that could caused incorrect log entry fields when
using FT4 mode and a priori (AP) decoding.
Release: WSJT-X 2.4.0-rc1
Feb 3, 2021
-------------------------
@ -351,7 +435,7 @@ prior v2.2.0 release. Here is a brief summary;
- Italian UI translation, tnx Marco, PY1ZRJ.
- Updated Spanish UI translation, tnx Cédric, EA4AC.
- Updated Spanish UI translation, tnx Cédric, EA4AC.
Release: WSJT-X 2.2

View File

@ -9,10 +9,94 @@
\$$ \$$ \$$$$$$ \$$$$$$ \$$ \$$ \$$
Copyright 2001 - 2021 by Joe Taylor, K1JT.
Release: WSJT-X 2.4.0-rc2
Mar 6, 2021
-------------------------
WSJT-X 2.4.0 Release Candidate 2 adds new Q65 mode functionality and
decoder optimizations; repairs defects and regressions discovered in
the RC1 release.
- Q65 sample .WAV files added.
- Repair a defect that caused WSJT-X to crash when launched from an
icon on macOS.
- Repair a crash when using the JT4 mode.
- Sequencing improvements to hold transmitted signal report fixed
during a QSO.
- UI translation updates tnx to Sze-to, VR2UPU, and Michael, 5P1KZX.
- Enable the "Call 1st" option for Q65.
- Improved Q65 message averaging that linearly averages the first 4
sequences and averages exponentially thereafter using a
time-constant of 4 sequences.
- Improved macOS post-install instructions, tnx to John, G4KLA.
- Enhanced Q65 simulator that generates file names compatible with
message averaging, tnx Charlie, G3WDG.
- Q65 simulator option to generate single tone waveforms, tnx to
Charlie, G3WDG.
- Better suppression of birdies in the Q65 decoder.
- Blank Q65 decode messages removed.
- Automatic low Tx audio offset for the widest Q65 modes to keep Tx
signal in transmitter passband, tnx to Charlie, G3WDG.
- Improved SNR estimates for Q65 mode.
- Decode depths Fast/Normal/Deep are now identical in Q65 mode.
- "Save decoded" is now enabled for Q65 mode.
- The obsolete ISCAT mode has been removed.
Release: WSJT-X 2.3.1
Mar 8, 2021
---------------------
WSJT-X 2.3.1 General Availability release updates the User Guide to
cover the new modes FST4 and FST4W along with sample .WAV files and
decoding tutorials. This release also repairs a number of defects and
regressions discovered since the v2.3.0 release, including those
below.
- When sending traffic to a multicast UDP server ensure that the
local loop-back interface is used if no others are selected.
- Repair a defect in instance lock file handling that causes an
infinite loop on start up.
- Invert the PTT serial port sharing default behaviour, and enable
sharing when non-Hamlib CAT control is combined with direct serial
port PTT control.
- Allow the FST4 and FST4W decoders to continue after the first
successful decode when using negative NB values to try multiple NB
values.
- Repair defects in auto-sequencing, particularly with responding to
a repeated final message. In general a double-click of the repeated
message now does the right thing.
- Repair a regression that had inadvertently disabled EU VHF Contest
mode when using the MSK144 mode.
- Repair a defect that could caused incorrect log entry fields when
using FT4 mode and a priori (AP) decoding.
Release: WSJT-X 2.4.0-rc1
Feb 3, 2021
-------------------------
@ -352,7 +436,7 @@ prior v2.2.0 release. Here is a brief summary;
- Italian UI translation, tnx Marco, PY1ZRJ.
- Updated Spanish UI translation, tnx Cédric, EA4AC.
- Updated Spanish UI translation, tnx Cédric, EA4AC.
Release: WSJT-X 2.2

View File

@ -117,7 +117,7 @@ SampleDownloader::impl::impl (QSettings * settings
main_layout_.addLayout (&left_layout_, 0, 0);
main_layout_.addWidget (&button_box_, 0, 1);
main_layout_.addWidget (&details_widget_, 1, 0, 1, 2);
main_layout_.setRowStretch (1, 2);
main_layout_.setRowStretch (0, 2);
setLayout (&main_layout_);
connect (&button_box_, &QDialogButtonBox::clicked, this, &SampleDownloader::impl::button_clicked);

View File

@ -49,6 +49,8 @@ Directory::Directory (Configuration const * configuration
setColumnCount (2);
setHeaderLabels ({tr ("File"), tr ("Progress")});
headerItem ()->setTextAlignment (0, Qt::AlignHCenter);
headerItem ()->setTextAlignment (1, Qt::AlignHCenter);
header ()->setSectionResizeMode (QHeaderView::ResizeToContents);
setItemDelegate (&item_delegate_);
@ -294,14 +296,15 @@ void Directory::update (QTreeWidgetItem * item)
int counted {0};
// get the count, progress and size of children
int items {recurse_children (item, &counted, &bytes, &max)};
// int items {recurse_children (item, &counted, &bytes, &max)};
recurse_children (item, &counted, &bytes, &max);
// estimate size of items not yet downloaded as average of
// those actually present
if (counted)
{
max += (items - counted) * max / counted;
}
// if (counted)
// {
// max += (items - counted) * max / counted;
// }
// save as our progress
item->setData (1, Qt::UserRole, max);

View File

@ -14,28 +14,42 @@ void DirectoryDelegate::paint (QPainter * painter, QStyleOptionViewItem const& o
{
if (1 == index.column ())
{
QStyleOptionProgressBar progress_bar_option;
progress_bar_option.rect = option.rect;
progress_bar_option.state = QStyle::State_Enabled;
progress_bar_option.direction = QApplication::layoutDirection ();
progress_bar_option.fontMetrics = QApplication::fontMetrics ();
progress_bar_option.minimum = 0;
progress_bar_option.maximum = 100;
auto progress = index.data ().toLongLong ();
qint64 percent;
if (progress > 0)
{
auto percent = int (progress * 100 / index.data (Qt::UserRole).toLongLong ());
progress_bar_option.progress = percent;
progress_bar_option.text = QString::number (percent) + '%';
progress_bar_option.textVisible = true;
progress_bar_option.textAlignment = Qt::AlignCenter;
percent = int (progress * 100 / index.data (Qt::UserRole).toLongLong ());
}
#if !defined (Q_OS_DARWIN)
QStyleOptionProgressBar progress_option;
auto control_element = QStyle::CE_ProgressBar;
progress_option.minimum = 0;
progress_option.maximum = 100;
progress_option.textAlignment = Qt::AlignCenter;
if (progress > 0)
{
progress_option.progress = percent;
progress_option.textVisible = true;
}
else
{
// not started
progress_bar_option.progress = -1;
progress_option.progress = -1;
}
QApplication::style ()->drawControl (QStyle::CE_ProgressBar, &progress_bar_option, painter);
#else
// workaround for broken QProgressBar item delegates on macOS
QStyleOptionViewItem progress_option;
auto control_element = QStyle::CE_ItemViewItem;
progress_option.displayAlignment = Qt::AlignHCenter;
progress_option.index = index;
progress_option.features = QStyleOptionViewItem::HasDisplay;
#endif
progress_option.rect = option.rect;
progress_option.state = QStyle::State_Enabled;
progress_option.direction = QApplication::layoutDirection ();
progress_option.fontMetrics = QApplication::fontMetrics ();
progress_option.text = QString::number (progress > 0 ? percent : 0) + '%';
QApplication::style ()->drawControl (control_element, &progress_option, painter);
}
else
{

View File

@ -27,7 +27,12 @@ FileNode::FileNode (QTreeWidgetItem * parent
void FileNode::error (QString const& title, QString const& message)
{
MessageBox::warning_message (treeWidget (), title, message);
if (MessageBox::Retry == MessageBox::warning_message (treeWidget (), title, message
, QString {}, MessageBox::Cancel | MessageBox::Retry
, MessageBox::Cancel))
{
sync (true);
}
}
bool FileNode::sync (bool local)

View File

@ -436,7 +436,11 @@ HamlibTransceiver::HamlibTransceiver (logger_type * logger,
{
m_->set_conf ("ptt_type", "RTS");
}
m_->set_conf ("ptt_share", "1");
}
// do this late to allow any configuration option to be overriden
load_user_settings ();
}
HamlibTransceiver::HamlibTransceiver (logger_type * logger,
@ -453,51 +457,6 @@ HamlibTransceiver::HamlibTransceiver (logger_type * logger,
// m_->rig_->state.obj = this;
//
// user defined Hamlib settings
//
auto settings_file_name = QStandardPaths::locate (QStandardPaths::AppConfigLocation
, "hamlib_settings.json");
if (!settings_file_name.isEmpty ())
{
QFile settings_file {settings_file_name};
qDebug () << "Using Hamlib settings file:" << settings_file_name;
if (settings_file.open (QFile::ReadOnly))
{
QJsonParseError status;
auto settings_doc = QJsonDocument::fromJson (settings_file.readAll (), &status);
if (status.error)
{
throw error {tr ("Hamlib settings file error: %1 at character offset %2")
.arg (status.errorString ()).arg (status.offset)};
}
qDebug () << "Hamlib settings JSON:" << settings_doc.toJson ();
if (!settings_doc.isObject ())
{
throw error {tr ("Hamlib settings file error: top level must be a JSON object")};
}
auto const& settings = settings_doc.object ();
//
// configuration settings
//
auto const& config = settings["config"];
if (!config.isUndefined ())
{
if (!config.isObject ())
{
throw error {tr ("Hamlib settings file error: config must be a JSON object")};
}
auto const& config_list = config.toObject ();
for (auto item = config_list.constBegin (); item != config_list.constEnd (); ++item)
{
m_->set_conf (item.key ().toLocal8Bit ().constData ()
, (*item).toVariant ().toString ().toLocal8Bit ().constData ());
}
}
}
}
if (!m_->is_dummy_)
{
switch (rig_get_caps_int (m_->model_, RIG_CAPS_PORT_TYPE))
@ -592,17 +551,69 @@ HamlibTransceiver::HamlibTransceiver (logger_type * logger,
{
m_->set_conf ("ptt_type", "RTS");
}
m_->set_conf ("ptt_share", "1");
}
// Make Icom CAT split commands less glitchy
m_->set_conf ("no_xchg", "1");
// do this late to allow any configuration option to be overriden
load_user_settings ();
// would be nice to get events but not supported on Windows and also not on a lot of rigs
// rig_set_freq_callback (m_->rig_.data (), &frequency_change_callback, this);
}
HamlibTransceiver::~HamlibTransceiver () = default;
void HamlibTransceiver::load_user_settings ()
{
//
// user defined Hamlib settings
//
auto settings_file_name = QStandardPaths::locate (QStandardPaths::AppConfigLocation
, "hamlib_settings.json");
if (!settings_file_name.isEmpty ())
{
QFile settings_file {settings_file_name};
qDebug () << "Using Hamlib settings file:" << settings_file_name;
if (settings_file.open (QFile::ReadOnly))
{
QJsonParseError status;
auto settings_doc = QJsonDocument::fromJson (settings_file.readAll (), &status);
if (status.error)
{
throw error {tr ("Hamlib settings file error: %1 at character offset %2")
.arg (status.errorString ()).arg (status.offset)};
}
qDebug () << "Hamlib settings JSON:" << settings_doc.toJson ();
if (!settings_doc.isObject ())
{
throw error {tr ("Hamlib settings file error: top level must be a JSON object")};
}
auto const& settings = settings_doc.object ();
//
// configuration settings
//
auto const& config = settings["config"];
if (!config.isUndefined ())
{
if (!config.isObject ())
{
throw error {tr ("Hamlib settings file error: config must be a JSON object")};
}
auto const& config_list = config.toObject ();
for (auto item = config_list.constBegin (); item != config_list.constEnd (); ++item)
{
m_->set_conf (item.key ().toLocal8Bit ().constData ()
, (*item).toVariant ().toString ().toLocal8Bit ().constData ());
}
}
}
}
}
int HamlibTransceiver::do_start ()
{
CAT_TRACE ("starting: " << rig_get_caps_cptr (m_->model_, RIG_CAPS_MFG_NAME_CPTR)

View File

@ -24,6 +24,7 @@ public:
~HamlibTransceiver ();
private:
void load_user_settings ();
int do_start () override;
void do_stop () override;
void do_frequency (Frequency, MODE, bool no_ignore) override;

View File

@ -5,23 +5,37 @@ RxFreq: 1000/10
Commit No_AP MyCall BothCalls
-----------------------------------------------
ef4787: 3 10 6 14 30 33
ada5a6: 3 6 6 10 29 36
10f574: 2 7 97.6 6 10 95.4 21 33 80.7
b8ea4c: 2 7 100.5 6 10 96.9 21 33 81.0
767f53: 1 1 5 116 6 10 85 21 32 59 RC1
767f53: 2 2 7 301 6 10 241 21 33 168
767f53: 3 2 7 334 6 10 283 21 33 194
94c315: 1 1 5 61 6 10 56 21 33 39
94c315: 2 2 7 205 6 12 183 21 34 126
94c315: 3 2 7 234 6 12 209 21 34 152
7ad881: 1 2 7 69 6 12 61 21 33 46
7ad881: 2 2 7 184 6 12 188 21 34 128
7ad881: 3 2 7 244 6 12 216 21 34 148
Mode: Q65-30A
Data: 30A_N0AN_6m_Ionoscatter (69 files, 6m ionoscatter)
Message: "N0AN K1JT -19"
RxFreq: 1500/10
Commit No_AP MyCall BothCalls
------------------------------------------------
ef4787: 7 14 16 22 38 40
70a348: 38 43
ada5a6: 10 17 11 23 40 46
10f574: 8 16 99.4 15 24 91.8 34 44 68.8
b8ea4c: 8 16 96.0 15 23 92.4 34 44 68.8
Commit No_AP MyCall BothCalls
-----------------------------------------------
767f53: 1 8 16 76 15 23 70 33 42 48
767f53: 2 10 16 225 15 24 217 34 44 134
767f53: 3 10 16 266 15 24 260 34 44 155
94c315: 1 8 16 45 16 23 43 33 42 32
94c315: 2 11 17 163 16 23 159 34 44 101
94c315: 3 11 17 241 16 23 184 34 44 117
7ad881: 1 10 18 94 17 24 101 35 45 90
7ad881: 2 12 18 259 17 24 279 35 45 244
7ad881: 3 12 18 299 17 24 322 35 45 284
Mode: Q65-60B
Data: 60B_1296_Troposcatter (75 files)
@ -30,10 +44,18 @@ RxFreq: 1000/10
Commit No_AP MyCall BothCalls
--------------------------------------------------
ef4787: 1 2 11 23 64 67
ada5a6: 1 5 14 28 64 67
10f574: 1 5 142.7 11 27 129.8 65 67 36.8
b8ea4c: 1 5 144.3 11 27 132.2 65 67 39.3
767f53: 1 1 5 115 12 27 105 68 69 22 RC1
767f53: 2 1 5 322 12 28 304 65 67 53
767f53: 3 1 5 401 12 28 354 65 67 63
94c315: 1 1 8 81 12 26 71 68 69 19
94c315: 2 1 8 249 14 28 235 68 69 36
94c315: 3 1 8 283 14 28 270 68 69 39
7ad881: 1 1 8 97 12 27 90 68 69 24
7ad881: 2 1 8 253 14 28 238 68 69 47
7ad881: 3 1 8 274 14 28 263 69 69 52
Mode: Q65-60D
Data: MsgAvg (22 files, simulated fDop = 50 Hz)
@ -42,10 +64,17 @@ RxFreq: 1000/10
Commit No_AP MyCall BothCalls
------------------------------------------------
ef4787: 0 10 21 21 22 22
ada5a6 0 11 21 21 22 22
10f574: 0 11 47.7 21 21 33.9 22 22 11.6
b8ea4c: 0 11 46.4 21 21 33.8 22 22 11.9
767f53: 1 0 11 39 19 19 28 22 22 7
767f53: 2 0 11 103 21 21 70 22 22 7
767f53: 3 0 11 106 21 21 73 22 22 7
94c315: 1 0 11 27 19 19 20 22 22 7
94c315: 2 0 11 83 21 21 57 22 22 7
94c315: 3 0 11 92 21 21 64 22 22 7
7ad881: 1 0 11 32 21 21 23 22 22 7
7ad881: 2 0 11 77 21 21 53 22 22 7
7ad881: 3 0 11 86 21 21 63 22 22 11
Mode: Q65-60D
Data: 60D_2 (21 files, 1296 troposcatter)
@ -54,18 +83,36 @@ RxFreq: 1000/20
Commit No_AP MyCall BothCalls
----------------------------------------------
10f574: 5 5 33.6 7 8 31.8 12 14 25.1
b8ea4v: 5 5 39.1 7 8 38.0 13 14 30.8
767f53: 1 2 4 36 6 8 35 13 14 22
767f53: 2 5 5 84 9 10 78 13 14 47
767f53: 3 5 5 85 9 10 83 13 14 50
94c315: 1 2 4 27 6 8 25 13 15 17
94c315: 2 5 5 67 7 8 65 13 15 39
94c315: 3 5 5 76 9 10 71 13 15 44
7ad881: 1
7ad881: 2
7ad881: 3
Mode: Q65-120D
Data: 120D (14 files, 10 GHz troposcatter)
Message: "VK7MO VK3WE QF32"
Message: "VK7MO VK3WE QF32", "VK7MO VK3WE R-18"
RxFreq: 1000/20
Commit No_AP MyCall BothCalls
----------------------------------------------
10f574: 0 0 24.9 0 0 25.0 1 4 25.0
b8ea4v: 0 0 39.1 0 0 25.4 1 5 40.1
767f53: 1 0 0 33 0 0 34 1 5 31 RC1
767f53: 2 0 0 83 0 0 80 1 5 74
767f53: 3 0 0 89 0 0 89 1 5 83
94c315: 1 0 0 26 0 0 26 1 5 25
94c315: 2 0 0 66 0 0 66 1 5 61
94c315: 3 0 0 72 0 0 72 1 5 67
7ad881: 1
7ad881: 2
7ad881: 3
Mode: Q65-60D
Data: 60D_10_GHz_EME (14 files)
@ -74,5 +121,14 @@ RxFreq: 1000/50
Commit No_AP MyCall BothCalls
----------------------------------------------
10f574: 9 10 13.6 10 11 12.7 14 14 7.1
b8ea4v: 9 10 13.7 10 11 12.6 14 14 7.5
767f53: 1 8 9 13 9 10 12 14 14 6 RC1
767f53: 2 9 10 26 10 11 25 14 14 6
767f53: 3 9 10 27 10 11 26 14 14 6
94c315: 1 8 9 11 9 10 10 14 14 6
94c315: 2 9 10 22 10 11 20 14 14 6
94c315: 3 9 10 24 10 11 23 14 14 6
7ad881: 1
7ad881: 2
7ad881: 3

View File

@ -192,7 +192,7 @@ WSJTXLogging::WSJTXLogging ()
(
sinks::file::make_collector
(
keywords::max_size = 40 * 1024 * 1024
keywords::max_size = 5 * 1024 * 1024
, keywords::min_free_space = 1024 * 1024 * 1024
, keywords::max_files = 12
, keywords::target = app_data.absoluteFilePath ("logs").toStdWString ()

842
cty.dat

File diff suppressed because it is too large Load Diff

View File

@ -10,8 +10,7 @@ JT9/VHF 1111101010001111100100000000000000000
JT9+JT65 1110100000011110000100000000000010000
JT65 1110100000001110000100000000000010000
JT65/VHF 1111100100001101101011000100000000000
QRA64 1111100101101101100000000010000000000
Q65 1111110101101101001110000011000000001
Q65 1111110101101101001110000001000000001
ISCAT 1001110000000001100000000000000000000
MSK144 1011111101000000000100010000000000000
WSPR 0000000000000000010100000000000000000

View File

@ -166,9 +166,9 @@ function (document)
COMMAND ${ASCIIDOCTOR_EXECUTABLE} ${_args_ASCIIDOCTOR_OPTIONS}
-b html5
-a nofooter
-a VERSION_MAJOR=${WSJTX_VERSION_MAJOR}
-a VERSION_MINOR=${WSJTX_VERSION_MINOR}
-a VERSION_PATCH=${WSJTX_VERSION_PATCH}
-a VERSION_MAJOR=${PROJECT_VERSION_MAJOR}
-a VERSION_MINOR=${PROJECT_VERSION_MINOR}
-a VERSION_PATCH=${PROJECT_VERSION_PATCH}
-a VERSION=${wsjtx_VERSION}
--out-file=${_html_file} ${_source_name}
DEPENDS ${_args_DEPENDS}
@ -195,9 +195,9 @@ function (document)
COMMAND ${ASCIIDOCTOR_EXECUTABLE} ARGS ${_args_ASCIIDOCTOR_OPTIONS}
-b docbook
-a data-uri!
-a VERSION_MAJOR=${WSJTX_VERSION_MAJOR}
-a VERSION_MINOR=${WSJTX_VERSION_MINOR}
-a VERSION_PATCH=${WSJTX_VERSION_PATCH}${BUILD_TYPE_REVISION}
-a VERSION_MAJOR=${wsjtx_VERSION_MAJOR}
-a VERSION_MINOR=${wsjtx_VERSION_MINOR}
-a VERSION_PATCH=${wsjtx_VERSION_PATCH}${BUILD_TYPE_REVISION}
-a VERSION=${wsjtx_VERSION}
-D ${CMAKE_CURRENT_BINARY_DIR}
-o ${_docbook_file} ${_source_name}

View File

@ -27,9 +27,10 @@ our work under terms of the GNU General Public License must display
the following copyright notice prominently:
*The algorithms, source code, look-and-feel of _{prog}_ and related
programs, and protocol specifications for the modes FSK441, FT4, FT8,
JT4, JT6M, JT9, JT65, JTMS, QRA64, ISCAT, and MSK144 are Copyright (C)
2001-2020 by one or more of the following authors: Joseph Taylor,
K1JT; Bill Somerville, G4WJS; Steven Franke, K9AN; Nico Palermo,
IV3NWV; Greg Beam, KI7MT; Michael Black, W9MDB; Edson Pereira, PY2SDR;
Philip Karn, KA9Q; and other members of the WSJT Development Group.*
programs, and protocol specifications for the modes FSK441, FST4,
FST4W, FT4, FT8, JT4, JT6M, JT9, JT44, JT65, JTMS, Q65, QRA64, ISCAT,
and MSK144 are Copyright (C) 2001-2021 by one or more of the following
authors: Joseph Taylor, K1JT; Bill Somerville, G4WJS; Steven Franke,
K9AN; Nico Palermo, IV3NWV; Greg Beam, KI7MT; Michael Black, W9MDB;
Edson Pereira, PY2SDR; Philip Karn, KA9Q; and other members of the
WSJT Development Group.*

View File

@ -94,8 +94,8 @@ d). Edit lines as needed. Keeping them in alphabetic order help see dupes.
:sourceforge-jtsdk: https://sourceforge.net/projects/jtsdk[SourceForge JTSDK]
:ubuntu_sdk: https://launchpad.net/~ubuntu-sdk-team/+archive/ppa[Ubuntu SDK Notice]
:win_openssl_packages: https://slproweb.com/products/Win32OpenSSL.html[Windows OpenSSL Packages]
:win32_openssl: https://slproweb.com/download/Win32OpenSSL_Light-1_1_1h.msi[Win32 OpenSSL Light Package]
:win64_openssl: https://slproweb.com/download/Win64OpenSSL_Light-1_1_1h.msi[Win64 OpenSSL Light Package]
:win32_openssl: https://slproweb.com/download/Win32OpenSSL_Light-1_1_1j.msi[Win32 OpenSSL Light Package]
:win64_openssl: https://slproweb.com/download/Win64OpenSSL_Light-1_1_1j.msi[Win64 OpenSSL Light Package]
:writelog: https://writelog.com/[Writelog]
:wsjtx_group: https://groups.io/g/WSJTX[WSJTX Group]
:wsjtx: https://physics.princeton.edu/pulsar/K1JT/wsjtx.html[WSJT-X]

View File

@ -42,7 +42,7 @@ control. The *Sync* control sets a minimum threshold for establishing
time and frequency synchronization with a received signal.
* Spinner control *T/R xx s* sets sequence lengths for transmission
and reception in ISCAT, MSK144, and the fast JT9 modes.
and reception in Q65, MSK144, and the fast JT9 modes.
* With *Split operation* activated on the *File -> Settings -> Radio* tab, in
MSK144 and the fast JT9 submodes you can activate the spinner control
@ -60,7 +60,7 @@ specified response frequency.
* Checkboxes at bottom center of the main window control special
features for particular operating modes:
** *Sh* enables shorthand messages in JT4, JT65, QRA64 and MSK144 modes
** *Sh* enables shorthand messages in JT4, JT65, Q65, and MSK144 modes
** *Fast* enables fast JT9 submodes
@ -69,4 +69,5 @@ features for particular operating modes:
** *Call 1st* enables automatic response to the first decoded
responder to your CQ
** *Tx6* toggles between two types of shorthand messages in JT4 mode
** *Tx6* toggles between two types of shorthand messages in JT4 and
Q65 modes

View File

@ -37,6 +37,12 @@ examples for configurations `FT8` and `Echo`:
==== View Menu
image::view-menu.png[align="left",alt="View Menu"]
The *SWL Mode* action reduces the _WSJT-X_ main window to a minimum
size with just the menus, decodes windows, and status bar visible. You
may find this useful when running multiple instances of the
application. Both size and location of the main window are saved and
recalled independently for this view.
[[MODE_MENU]]
==== Mode Menu
image::mode-menu.png[align="left",alt="Mode Menu"]

View File

@ -1,11 +1,10 @@
// Status=edited
Two arrangements of controls are provided for generating and selecting
Tx messages. Controls familiar to users of program _WSJT_
appear on *Tab 1*, providing six fields for message entry.
Pre-formatted messages for the standard minimal QSO are generated when
you click *Generate Std Msgs* or double-click on an appropriate line
in one of the decoded text windows.
Controls familiar to users of program _WSJT_ appear on *Tab 1*,
providing six fields for message entry. Pre-formatted messages for
the standard minimal QSO are generated when you click *Generate Std
Msgs* or double-click on an appropriate line in one of the decoded
text windows.
//.Traditional Message Menu
image::traditional-msg-box.png[align="center",alt="Traditional Message Menu"]
@ -28,31 +27,12 @@ stored messages entered on the *Files -> Settings -> Tx Macros* tab.
Pressing *Enter* on a modified message #5 automatically adds that
message to the stored macros.
* In some circumstances it may be desirable to make your QSOs as
short as possible. To configure the program to start contacts with
message #2, disable message #1 by double-clicking its radio-button in the *Next* column or *Tx 1* button in the *Now* column. Similarly, to send RR73
rather than RRR for message #4, double-click one of its buttons.
The second arrangement of controls for generating and selecting
Tx messages appears on *Tab 2* of the Message Control Panel:
//.New Message Menu
image::new-msg-box.png[align="center",alt="New Message Menu"]
With this setup you normally follow a top-to-bottom sequence of
transmissions from the left column if you are calling CQ, or the right
column if answering a CQ.
* Clicking a button puts the appropriate message in the *Gen Msg* box.
If you are already transmitting, the Tx message is changed
immediately.
* You can enter and transmit anything (up to 13 characters, including
spaces) in the *Free Msg* box.
* Click the pull-down arrow in the *Free Msg* box to select a
stored macro. Pressing *Enter* on a modified message here
automatically adds that message to the table of stored macros.
* In some circumstances it may be desirable to make your QSOs as short
as possible. To configure the program to start contacts with message
#2, disable message #1 by double-clicking its radio-button in the
*Next* column or *Tx 1* button in the *Now* column. Similarly, to
send RR73 rather than RRR for message #4, double-click one of its
buttons.
+

View File

@ -2,12 +2,12 @@
=== AP Decoding
The _WSJT-X_ decoders for FT4, FT8, JT65, QRA64, include
The _WSJT-X_ decoders for FST4, FT4, FT8, JT65, and Q65 include
procedures that use naturally accumulating information during a
minimal QSO. This _a priori_ (AP) information increases sensitivity
of the decoder by up to 4 dB, at the cost of a slightly higher rate of
false decodes. AP is optional in FT8, JT65, and QRA64, but is always
enabled for FT4.
false decodes. AP is optional in FT8 and JT65, but is always enabled
for Q65 and for FT4 and FST4 when decode depth is Normal or Deep.
For example: when you decide to answer a CQ, you already know your own
callsign and that of your potential QSO partner. The software
@ -27,7 +27,7 @@ example, `a2` indicates that the successful decode used MyCall as
hypothetically known information.
[[FT8_AP_INFO_TABLE]]
.FT4 and FT8 AP information types
.FST4, FT4, and FT8 AP information types
[width="35%",cols="h10,<m20",frame=topbot,options="header"]
|===============================================
|aP | Message components
@ -47,7 +47,9 @@ forwarded to {pskreporter}.
Table 2 lists the six possible QSO states that are tracked by the
_WSJT-X_ auto-sequencer, along with the type of AP decoding that would
be attempted in each state.
be attempted in each state in FT4 or FT8. The FST4 table (not shown)
is the same except that it omits the decoding attempts for AP types
4 and 5 to save time.
[[FT8_AP_DECODING_TYPES_TABLE]]
.FT4 and FT8 AP decoding types for each QSO state
@ -109,14 +111,14 @@ summarized in the following Table:
[width="50%",cols="h,3*^",frame=topbot,options="header"]
|===========================================
|Mode |Mode character|Sync character|End of line information
|FST4 | ` | | ? &#160; aP
|FT4 | ~ | | ? &#160; aP
|FT8 | ~ | | ? &#160; aP
|JT4 | $ | *, # | f, fN, dCN
|JT9 | @ | |
|JT65 | # | |
|JT65 VHF| # | *, # | f, fN, dCN
|QRA64 | : | * | R
|ISCAT | | * | M N C T
|Q65 | : | | qP
|MSK144 | & | |
|===========================================
Sync character::
@ -126,32 +128,20 @@ Sync character::
End of line information::
`?` - Decoded with lower confidence +
`a` - Decoded with aid of some _a priori_ (AP) information +
`C` - Confidence indicator [ISCAT and Deep Search; (0-9,*)] +
`C` - Confidence indicator [Deep Search; (0-9,*)] +
`d` - Deep Search algorithm +
`f` - Franke-Taylor or Fano algorithm +
`M` - Message length (characters) +
`N` - Number of Rx intervals or frames averaged +
`P` - Number indicating type of AP information (Table 1, above) +
`R` - Return code from QRA64 decoder +
`T` - Length of analyzed region (s)
`P` - Number indicating type of AP information (Table 1 or Table 6) +
Table 6 below shows the meaning of the return codes R in QRA64 mode.
[[QRA64_AP_INFO_TABLE]]
.QRA64 AP return codes
[width="35%",cols="h10,<m20",frame=topbot,options="header"]
[[Q65_AP_INFO_TABLE]]
.Q65 end-of-line codes
[width="45%",cols="h10,<m20",frame=topbot,options="header"]
|===============================================
|rc | Message components
|0 | ? &#160; &#160; ? &#160; &#160; ?
|1 | CQ &#160; &#160; ? &#160; &#160; ?
|2 | CQ &#160; &#160; ?
|3 | MyCall &#160; &#160; ? &#160; &#160; ?
|4 | MyCall &#160; &#160; ?
|5 | MyCall DxCall &#160; &#160; ?
|6 | ? &#160; &#160; DxCall &#160; &#160; ?
|7 | ? &#160; &#160; DxCall
|8 | MyCall DxCall DxGrid
|9 | CQ DxCall &#160; &#160; ?
|10 | CQ DxCall
|11 | CQ DxCall DxGrid
| | Message components
|q0 | ? &#160; &#160; ? &#160; &#160; ?
|q1 | CQ &#160; &#160; ? &#160; &#160; ?
|q2 | MyCall &#160; &#160; ? &#160; &#160; ?
|q3 | MyCall DxCall &#160; &#160; ?
|q4 | MyCall DxCall &#160; &#160; [<blank> \| RRR \| RR73 \| 73]
|===============================================

Binary file not shown.

Before

Width:  |  Height:  |  Size: 230 KiB

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 161 KiB

After

Width:  |  Height:  |  Size: 175 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -8,45 +8,44 @@ as an extended branch of an earlier program, _WSJT_, first released in
2001. Bill Somerville, G4WJS, and Steve Franke, K9AN, have been major
contributors to development of _WSJT-X_ since 2013 and 2015, respectively.
_WSJT-X_ Version {VERSION_MAJOR}.{VERSION_MINOR} offers twelve
_WSJT-X_ Version {VERSION_MAJOR}.{VERSION_MINOR} offers eleven
different protocols or modes: *FST4*, *FT4*, *FT8*, *JT4*, *JT9*,
*JT65*, *QRA64*, *ISCAT*, *MSK144*, *WSPR*, *FST4W*, and *Echo*. The
*JT65*, *Q65*, *MSK144*, *WSPR*, *FST4W*, and *Echo*. The
first seven are designed for making reliable QSOs under weak-signal
conditions. They use nearly identical message structure and source
encoding. JT65 and QRA64 were designed for EME ("`moonbounce`") on
the VHF/UHF bands and have also proven very effective for worldwide
QRP communication on the HF bands. QRA64 has some advantages over
JT65, including better performance for EME on the higher microwave
bands. JT9 was originally designed for the HF and lower bands. Its
submode JT9A is 1 dB more sensitive than JT65 while using less than
10% of the bandwidth. JT4 offers a wide variety of tone spacings and
has proven highly effective for EME on microwave bands up to 24 GHz.
These four "`slow`" modes use one-minute timed sequences of
alternating transmission and reception, so a minimal QSO takes four to
six minutes — two or three transmissions by each station, one sending
in odd UTC minutes and the other even. FT8 is operationally similar
but four times faster (15-second T/R sequences) and less sensitive by
a few dB. FT4 is faster still (7.5 s T/R sequences) and especially
well-suited for radio contesting. FST4 was added to _WSJT-X_ in
version 2.3.0. It is intended especially for use on the LF and MF
bands, and already during its first few months of testing
intercontinental paths have been spanned many times on the 2200 and
630 m bands. Further details can be found in the following section,
<<NEW_FEATURES,New Features in Version 2.3.0>>. On the HF bands,
world-wide QSOs are possible with any of these modes using power
levels of a few watts (or even milliwatts) and compromise antennas.
On VHF bands and higher, QSOs are possible (by EME and other
propagation types) at signal levels 10 to 15 dB below those required
for CW.
encoding. JT65 was designed for EME ("`moonbounce`") on VHF and
higher bands and is mostly used for that purpose today. Q65 replaces
an earlier mode, QRA64. Q65 is particularly effective for tropospheric
scatter, rain scatter, ionospheric scatter, TEP, and EME on VHF and
higher bands, as well as other types of fast-fading signals. JT9 was
originally designed for the HF and lower bands. Its submode JT9A is 1
dB more sensitive than JT65 while using less than 10% of the
bandwidth. JT4 offers a wide variety of tone spacings and has proven
highly effective for EME on microwave bands up to 24 GHz. These four
"`slow`" modes use one-minute timed sequences of alternating
transmission and reception, so a minimal QSO takes four to six minutes
— two or three transmissions by each station, one sending in odd UTC
minutes and the other even. FT8 is operationally similar but four
times faster (15-second T/R sequences) and less sensitive by a few dB.
FT4 is faster still (7.5 s T/R sequences) and especially well-suited
for radio contesting. FST4 was added to _WSJT-X_ in version 2.3.0.
It is intended especially for use on the LF and MF bands, and already
during its first few months of testing intercontinental paths have
been spanned many times on the 2200 and 630 m bands. Further details
can be found in the following section, <<NEW_FEATURES,New Features in
Version 2.4.0>>. On the HF bands, world-wide QSOs are possible with
any of these modes using power levels of a few watts (or even
milliwatts) and compromise antennas. On VHF bands and higher, QSOs
are possible (by EME, scatter, and other propagation types) at signal
levels 10 to 15 dB below those required for CW.
*ISCAT*, *MSK144*, and optionally submodes *JT9E-H* are "`fast`"
*MSK144*, and optionally submodes *JT9E-H* are "`fast`"
protocols designed to take advantage of brief signal enhancements from
ionized meteor trails, aircraft scatter, and other types of scatter
propagation. These modes use timed sequences of 5, 10, 15, or 30 s
duration. User messages are transmitted repeatedly at high rate (up
to 250 characters per second for MSK144) to make good use of the
shortest meteor-trail reflections or "`pings`". ISCAT uses free-form
messages up to 28 characters long, while MSK144 uses the same
shortest meteor-trail reflections or "`pings`". MSK144 uses the same
structured messages as the slow modes and optionally an abbreviated
format with hashed callsigns.

View File

@ -60,12 +60,10 @@ or rag-chewing.
=== Auto-Sequencing
The 15-second T/R cycles of FT8 allow only about two seconds to inspect
decoded messages and decide how to reply, which is often not enough.
The slow modes JT4, JT9, JT65, and QRA64 allow nearly 10 seconds
for this task, but operators may find that this is still insufficient
when workload is high, especially on EME. For these reasons a basic
auto-sequencing feature is offered.
The T/R cycles of many _WSJT-X_ modes allow only a few seconds to
inspect decoded messages and decide how to reply. Often this is not
enough time, so for FST4, FT4, FT8, MSK144, and Q65 the program
offers a basic auto-sequencing feature.
Check *Auto Seq* on the main window to enable this feature:
@ -77,7 +75,8 @@ responder to your CQ.
NOTE: When *Auto-Seq* is enabled, the program de-activates *Enable Tx*
at the end of each QSO. It is not intended that _WSJT-X_ should make
fully automated QSOs.
fully automated QSOs. *Auto-sequencing is an operator aid, not an
operator replacement.*
[[CONTEST_MSGS]]
=== Contest Messages
@ -160,7 +159,7 @@ guidelines for contest logging with FT4, FT8, and MSK144:
[[COMP-CALL]]
=== Nonstandard Callsigns
*FT4, FT8, and MSK144*
*FST4, FT4, FT8, MSK144, and Q65*
Compound callsigns like xx/K1ABC or K1ABC/x and special event
callsigns like YW18FIFA are supported for normal QSOs but not for
@ -196,7 +195,7 @@ the types of information that can be included in a message. It
prevents including your locator in standard messages, which
necessarily impairs the usefulness of tools like PSK Reporter.
*JT4, JT9, JT65, and QRA64*
*JT4, JT9, and JT65*
In the 72-bit modes, compound callsigns are handled in one of two
possible ways:

View File

@ -1,34 +1,15 @@
[[NEW_FEATURES]]
=== New in Version {VERSION}
_WSJT-X 2.3.0_ introduces *FST4* and *FST4W*, new digital protocols
designed particularly for the LF and MF bands. Decoders for these
modes can take advantage of the very small Doppler spreads present at
these frequencies, even over intercontinental distances. As a
consequence, fundamental sensitivities of FST4 and FST4W are better
than other _WSJT-X_ modes with the same sequence lengths, approaching
the theoretical limits for their rates of information throughput. The
FST4 protocol is optimized for two-way QSOs, while FST4W is for
quasi-beacon transmissions of WSPR-style messages. FST4 and FST4W do
not require the strict, independent phase locking and time
synchronization of modes like EbNaut.
_WSJT-X 2.4.0_ introduces *Q65*, a new digital protocol designed for
minimal two-way QSOs over especially difficult propagation paths. On
paths with Doppler spread more than a few Hz, the weak-signal
performance of Q65 is the best among all WSJT-X modes.
The new modes use 4-GFSK modulation and share common software for
encoding and decoding messages. FST4 offers T/R sequence lengths of
15, 30, 60, 120, 300, 900, and 1800 seconds, while FST4W omits the
lengths shorter than 120 s. Submodes are given names like FST4-60,
FST4W-300, etc., the appended numbers indicating sequence length in
seconds. Message payloads contain either 77 bits, as in FT4, FT8, and
MSK144, or 50 bits for the WSPR-like messages of FST4W. Message
formats displayed to the user are like those in the other 77-bit and
50-bit modes in _WSJT-X_. Forward error correction uses a low density
parity check (LDPC) code with 240 information and parity bits.
Transmissions consist of 160 symbols: 120 information-carrying symbols
of two bits each, interspersed with five groups of eight predefined
synchronization symbols.
*We recommend that on the 2200 and 630 m bands FST4 should replace JT9
for making 2-way QSOs, and FST4W should replace WSPR for propagation
tests*. Operating conventions on these LF and MF bands will
eventually determine the most useful T/R sequence lengths for each
type of operation.
Q65 uses message formats and sequencing identical to those used in
FST4, FT4, FT8, and MSK144. Submodes are provided with a wide variety
of tone spacings and T/R sequence lengths 15, 30, 60, 120, and 300 s.
A new, highly reliable list-decoding technique is used for messages
that contain previously copied message fragments. Message averaging
is provided for situations where single transmissions are too weak or
signal enhancements too sparse for a signal to be decoded.

View File

@ -3,9 +3,9 @@
[[PROTOCOL_OVERVIEW]]
=== Overview
All QSO modes except ISCAT use structured messages that compress
user-readable information into fixed-length packets. JT4, JT9, JT65,
and QRA64 use 72-bit payloads. Standard messages consist of two
All QSO modes use structured messages that compress
user-readable information into fixed-length packets. JT4, JT9, and JT65
use 72-bit payloads. Standard messages consist of two
28-bit fields normally used for callsigns and a 15-bit field for a
grid locator, report, acknowledgment, or 73. An additional bit flags
a message containing arbitrary free text, up to 13 characters.
@ -14,7 +14,7 @@ Special cases allow other information such as add-on callsign prefixes
aim is to compress the most common messages used for minimally valid
QSOs into a fixed 72-bit length.
Information payloads for FST4, FT4, FT8, and MSK144 contain 77 bits.
Information payloads for FST4, FT4, FT8, Q65, and MSK144 contain 77 bits.
The 5 additional bits are used to flag special message types used for
nonstandard callsigns, contest exchanges, FT8 DXpedition Mode, and a
few other possibilities. Full details have been published in QEX, see
@ -169,25 +169,25 @@ same as that of the sync tone used in long messages, and the frequency
separation is 110250/4096 = 26.92 Hz multiplied by n for JT65A, with n
= 2, 3, 4 used to convey the messages RO, RRR, and 73, respectively.
[[QRA64_PROTOCOL]]
==== QRA64
[[Q65_PROTOCOL]]
==== Q65
QRA64 is intended for EME and other extreme weak-signal applications.
Its internal code was designed by IV3NWV. The protocol uses a (63,12)
**Q**-ary **R**epeat **A**ccumulate code that is inherently better
than the Reed Solomon (63,12) code used in JT65, yielding a 1.3 dB
advantage. A new synchronizing scheme is based on three 7 x 7 Costas
arrays. This change yields another 1.9 dB advantage.
Q65 is intended for scatter, EME, and other extreme weak-signal
applications. Forward error correction (FEC) uses a specially
designed (65,15) block code with six-bit symbols. Two symbols are
“punctured” from the code, yielding an effective (63,13) code with a
payload of k = 13 information symbols conveyed by n = 63 channel
symbols. The punctured symbols consist of a 12-bit CRC computed from
the 13 information symbols. The CRC is used to reduce the
false-decode rate to a very low value. A 22-symbol pseudo-random
sequence spread throughout a transmission is sent as “tone 0” and used
for synchronization. The total number of channel symbols in a Q65
transmission is thus 63 + 22 = 85.
In most respects the current implementation of QRA64 is operationally
similar to JT65. QRA64 does not use two-tone shorthand messages, and
it makes no use of a callsign database. Rather, additional
sensitivity is gained by making use of already known information as a
QSO progresses -- for example, when reports are being exchanged and
you have already decoded both callsigns in a previous transmission.
QRA64 presently offers no message averaging capability, though that
feature may be added. In early tests, many EME QSOs were made using
submodes QRA64A-E on bands from 144 MHz to 24 GHz.
For each T/R sequence length, submodes A - E have tone spacings and
occupied bandwidths 1, 2, 4, 8, and 16 times those specified in the
above table. Full submode designations include a number for sequence
length and a letter for tone spacing, as in Q65-15A, Q65-120C, etc.
[[WSPR_PROTOCOL]]
==== WSPR
@ -277,8 +277,12 @@ which the probability of decoding is 50% or higher.
|FT8 |LDPC |(174,91)| 8| 8-GFSK| 6.25 | 50.0 | 0.27| 12.6 | -21
|JT4A |K=32, r=1/2|(206,72)| 2| 4-FSK| 4.375| 17.5 | 0.50| 47.1 | -23
|JT9A |K=32, r=1/2|(206,72)| 8| 9-FSK| 1.736| 15.6 | 0.19| 49.0 | -26
|JT65A |Reed Solomon|(63,12) |64|65-FSK| 2.692| 177.6 | 0.50| 46.8 | -25
|QRA64A|Q-ary Repeat Accumulate|(63,12) |64|64-FSK|1.736|111.1|0.25|48.4| -26
|JT65A |RS|(63,12) |64|65-FSK| 2.692| 177.6 | 0.50| 46.8 | -25
|Q65-15A |QRA|(63,13) |64|65-FSK|6.667|433|0.26| 12.8| -22.2
|Q65-30A |QRA|(63,13) |64|65-FSK|3.333|217|0.26| 25.5| -24.8
|Q65-60A |QRA|(63,13) |64|65-FSK|1.667|108|0.26| 51.0| -27.6
|Q65-120A|QRA|(63,13) |64|65-FSK|0.750| 49|0.26|113.3| -30.8
|Q65-300A|QRA|(63,13) |64|65-FSK|0.289| 19|0.26|293.8| -33.8
| WSPR |K=32, r=1/2|(162,50)| 2| 4-FSK| 1.465| 5.9 | 0.50|110.6 | -31
|FST4W-120 |LDPC | (240,74)| 4| 4-GFSK| 1.46 | 5.9 | 0.25| 109.3 | -32.8
|FST4W-300 |LDPC | (240,74)| 4| 4-GFSK| 0.558 | 2.2 | 0.25| 286.7 | -36.8
@ -286,14 +290,18 @@ which the probability of decoding is 50% or higher.
|FST4W-1800 |LDPC | (240,74)| 4| 4-GFSK| 0.089 | 0.36 | 0.25| 1792.0| -44.8
|===============================================================================
Submodes of JT4, JT9, JT65, and QRA64 offer wider tone spacings for
LDPC = Low Density Parity Check
RS = Reed Solomon
QRA = Q-ary Repeat Accumulate
Submodes of JT4, JT9, and JT65 offer wider tone spacings for
circumstances that may require them, such as significant Doppler spread.
Table 8 summarizes the tone spacings, bandwidths, and approximate
threshold sensitivities of the various submodes when spreading is
comparable to tone spacing.
[[SLOW_SUBMODES]]
.Parameters of Slow Submodes with Selectable Tone Spacings
.Parameters of Slow Submodes JT4, JT9, and JT65 with Selectable Tone Spacings
[width="50%",cols="h,3*^",frame=topbot,options="header"]
|=====================================
|Mode |Tone Spacing |BW (Hz)|S/N (dB)
@ -315,56 +323,22 @@ comparable to tone spacing.
|JT65A |2.692| 177.6 |-25
|JT65B |5.383| 352.6 |-25
|JT65C |10.767| 702.5 |-25
|QRA64A|1.736| 111.1 |-26
|QRA64B|3.472| 220.5 |-25
|QRA64C|6.944| 439.2 |-24
|QRA64D|13.889| 876.7 |-23
|QRA64E|27.778|1751.7 |-22
|=====================================
.Parameters of Q65 Submodes
[width="100%",cols="h,5*^",frame=topbot,options="header"]
|=====================================
|T/R Period (s) |A Spacing Width (Hz)|B Spacing Width (Hz)|C Spacing Width (Hz)|D Spacing Width (Hz)|E Spacing Width (Hz)
|15|6.67 &#160; &#160; 4.33|13.33 &#160; &#160; 867|26.67 &#160; &#160; 1733|N/A|N/A
|30|3.33 &#160; &#160; 217|6.67 &#160; &#160; 433|13.33 &#160; &#160; 867| 26.67 &#160; &#160; 1733| N/A
|60|1.67 &#160; &#160; 108|3.33 &#160; &#160; 217|6.67 &#160; &#160; 433|13.33 &#160; &#160; 867|26.67 &#160; &#160; 1733
|120|0.75 &#160; &#160; 49|1.50 &#160; &#160; 98|3.00 &#160; &#160; 195|6.00 &#160; &#160; 390| 12.00 &#160; &#160; 780
|300|0.29 &#160; &#160; 19|0.58 &#160; &#160; 38|1.16 &#160; &#160; 75|2.31 &#160; &#160; 150|4.63 &#160; &#160; 301
|=====================================
[[FAST_MODES]]
=== Fast Modes
==== ISCAT
ISCAT messages are free-form, up to 28 characters in length.
Modulation is 42-tone frequency-shift keying at 11025 / 512 = 21.533
baud (ISCAT-A), or 11025 / 256 = 43.066 baud (ISCAT-B). Tone
frequencies are spaced by an amount in Hz equal to the baud rate. The
available character set is:
----
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ /.?@-
----
Transmissions consist of sequences of 24 symbols: a synchronizing
pattern of four symbols at tone numbers 0, 1, 3, and 2, followed by
two symbols with tone number corresponding to (message length) and
(message length + 5), and, finally, 18 symbols conveying the user's
message, sent repeatedly character by character. The message always
starts with `@`, the beginning-of-message symbol, which is not
displayed to the user. The sync pattern and message-length indicator
have a fixed repetition period, recurring every 24 symbols. Message
information occurs periodically within the 18 symbol positions set
aside for its use, repeating at its own natural length.
For example, consider the user message `CQ WA9XYZ`. Including the
beginning-of-message symbol `@`, the message is 10 characters long.
Using the character sequence displayed above to indicate tone numbers,
the transmitted message will therefore start out as shown in the first
line below:
----
0132AF@CQ WA9XYZ@CQ WA9X0132AFYZ@CQ WA9XYZ@CQ W0132AFA9X ...
sync## sync## sync##
----
Note that the first six symbols (four for sync, two for message
length) repeat every 24 symbols. Within the 18 information-carrying
symbols in each 24, the user message `@CQ WA9XYZ` repeats at its own
natural length, 10 characters. The resulting sequence is extended as
many times as will fit into a Tx sequence.
==== JT9
The JT9 slow modes all use keying rate 12000/6912 = 1.736 baud. By contrast, with
@ -419,8 +393,6 @@ and your QSO partner ± 200 Hz.
|=====================================================================
|Mode |FEC Type |(n,k) | Q|Modulation Type|Keying rate (Baud)
|Bandwidth (Hz)|Sync Energy|Tx Duration (s)
|ISCAT-A | - | - |42|42-FSK| 21.5 | 905 | 0.17| 1.176
|ISCAT-B | - | - |42|42-FSK| 43.1 | 1809 | 0.17| 0.588
|JT9E |K=32, r=1/2|(206,72)| 8| 9-FSK| 25.0 | 225 | 0.19| 3.400
|JT9F |K=32, r=1/2|(206,72)| 8| 9-FSK| 50.0 | 450 | 0.19| 1.700
|JT9G |K=32, r=1/2|(206,72)| 8| 9-FSK|100.0 | 900 | 0.19| 0.850

View File

@ -18,6 +18,13 @@ image::colors.png[align="center",alt="Colors Screen"]
* Check *Highlight by Mode* if you wish worked before status to be per
<<INTRO,mode>>.
* Check *Only grid Fields sought* if you are only interested in the
leading two character grid locator Fields rather than teh four
character grid locator Squares.
* Check *Include extra WAE entities* if you are interested in the
extra entities defined for DARC WAE and CQ Marathon awards.
* Worked before status is calculated from your _WSJT-X_ ADIF
<<LOGGING, Logging>> file, you may replace ADIF log file with one
exported from your station logging application, *Rescan ADIF Log*

View File

@ -96,5 +96,6 @@ green to indicate that proper communication has been established.
Failure of the CAT-control test turns the button red and displays an
error message. After a successful CAT test, toggle the *Test PTT*
button to confirm that your selected method of T/R control is working
properly. (If you selected *VOX* for _PTT Method_, you can test T/R
properly, the button turns red if the rig has been successfully
keyed. (If you selected *VOX* for _PTT Method_, you can test T/R
switching later by using the *Tune* button on the main window.)

View File

@ -19,6 +19,10 @@ QRZ messages. Full details of the protocol can be found in comments
at the top of this file in our source code repository:
https://sourceforge.net/p/wsjt/wsjtx/ci/master/tree/Network/NetworkMessage.hpp
NOTE: The *Outgoing interfaces* and *Multicast TTL* fields are only
present when a multicast group IP address has been entered in
the *UDP Server* field.
Programs like _JTAlert_ use the _UDP Server_ feature to obtain
information about running _WSJT-X_ instances. If you are using
_JTAlert_ to control _WSJT-X_, be sure to check the

View File

@ -16,6 +16,5 @@ characters) in the entry field at top, then click *Add*.
- You can reorder your macro messages by using drag-and-drop. The
new order will be preserved when _WSJT-X_ is restarted.
- Messages can also be added from the main window's *Tx5* field on Tab
1 or the *Free msg* field on Tab 2. Simply hit [Enter] after the
message has been entered.
- Messages can also be added from the main window's *Tx5*
field. Simply hit [Enter] after the message has been entered.

View File

@ -31,7 +31,7 @@ TIP: The PC audio mixer normally has two sliders, one for each
conventional JT65 and JT9 sub-bands simultaneously on most HF bands.
Further details are provided in the <<TUTORIAL,Basic Operating
Tutorial>>. A wider displayed bandwidth may also be helpful at VHF
and above, where FT8, JT4, JT65, and QRA64 signals may be found over
and above, where FT8, JT4, JT65, and Q65 signals may be found over
much wider ranges of frequencies.
- If you have only a standard SSB filter you wont be able to display

View File

@ -1,5 +1,19 @@
Do not confuse FST4 with FT4, which has a very different purpose!
FST4 is is designed for making 2-way QSOs on the LF and MF bands.
FST4 is designed primarily for making weak-signal 2-way QSOs on the
LF and MF bands. T/R periods from 15 s up to 1800 s are
available. Longer T/R periods provide better sensitivity only if
Tx and Rx frequency instability and channel Doppler spread
are small enough so that received signals
remain phase coherent over periods spanning several transmitted symbols.
Generally speaking, Rx and Tx frequency changes
during the transmission and channel Doppler spread should each be small compared
to the symbol keying rate shown for each T/R duration in Table 7 within section
<<PROTOCOL_OVERVIEW,Protocol Specifications>>. For example, the keying rate for
the 1800 s T/R period is 0.089 Baud, so
successful operation using this T/R length requires Tx and Rx frequency
stability better than 0.089 Hz over the duration of the 1800 s transmission in
addition to channel Doppler spread smaller than 0.089 Hz.
Operation with FST4 is similar to that with other _WSJT-X_ modes: most
on-screen controls, auto-sequencing, and other features behave in
familiar ways. However, operating conventions on the 2200 and 630 m
@ -21,3 +35,26 @@ decoding process (and of course will be undecodable). By checking
further limit the decoding range to the setting of *F Tol* on
either side of *Rx Freq*.
A noise blanker can be enabled by setting the *NB* percentage to a non-zero value.
This setting determines how many of the largest-amplitude samples will be
blanked (zeroed) before the data is submitted to the decoder. Most users find
that settings between 0% (no blanking) and 10% work best. If the noise
blanker percentage is set to -1%, then the decoder will try 0, 5, 10, 15, and 20 %
in succession. Similarly, a setting of -2% causes the decoder to loop over
blanking percentages 0, 2, 4, ... 20 %. To save time, the multiple blanking
percentages triggered by negative *NB* settings are tried only for signal
candidates located near (within +/- 20 Hz) of the *Rx* frequency setting.
.Open a sample Wave File:
- Select *FST4* on the *Mode* menu. Set *T/R* to 60 s and *Decode | Deep*.
- Set *NB* (noise blanker) to 0%.
- Set up the Wide Graph display with settings appropriate for the FST4-60 mode.
For example, try *Bins/Pixel* 2 and *N Avg* 4. Set the *Start* frequency and the width of
the Wide Graph to include the frequency range that you want to decode. For this
example, make sure that *Start* is less than 1000 Hz and that the Wide Graph extends to above 1400 Hz.
- Set *F Low* 1000, *F High* 1400. These settings define the decoder's frequency search range.
- Open a sample Wave file using *File | Open* and select the file
...\save\samples\FST4+FST4W\210115_0058.wav. After _WSJT-X_ has processed the file you should see something similar to the following screen shot:
image::FST4-1.png[align="left"]

View File

@ -1,5 +1,5 @@
FST4W is used in the same way as WSPR, but FST4W has significant
advantages for use on the 2200 and 630 m bands. By default the
advantages for use on the 2200 m and 630 m bands. By default the
central *Rx Freq* is 1500 Hz and *F Tol* is 100 Hz, so the active
decoding range is 1400 to 1600 Hz. However, for added flexibility you
can select different center frequencies and *F Tol* values. We expect
@ -16,3 +16,19 @@ If three operators agree in advance to select the options *1/3*,
a fixed sequence with no two stations transmitting simultaneously.
Sequence 1 is the first sequence after 00:00 UTC. For WSPR-like
scheduling behavior, you should select *Random* with this control.
.Open a Wave File:
- Select *FST4W* on the *Mode* menu. Set *T/R* to 1800 s and *Decode | Deep*.
- Set *NB* to 0%.
- Select appropriate wide graph settings. For example, try *Bins/Pixel* 1,
*Start* 1200 Hz and *N Avg* 150.
- Open a sample Wave file using *File | Open* and select the file
...\save\samples\FST4+FST4W\201230_0300.wav.
When it is finished you should see a single decode as shown in the
screenshot:
image::FST4W-1.png[align="left"]
Note that the weak signal associated with the single decode is all but invisible on the
widegraph spectrogram.

View File

@ -13,9 +13,6 @@ and *Page Up/Down* key presses, with the *Page* keys moving the
controls in larger steps. You can also type numbers directly into
the spinner controls or use the mouse wheel.
- Select *Tab 2* (below the *Decode* button) to choose the alternative
set of controls for generating and selecting Tx messages.
[[DOWNLOAD_SAMPLES]]
=== Download Samples

View File

@ -89,25 +89,6 @@ You will discover that every possible JT65 message differs from every
other possible JT65 message in at least 52 of the 63
information-carrying channel symbols.
Here's an example using the QRA64 mode:
C:\WSJTX\bin qra64code "KA1ABC WB9XYZ EN37"
Message Decoded Err? Type
--------------------------------------------------------------------------
1 KA1ABC WB9XYZ EN37 KA1ABC WB9XYZ EN37 1: Std Msg
Packed message, 6-bit symbols 34 16 49 32 51 26 31 40 41 22 0 41
Information-carrying channel symbols
34 16 49 32 51 26 31 40 41 22 0 41 16 46 14 24 58 45 22 45 38 54 7 23 2 49 32 50 20 33
55 51 7 31 31 46 41 25 55 14 62 33 29 24 2 49 4 38 15 21 1 41 56 56 16 44 17 30 46 36
23 23 41
Channel symbols including sync
20 50 60 0 40 10 30 34 16 49 32 51 26 31 40 41 22 0 41 16 46 14 24 58 45 22 45 38 54 7
23 2 49 32 50 20 33 55 51 20 50 60 0 40 10 30 7 31 31 46 41 25 55 14 62 33 29 24 2 49
4 38 15 21 1 41 56 56 16 44 17 30 46 36 23 23 41 20 50 60 0 40 10 30
Execution of any of these utility programs with "-t" as the only
command-line argument produces examples of all supported message
types. For example, using `jt65code -t`:

View File

@ -11,12 +11,11 @@ higher bands. These features include:
- *JT65*, widely used for EME on VHF and higher bands
- *QRA64*, another mode for EME
- *Q65*, for ionospheric scatter, tropospheric scatter, rain scatter,
TEP, and EME
- *MSK144*, for meteor scatter
- *ISCAT*, for aircraft scatter and other types of scatter propagation
- *Echo* mode, for detecting and measuring your own lunar echoes
- *Doppler tracking*, which becomes increasingly important for EME
@ -174,55 +173,33 @@ RO, RRR, and 73.
image::JT65B.png[align="center",alt="JT65B"]
=== QRA64
=== Q65
QRA64 is designed for EME on VHF and higher bands; its
operation is generally similar to JT4 and JT65. The following screen
shot shows an example of a QRA64C transmission from DL7YC recorded at
G3WDG over the EME path at 24 GHz. Doppler spread on the path was 78
Hz, so although the signal is reasonably strong its tones are
broadened enough to make them hard to see on the waterfall. The
triangular red marker below the frequency scale shows that the decoder
has achieved synchronization with a signal at approximately 967 Hz.
Q65 is designed for propagation paths that produce fast fading
signals: tropospheric scatter, rain scatter, ionospheric scatter,
trans-equatorial propagation (TEP), EME, and the like. The following
screen shot shows an example with submode Q65-30A on a 6-meter
ionospheric scatter path of about 1100 km.
image::QRA64.png[align="center",alt="QRA64"]
image::Q65_6m_ionoscatter.png[align="center",alt="Q65"]
The QRA64 decoder makes no use of a callsign database. Instead, it
The Q65 decoder makes no use of a callsign database. Instead, it
takes advantage of _a priori_ (AP) information such as one's own
callsign and the encoded form of message word `CQ`. In normal usage,
as a QSO progresses the available AP information increases to include
the callsign of the station being worked and perhaps also his/her
4-digit grid locator. The decoder always begins by attempting to
decode the full message using no AP information. If this attempt
fails, additional attempts are made using available AP information to
provide initial hypotheses about the message content. At the end of
each iteration the decoder computes the extrinsic probability of the
most likely value for each of the message's 12 six-bit information
symbols. A decode is declared only when the total probability for all
12 symbols has converged to an unambiguous value very close to 1.
callsign and the message word `CQ`. In normal usage, as a QSO
progresses the available AP information increases to include the
callsign of the station being worked and perhaps also his/her 4-digit
grid locator. The decoder takes advantage of whatever AP information
is available.
For EME QSOs some operators use short-form QRA64 messages consisting
of a single tone. To activate automatic generation of these messages,
check the box labeled *Sh*. This also enables the generation of a
single tone at 1000Hz by selecting Tx6, to assist in finding signals
initially, as the QRA64 tones are often not visible on the waterfall.
The box labeled *Tx6* switches the Tx6 message from 1000Hz to 1250Hz
to indicate to the other station that you are ready to receive messages.
For Q65 EME QSOs, particularly on the micriowave bands, some operators
use short-form messages consisting of a single tone. To activate
automatic generation of these messages, check the box labeled *Sh*.
This also enables the generation of a single tone at 1000Hz by
selecting Tx6, to assist in finding signals initially. The box
labeled *Tx6* switches the Tx6 message from 1000Hz to 1250Hz to
indicate to the other station that you are ready to receive messages.
TIP: QRA64 attempts to find and decode only a single signal in the
receiver passband. If many signals are present, you may be able to
decode them by double-clicking on the lowest tone of each one in the
waterfall.
TIP: G3WDG has prepared a more detailed tutorial on using {QRA64_EME}.
=== ISCAT
ISCAT is a useful mode for signals that are weak but more or less
steady in amplitude over several seconds or longer. Aircraft scatter
at 10 GHz is a good example. ISCAT messages are free-format and may
have any length from 1 to 28 characters. This protocol includes no
error-correction facility.
// TIP: G3WDG has prepared a more detailed tutorial on using {QRA64_EME}.
=== MSK144
@ -335,21 +312,28 @@ image::echo_144.png[align="center",alt="Echo 144 MHz"]
=== Tips for EME
Current conventions dictate that digital EME is usually done with
JT65A on the 50 MHz band, JT65B on 144 and 432 MHz, and JT65C on 1296
MHz. On higher microwave bands typical choices are JT65C or one of
Until the advent of Q65, digital EME has mostly been done using JT65A
on the 50 MHz band, JT65B on 144 and 432 MHz, and JT65C on 1296 MHz.
On higher microwave bands typical choices have been JT65C or one of
the wider QRA64 or JT4 submodes, depending on the expected amount of
Doppler spread. JT4 and JT65 offer message *Averaging* -- the
summation of subsequent transmissions that convey the same message --
to enable decodes at signal-to-noise ratios several dB below the
threshold for single transmissions. These modes also allow *Deep
Search* decoding, in which the decoder hypothesizes messages
containing known or previously decoded callsigns and tests them for
reliability using a correlation algorithm. Finally, JT65 and QRA64
offer _a priori_ (AP) decoding, which takes advantage of naturally
accumulating information during a QSO. The following tutorial aims to
familiarize you with these program features, all of which are of
special interest for EME and other extreme weak-signal conditions.
Doppler spread. We now recommend a suitable submodes of Q65 for EME
on all bands: for example, Q65-60A on 50 and 144 MHz, -60B on
432 MHz, -60C on 1296 MHz, and -60D on 10 GHz.
JT4, JT65, and Q65 offer *Message Averaging* -- the summation of
subsequent transmissions that convey the same message -- to enable
decodes at signal-to-noise ratios several dB below the threshold for
single transmissions. JT4 and JT65 also allow *Deep Search* decoding,
in which the decoder hypothesizes messages containing known or
previously decoded callsigns and tests them for reliability using a
correlation algorithm. JT65 and Q65 offer _a priori_ (AP)
decoding, which takes advantage of naturally accumulating information
during a QSO.
////
The following tutorial aims to familiarize you with
these program features, all of which are of special interest for EME
and other extreme weak-signal conditions.
As a starting point, configure _WSJT-X_ as follows:
@ -381,7 +365,7 @@ decode*, *Decode after EME delay*
.Wide Graph:
- *Bins/Pixel* = 3, *N Avg* = 10
- *Bins/Pixel* = 4, *N Avg* = 10
- Adjust the width of the window so that the frequency range extends
up to at least 2400 Hz.
@ -437,3 +421,5 @@ You might wish to experiment with other combinations of entries for
options of the *Decode* menu on and off. For best sensitivity, most
users will want to use *Deep* decoding with *Enable averaging*,
*Enable deep search*, and *Enable AP* all turned on.
////

View File

@ -119,6 +119,15 @@ In macOS, enter the following command from a terminal:
open /Applications/wsjtx.app --args -stylesheet :/qdarkstyle/style.qss
In Linux using the Unity or GNOME GUI the following commands will
update the _WSJT-X_ start up:
....
sed '/Exec=wsjtx/ s/$/ -stylesheet :\/qdarkstyle\/style.qss/' \
/usr/share/applications/wsjtx.desktop >~/.local/share/applications/wsjtx.desktop
update-desktop-database ~/.local/share/applications/
....
Depending on your operating system, the main _WSJT-X_ window will look
something like this:
@ -193,7 +202,7 @@ include::wspr.adoc[]
include::controls-functions-menus.adoc[]
[[CONTROLS_MAIN]]
=== Button Row
=== Button Row
include::controls-functions-main-window.adoc[]
[[CONTROLS_LEFT]]

View File

@ -7,7 +7,7 @@ TargetFileName="${AppLocalDataLocation}/logs/wsjtx_syslog_%Y-%m.log"
RotationTimePoint="01 00:00:00"
Append=true
EnableFinalRotation=false
MaxSize=41943040
MaxSize=52428800
MinFreeSpace=1073741824
MaxFiles=12
Target="${AppLocalDataLocation}/logs"

View File

@ -368,7 +368,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
endif
if(params%nmode.ne.8 .or. params%nzhsym.eq.50 .or. &
.not.params%ndiskdat) then
write(*,1010) nsynced,ndecoded,navg0
1010 format('<DecodeFinished>',2i4,i9)
call flush(6)
@ -806,7 +806,7 @@ contains
select type(this)
type is (counting_q65_decoder)
if(idec.gt.0) this%decoded = this%decoded + 1
if(idec.ge.0) this%decoded = this%decoded + 1
end select
return

View File

@ -86,13 +86,6 @@ subroutine fast_decode(id2,narg,trperiod,line,mycall_12, &
endif
jz=ib-ia+1
line(1:100)(1:1)=char(0)
if(npick.eq.2) then
call iscat(cdat2(ia),jz,3,40,t2,pick,cfile6,minsync,ntol, &
mousebutton,mode4,nafc,ndebug,psavg,nmax,nlines,line)
else
call iscat(cdat(ia),jz,3,40,t2,pick,cfile6,minsync,ntol, &
mousebutton,mode4,nafc,ndebug,psavg,maxlines,nlines,line)
endif
900 return
end subroutine fast_decode

View File

@ -614,7 +614,7 @@ contains
endif
call this%callback(nutc,smax1,nsnr,xdt,fsig,msg, &
iaptype,qual,ntrperiod,lwspr,fmid,w50)
if(iwspr.eq.0 .and. nb.lt.0) go to 900
! if(iwspr.eq.0 .and. nb.lt.0) go to 900
goto 800
endif
enddo ! metrics

View File

@ -65,7 +65,8 @@ program ft4code
if(i3.eq.2) msgtype="EU VHF Contest"
if(i3.eq.3) msgtype="ARRL RTTY Roundup"
if(i3.eq.4) msgtype="Nonstandard calls"
if(i3.ge.5) msgtype="Undefined msg type"
if(i3.eq.5) msgtype="EU VHF Contest"
if(i3.ge.6) msgtype="Undefined msg type"
if(i3.ge.1) n3=-1
bad=" "
comment=' '

View File

@ -64,7 +64,8 @@ program ft8code
if(i3.eq.2) msgtype="EU VHF Contest"
if(i3.eq.3) msgtype="ARRL RTTY Roundup"
if(i3.eq.4) msgtype="Nonstandard call"
if(i3.ge.5) msgtype="Undefined type"
if(i3.eq.5) msgtype="EU VHF Contest"
if(i3.ge.6) msgtype="Undefined type"
if(i3.ge.1) n3=-1
bad=" "
comment=' '

View File

@ -1,55 +0,0 @@
subroutine geniscat(msg,msgsent,itone)
! Generate an ISCAT waveform.
parameter (NSZ=1291)
character msg*28,msgsent*28 !Message to be transmitted
integer imsg(30)
integer itone(NSZ)
real*8 sps
character c*42
integer icos(4) !Costas array
data icos/0,1,3,2/
data nsync/4/,nlen/2/,ndat/18/
data c/'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ /.?@-'/
sps=256.d0*12000.d0/11025.d0
nsym=int(30*12000.d0/sps)
nblk=nsync+nlen+ndat
do i=22,1,-1
if(msg(i:i).ne.' ' .and. msg(i:i).ne.char(0)) exit
enddo
nmsg=i
msglen=nmsg+1
k=0
kk=1
imsg(1)=40 !Always start with BOM char: '@'
do i=1,nmsg !Define the tone sequence
imsg(i+1)=36 !Illegal char set to blank
do j=1,42
if(msg(i:i).eq.c(j:j)) imsg(i+1)=j-1
enddo
enddo
do i=1,nsym !Total symbols in 30 s
j=mod(i-1,nblk)+1
if(j.le.nsync) then
itone(i)=icos(j) !Insert 4x4 Costas array
else if(j.gt.nsync .and. j.le.nsync+nlen) then
itone(i)=msglen !Insert message-length indicator
if(j.ge.nsync+2) then
n=msglen + 5*(j-nsync-1)
if(n.gt.41) n=n-42
itone(i)=n
endif
else
k=k+1
kk=mod(k-1,msglen)+1
itone(i)=imsg(kk)
endif
enddo
msgsent=msg
return
end subroutine geniscat

View File

@ -1,206 +0,0 @@
subroutine iscat(cdat0,npts0,nh,npct,t2,pick,cfile6,minsync,ntol, &
mousebutton,mode4,nafc,nmore,psavg,maxlines,nlines,line)
! Decode an ISCAT signal
parameter (NMAX=30*3101)
parameter (NSZ=4*1400)
character cfile6*6 !File time
character c42*42
character msg*29,msg1*29,msgbig*29
character*80 line(100)
character csync*1
complex cdat0(NMAX)
complex cdat(NMAX)
real s0(288,NSZ)
real fs1(0:41,30)
real psavg(72) !Average spectrum of whole file
integer nsum(30)
integer ntol
integer icos(4)
logical pick,last
data icos/0,1,3,2/
data nsync/4/,nlen/2/,ndat/18/
data c42/'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ /.?@-'/
save cdat,s0
nlines = 0
fsample=3100.78125 !Sample rate after 9/32 downsampling
nsps=144/mode4
bigworst=-1.e30 !Silence compiler warnings ...
bigxsync=0.
bigsig=-1.e30
msglenbig=0
ndf0big=0
nfdotbig=0
bigt2=0.
bigavg=0.
bigtana=0.
if(nmore.eq.-999) bigsig=-1 !... to here
last=.false.
do inf=1,6 !Loop over data-segment sizes
nframes=2**inf
if(nframes*24*nsps.gt.npts0) then
nframes=npts0/(24*nsps)
last=.true.
endif
npts=nframes*24*nsps
do ia=1,npts0-npts,nsps*24 !Loop over start times stepped by 1 frame
ib=ia+npts-1
cdat(1:npts)=cdat0(ia:ib)
t3=(ia + 0.5*npts)/fsample + 0.9
if(pick) t3=t2+t3
! Compute symbol spectra and establish sync:
call synciscat(cdat,npts,nh,npct,s0,jsym,df,ntol, &
mousebutton,mode4,nafc,psavg,xsync,sig,ndf0,msglen, &
ipk,jpk,idf,df1)
nfdot=nint(idf*df1)
isync=xsync
if(msglen.eq.0 .or. isync.lt.max(minsync,0)) then
msglen=0
worst=1.
avg=1.
ndf0=0
cycle
endif
ipk3=0 !Silence compiler warning
nblk=nsync+nlen+ndat
fs1=0.
nsum=0
nfold=jsym/96
jb=96*nfold
k=0
n=0
do j=jpk,jsym,4 !Fold information symbols into fs1
k=k+1
km=mod(k-1,nblk)+1
if(km.gt.6) then
n=n+1
m=mod(n-1,msglen)+1
ii=nint(idf*float(j-jb/2)/float(jb))
do i=0,41
iii=ii+ipk+2*i
if(iii.ge.1 .and. iii.le.288) fs1(i,m)=fs1(i,m) + s0(iii,j)
enddo
nsum(m)=nsum(m)+1
endif
enddo
do m=1,msglen
fs1(0:41,m)=fs1(0:41,m)/nsum(m)
enddo
! Read out the message contents:
msg= ' '
msg1=' '
mpk=0
worst=9999.
sum=0.
do m=1,msglen
smax=0.
smax2=0.
do i=0,41
if(fs1(i,m).gt.smax) then
smax=fs1(i,m)
ipk3=i
endif
enddo
do i=0,41
if(fs1(i,m).gt.smax2 .and. i.ne.ipk3) smax2=fs1(i,m)
enddo
rr=0.
if(smax2.gt.0.0) rr=smax/smax2
sum=sum + rr
if(rr.lt.worst) worst=rr
if(ipk3.eq.40) mpk=m
msg1(m:m)=c42(ipk3+1:ipk3+1)
enddo
avg=sum/msglen
if(mpk.eq.1) then
msg=msg1(2:)
else if(mpk.lt.msglen) then
msg=msg1(mpk+1:msglen)//msg1(1:mpk-1)
else
msg=msg1(1:msglen-1)
endif
ttot=npts/3100.78125
if(worst.gt.bigworst) then
bigworst=worst
bigavg=avg
bigxsync=xsync
bigsig=sig
ndf0big=ndf0
nfdotbig=nfdot
msgbig=msg
msglenbig=msglen
bigt2=t3
bigtana=nframes*24*nsps/fsample
endif
isync = xsync
if(avg.gt.2.5 .and. xsync.ge.max(float(minsync),1.5) .and. &
maxlines.ge.2) then
nsig=nint(sig)
nworst=10.0*(worst-1.0)
navg=10.0*(avg-1.0)
if(nworst.gt.10) nworst=10
if(navg.gt.10) navg=10
tana=nframes*24*nsps/fsample
csync=' '
if(isync.ge.1) csync='*'
if(nlines.le.maxlines-1) nlines = nlines + 1
write(line(nlines),1020) cfile6,isync,nsig,t2,ndf0,nfdot,csync, &
msg(1:28),msglen,navg,nworst,tana,char(0)
endif
enddo
if(last) exit
enddo
worst=bigworst
avg=bigavg
xsync=bigxsync
sig=bigsig
ndf0=ndf0big
nfdot=nfdotbig
msg=msgbig
msglen=msglenbig
t2=bigt2
tana=bigtana
isync=xsync
nworst=10.0*(worst-1.0)
navg=10.0*(avg-1.0)
if(nworst.gt.10) nworst=10
if(navg.gt.10) navg=10
if(navg.le.0 .or. isync.lt.max(minsync,0)) then
msg=' '
nworst=0
navg=0
ndf0=0
nfdot=0
sig=-20
msglen=0
tana=0.
t2=0.
endif
csync=' '
if(isync.ge.1) csync='*'
nsig=nint(sig)
if(nlines.le.maxlines-1) nlines = nlines + 1
write(line(nlines),1020) cfile6,isync,nsig,t2,ndf0,nfdot,csync,msg(1:28), &
msglen,navg,nworst,tana,char(0)
1020 format(a6,2i4,f5.1,i5,i4,1x,a1,2x,a28,i4,i3,2x,i1,f5.1,a1)
return
end subroutine iscat

View File

@ -206,6 +206,12 @@ program jt9
go to 999
endif
if(mycall.eq.'b') mycall=' '
if(hiscall.eq.'b') then
hiscall=' '
hisgrid=' '
endif
if (mode .eq. 241) then
ntol = min (ntol, 100)
else if (mode .eq. 65 + 9 .and. .not. have_ntol) then

View File

@ -51,7 +51,8 @@ program msk144code
if(i3.eq.2) msgtype="EU VHF Contest"
if(i3.eq.3) msgtype="ARRL RTTY Roundup"
if(i3.eq.4) msgtype="Nonstandard calls"
if(i3.ge.5) msgtype="Undefined msg type"
if(i3.eq.5) msgtype="EU VHF Contest"
if(i3.ge.6) msgtype="Undefined msg type"
if(i3.ge.1) n3=-1
if(i4tone(41).lt.0) then
msgtype="Sh msg"

View File

@ -100,7 +100,7 @@ subroutine msk144decodeframe(c,softbits,msgreceived,nsuccess)
nsuccess=1
write(c77,'(77i1)') decoded77
read(c77(72:77),'(2b3)') n3,i3
if( (i3.eq.0.and.(n3.eq.1 .or. n3.eq.3 .or. n3.eq.4 .or. n3.gt.5)) .or. i3.eq.3 .or. i3.gt.4 ) then
if( (i3.eq.0.and.(n3.eq.1 .or. n3.eq.3 .or. n3.eq.4 .or. n3.gt.5)) .or. i3.eq.3 .or. i3.gt.5 ) then
nsuccess=0
else
call unpack77(c77,1,msgreceived,unpk77_success)

View File

@ -67,10 +67,10 @@ contains
integer dat4(13) !Decoded message as 12 6-bit integers
integer dgen(13)
logical lclearave,lnewdat0,lapcqonly,unpk77_success
logical single_decode,lagain
logical single_decode,lagain,ex
complex, allocatable :: c00(:) !Analytic signal, 6000 Sa/s
complex, allocatable :: c0(:) !Analytic signal, 6000 Sa/s
! Start by setting some parameters and allocating storage for large arrays
call sec0(0,tdecode)
nfa=nfa0
@ -79,7 +79,7 @@ contains
idec=-1
idf=0
idt=0
irc=0
nrc=-2
mode_q65=2**nsubmode
npts=ntrperiod*12000
nfft1=ntrperiod*12000
@ -98,9 +98,8 @@ contains
allocate (c00(0:nfft1-1))
allocate (c0(0:nfft1-1))
if(ntrperiod.eq.15) then
nsps=1800
else if(ntrperiod.eq.30) then
nsps=1800
if(ntrperiod.eq.30) then
nsps=3600
else if(ntrperiod.eq.60) then
nsps=7200
@ -108,23 +107,26 @@ contains
nsps=16000
else if(ntrperiod.eq.300) then
nsps=41472
else
stop 'Invalid TR period'
endif
baud=12000.0/nsps
this%callback => callback
nFadingModel=1
inquire(file='ndepth.dat',exist=ex)
if(.not.ex) ndepth=iand(ndepth,not(3)) + 1 !Treat any ndepth as "Fast"
maxiters=67
ibwa=max(1,int(1.8*log(baud*mode_q65)) + 1)
ibwb=min(10,ibwa+3)
ibwb=min(10,ibwa+4)
if(iand(ndepth,3).ge.2) then
ibwa=max(1,int(1.8*log(baud*mode_q65)) + 2)
ibwa=max(1,int(1.8*log(baud*mode_q65)) + 1)
ibwb=min(10,ibwa+5)
else if(iand(ndepth,3).eq.3) then
ibwa=max(1,ibwa-1)
ibwb=min(10,ibwb+1)
maxiters=100
endif
! Generate codewords for full-AP list decoding
call q65_set_list(mycall,hiscall,hisgrid,codewords,ncw)
dgen=0
@ -175,7 +177,6 @@ contains
call timer('q65loops',0)
call q65_loops(c00,npts/2,nsps/2,nsubmode,ndepth,jpk0, &
xdt,f0,iaptype,xdt1,f1,snr2,dat4,idec)
! idec=-1 !### TEMPORARY ###
call timer('q65loops',1)
if(idec.ge.0) then
dtdec=xdt1
@ -229,6 +230,7 @@ contains
write(c77,1000) dat4(1:12),dat4(13)/2
1000 format(12b6.6,b5.5)
call unpack77(c77,0,decoded,unpk77_success) !Unpack to get msgsent
call q65_snr(dat4,dtdec,f0dec,mode_q65,nused,snr2)
nsnr=nint(snr2)
call this%callback(nutc,snr1,nsnr,dtdec,f0dec,decoded, &
idec,nused,ntrperiod)
@ -244,21 +246,22 @@ contains
if(c6.eq.' ') c6='<b> '
c4=hisgrid(1:4)
if(c4.eq.' ') c4='<b> '
fmt='(i6.4,1x,a4,5i2,3i3,f6.2,f7.1,f7.2,f6.1,f6.2,'// &
fmt='(i6.4,1x,a4,4i2,6i3,i4,f6.2,f7.1,f6.1,f6.2,'// &
'1x,a6,1x,a6,1x,a4,1x,a)'
if(ntrperiod.le.30) fmt(5:5)='6'
write(22,fmt) nutc,cmode,nQSOprogress,idec,idf,idt,ibw,nused, &
icand,ncand,xdt,f0,snr1,snr2,tdecode,mycall(1:6),c6,c4, &
trim(decoded)
if(idec.eq.3) nrc=0
write(22,fmt) nutc,cmode,nQSOprogress,idec,idfbest,idtbest,ibw, &
ndistbest,nused,icand,ncand,nrc,ndepth,xdt,f0,snr2,tdecode, &
mycall(1:6),c6,c4,trim(decoded)
close(22)
endif
else
! else
! Report snr1, even if no decode.
nsnr=db(snr1) - 35.0
if(nsnr.lt.-35) nsnr=-35
idec=-1
call this%callback(nutc,snr1,nsnr,xdt,f0,decoded, &
idec,0,ntrperiod)
! nsnr=db(snr1) - 35.0
! if(nsnr.lt.-35) nsnr=-35
! idec=-1
! call this%callback(nutc,snr1,nsnr,xdt,f0,decoded, &
! idec,0,ntrperiod)
endif
navg0=1000*navg(0) + navg(1)
if(single_decode .or. lagain) go to 900
@ -309,6 +312,7 @@ contains
! Unpack decoded message for display to user
write(c77,1000) dat4(1:12),dat4(13)/2
call unpack77(c77,0,decoded,unpk77_success) !Unpack to get msgsent
call q65_snr(dat4,dtdec,f0dec,mode_q65,nused,snr2)
nsnr=nint(snr2)
call this%callback(nutc,snr1,nsnr,dtdec,f0dec,decoded, &
idec,nused,ntrperiod)
@ -324,12 +328,13 @@ contains
if(c6.eq.' ') c6='<b> '
c4=hisgrid(1:4)
if(c4.eq.' ') c4='<b> '
fmt='(i6.4,1x,a4,5i2,3i3,f6.2,f7.1,f7.2,f6.1,f6.2,'// &
fmt='(i6.4,1x,a4,4i2,6i3,i4,f6.2,f7.1,f6.1,f6.2,'// &
'1x,a6,1x,a6,1x,a4,1x,a)'
if(ntrperiod.le.30) fmt(5:5)='6'
write(22,fmt) nutc,cmode,nQSOprogress,idec,idf,idt,ibw,nused, &
icand,ncand,xdt,f0,snr1,snr2,tdecode,mycall(1:6),c6,c4, &
trim(decoded)
if(idec.eq.3) nrc=0
write(22,fmt) nutc,cmode,nQSOprogress,idec,idfbest,idtbest,ibw, &
ndistbest,nused,icand,ncand,nrc,ndepth,xdt,f0,snr2,tdecode, &
mycall(1:6),c6,c4,trim(decoded)
close(22)
endif
endif

View File

@ -522,7 +522,9 @@ int q65_esnodb_fastfading(
}
int q65_decode(q65_codec_ds *pCodec, int* pDecodedCodeword, int *pDecodedMsg, const float *pIntrinsics, const int *pAPMask, const int *pAPSymbols)
int q65_decode(q65_codec_ds *pCodec, int* pDecodedCodeword, int *pDecodedMsg,
const float *pIntrinsics, const int *pAPMask,
const int *pAPSymbols, const int maxiters)
{
const qracode *pQraCode;
float *ix, *ex;
@ -579,7 +581,7 @@ int q65_decode(q65_codec_ds *pCodec, int* pDecodedCodeword, int *pDecodedMsg, co
rc = qra_extrinsic( pQraCode,
ex,
ix,
100,
maxiters,
pCodec->qra_v2cmsg,
pCodec->qra_c2vmsg);

View File

@ -11,13 +11,15 @@ module q65
38,46,50,55,60,62,66,69,74,76,85/)
integer codewords(63,206)
integer ibwa,ibwb,ncw,nsps,mode_q65,nfa,nfb
integer idf,idt,ibw
integer istep,nsmo,lag1,lag2,npasses,nused,iseq,ncand
integer idfbest,idtbest,ibw,ndistbest,maxiters
integer istep,nsmo,lag1,lag2,npasses,nused,iseq,ncand,nrc
integer i0,j0
integer navg(0:1)
logical lnewdat
real candidates(20,3) !snr, xdt, and f0 of top candidates
real,allocatable,save :: s1a(:,:,:) !Cumulative symbol spectra
real, allocatable :: s1raw(:,:) !Symbol spectra, 1/8-symbol steps
real, allocatable :: s1(:,:) !Symbol spectra w/suppressed peaks
real, allocatable,save :: s1a(:,:,:) !Cumulative symbol spectra
real sync(85) !sync vector
real df,dtstep,dtdec,f0dec,ftol
@ -45,7 +47,7 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
! width Estimated Doppler spread
! dat4(13) Decoded message as 13 six-bit integers
! snr2 Estimated SNR of decoded signal
! idec Flag for decing results
! idec Flag for decoding results
! -1 No decode
! 0 No AP
! 1 "CQ ? ?"
@ -60,7 +62,6 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
integer dat4(13)
character*37 decoded
logical first,lclearave
real, allocatable :: s1(:,:) !Symbol spectra, 1/8-symbol steps
real, allocatable :: s3(:,:) !Data-symbol energies s3(LL,63)
real, allocatable :: ccf1(:) !CCF(freq) at fixed lag (red)
real, allocatable :: ccf2(:) !Max CCF(freq) at any lag (orange)
@ -71,6 +72,7 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
! Set some parameters and allocate storage for large arrays
irc=-2
nrc=-2
idec=-1
snr1=0.
dat4=0
@ -94,13 +96,17 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
enddo
endif
allocate(s1(iz,jz))
allocate(s3(-64:LL-65,63))
allocate(ccf1(-ia2:ia2))
allocate(ccf2(iz))
if(LL.ne.LL0 .or. iz.ne.iz0 .or. jz.ne.jz0 .or. lclearave) then
if(allocated(s1raw)) deallocate(s1raw)
allocate(s1raw(iz,jz))
if(allocated(s1)) deallocate(s1)
allocate(s1(iz,jz))
if(allocated(s1a)) deallocate(s1a)
allocate(s1a(iz,jz,0:1))
s1=0.
s1a=0.
navg=0
LL0=LL
@ -127,8 +133,9 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
i0=nint(nfqso/df) !Target QSO frequency
if(i0-64.lt.1 .or. i0-65+LL.gt.iz) go to 900 !Frequency out of range
call pctile(s1(i0-64:i0-65+LL,1:jz),LL*jz,40,base)
call pctile(s1(i0-64:i0-65+LL,1:jz),LL*jz,45,base)
s1=s1/base
s1raw=s1
! Apply fast AGC to the symbol spectra
s1max=20.0 !Empirical choice
@ -233,9 +240,11 @@ subroutine q65_symspec(iwave,nmax,iz,jz,s1)
enddo
enddo
if(lnewdat) then
s1a(:,:,iseq)=s1a(:,:,iseq) + s1
navg(iseq)=navg(iseq) + 1
endif
ntc=min(navg(iseq),4) !Averaging time constant in sequences
u=1.0/ntc
s1a(:,:,iseq)=u*s1 + (1.0-u)*s1a(:,:,iseq)
endif
return
end subroutine q65_symspec
@ -263,6 +272,7 @@ subroutine q65_dec_q3(s1,iz,jz,s3,LL,ipk,jpk,snr2,dat4,idec,decoded)
b90=1.72**ibw
b90ts=b90/baud
call q65_dec1(s3,nsubmode,b90ts,esnodb,irc,dat4,decoded)
nrc=irc
if(irc.ge.0) then
snr2=esnodb - db(2500.0/baud) + 3.0 !Empirical adjustment
idec=3
@ -314,6 +324,7 @@ subroutine q65_dec_q012(s3,LL,snr2,dat4,idec,decoded)
b90=1.72**ibw
b90ts=b90/baud
call q65_dec2(s3,nsubmode,b90ts,esnodb,irc,dat4,decoded)
nrc=irc
if(irc.ge.0) then
snr2=esnodb - db(2500.0/baud) + 3.0 !Empirical adjustment
idec=iaptype
@ -486,6 +497,7 @@ subroutine q65_dec1(s3,nsubmode,b90ts,esnodb,irc,dat4,decoded)
else
irc=-1
endif
nrc=irc
return
end subroutine q65_dec1
@ -504,8 +516,9 @@ subroutine q65_dec2(s3,nsubmode,b90ts,esnodb,irc,dat4,decoded)
nFadingModel=1
decoded=' '
call q65_intrinsics_ff(s3,nsubmode,b90ts,nFadingModel,s3prob)
call q65_dec(s3,s3prob,APmask,APsymbols,esnodb,dat4,irc)
call q65_dec(s3,s3prob,APmask,APsymbols,maxiters,esnodb,dat4,irc)
if(sum(dat4).le.0) irc=-2
nrc=irc
if(irc.ge.0) then
write(c77,1000) dat4(1:12),dat4(13)/2
1000 format(12b6.6,b5.5)
@ -537,7 +550,8 @@ subroutine q65_s1_to_s3(s1,iz,jz,ipk,jpk,LL,mode_q65,sync,s3)
if(j.ge.1 .and. j.le.jz) s3(-64:LL-65,n)=s1(i1:i2,j)
enddo
endif
call q65_bzap(s3,LL) !Zap birdies
return
end subroutine q65_s1_to_s3
@ -589,4 +603,88 @@ subroutine q65_sync_curve(ccf1,ia,ib,rms1)
return
end subroutine q65_sync_curve
subroutine q65_bzap(s3,LL)
parameter (NBZAP=15)
real s3(-64:LL-65,63)
integer ipk1(1)
integer, allocatable :: hist(:)
allocate(hist(-64:LL-65))
hist=0
do j=1,63
ipk1=maxloc(s3(:,j))
i=ipk1(1) - 65
hist(i)=hist(i)+1
enddo
if(maxval(hist).gt.NBZAP) then
do i=-64,LL-65
if(hist(i).gt.NBZAP) s3(i,1:63)=1.0
enddo
endif
return
end subroutine q65_bzap
subroutine q65_snr(dat4,dtdec,f0dec,mode_q65,nused,snr2)
! Estimate SNR of a decoded transmission by aligning the spectra of
! all 85 symbols.
integer dat4(13)
integer codeword(63)
integer itone(85)
real, allocatable :: spec(:)
allocate(spec(iz0))
call q65_enc(dat4,codeword)
i=1
k=0
do j=1,85
if(j.eq.isync(i)) then
i=i+1
itone(j)=0
else
k=k+1
itone(j)=codeword(k) + 1
endif
enddo
spec=0.
lagpk=nint(dtdec/dtstep)
do k=1,85
j=j0 + NSTEP*(k-1) + 1 + lagpk
if(j.ge.1 .and. j.le.jz0) then
do i=1,iz0
ii=i+mode_q65*itone(k)
if(ii.ge.1 .and. ii.le.iz0) spec(i)=spec(i) + s1raw(ii,j)
enddo
endif
enddo
i0=nint(f0dec/df)
nsum=max(10*mode_q65,nint(50.0/df))
ia=i0 - 2*nsum
ib=i0 + 2*nsum
sum1=sum(spec(ia:ia+nsum-1))
sum2=sum(spec(ib-nsum+1:ib))
avg=(sum1+sum2)/(2.0*nsum)
spec=spec/avg !Baseline level is now 1.0
smax=maxval(spec(ia:ib))
sig_area=sum(spec(ia+nsum:ib-nsum)-1.0)
w_equiv=sig_area/(smax-1.0)
snr2=db(max(1.0,sig_area)) - db(2500.0/df)
if(nused.eq.2) snr2=snr2 - 2.0
if(nused.eq.3) snr2=snr2 - 2.9
if(nused.ge.4) snr2=snr2 - 3.5
! do i=ia,ib
! write(71,3071) i*df,spec(i),db(spec(i))
!3071 format(3f10.3)
! enddo
! flush(71)
return
end subroutine q65_snr
end module q65

View File

@ -75,11 +75,12 @@ int q65_intrinsics_fastfading(q65_codec_ds *pCodec,
int q65_decode(q65_codec_ds *pCodec,
int* pDecodedCodeword,
int *pDecodedMsg,
const float *pIntrinsics,
const int *pAPMask,
const int *pAPSymbols);
int* pDecodedCodeword,
int *pDecodedMsg,
const float *pIntrinsics,
const int *pAPMask,
const int *pAPSymbols,
const int maxiters);
int q65_decode_fullaplist(q65_codec_ds *codec,
int *ydec,

View File

@ -38,6 +38,9 @@ subroutine q65_loops(c00,npts2,nsps2,nsubmode,ndepth,jpk0, &
napmin=99
xdt1=xdt0
f1=f0
idfbest=0
idtbest=0
ndistbest=0
do idf=1,idfmax
ndf=idf/2
@ -56,6 +59,7 @@ subroutine q65_loops(c00,npts2,nsps2,nsubmode,ndepth,jpk0, &
call pctile(s3,LL*NN,40,base)
s3=s3/base
where(s3(1:LL*NN)>s3lim) s3(1:LL*NN)=s3lim
call q65_bzap(s3,LL) !Zap birdies
do ibw=ibwa,ibwb
ndist=ndf**2 + ndt**2 + (ibw-ibw0)**2
if(ndist.gt.maxdist) cycle
@ -69,7 +73,13 @@ subroutine q65_loops(c00,npts2,nsps2,nsubmode,ndepth,jpk0, &
! -1 = invalid params
! -2 = decode failed
! -3 = CRC mismatch
if(irc.ge.0) go to 100
if(irc.ge.0) then
idfbest=idf
idtbest=idt
ndistbest=ndist
nrc=irc
go to 100
endif
enddo ! ibw (b90 loop)
enddo ! idt (DT loop)
enddo ! idf (f0 loop)

View File

@ -77,7 +77,7 @@ void q65_intrinsics_ff_(float s3[], int* submode, float* B90Ts,
}
void q65_dec_(float s3[], float s3prob[], int APmask[], int APsymbols[],
float* esnodb0, int xdec[], int* rc0)
int* maxiters0, float* esnodb0, int xdec[], int* rc0)
{
/* Input: s3[LL,NN] Symbol spectra
@ -93,8 +93,9 @@ void q65_dec_(float s3[], float s3prob[], int APmask[], int APsymbols[],
int rc;
int ydec[63];
float esnodb;
int maxiters=*maxiters0;
rc = q65_decode(&codec,ydec,xdec,s3prob,APmask,APsymbols);
rc = q65_decode(&codec,ydec,xdec,s3prob,APmask,APsymbols,maxiters);
*rc0=rc;
// rc = -1: Invalid params
// rc = -2: Decode failed

View File

@ -9,10 +9,13 @@ program q65sim
integer*2 iwave(NMAX) !Generated waveform
integer itone(85) !Channel symbols (values 0-65)
integer y(63) !Codeword
integer istart !averaging compatible start seconds
integer imins !minutes for 15s period timestamp
integer isecs !seconds for 15s period timestamp
real*4 xnoise(NMAX) !Generated random noise
real*4 dat(NMAX) !Generated real data
complex cdat(NMAX) !Generated complex waveform
complex cspread(0:NMAX-1) !Complex amplitude for Rayleigh fading
complex cspread(0:NMAX-1) !Complex amplitude for Rayleigh fading
complex z
real*8 f0,dt,twopi,phi,dphi,baud,fsample,freq
character msg*37,fname*17,csubmode*1,arg*12
@ -22,10 +25,13 @@ program q65sim
if(nargs.ne.10) then
print*,'Usage: q65sim "msg" A-E freq fDop DT f1 Stp TRp Nfile SNR'
print*,'Example: q65sim "K1ABC W9XYZ EN37" A 1500 0.0 0.0 0.0 1 60 1 -26'
print*,'Example: q65sim "ST" A 1500 0.0 0.0 0.0 1 60 1 -26'
print*,' fDop = Doppler spread'
print*,' f1 = Drift or Doppler rate (Hz/min)'
print*,' Stp = Step size (Hz)'
print*,' Stp = 0 implies no Doppler tracking'
print*,' Creates filenames which increment to permit averaging in first period'
print*,' If msg = ST program produces a single tone at freq'
go to 999
endif
call getarg(1,msg)
@ -94,14 +100,17 @@ program q65sim
h=default_header(12000,npts)
write(*,1004)
1004 format('File TR Freq Mode S/N Dop DT f1 Stp Message'/70('-'))
1004 format('File TR Freq Mode S/N Dop DT f1 Stp Message'/70('-'))
do ifile=1,nfiles !Loop over requested number of files
if(ntrperiod.lt.60) then
write(fname,1005) ifile !Output filename
1005 format('000000_',i6.6,'.wav')
do ifile=1,nfiles !Loop over requested number of files
istart = (ifile*ntrperiod*2) - (ntrperiod*2)
if(ntrperiod.lt.30) then !wdg was 60
imins=istart/60
isecs=istart-(60*imins)
write(fname,1005) imins,isecs !Construction of output filename for 15s periods with averaging
1005 format('000000_',i4.4, i2.2,'.wav')
else
write(fname,1106) ifile
write(fname,1106) istart/60 !Output filename to be compatible with averaging 30-300s periods
1106 format('000000_',i4.4,'.wav')
endif
@ -118,7 +127,7 @@ program q65sim
sig=sqrt(2*bandwidth_ratio)*10.0**(0.05*snrdb)
if(snrdb.gt.90.0) sig=1.0
write(*,1020) ifile,ntrperiod,f0,csubmode,snrdb,fspread,xdt,f1,nstp,trim(msgsent)
1020 format(i4,i6,f7.1,2x,a1,2x,f5.1,f6.2,2f6.1,i4,2x,a)
1020 format(i4,i6,f7.1,2x,a1,2x,f5.1,1x,f6.2,2f6.1,i4,2x,a)
phi=0.d0
dphi=0.d0
k=(xdt+0.5)*12000 !Start audio at t=xdt+0.5 s (TR=15 and 30 s)
@ -130,7 +139,11 @@ program q65sim
if(isym.ne.isym0) then
freq_drift=f1*i*dt/60.0
if(nstp.ne.0) freq_drift=freq_drift - nstp*nint(freq_drift/nstp)
freq = f0 + freq_drift + itone(isym)*baud*mode65
if (msg(1:2).eq.'ST') then
freq = f0 + freq_drift
else
freq = f0 + freq_drift + itone(isym)*baud*mode65
endif
dphi=twopi*freq*dt
isym0=isym
endif

View File

@ -1,30 +0,0 @@
FC = gfortran
CC = gcc
CFLAGS = -O2 -Wall -I. -D_WIN32
# Default rules
%.o: %.c
${CC} ${CFLAGS} -c $<
%.o: %.f
${FC} ${FFLAGS} -c $<
%.o: %.F
${FC} ${FFLAGS} -c $<
%.o: %.f90
${FC} ${FFLAGS} -c $<
%.o: %.F90
${FC} ${FFLAGS} -c $<
all: qra64.exe
OBJS1 = main.o qra64.o
qra64.exe: $(OBJS1)
${CC} -o qra64.exe $(OBJS1) ../qracodes/libqra64.a -lm
OBJS2 = qra64sim.o options.o wavhdr.o
qra64sim.exe: $(OBJS2)
${FC} -o qra64sim.exe $(OBJS2) ../qracodes/libqra64.a -lm
.PHONY : clean
clean:
$(RM) *.o qra64.exe qra64sim.exe

View File

@ -1,302 +0,0 @@
// Gaussian energy fading tables for QRA64
static const int glen_tab_gauss[64] = {
2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 5, 5, 5, 6,
6, 6, 7, 7, 8, 8, 9, 10,
10, 11, 12, 13, 14, 15, 17, 18,
19, 21, 23, 25, 27, 29, 32, 34,
37, 41, 44, 48, 52, 57, 62, 65
};
static const float ggauss1[2] = {
0.0296f, 0.9101f
};
static const float ggauss2[2] = {
0.0350f, 0.8954f
};
static const float ggauss3[2] = {
0.0411f, 0.8787f
};
static const float ggauss4[2] = {
0.0483f, 0.8598f
};
static const float ggauss5[2] = {
0.0566f, 0.8387f
};
static const float ggauss6[2] = {
0.0660f, 0.8154f
};
static const float ggauss7[2] = {
0.0767f, 0.7898f
};
static const float ggauss8[2] = {
0.0886f, 0.7621f
};
static const float ggauss9[2] = {
0.1017f, 0.7325f
};
static const float ggauss10[2] = {
0.1159f, 0.7012f
};
static const float ggauss11[2] = {
0.1310f, 0.6687f
};
static const float ggauss12[2] = {
0.1465f, 0.6352f
};
static const float ggauss13[2] = {
0.1621f, 0.6013f
};
static const float ggauss14[2] = {
0.1771f, 0.5674f
};
static const float ggauss15[2] = {
0.1911f, 0.5339f
};
static const float ggauss16[2] = {
0.2034f, 0.5010f
};
static const float ggauss17[3] = {
0.0299f, 0.2135f, 0.4690f
};
static const float ggauss18[3] = {
0.0369f, 0.2212f, 0.4383f
};
static const float ggauss19[3] = {
0.0454f, 0.2263f, 0.4088f
};
static const float ggauss20[3] = {
0.0552f, 0.2286f, 0.3806f
};
static const float ggauss21[3] = {
0.0658f, 0.2284f, 0.3539f
};
static const float ggauss22[3] = {
0.0766f, 0.2258f, 0.3287f
};
static const float ggauss23[3] = {
0.0869f, 0.2212f, 0.3049f
};
static const float ggauss24[3] = {
0.0962f, 0.2148f, 0.2826f
};
static const float ggauss25[4] = {
0.0351f, 0.1041f, 0.2071f, 0.2616f
};
static const float ggauss26[4] = {
0.0429f, 0.1102f, 0.1984f, 0.2420f
};
static const float ggauss27[4] = {
0.0508f, 0.1145f, 0.1890f, 0.2237f
};
static const float ggauss28[4] = {
0.0582f, 0.1169f, 0.1791f, 0.2067f
};
static const float ggauss29[5] = {
0.0289f, 0.0648f, 0.1176f, 0.1689f, 0.1908f
};
static const float ggauss30[5] = {
0.0351f, 0.0703f, 0.1168f, 0.1588f, 0.1760f
};
static const float ggauss31[5] = {
0.0411f, 0.0745f, 0.1146f, 0.1488f, 0.1623f
};
static const float ggauss32[6] = {
0.0246f, 0.0466f, 0.0773f, 0.1115f, 0.1390f, 0.1497f
};
static const float ggauss33[6] = {
0.0297f, 0.0512f, 0.0788f, 0.1075f, 0.1295f, 0.1379f
};
static const float ggauss34[6] = {
0.0345f, 0.0549f, 0.0791f, 0.1029f, 0.1205f, 0.1270f
};
static const float ggauss35[7] = {
0.0240f, 0.0387f, 0.0575f, 0.0784f, 0.0979f, 0.1118f, 0.1169f
};
static const float ggauss36[7] = {
0.0281f, 0.0422f, 0.0590f, 0.0767f, 0.0926f, 0.1037f, 0.1076f
};
static const float ggauss37[8] = {
0.0212f, 0.0318f, 0.0449f, 0.0596f, 0.0744f, 0.0872f, 0.0960f, 0.0991f
};
static const float ggauss38[8] = {
0.0247f, 0.0348f, 0.0467f, 0.0593f, 0.0716f, 0.0819f, 0.0887f, 0.0911f
};
static const float ggauss39[9] = {
0.0199f, 0.0278f, 0.0372f, 0.0476f, 0.0584f, 0.0684f, 0.0766f, 0.0819f,
0.0838f
};
static const float ggauss40[10] = {
0.0166f, 0.0228f, 0.0303f, 0.0388f, 0.0478f, 0.0568f, 0.0649f, 0.0714f,
0.0756f, 0.0771f
};
static const float ggauss41[10] = {
0.0193f, 0.0254f, 0.0322f, 0.0397f, 0.0474f, 0.0548f, 0.0613f, 0.0664f,
0.0697f, 0.0709f
};
static const float ggauss42[11] = {
0.0168f, 0.0217f, 0.0273f, 0.0335f, 0.0399f, 0.0464f, 0.0524f, 0.0576f,
0.0617f, 0.0643f, 0.0651f
};
static const float ggauss43[12] = {
0.0151f, 0.0191f, 0.0237f, 0.0288f, 0.0342f, 0.0396f, 0.0449f, 0.0498f,
0.0540f, 0.0572f, 0.0592f, 0.0599f
};
static const float ggauss44[13] = {
0.0138f, 0.0171f, 0.0210f, 0.0252f, 0.0297f, 0.0343f, 0.0388f, 0.0432f,
0.0471f, 0.0504f, 0.0529f, 0.0545f, 0.0550f
};
static const float ggauss45[14] = {
0.0128f, 0.0157f, 0.0189f, 0.0224f, 0.0261f, 0.0300f, 0.0339f, 0.0377f,
0.0412f, 0.0444f, 0.0470f, 0.0489f, 0.0501f, 0.0505f
};
static const float ggauss46[15] = {
0.0121f, 0.0146f, 0.0173f, 0.0202f, 0.0234f, 0.0266f, 0.0299f, 0.0332f,
0.0363f, 0.0391f, 0.0416f, 0.0437f, 0.0452f, 0.0461f, 0.0464f
};
static const float ggauss47[17] = {
0.0097f, 0.0116f, 0.0138f, 0.0161f, 0.0186f, 0.0212f, 0.0239f, 0.0267f,
0.0294f, 0.0321f, 0.0346f, 0.0369f, 0.0389f, 0.0405f, 0.0417f, 0.0424f,
0.0427f
};
static const float ggauss48[18] = {
0.0096f, 0.0113f, 0.0131f, 0.0151f, 0.0172f, 0.0194f, 0.0217f, 0.0241f,
0.0264f, 0.0287f, 0.0308f, 0.0329f, 0.0347f, 0.0362f, 0.0375f, 0.0384f,
0.0390f, 0.0392f
};
static const float ggauss49[19] = {
0.0095f, 0.0110f, 0.0126f, 0.0143f, 0.0161f, 0.0180f, 0.0199f, 0.0219f,
0.0239f, 0.0258f, 0.0277f, 0.0294f, 0.0310f, 0.0325f, 0.0337f, 0.0347f,
0.0354f, 0.0358f, 0.0360f
};
static const float ggauss50[21] = {
0.0083f, 0.0095f, 0.0108f, 0.0122f, 0.0136f, 0.0152f, 0.0168f, 0.0184f,
0.0201f, 0.0217f, 0.0234f, 0.0250f, 0.0265f, 0.0279f, 0.0292f, 0.0303f,
0.0313f, 0.0320f, 0.0326f, 0.0329f, 0.0330f
};
static const float ggauss51[23] = {
0.0074f, 0.0084f, 0.0095f, 0.0106f, 0.0118f, 0.0131f, 0.0144f, 0.0157f,
0.0171f, 0.0185f, 0.0199f, 0.0213f, 0.0227f, 0.0240f, 0.0252f, 0.0263f,
0.0273f, 0.0282f, 0.0290f, 0.0296f, 0.0300f, 0.0303f, 0.0303f
};
static const float ggauss52[25] = {
0.0068f, 0.0076f, 0.0085f, 0.0094f, 0.0104f, 0.0115f, 0.0126f, 0.0137f,
0.0149f, 0.0160f, 0.0172f, 0.0184f, 0.0196f, 0.0207f, 0.0218f, 0.0228f,
0.0238f, 0.0247f, 0.0255f, 0.0262f, 0.0268f, 0.0273f, 0.0276f, 0.0278f,
0.0279f
};
static const float ggauss53[27] = {
0.0063f, 0.0070f, 0.0078f, 0.0086f, 0.0094f, 0.0103f, 0.0112f, 0.0121f,
0.0131f, 0.0141f, 0.0151f, 0.0161f, 0.0170f, 0.0180f, 0.0190f, 0.0199f,
0.0208f, 0.0216f, 0.0224f, 0.0231f, 0.0237f, 0.0243f, 0.0247f, 0.0251f,
0.0254f, 0.0255f, 0.0256f
};
static const float ggauss54[29] = {
0.0060f, 0.0066f, 0.0072f, 0.0079f, 0.0086f, 0.0093f, 0.0101f, 0.0109f,
0.0117f, 0.0125f, 0.0133f, 0.0142f, 0.0150f, 0.0159f, 0.0167f, 0.0175f,
0.0183f, 0.0190f, 0.0197f, 0.0204f, 0.0210f, 0.0216f, 0.0221f, 0.0225f,
0.0228f, 0.0231f, 0.0233f, 0.0234f, 0.0235f
};
static const float ggauss55[32] = {
0.0053f, 0.0058f, 0.0063f, 0.0068f, 0.0074f, 0.0080f, 0.0086f, 0.0093f,
0.0099f, 0.0106f, 0.0113f, 0.0120f, 0.0127f, 0.0134f, 0.0141f, 0.0148f,
0.0155f, 0.0162f, 0.0168f, 0.0174f, 0.0180f, 0.0186f, 0.0191f, 0.0196f,
0.0201f, 0.0204f, 0.0208f, 0.0211f, 0.0213f, 0.0214f, 0.0215f, 0.0216f
};
static const float ggauss56[34] = {
0.0052f, 0.0056f, 0.0060f, 0.0065f, 0.0070f, 0.0075f, 0.0080f, 0.0086f,
0.0091f, 0.0097f, 0.0103f, 0.0109f, 0.0115f, 0.0121f, 0.0127f, 0.0133f,
0.0138f, 0.0144f, 0.0150f, 0.0155f, 0.0161f, 0.0166f, 0.0170f, 0.0175f,
0.0179f, 0.0183f, 0.0186f, 0.0189f, 0.0192f, 0.0194f, 0.0196f, 0.0197f,
0.0198f, 0.0198f
};
static const float ggauss57[37] = {
0.0047f, 0.0051f, 0.0055f, 0.0058f, 0.0063f, 0.0067f, 0.0071f, 0.0076f,
0.0080f, 0.0085f, 0.0090f, 0.0095f, 0.0100f, 0.0105f, 0.0110f, 0.0115f,
0.0120f, 0.0125f, 0.0130f, 0.0134f, 0.0139f, 0.0144f, 0.0148f, 0.0152f,
0.0156f, 0.0160f, 0.0164f, 0.0167f, 0.0170f, 0.0173f, 0.0175f, 0.0177f,
0.0179f, 0.0180f, 0.0181f, 0.0181f, 0.0182f
};
static const float ggauss58[41] = {
0.0041f, 0.0044f, 0.0047f, 0.0050f, 0.0054f, 0.0057f, 0.0060f, 0.0064f,
0.0068f, 0.0072f, 0.0076f, 0.0080f, 0.0084f, 0.0088f, 0.0092f, 0.0096f,
0.0101f, 0.0105f, 0.0109f, 0.0113f, 0.0117f, 0.0121f, 0.0125f, 0.0129f,
0.0133f, 0.0137f, 0.0140f, 0.0144f, 0.0147f, 0.0150f, 0.0153f, 0.0155f,
0.0158f, 0.0160f, 0.0162f, 0.0163f, 0.0164f, 0.0165f, 0.0166f, 0.0167f,
0.0167f
};
static const float ggauss59[44] = {
0.0039f, 0.0042f, 0.0044f, 0.0047f, 0.0050f, 0.0053f, 0.0056f, 0.0059f,
0.0062f, 0.0065f, 0.0068f, 0.0072f, 0.0075f, 0.0079f, 0.0082f, 0.0086f,
0.0089f, 0.0093f, 0.0096f, 0.0100f, 0.0104f, 0.0107f, 0.0110f, 0.0114f,
0.0117f, 0.0120f, 0.0124f, 0.0127f, 0.0130f, 0.0132f, 0.0135f, 0.0138f,
0.0140f, 0.0142f, 0.0144f, 0.0146f, 0.0148f, 0.0149f, 0.0150f, 0.0151f,
0.0152f, 0.0153f, 0.0153f, 0.0153f
};
static const float ggauss60[48] = {
0.0036f, 0.0038f, 0.0040f, 0.0042f, 0.0044f, 0.0047f, 0.0049f, 0.0052f,
0.0055f, 0.0057f, 0.0060f, 0.0063f, 0.0066f, 0.0068f, 0.0071f, 0.0074f,
0.0077f, 0.0080f, 0.0083f, 0.0086f, 0.0089f, 0.0092f, 0.0095f, 0.0098f,
0.0101f, 0.0104f, 0.0107f, 0.0109f, 0.0112f, 0.0115f, 0.0117f, 0.0120f,
0.0122f, 0.0124f, 0.0126f, 0.0128f, 0.0130f, 0.0132f, 0.0134f, 0.0135f,
0.0136f, 0.0137f, 0.0138f, 0.0139f, 0.0140f, 0.0140f, 0.0140f, 0.0140f
};
static const float ggauss61[52] = {
0.0033f, 0.0035f, 0.0037f, 0.0039f, 0.0041f, 0.0043f, 0.0045f, 0.0047f,
0.0049f, 0.0051f, 0.0053f, 0.0056f, 0.0058f, 0.0060f, 0.0063f, 0.0065f,
0.0068f, 0.0070f, 0.0073f, 0.0075f, 0.0078f, 0.0080f, 0.0083f, 0.0085f,
0.0088f, 0.0090f, 0.0093f, 0.0095f, 0.0098f, 0.0100f, 0.0102f, 0.0105f,
0.0107f, 0.0109f, 0.0111f, 0.0113f, 0.0115f, 0.0116f, 0.0118f, 0.0120f,
0.0121f, 0.0122f, 0.0124f, 0.0125f, 0.0126f, 0.0126f, 0.0127f, 0.0128f,
0.0128f, 0.0129f, 0.0129f, 0.0129f
};
static const float ggauss62[57] = {
0.0030f, 0.0031f, 0.0033f, 0.0034f, 0.0036f, 0.0038f, 0.0039f, 0.0041f,
0.0043f, 0.0045f, 0.0047f, 0.0048f, 0.0050f, 0.0052f, 0.0054f, 0.0056f,
0.0058f, 0.0060f, 0.0063f, 0.0065f, 0.0067f, 0.0069f, 0.0071f, 0.0073f,
0.0075f, 0.0077f, 0.0080f, 0.0082f, 0.0084f, 0.0086f, 0.0088f, 0.0090f,
0.0092f, 0.0094f, 0.0096f, 0.0097f, 0.0099f, 0.0101f, 0.0103f, 0.0104f,
0.0106f, 0.0107f, 0.0108f, 0.0110f, 0.0111f, 0.0112f, 0.0113f, 0.0114f,
0.0115f, 0.0116f, 0.0116f, 0.0117f, 0.0117f, 0.0118f, 0.0118f, 0.0118f,
0.0118f
};
static const float ggauss63[62] = {
0.0027f, 0.0029f, 0.0030f, 0.0031f, 0.0032f, 0.0034f, 0.0035f, 0.0037f,
0.0038f, 0.0040f, 0.0041f, 0.0043f, 0.0045f, 0.0046f, 0.0048f, 0.0049f,
0.0051f, 0.0053f, 0.0055f, 0.0056f, 0.0058f, 0.0060f, 0.0062f, 0.0063f,
0.0065f, 0.0067f, 0.0069f, 0.0071f, 0.0072f, 0.0074f, 0.0076f, 0.0078f,
0.0079f, 0.0081f, 0.0083f, 0.0084f, 0.0086f, 0.0088f, 0.0089f, 0.0091f,
0.0092f, 0.0094f, 0.0095f, 0.0096f, 0.0098f, 0.0099f, 0.0100f, 0.0101f,
0.0102f, 0.0103f, 0.0104f, 0.0105f, 0.0105f, 0.0106f, 0.0107f, 0.0107f,
0.0108f, 0.0108f, 0.0108f, 0.0108f, 0.0109f, 0.0109f
};
static const float ggauss64[65] = {
0.0028f, 0.0029f, 0.0030f, 0.0031f, 0.0032f, 0.0034f, 0.0035f, 0.0036f,
0.0037f, 0.0039f, 0.0040f, 0.0041f, 0.0043f, 0.0044f, 0.0046f, 0.0047f,
0.0048f, 0.0050f, 0.0051f, 0.0053f, 0.0054f, 0.0056f, 0.0057f, 0.0059f,
0.0060f, 0.0062f, 0.0063f, 0.0065f, 0.0066f, 0.0068f, 0.0069f, 0.0071f,
0.0072f, 0.0074f, 0.0075f, 0.0077f, 0.0078f, 0.0079f, 0.0081f, 0.0082f,
0.0083f, 0.0084f, 0.0086f, 0.0087f, 0.0088f, 0.0089f, 0.0090f, 0.0091f,
0.0092f, 0.0093f, 0.0094f, 0.0094f, 0.0095f, 0.0096f, 0.0097f, 0.0097f,
0.0098f, 0.0098f, 0.0099f, 0.0099f, 0.0099f, 0.0099f, 0.0100f, 0.0100f,
0.0100f
};
static const float *gptr_tab_gauss[64] = {
ggauss1, ggauss2, ggauss3, ggauss4,
ggauss5, ggauss6, ggauss7, ggauss8,
ggauss9, ggauss10, ggauss11, ggauss12,
ggauss13, ggauss14, ggauss15, ggauss16,
ggauss17, ggauss18, ggauss19, ggauss20,
ggauss21, ggauss22, ggauss23, ggauss24,
ggauss25, ggauss26, ggauss27, ggauss28,
ggauss29, ggauss30, ggauss31, ggauss32,
ggauss33, ggauss34, ggauss35, ggauss36,
ggauss37, ggauss38, ggauss39, ggauss40,
ggauss41, ggauss42, ggauss43, ggauss44,
ggauss45, ggauss46, ggauss47, ggauss48,
ggauss49, ggauss50, ggauss51, ggauss52,
ggauss53, ggauss54, ggauss55, ggauss56,
ggauss57, ggauss58, ggauss59, ggauss60,
ggauss61, ggauss62, ggauss63, ggauss64
};

View File

@ -1,304 +0,0 @@
// Lorentz energy fading tables for QRA64
static const int glen_tab_lorentz[64] = {
2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 3, 3,
3, 3, 3, 3, 3, 4, 4, 4,
4, 4, 5, 5, 5, 5, 6, 6,
7, 7, 7, 8, 8, 9, 10, 10,
11, 12, 13, 14, 15, 16, 17, 19,
20, 22, 23, 25, 27, 30, 32, 35,
38, 41, 45, 49, 53, 57, 62, 65
};
static const float glorentz1[2] = {
0.0214f, 0.9107f
};
static const float glorentz2[2] = {
0.0244f, 0.9030f
};
static const float glorentz3[2] = {
0.0280f, 0.8950f
};
static const float glorentz4[2] = {
0.0314f, 0.8865f
};
static const float glorentz5[2] = {
0.0349f, 0.8773f
};
static const float glorentz6[2] = {
0.0388f, 0.8675f
};
static const float glorentz7[2] = {
0.0426f, 0.8571f
};
static const float glorentz8[2] = {
0.0463f, 0.8459f
};
static const float glorentz9[2] = {
0.0500f, 0.8339f
};
static const float glorentz10[2] = {
0.0538f, 0.8210f
};
static const float glorentz11[2] = {
0.0579f, 0.8074f
};
static const float glorentz12[2] = {
0.0622f, 0.7930f
};
static const float glorentz13[2] = {
0.0668f, 0.7777f
};
static const float glorentz14[2] = {
0.0715f, 0.7616f
};
static const float glorentz15[3] = {
0.0196f, 0.0765f, 0.7445f
};
static const float glorentz16[3] = {
0.0210f, 0.0816f, 0.7267f
};
static const float glorentz17[3] = {
0.0226f, 0.0870f, 0.7080f
};
static const float glorentz18[3] = {
0.0242f, 0.0925f, 0.6885f
};
static const float glorentz19[3] = {
0.0259f, 0.0981f, 0.6682f
};
static const float glorentz20[3] = {
0.0277f, 0.1039f, 0.6472f
};
static const float glorentz21[3] = {
0.0296f, 0.1097f, 0.6255f
};
static const float glorentz22[4] = {
0.0143f, 0.0316f, 0.1155f, 0.6031f
};
static const float glorentz23[4] = {
0.0153f, 0.0337f, 0.1213f, 0.5803f
};
static const float glorentz24[4] = {
0.0163f, 0.0358f, 0.1270f, 0.5570f
};
static const float glorentz25[4] = {
0.0174f, 0.0381f, 0.1325f, 0.5333f
};
static const float glorentz26[4] = {
0.0186f, 0.0405f, 0.1378f, 0.5095f
};
static const float glorentz27[5] = {
0.0113f, 0.0198f, 0.0429f, 0.1428f, 0.4855f
};
static const float glorentz28[5] = {
0.0120f, 0.0211f, 0.0455f, 0.1473f, 0.4615f
};
static const float glorentz29[5] = {
0.0129f, 0.0225f, 0.0481f, 0.1514f, 0.4376f
};
static const float glorentz30[5] = {
0.0137f, 0.0239f, 0.0508f, 0.1549f, 0.4140f
};
static const float glorentz31[6] = {
0.0095f, 0.0147f, 0.0254f, 0.0536f, 0.1578f, 0.3907f
};
static const float glorentz32[6] = {
0.0101f, 0.0156f, 0.0270f, 0.0564f, 0.1600f, 0.3680f
};
static const float glorentz33[7] = {
0.0076f, 0.0109f, 0.0167f, 0.0287f, 0.0592f, 0.1614f, 0.3458f
};
static const float glorentz34[7] = {
0.0081f, 0.0116f, 0.0178f, 0.0305f, 0.0621f, 0.1620f, 0.3243f
};
static const float glorentz35[7] = {
0.0087f, 0.0124f, 0.0190f, 0.0324f, 0.0649f, 0.1618f, 0.3035f
};
static const float glorentz36[8] = {
0.0069f, 0.0093f, 0.0133f, 0.0203f, 0.0343f, 0.0676f, 0.1607f, 0.2836f
};
static const float glorentz37[8] = {
0.0074f, 0.0100f, 0.0142f, 0.0216f, 0.0362f, 0.0702f, 0.1588f, 0.2645f
};
static const float glorentz38[9] = {
0.0061f, 0.0080f, 0.0107f, 0.0152f, 0.0230f, 0.0382f, 0.0726f, 0.1561f,
0.2464f
};
static const float glorentz39[10] = {
0.0052f, 0.0066f, 0.0086f, 0.0115f, 0.0162f, 0.0244f, 0.0402f, 0.0747f,
0.1526f, 0.2291f
};
static const float glorentz40[10] = {
0.0056f, 0.0071f, 0.0092f, 0.0123f, 0.0173f, 0.0259f, 0.0422f, 0.0766f,
0.1484f, 0.2128f
};
static const float glorentz41[11] = {
0.0049f, 0.0061f, 0.0076f, 0.0098f, 0.0132f, 0.0184f, 0.0274f, 0.0441f,
0.0780f, 0.1437f, 0.1975f
};
static const float glorentz42[12] = {
0.0044f, 0.0053f, 0.0065f, 0.0082f, 0.0106f, 0.0141f, 0.0196f, 0.0290f,
0.0460f, 0.0791f, 0.1384f, 0.1831f
};
static const float glorentz43[13] = {
0.0040f, 0.0048f, 0.0057f, 0.0070f, 0.0088f, 0.0113f, 0.0150f, 0.0209f,
0.0305f, 0.0477f, 0.0797f, 0.1327f, 0.1695f
};
static const float glorentz44[14] = {
0.0037f, 0.0043f, 0.0051f, 0.0062f, 0.0075f, 0.0094f, 0.0121f, 0.0160f,
0.0221f, 0.0321f, 0.0493f, 0.0799f, 0.1267f, 0.1568f
};
static const float glorentz45[15] = {
0.0035f, 0.0040f, 0.0047f, 0.0055f, 0.0066f, 0.0081f, 0.0101f, 0.0129f,
0.0171f, 0.0234f, 0.0335f, 0.0506f, 0.0795f, 0.1204f, 0.1450f
};
static const float glorentz46[16] = {
0.0033f, 0.0037f, 0.0043f, 0.0050f, 0.0059f, 0.0071f, 0.0087f, 0.0108f,
0.0138f, 0.0181f, 0.0246f, 0.0349f, 0.0517f, 0.0786f, 0.1141f, 0.1340f
};
static const float glorentz47[17] = {
0.0031f, 0.0035f, 0.0040f, 0.0046f, 0.0054f, 0.0064f, 0.0077f, 0.0093f,
0.0116f, 0.0147f, 0.0192f, 0.0259f, 0.0362f, 0.0525f, 0.0773f, 0.1076f,
0.1237f
};
static const float glorentz48[19] = {
0.0027f, 0.0030f, 0.0034f, 0.0038f, 0.0043f, 0.0050f, 0.0058f, 0.0069f,
0.0082f, 0.0100f, 0.0123f, 0.0156f, 0.0203f, 0.0271f, 0.0374f, 0.0530f,
0.0755f, 0.1013f, 0.1141f
};
static const float glorentz49[20] = {
0.0026f, 0.0029f, 0.0032f, 0.0036f, 0.0041f, 0.0047f, 0.0054f, 0.0063f,
0.0074f, 0.0088f, 0.0107f, 0.0131f, 0.0165f, 0.0213f, 0.0282f, 0.0383f,
0.0531f, 0.0734f, 0.0950f, 0.1053f
};
static const float glorentz50[22] = {
0.0023f, 0.0025f, 0.0028f, 0.0031f, 0.0035f, 0.0039f, 0.0044f, 0.0050f,
0.0058f, 0.0067f, 0.0079f, 0.0094f, 0.0114f, 0.0139f, 0.0175f, 0.0223f,
0.0292f, 0.0391f, 0.0529f, 0.0709f, 0.0889f, 0.0971f
};
static const float glorentz51[23] = {
0.0023f, 0.0025f, 0.0027f, 0.0030f, 0.0034f, 0.0037f, 0.0042f, 0.0048f,
0.0054f, 0.0062f, 0.0072f, 0.0085f, 0.0100f, 0.0121f, 0.0148f, 0.0184f,
0.0233f, 0.0301f, 0.0396f, 0.0524f, 0.0681f, 0.0829f, 0.0894f
};
static const float glorentz52[25] = {
0.0021f, 0.0023f, 0.0025f, 0.0027f, 0.0030f, 0.0033f, 0.0036f, 0.0040f,
0.0045f, 0.0051f, 0.0058f, 0.0067f, 0.0077f, 0.0090f, 0.0107f, 0.0128f,
0.0156f, 0.0192f, 0.0242f, 0.0308f, 0.0398f, 0.0515f, 0.0650f, 0.0772f,
0.0824f
};
static const float glorentz53[27] = {
0.0019f, 0.0021f, 0.0022f, 0.0024f, 0.0027f, 0.0029f, 0.0032f, 0.0035f,
0.0039f, 0.0044f, 0.0049f, 0.0055f, 0.0062f, 0.0072f, 0.0083f, 0.0096f,
0.0113f, 0.0135f, 0.0164f, 0.0201f, 0.0249f, 0.0314f, 0.0398f, 0.0502f,
0.0619f, 0.0718f, 0.0759f
};
static const float glorentz54[30] = {
0.0017f, 0.0018f, 0.0019f, 0.0021f, 0.0022f, 0.0024f, 0.0026f, 0.0029f,
0.0031f, 0.0034f, 0.0038f, 0.0042f, 0.0047f, 0.0052f, 0.0059f, 0.0067f,
0.0076f, 0.0088f, 0.0102f, 0.0120f, 0.0143f, 0.0171f, 0.0208f, 0.0256f,
0.0317f, 0.0395f, 0.0488f, 0.0586f, 0.0666f, 0.0698f
};
static const float glorentz55[32] = {
0.0016f, 0.0017f, 0.0018f, 0.0019f, 0.0021f, 0.0022f, 0.0024f, 0.0026f,
0.0028f, 0.0031f, 0.0034f, 0.0037f, 0.0041f, 0.0045f, 0.0050f, 0.0056f,
0.0063f, 0.0071f, 0.0081f, 0.0094f, 0.0108f, 0.0127f, 0.0149f, 0.0178f,
0.0214f, 0.0261f, 0.0318f, 0.0389f, 0.0470f, 0.0553f, 0.0618f, 0.0643f
};
static const float glorentz56[35] = {
0.0014f, 0.0015f, 0.0016f, 0.0017f, 0.0018f, 0.0020f, 0.0021f, 0.0023f,
0.0024f, 0.0026f, 0.0028f, 0.0031f, 0.0033f, 0.0036f, 0.0040f, 0.0044f,
0.0049f, 0.0054f, 0.0060f, 0.0067f, 0.0076f, 0.0087f, 0.0099f, 0.0114f,
0.0133f, 0.0156f, 0.0184f, 0.0220f, 0.0264f, 0.0318f, 0.0381f, 0.0451f,
0.0520f, 0.0572f, 0.0591f
};
static const float glorentz57[38] = {
0.0013f, 0.0014f, 0.0015f, 0.0016f, 0.0017f, 0.0018f, 0.0019f, 0.0020f,
0.0021f, 0.0023f, 0.0024f, 0.0026f, 0.0028f, 0.0031f, 0.0033f, 0.0036f,
0.0039f, 0.0043f, 0.0047f, 0.0052f, 0.0058f, 0.0064f, 0.0072f, 0.0081f,
0.0092f, 0.0104f, 0.0120f, 0.0139f, 0.0162f, 0.0190f, 0.0224f, 0.0265f,
0.0315f, 0.0371f, 0.0431f, 0.0487f, 0.0529f, 0.0544f
};
static const float glorentz58[41] = {
0.0012f, 0.0013f, 0.0014f, 0.0014f, 0.0015f, 0.0016f, 0.0017f, 0.0018f,
0.0019f, 0.0020f, 0.0022f, 0.0023f, 0.0025f, 0.0026f, 0.0028f, 0.0030f,
0.0033f, 0.0036f, 0.0039f, 0.0042f, 0.0046f, 0.0050f, 0.0056f, 0.0061f,
0.0068f, 0.0076f, 0.0086f, 0.0097f, 0.0110f, 0.0125f, 0.0144f, 0.0167f,
0.0194f, 0.0226f, 0.0265f, 0.0309f, 0.0359f, 0.0409f, 0.0455f, 0.0488f,
0.0500f
};
static const float glorentz59[45] = {
0.0011f, 0.0012f, 0.0012f, 0.0013f, 0.0013f, 0.0014f, 0.0015f, 0.0016f,
0.0016f, 0.0017f, 0.0018f, 0.0019f, 0.0021f, 0.0022f, 0.0023f, 0.0025f,
0.0026f, 0.0028f, 0.0030f, 0.0033f, 0.0035f, 0.0038f, 0.0041f, 0.0045f,
0.0049f, 0.0054f, 0.0059f, 0.0065f, 0.0072f, 0.0081f, 0.0090f, 0.0102f,
0.0115f, 0.0130f, 0.0149f, 0.0171f, 0.0197f, 0.0227f, 0.0263f, 0.0302f,
0.0345f, 0.0387f, 0.0425f, 0.0451f, 0.0460f
};
static const float glorentz60[49] = {
0.0010f, 0.0011f, 0.0011f, 0.0012f, 0.0012f, 0.0013f, 0.0013f, 0.0014f,
0.0014f, 0.0015f, 0.0016f, 0.0017f, 0.0018f, 0.0019f, 0.0020f, 0.0021f,
0.0022f, 0.0024f, 0.0025f, 0.0027f, 0.0028f, 0.0030f, 0.0033f, 0.0035f,
0.0038f, 0.0041f, 0.0044f, 0.0048f, 0.0052f, 0.0057f, 0.0063f, 0.0069f,
0.0077f, 0.0085f, 0.0095f, 0.0106f, 0.0119f, 0.0135f, 0.0153f, 0.0174f,
0.0199f, 0.0227f, 0.0259f, 0.0293f, 0.0330f, 0.0365f, 0.0395f, 0.0415f,
0.0423f
};
static const float glorentz61[53] = {
0.0009f, 0.0010f, 0.0010f, 0.0011f, 0.0011f, 0.0011f, 0.0012f, 0.0012f,
0.0013f, 0.0014f, 0.0014f, 0.0015f, 0.0016f, 0.0016f, 0.0017f, 0.0018f,
0.0019f, 0.0020f, 0.0021f, 0.0023f, 0.0024f, 0.0025f, 0.0027f, 0.0029f,
0.0031f, 0.0033f, 0.0035f, 0.0038f, 0.0041f, 0.0044f, 0.0047f, 0.0051f,
0.0056f, 0.0061f, 0.0067f, 0.0073f, 0.0081f, 0.0089f, 0.0099f, 0.0110f,
0.0124f, 0.0139f, 0.0156f, 0.0176f, 0.0199f, 0.0225f, 0.0253f, 0.0283f,
0.0314f, 0.0343f, 0.0367f, 0.0383f, 0.0389f
};
static const float glorentz62[57] = {
0.0009f, 0.0009f, 0.0009f, 0.0010f, 0.0010f, 0.0011f, 0.0011f, 0.0011f,
0.0012f, 0.0012f, 0.0013f, 0.0013f, 0.0014f, 0.0015f, 0.0015f, 0.0016f,
0.0017f, 0.0018f, 0.0019f, 0.0020f, 0.0021f, 0.0022f, 0.0023f, 0.0024f,
0.0026f, 0.0027f, 0.0029f, 0.0031f, 0.0033f, 0.0035f, 0.0038f, 0.0040f,
0.0043f, 0.0047f, 0.0050f, 0.0055f, 0.0059f, 0.0064f, 0.0070f, 0.0077f,
0.0085f, 0.0093f, 0.0103f, 0.0114f, 0.0127f, 0.0142f, 0.0158f, 0.0177f,
0.0198f, 0.0221f, 0.0246f, 0.0272f, 0.0297f, 0.0321f, 0.0340f, 0.0353f,
0.0357f
};
static const float glorentz63[62] = {
0.0008f, 0.0008f, 0.0009f, 0.0009f, 0.0009f, 0.0010f, 0.0010f, 0.0010f,
0.0011f, 0.0011f, 0.0011f, 0.0012f, 0.0012f, 0.0013f, 0.0013f, 0.0014f,
0.0015f, 0.0015f, 0.0016f, 0.0017f, 0.0017f, 0.0018f, 0.0019f, 0.0020f,
0.0021f, 0.0022f, 0.0023f, 0.0025f, 0.0026f, 0.0028f, 0.0029f, 0.0031f,
0.0033f, 0.0035f, 0.0038f, 0.0040f, 0.0043f, 0.0046f, 0.0050f, 0.0053f,
0.0058f, 0.0062f, 0.0068f, 0.0074f, 0.0081f, 0.0088f, 0.0097f, 0.0106f,
0.0117f, 0.0130f, 0.0144f, 0.0159f, 0.0176f, 0.0195f, 0.0216f, 0.0237f,
0.0259f, 0.0280f, 0.0299f, 0.0315f, 0.0325f, 0.0328f
};
static const float glorentz64[65] = {
0.0008f, 0.0008f, 0.0008f, 0.0009f, 0.0009f, 0.0009f, 0.0010f, 0.0010f,
0.0010f, 0.0011f, 0.0011f, 0.0012f, 0.0012f, 0.0012f, 0.0013f, 0.0013f,
0.0014f, 0.0014f, 0.0015f, 0.0016f, 0.0016f, 0.0017f, 0.0018f, 0.0019f,
0.0020f, 0.0021f, 0.0022f, 0.0023f, 0.0024f, 0.0025f, 0.0027f, 0.0028f,
0.0030f, 0.0031f, 0.0033f, 0.0035f, 0.0038f, 0.0040f, 0.0043f, 0.0046f,
0.0049f, 0.0052f, 0.0056f, 0.0061f, 0.0066f, 0.0071f, 0.0077f, 0.0084f,
0.0091f, 0.0100f, 0.0109f, 0.0120f, 0.0132f, 0.0145f, 0.0159f, 0.0175f,
0.0192f, 0.0209f, 0.0228f, 0.0246f, 0.0264f, 0.0279f, 0.0291f, 0.0299f,
0.0301f
};
static const float *gptr_tab_lorentz[64] = {
glorentz1, glorentz2, glorentz3, glorentz4,
glorentz5, glorentz6, glorentz7, glorentz8,
glorentz9, glorentz10, glorentz11, glorentz12,
glorentz13, glorentz14, glorentz15, glorentz16,
glorentz17, glorentz18, glorentz19, glorentz20,
glorentz21, glorentz22, glorentz23, glorentz24,
glorentz25, glorentz26, glorentz27, glorentz28,
glorentz29, glorentz30, glorentz31, glorentz32,
glorentz33, glorentz34, glorentz35, glorentz36,
glorentz37, glorentz38, glorentz39, glorentz40,
glorentz41, glorentz42, glorentz43, glorentz44,
glorentz45, glorentz46, glorentz47, glorentz48,
glorentz49, glorentz50, glorentz51, glorentz52,
glorentz53, glorentz54, glorentz55, glorentz56,
glorentz57, glorentz58, glorentz59, glorentz60,
glorentz61, glorentz62, glorentz63, glorentz64
};

View File

@ -1,746 +0,0 @@
/*
main.c
QRA64 mode encode/decode tests
(c) 2016 - Nico Palermo, IV3NWV
Thanks to Andrea Montefusco IW0HDV for his help on adapting the sources
to OSs other than MS Windows
------------------------------------------------------------------------------
This file is part of the qracodes project, a Forward Error Control
encoding/decoding package based on Q-ary RA (Repeat and Accumulate) LDPC codes.
Files in this package:
main.c - this file
qra64.c/.h - qra64 mode encode/decoding functions
../qracodes/normrnd.{c,h} - random gaussian number generator
../qracodes/npfwht.{c,h} - Fast Walsh-Hadamard Transforms
../qracodes/pdmath.{c,h} - Elementary math on probability distributions
../qracodes/qra12_63_64_irr_b.{c,h} - Tables for a QRA(12,63) irregular RA
code over GF(64)
../qracodes/qra13_64_64_irr_e.{c,h} - Tables for a QRA(13,64) irregular RA
code over GF(64)
../qracodes/qracodes.{c,h} - QRA codes encoding/decoding functions
-------------------------------------------------------------------------------
qracodes is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
qracodes is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with qracodes source distribution.
If not, see <http://www.gnu.org/licenses/>.
-----------------------------------------------------------------------------
The code used by the QRA64 mode is the code: QRA13_64_64_IRR_E: K=13
N=64 Q=64 irregular QRA code (defined in qra13_64_64_irr_e.{h,c}).
This code has been designed to include a CRC as the 13th information
symbol and improve the code UER (Undetected Error Rate). The CRC
symbol is not sent along the channel (the codes are punctured) and the
resulting code is still a (12,63) code with an effective code rate of
R = 12/63.
*/
// OS dependent defines and includes ------------------------------------------
#if _WIN32 // note the underscore: without it, it's not msdn official!
// Windows (x64 and x86)
#include <windows.h> // required only for GetTickCount(...)
#include <process.h> // _beginthread
#endif
#if __linux__
#include <unistd.h>
#include <time.h>
unsigned GetTickCount(void) {
struct timespec ts;
unsigned theTick = 0U;
clock_gettime( CLOCK_REALTIME, &ts );
theTick = ts.tv_nsec / 1000000;
theTick += ts.tv_sec * 1000;
return theTick;
}
#endif
#if __APPLE__
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "qra64.h"
#include "../qracodes/normrnd.h" // gaussian numbers generator
// ----------------------------------------------------------------------------
// channel types
#define CHANNEL_AWGN 0
#define CHANNEL_RAYLEIGH 1
#define CHANNEL_FASTFADE 2
#define JT65_SNR_EBNO_OFFSET 29.1f // with the synch used in JT65
#define QRA64_SNR_EBNO_OFFSET 31.0f // with the costas array synch
void printwordd(char *msg, int *x, int size)
{
int k;
printf("\n%s ",msg);
for (k=0;k<size;k++)
printf("%2d ",x[k]);
printf("\n");
}
void printwordh(char *msg, int *x, int size)
{
int k;
printf("\n%s ",msg);
for (k=0;k<size;k++)
printf("%02hx ",x[k]);
printf("\n");
}
#define NSAMPLES (QRA64_N*QRA64_M)
static float rp[NSAMPLES];
static float rq[NSAMPLES];
static float chp[NSAMPLES];
static float chq[NSAMPLES];
static float r[NSAMPLES];
float *mfskchannel(int *x, int channel_type, float EbNodB)
{
/*
Simulate an MFSK channel, either AWGN or Rayleigh.
x is a pointer to the transmitted codeword, an array of QRA64_N
integers in the range 0..63.
Returns the received symbol energies (squared amplitudes) as an array of
(QRA64_M*QRA64_N) floats. The first QRA64_M entries of this array are
the energies of the first symbol in the codeword. The second QRA64_M
entries are those of the second symbol, and so on up to the last codeword
symbol.
*/
const float No = 1.0f; // noise spectral density
const float sigma = (float)sqrt(No/2.0f); // std dev of noise I/Q components
const float sigmach = (float)sqrt(1/2.0f); // std dev of channel I/Q gains
const float R = 1.0f*QRA64_K/QRA64_N;
float EbNo = (float)pow(10,EbNodB/10);
float EsNo = 1.0f*QRA64_m*R*EbNo;
float Es = EsNo*No;
float A = (float)sqrt(Es);
int k;
normrnd_s(rp,NSAMPLES,0,sigma);
normrnd_s(rq,NSAMPLES,0,sigma);
if(EbNodB>-15)
if (channel_type == CHANNEL_AWGN)
for (k=0;k<QRA64_N;k++)
rp[k*QRA64_M+x[k]]+=A;
else
if (channel_type == CHANNEL_RAYLEIGH) {
normrnd_s(chp,QRA64_N,0,sigmach);
normrnd_s(chq,QRA64_N,0,sigmach);
for (k=0;k<QRA64_N;k++) {
rp[k*QRA64_M+x[k]]+=A*chp[k];
rq[k*QRA64_M+x[k]]+=A*chq[k];
}
}
else {
return 0; // unknown channel type
}
// compute the squares of the amplitudes of the received samples
for (k=0;k<NSAMPLES;k++)
r[k] = rp[k]*rp[k] + rq[k]*rq[k];
return r;
}
// These defines are some packed fields as computed by JT65
#define CALL_IV3NWV 0x7F85AE7
#define CALL_K1JT 0xF70DDD7
#define GRID_JN66 0x3AE4 // JN66
#define GRID_73 0x7ED0 // 73
char decode_type[12][32] = {
"[? ? ?] AP0",
"[CQ ? ?] AP27",
"[CQ ? ] AP42",
"[CALL ? ?] AP29",
"[CALL ? ] AP44",
"[CALL CALL ?] AP57",
"[? CALL ?] AP29",
"[? CALL ] AP44",
"[CALL CALL G] AP72",
"[CQ CALL ?] AP55",
"[CQ CALL ] AP70",
"[CQ CALL G] AP70"
};
char apmode_type[3][32] = {
"NO AP",
"AUTO AP",
"USER AP"
};
int test_proc_1(int channel_type, float EbNodB, int mode)
{
/*
Here we simulate the following (dummy) QSO:
1) CQ IV3NWV
2) IV3NWV K1JT
3) K1JT IV3NWV 73
4) IV3NWV K1JT 73
No message repetition is attempted
The QSO is counted as successfull if IV3NWV received the last message
When mode=QRA_AUTOAP each decoder attempts to decode the message sent
by the other station using the a-priori information derived by what
has been already decoded in a previous phase of the QSO if decoding
with no a-priori information has not been successful.
Step 1) K1JT's decoder first attempts to decode msgs of type [? ? ?]
and if this attempt fails, it attempts to decode [CQ/QRZ ? ?] or
[CQ/QRZ ?] msgs
Step 2) if IV3NWV's decoder is unable to decode K1JT's without AP it
attempts to decode messages of the type [IV3NWV ? ?] and [IV3NWV ?].
Step 3) K1JT's decoder attempts to decode [? ? ?] and [K1JT IV3NWV ?]
(this last decode type has been enabled by K1JT's encoder at step 2)
Step 4) IV3NWV's decoder attempts to decode [? ? ?] and [IV3NWV K1JT
?] (this last decode type has been enabled by IV3NWV's encoder at step
3)
At each step the simulation reports if a decode was successful. In
this case it also reports the type of decode (see table decode_type
above)
When mode=QRA_NOAP, only [? ? ?] decodes are attempted and no a-priori
information is used by the decoder
The function returns 0 if all of the four messages have been decoded
by their recipients (with no retries) and -1 if any of them could not
be decoded
*/
int x[QRA64_K], xdec[QRA64_K];
int y[QRA64_N];
float *rx;
int rc;
// Each simulated station must use its own codec since it might work with
// different a-priori information.
qra64codec *codec_iv3nwv = qra64_init(mode); // codec for IV3NWV
qra64codec *codec_k1jt = qra64_init(mode); // codec for K1JT
// Step 1a: IV3NWV makes a CQ call (with no grid)
printf("IV3NWV tx: CQ IV3NWV\n");
encodemsg_jt65(x,CALL_CQ,CALL_IV3NWV,GRID_BLANK);
qra64_encode(codec_iv3nwv, y, x);
rx = mfskchannel(y,channel_type,EbNodB);
// Step 1b: K1JT attempts to decode [? ? ?], [CQ/QRZ ? ?] or [CQ/QRZ ?]
rc = qra64_decode(codec_k1jt, 0, xdec,rx);
if (rc>=0) { // decoded
printf("K1JT rx: received with apcode=%d %s\n",rc, decode_type[rc]);
// Step 2a: K1JT replies to IV3NWV (with no grid)
printf("K1JT tx: IV3NWV K1JT\n");
encodemsg_jt65(x,CALL_IV3NWV,CALL_K1JT, GRID_BLANK);
qra64_encode(codec_k1jt, y, x);
rx = mfskchannel(y,channel_type,EbNodB);
// Step 2b: IV3NWV attempts to decode [? ? ?], [IV3NWV ? ?] or [IV3NWV ?]
rc = qra64_decode(codec_iv3nwv, 0, xdec,rx);
if (rc>=0) { // decoded
printf("IV3NWV rx: received with apcode=%d %s\n",rc, decode_type[rc]);
// Step 3a: IV3NWV replies to K1JT with a 73
printf("IV3NWV tx: K1JT IV3NWV 73\n");
encodemsg_jt65(x,CALL_K1JT,CALL_IV3NWV, GRID_73);
qra64_encode(codec_iv3nwv, y, x);
rx = mfskchannel(y,channel_type,EbNodB);
// Step 3b: K1JT attempts to decode [? ? ?] or [K1JT IV3NWV ?]
rc = qra64_decode(codec_k1jt, 0, xdec,rx);
if (rc>=0) { // decoded
printf("K1JT rx: received with apcode=%d %s\n",rc, decode_type[rc]);
// Step 4a: K1JT replies to IV3NWV with a 73
printf("K1JT tx: IV3NWV K1JT 73\n");
encodemsg_jt65(x,CALL_IV3NWV,CALL_K1JT, GRID_73);
qra64_encode(codec_k1jt, y, x);
rx = mfskchannel(y,channel_type,EbNodB);
// Step 4b: IV3NWV attempts to decode [? ? ?], [IV3NWV ? ?], or [IV3NWV ?]
rc = qra64_decode(codec_iv3nwv, 0, xdec,rx);
if (rc>=0) { // decoded
printf("IV3NWV rx: received with apcode=%d %s\n",rc, decode_type[rc]);
return 0;
}
}
}
}
printf("no decode\n");
return -1;
}
int test_proc_2(int channel_type, float EbNodB, int mode)
{
/*
Here we simulate the decoder of K1JT after K1JT has sent a msg [IV3NWV K1JT]
and IV3NWV sends him the msg [K1JT IV3NWV JN66].
If mode=QRA_NOAP, K1JT decoder attempts to decode only msgs of type [? ? ?].
If mode=QRA_AUTOP, K1JT decoder will attempt to decode also the msgs
[K1JT IV3NWV] and [K1JT IV3NWV ?].
In the case a decode is successful the return code of the qra64_decode function
indicates the amount of a-priori information required to decode the received
message according to this table:
rc=0 [? ? ?] AP0
rc=1 [CQ ? ?] AP27
rc=2 [CQ ? ] AP42
rc=3 [CALL ? ?] AP29
rc=4 [CALL ? ] AP44
rc=5 [CALL CALL ?] AP57
rc=6 [? CALL ?] AP29
rc=7 [? CALL ] AP44
rc=8 [CALL CALL GRID] AP72
rc=9 [CQ CALL ?] AP55
rc=10 [CQ CALL ] AP70
rc=11 [CQ CALL GRID] AP70
The return code is <0 when decoding is unsuccessful
This test simulates the situation ntx times and reports how many times
a particular type decode among the above 6 cases succeded.
*/
int x[QRA64_K], xdec[QRA64_K];
int y[QRA64_N];
float *rx;
float ebnodbest, ebnodbavg=0;
int rc,k;
int ndecok[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int nundet = 0;
int ntx = 200,ndec=0;
qra64codec *codec_iv3nwv = qra64_init(mode); // codec for IV3NWV
qra64codec *codec_k1jt = qra64_init(mode); // codec for K1JT
printf("\nQRA64 Test #2 - Decoding with AP knowledge (SNR-Eb/No offset = %.1f dB)\n\n",
QRA64_SNR_EBNO_OFFSET);
// This will enable K1JT's decoder to look for calls directed to him [K1JT ? ?/b]
// printf("K1JT decoder enabled for [K1JT ? ?/blank]\n");
// qra64_apset(codec_k1jt, CALL_K1JT,0,0,APTYPE_MYCALL);
// This will enable K1JT's decoder to look for IV3NWV calls directed to him [K1JT IV3NWV ?/b]
// printf("K1JT decoder enabled for [K1JT IV3NWV ?]\n");
// qra64_apset(codec_k1jt, CALL_CQ,CALL_IV3NWV,0,APTYPE_BOTHCALLS);
// This will enable K1JT's decoder to look for msges sent by IV3NWV [? IV3NWV ?]
// printf("K1JT decoder enabled for [? IV3NWV ?/blank]\n");
// qra64_apset(codec_k1jt, 0,CALL_IV3NWV,GRID_BLANK,APTYPE_HISCALL);
// This will enable K1JT's decoder to look for full-knowledge [K1JT IV3NWV JN66] msgs
printf("K1JT decoder enabled for [K1JT IV3NWV JN66]\n");
qra64_apset(codec_k1jt, CALL_K1JT,CALL_IV3NWV,GRID_JN66,APTYPE_FULL);
// This will enable K1JT's decoder to look for calls from IV3NWV [CQ IV3NWV ?/b] msgs
printf("K1JT decoder enabled for [CQ IV3NWV ?/b/JN66]\n");
qra64_apset(codec_k1jt, 0,CALL_IV3NWV,GRID_JN66,APTYPE_CQHISCALL);
// Dx station IV3NWV calls
printf("\nIV3NWV encoder sends msg: [K1JT IV3NWV JN66]\n\n");
encodemsg_jt65(x,CALL_CQ,CALL_IV3NWV,GRID_JN66);
// printf("\nIV3NWV encoder sends msg: [CQ IV3NWV JN66]\n\n");
// encodemsg_jt65(x,CALL_CQ,CALL_IV3NWV,GRID_JN66);
// printf("\nIV3NWV encoder sends msg: [CQ IV3NWV]\n\n");
// encodemsg_jt65(x,CALL_CQ,CALL_IV3NWV,GRID_BLANK);
qra64_encode(codec_iv3nwv, y, x);
printf("Simulating K1JT decoder up to AP72\n");
for (k=0;k<ntx;k++) {
printf(".");
rx = mfskchannel(y,channel_type,EbNodB);
rc = qra64_decode(codec_k1jt, &ebnodbest, xdec,rx);
if (rc>=0) {
ebnodbavg +=ebnodbest;
if (memcmp(xdec,x,12*sizeof(int))==0)
ndecok[rc]++;
else
nundet++;
}
}
printf("\n\n");
printf("Transimtted msgs:%d\nDecoded msgs:\n\n",ntx);
for (k=0;k<12;k++) {
printf("%3d with %s\n",ndecok[k],decode_type[k]);
ndec += ndecok[k];
}
printf("\nTotal: %d/%d (%d undetected errors)\n\n",ndec,ntx,nundet);
printf("");
ebnodbavg/=(ndec+nundet);
printf("Estimated SNR (average in dB) = %.2f dB\n\n",ebnodbavg-QRA64_SNR_EBNO_OFFSET);
return 0;
}
int test_fastfading(float EbNodB, float B90, int fadingModel, int submode, int apmode, int olddec, int channel_type, int ntx)
{
int x[QRA64_K], xdec[QRA64_K];
int y[QRA64_N];
float *rx;
float ebnodbest, ebnodbavg=0;
int rc,k;
float rxolddec[QRA64_N*QRA64_M]; // holds the energies at nominal tone freqs
int ndecok[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int nundet = 0;
int ndec=0;
qra64codec *codec_iv3nwv;
qra64codec *codec_k1jt;
codec_iv3nwv=qra64_init(QRA_NOAP);
codec_k1jt =qra64_init(apmode);
if (channel_type==2) { // fast-fading case
printf("Simulating the fast-fading channel\n");
printf("B90=%.2f Hz - Fading Model=%s - Submode=QRA64%c\n",B90,fadingModel?"Lorentz":"Gauss",submode+'A');
printf("Decoder metric = %s\n",olddec?"AWGN":"Matched to fast-fading signal");
}
else {
printf("Simulating the %s channel\n",channel_type?"Rayleigh block fading":"AWGN");
printf("Decoder metric = AWGN\n");
}
printf("\nEncoding msg [K1JT IV3NWV JN66]\n");
encodemsg_jt65(x,CALL_K1JT,CALL_IV3NWV,GRID_JN66);
// printf("[");
// for (k=0;k<11;k++) printf("%02hX ",x[k]); printf("%02hX]\n",x[11]);
qra64_encode(codec_iv3nwv, y, x);
printf("%d transmissions will be simulated\n\n",ntx);
if (apmode==QRA_USERAP) {
// This will enable K1JT's decoder to look for cq/qrz calls [CQ/QRZ ? ?/b]
printf("K1JT decoder enabled for [CQ ? ?/blank]\n");
qra64_apset(codec_k1jt, CALL_K1JT,0,0,APTYPE_CQQRZ);
// This will enable K1JT's decoder to look for calls directed to him [K1JT ? ?/b]
printf("K1JT decoder enabled for [K1JT ? ?/blank]\n");
qra64_apset(codec_k1jt, CALL_K1JT,0,0,APTYPE_MYCALL);
// This will enable K1JT's decoder to look for msges sent by IV3NWV [? IV3NWV ?]
printf("K1JT decoder enabled for [? IV3NWV ?/blank]\n");
qra64_apset(codec_k1jt, 0,CALL_IV3NWV,GRID_BLANK,APTYPE_HISCALL);
// This will enable K1JT's decoder to look for IV3NWV calls directed to him [K1JT IV3NWV ?/b]
printf("K1JT decoder enabled for [K1JT IV3NWV ?]\n");
qra64_apset(codec_k1jt, CALL_K1JT,CALL_IV3NWV,0,APTYPE_BOTHCALLS);
// This will enable K1JT's decoder to look for full-knowledge [K1JT IV3NWV JN66] msgs
printf("K1JT decoder enabled for [K1JT IV3NWV JN66]\n");
qra64_apset(codec_k1jt, CALL_K1JT,CALL_IV3NWV,GRID_JN66,APTYPE_FULL);
// This will enable K1JT's decoder to look for calls from IV3NWV [CQ IV3NWV ?/b] msgs
printf("K1JT decoder enabled for [CQ IV3NWV ?/b/JN66]\n");
qra64_apset(codec_k1jt, 0,CALL_IV3NWV,GRID_JN66,APTYPE_CQHISCALL);
}
printf("\nNow decoding with K1JT's decoder...\n");
/*
if (channel_type==2) // simulate a fast-faded signal
printf("Simulating a fast-fading channel with given B90 and spread type\n");
else
printf("Simulating a %s channel\n",channel_type?"Rayleigh block fading":"AWGN");
*/
for (k=0;k<ntx;k++) {
if ((k%10)==0)
printf(" %5.1f %%\r",100.0*k/ntx);
// printf("."); // work in progress
if (channel_type==2) {
// generate a fast-faded signal
rc = qra64_fastfading_channel(&rx,y,submode,EbNodB,B90,fadingModel);
if (rc<0) {
printf("\nqra64_fastfading_channel error. rc=%d\n",rc);
return -1;
}
}
else // generate a awgn or Rayleigh block fading signal
rx = mfskchannel(y, channel_type, EbNodB);
if (channel_type==2) // fast-fading case
if (olddec==1) {
int k, j;
int jj = 1<<submode;
int bps = QRA64_M*(2+jj);
float *rxbase;
float *out = rxolddec;
// calc energies at nominal freqs
for (k=0;k<QRA64_N;k++) {
rxbase = rx + QRA64_M + k*bps;
for (j=0;j<QRA64_M;j++) {
*out++=*rxbase;
rxbase+=jj;
}
}
// decode with awgn decoder
rc = qra64_decode(codec_k1jt,&ebnodbest,xdec,rxolddec);
}
else // use fast-fading decoder
rc = qra64_decode_fastfading(codec_k1jt,&ebnodbest,xdec,rx,submode,B90,fadingModel);
else // awgn or rayleigh channel. use the old decoder whatever the olddec option is
rc = qra64_decode(codec_k1jt,&ebnodbest,xdec,rx);
if (rc>=0) {
ebnodbavg +=ebnodbest;
if (memcmp(xdec,x,12*sizeof(int))==0)
ndecok[rc]++;
else {
fprintf(stderr,"\nUndetected error with rc=%d\n",rc);
nundet++;
}
}
}
printf(" %5.1f %%\r",100.0*k/ntx);
printf("\n\n");
printf("Msgs transmitted:%d\nMsg decoded:\n\n",ntx);
for (k=0;k<12;k++) {
printf("rc=%2d %3d with %s\n",k,ndecok[k],decode_type[k]);
ndec += ndecok[k];
}
printf("\nTotal: %d/%d (%d undetected errors)\n\n",ndec,ntx,nundet);
printf("");
if (ndec>0) {
ebnodbavg/=(ndec+nundet);
printf("Estimated SNR (average in dB) = %.2f dB\n\n",ebnodbavg-QRA64_SNR_EBNO_OFFSET);
}
return 0;
}
void syntax(void)
{
printf("\nQRA64 Mode Tests\n");
printf("2016, Nico Palermo - IV3NWV\n\n");
printf("---------------------------\n\n");
printf("Syntax: qra64 [-s<snrdb>] [-c<channel>] [-a<ap-type>] [-t<testtype>] [-h]\n");
printf("Options: \n");
printf(" -s<snrdb> : set simulation SNR in 2500 Hz BW (default:-27.5 dB)\n");
printf(" -c<channel> : set channel type 0=AWGN (default) 1=Rayleigh 2=Fast-fading\n");
printf(" -a<ap-type> : set decode type 0=NOAP 1=AUTOAP (default) 2=USERAP\n");
printf(" -t<testtype>: 0=simulate seq of msgs between IV3NWV and K1JT (default)\n");
printf(" 1=simulate K1JT receiving K1JT IV3NWV JN66\n");
printf(" 2=simulate fast-fading/awgn/rayliegh decoders performance\n");
printf(" -n<ntx> : simulate the transmission of ntx codewords (default=100)\n");
printf("Options used only for fast-fading simulations (-c2):\n");
printf(" -b : 90%% fading bandwidth in Hz [1..230 Hz] (default = 2.5 Hz)\n");
printf(" -m : fading model. 0=Gauss, 1=Lorentz (default = Lorentz)\n");
printf(" -q : qra64 submode. 0=QRA64A,... 4=QRA64E (default = QRA64A)\n");
printf(" -d : use the old awgn decoder\n");
printf(" -h: this help\n");
printf("Example:\n");
printf(" qra64 -t2 -c2 -a2 -b50 -m1 -q2 -n10000 -s-26\n");
printf(" runs the error performance test (-t2)\n");
printf(" with USER_AP (-a2)\n");
printf(" simulating a fast fading channel (-c2)\n");
printf(" with B90 = 50 Hz (-b50), Lorentz Doppler (-m1), mode QRA64C (-q2)\n");
printf(" ntx = 10000 codewords (-n10000) and SNR = -26 dB (-s-26)\n");
}
int main(int argc, char* argv[])
{
int k, rc, nok=0;
float SNRdB = -27.5f;
unsigned int channel = CHANNEL_AWGN;
unsigned int mode = QRA_AUTOAP;
unsigned int testtype=0;
int nqso = 100;
float EbNodB;
float B90 = 2.5;
int fadingModel = 1;
int submode = 0;
int olddec = 0;
int ntx = 100;
// Parse the command line
while(--argc) {
argv++;
if (strncmp(*argv,"-h",2)==0) {
syntax();
return 0;
}
else
if (strncmp(*argv,"-n",2)==0) {
ntx = ( int)atoi((*argv)+2);
if (ntx<100 || ntx>1000000) {
printf("Invalid -n option. ntx must be in the range [100..1000000]\n");
syntax();
return -1;
}
}
else
if (strncmp(*argv,"-a",2)==0) {
mode = ( int)atoi((*argv)+2);
if (mode>2) {
printf("Invalid decoding mode\n");
syntax();
return -1;
}
}
else
if (strncmp(*argv,"-s",2)==0) {
SNRdB = (float)atof((*argv)+2);
if (SNRdB>20 || SNRdB<-50) {
printf("SNR should be in the range [-50..20]\n");
syntax();
return -1;
}
}
else
if (strncmp(*argv,"-t",2)==0) {
testtype = ( int)atoi((*argv)+2);
if (testtype>2) {
printf("Invalid test type\n");
syntax();
return -1;
}
}
else
if (strncmp(*argv,"-c",2)==0) {
channel = ( int)atoi((*argv)+2);
if (channel>CHANNEL_FASTFADE) {
printf("Invalid channel type\n");
syntax();
return -1;
}
}
else
if (strncmp(*argv,"-b",2)==0) {
B90 = (float)atof((*argv)+2);
if (B90<1 || B90>230) {
printf("Invalid B90\n");
syntax();
return -1;
}
}
else
if (strncmp(*argv,"-m",2)==0) {
fadingModel = (int)atoi((*argv)+2);
if (fadingModel<0 || fadingModel>1) {
printf("Invalid fading model\n");
syntax();
return -1;
}
}
else
if (strncmp(*argv,"-q",2)==0) {
submode = (int)atoi((*argv)+2);
if (submode<0 || submode>4) {
printf("Invalid submode\n");
syntax();
return -1;
}
}
else
if (strncmp(*argv,"-d",2)==0) {
olddec = 1;
}
else {
printf("Invalid option\n");
syntax();
return -1;
}
}
if (testtype<2) // old tests
if (channel==CHANNEL_FASTFADE) {
printf("Invalid Option. Test type 0 and 1 supports only AWGN or Rayleigh Channel model\n");
return -1;
}
EbNodB = SNRdB+QRA64_SNR_EBNO_OFFSET;
#if defined(__linux__) || defined(__unix__)
srand48(GetTickCount());
#endif
if (testtype==0) {
for (k=0;k<nqso;k++) {
printf("\n\n------------------------\n");
rc = test_proc_1(channel, EbNodB, mode);
if (rc==0)
nok++;
}
printf("\n\n%d/%d QSOs to end without repetitions\n",nok,nqso);
printf("Input SNR = %.1fdB channel=%s ap-mode=%s\n\n",
SNRdB,
channel==CHANNEL_AWGN?"AWGN":"RAYLEIGH",
apmode_type[mode]
);
}
else if (testtype==1) {
test_proc_2(channel, EbNodB, mode);
printf("Input SNR = %.1fdB channel=%s ap-mode=%s\n\n",
SNRdB,
channel==CHANNEL_AWGN?"AWGN":"RAYLEIGH",
apmode_type[mode]
);
}
else {
printf("Input SNR = %.1fdB ap-mode=%s\n\n",
SNRdB,
apmode_type[mode]
);
test_fastfading(EbNodB,B90,fadingModel,submode,mode,olddec, channel, ntx);
}
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,269 +0,0 @@
// qra64.h
// Encoding/decoding functions for the QRA64 mode
//
// (c) 2016 - Nico Palermo, IV3NWV
// ------------------------------------------------------------------------------
// This file is part of the qracodes project, a Forward Error Control
// encoding/decoding package based on Q-ary RA (Repeat and Accumulate) LDPC codes.
//
// qracodes is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// qracodes is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with qracodes source distribution.
// If not, see <http://www.gnu.org/licenses/>.
#ifndef _qra64_h_
#define _qra64_h_
// qra64_init(...) initialization flags
#define QRA_NOAP 0 // don't use a-priori knowledge
#define QRA_AUTOAP 1 // use auto a-priori knowledge
#define QRA_USERAP 2 // a-priori knowledge messages provided by the user
// QRA code parameters
#define QRA64_K 12 // information symbols
#define QRA64_N 63 // codeword length
#define QRA64_C 51 // (number of parity checks C=(N-K))
#define QRA64_M 64 // code alphabet size
#define QRA64_m 6 // bits per symbol
// packed predefined callsigns and fields as defined in JT65
#define CALL_CQ 0xFA08319
#define CALL_QRZ 0xFA0831A
#define CALL_CQ000 0xFA0831B
#define CALL_CQ999 0xFA08702
#define CALL_CQDX 0x5624C39
#define CALL_DE 0xFF641D1
#define GRID_BLANK 0x7E91
// Types of a-priori knowledge messages
#define APTYPE_CQQRZ 0 // [cq/qrz ? ?/blank]
#define APTYPE_MYCALL 1 // [mycall ? ?/blank]
#define APTYPE_HISCALL 2 // [? hiscall ?/blank]
#define APTYPE_BOTHCALLS 3 // [mycall hiscall ?]
#define APTYPE_FULL 4 // [mycall hiscall grid]
#define APTYPE_CQHISCALL 5 // [cq/qrz hiscall ?/blank]
#define APTYPE_SIZE (APTYPE_CQHISCALL+1)
typedef struct {
float decEsNoMetric;
int apflags;
int apmsg_set[APTYPE_SIZE]; // indicate which ap type knowledge has
// been set by the user
// ap messages buffers
int apmsg_cqqrz[12]; // [cq/qrz ? ?/blank]
int apmsg_call1[12]; // [mycall ? ?/blank]
int apmsg_call2[12]; // [? hiscall ?/blank]
int apmsg_call1_call2[12]; // [mycall hiscall ?]
int apmsg_call1_call2_grid[12]; // [mycall hiscall grid]
int apmsg_cq_call2[12]; // [cq hiscall ?/blank]
int apmsg_cq_call2_grid[12]; // [cq hiscall grid]
// ap messages masks
int apmask_cqqrz[12];
int apmask_cqqrz_ooo[12];
int apmask_call1[12];
int apmask_call1_ooo[12];
int apmask_call2[12];
int apmask_call2_ooo[12];
int apmask_call1_call2[12];
int apmask_call1_call2_grid[12];
int apmask_cq_call2[12];
int apmask_cq_call2_ooo[12];
} qra64codec;
#ifdef __cplusplus
extern "C" {
#endif
qra64codec *qra64_init(int flags);
// QRA64 mode initialization function
// arguments:
// flags: set the decoder mode
// QRA_NOAP use no a-priori information
// QRA_AUTOAP use any relevant previous decodes
// QRA_USERAP use a-priori information provided via qra64_apset(...)
// returns:
// Pointer to initialized qra64codec data structure
// this pointer should be passed to the encoding/decoding functions
//
// 0 if unsuccessful (can't allocate memory)
// ----------------------------------------------------------------------------
void qra64_encode(qra64codec *pcodec, int *y, const int *x);
// QRA64 encoder
// arguments:
// pcodec = pointer to a qra64codec data structure as returned by qra64_init
// x = pointer to the message to be encoded, int x[12]
// x must point to an array of integers (i.e. defined as int x[12])
// y = pointer to encoded message, int y[63]=
// ----------------------------------------------------------------------------
int qra64_decode(qra64codec *pcodec, float *ebno, int *x, const float *r);
// QRA64 mode decoder
// arguments:
// pcodec = pointer to a qra64codec data structure as returned by qra64_init
// ebno = pointer to a float where the avg Eb/No (in dB) will be stored
// in case of successfull decoding
// (pass a null pointer if not interested)
// x = pointer to decoded message, int x[12]
// r = pointer to received symbol energies (squared amplitudes)
// r must point to an array of length QRA64_M*QRA64_N (=64*63=4032)
// The first QRA_M entries should be the energies of the first
// symbol in the codeword; the last QRA_M entries should be the
// energies of the last symbol in the codeword
//
// return code:
//
// The return code is <0 when decoding is unsuccessful
// -16 indicates that the definition of QRA64_NMSG does not match what required by the code
// If the decoding process is successfull the return code is accordingly to the following table
// rc=0 [? ? ?] AP0 (decoding with no a-priori)
// rc=1 [CQ ? ?] AP27
// rc=2 [CQ ? ] AP44
// rc=3 [CALL ? ?] AP29
// rc=4 [CALL ? ] AP45
// rc=5 [CALL CALL ?] AP57
// rc=6 [? CALL ?] AP29
// rc=7 [? CALL ] AP45
// rc=8 [CALL CALL GRID] AP72 (actually a AP68 mask to reduce false decodes)
// rc=9 [CQ CALL ?] AP55
// rc=10 [CQ CALL ] AP70 (actaully a AP68 mask to reduce false decodes)
// return codes in the range 1-10 indicate the amount and the type of a-priori
// information was required to decode the received message.
// Decode a QRA64 msg using a fast-fading metric
int qra64_decode_fastfading(
qra64codec *pcodec, // ptr to the codec structure
float *ebno, // ptr to where the estimated Eb/No value will be saved
int *x, // ptr to decoded message
const float *rxen, // ptr to received symbol energies array
const int submode, // submode idx (0=QRA64A ... 4=QRA64E)
const float B90, // spread bandwidth (90% fractional energy)
const int fadingModel); // 0=Gaussian 1=Lorentzian fade model
//
// rxen: The array of the received bin energies
// Bins must be spaced by integer multiples of the symbol rate (1/Ts Hz)
// The array must be an array of total length U = L x N where:
// L: is the number of frequency bins per message symbol (see after)
// N: is the number of symbols in a QRA64 msg (63)
//
// The number of bins/symbol L depends on the selected submode accordingly to
// the following rule:
// L = (64+64*2^submode+64) = 64*(2+2^submode)
// Tone 0 is always supposed to be at offset 64 in the array.
// The m-th tone nominal frequency is located at offset 64 + m*2^submode (m=0..63)
//
// Submode A: (2^submode = 1)
// L = 64*3 = 196 bins/symbol
// Total length of the energies array: U = 192*63 = 12096 floats
//
// Submode B: (2^submode = 2)
// L = 64*4 = 256 bins/symbol
// Total length of the energies array: U = 256*63 = 16128 floats
//
// Submode C: (2^submode = 4)
// L = 64*6 = 384 bins/symbol
// Total length of the energies array: U = 384*63 = 24192 floats
//
// Submode D: (2^submode = 8)
// L = 64*10 = 640 bins/symbol
// Total length of the energies array: U = 640*63 = 40320 floats
//
// Submode E: (2^submode = 16)
// L = 64*18 = 1152 bins/symbol
// Total length of the energies array: U = 1152*63 = 72576 floats
//
// Note: The rxen array is modified and reused for internal calculations.
//
//
// B90: spread fading bandwidth in Hz (90% fractional average energy)
//
// B90 should be in the range 1 Hz ... 238 Hz
// The value passed to the call is rounded to the closest value among the
// 64 available values:
// B = 1.09^k Hz, with k=0,1,...,63
//
// I.e. B90=27 Hz will be approximated in this way:
// k = rnd(log(27)/log(1.09)) = 38
// B90 = 1.09^k = 1.09^38 = 26.4 Hz
//
// For any input value the maximum rounding error is not larger than +/- 5%
//
// return codes: same return codes of qra64_decode (+some additional error codes)
// Simulate the fast-fading channel (to be used with qra64_decode_fastfading)
int qra64_fastfading_channel(
float **rxen,
const int *xmsg,
const int submode,
const float EbN0dB,
const float B90,
const int fadingModel);
// Simulate transmission over a fading channel with given B90, fading model and submode
// and non coherent detection.
// Sets rxen to point to an array of bin energies formatted as required
// by the (fast-fading) decoding routine.
// returns 0 on success or negative values on error conditions
int qra64_apset(qra64codec *pcodec, const int mycall, const int hiscall, const int grid, const int aptype);
// Set decoder a-priori knowledge accordingly to the type of the message to
// look up for
// arguments:
// pcodec = pointer to a qra64codec data structure as returned by qra64_init
// mycall = mycall to look for
// hiscall = hiscall to look for
// grid = grid to look for
// aptype = define the type of AP to be set:
// APTYPE_CQQRZ set [cq/qrz ? ?/blank]
// APTYPE_MYCALL set [mycall ? ?/blank]
// APTYPE_HISCALL set [? hiscall ?/blank]
// APTYPE_BOTHCALLS set [mycall hiscall ?]
// APTYPE_FULL set [mycall hiscall grid]
// APTYPE_CQHISCALL set [cq/qrz hiscall ?/blank]
// returns:
// 0 on success
// -1 when qra64_init was called with the QRA_NOAP flag
// -2 invalid apytpe (valid range [APTYPE_CQQRZ..APTYPE_CQHISCALL]
// (APTYPE_CQQRZ [cq/qrz ? ?] is set by default )
void qra64_apdisable(qra64codec *pcodec, const int aptype);
// disable specific AP type
// arguments:
// pcodec = pointer to a qra64codec data structure as returned by qra64_init
// aptype = define the type of AP to be disabled
// APTYPE_CQQRZ disable [cq/qrz ? ?/blank]
// APTYPE_MYCALL disable [mycall ? ?/blank]
// APTYPE_HISCALL disable [ ? hiscall ?/blank]
// APTYPE_BOTHCALLS disable [mycall hiscall ? ]
// APTYPE_FULL disable [mycall hiscall grid]
// APTYPE_CQHISCALL set [cq/qrz hiscall ?/blank]
void qra64_close(qra64codec *pcodec);
// Free memory allocated by qra64_init
// arguments:
// pcodec = pointer to a qra64codec data structure as returned by qra64_init
// ----------------------------------------------------------------------------
// encode/decode std msgs in 12 symbols as done in jt65
void encodemsg_jt65(int *y, const int call1, const int call2, const int grid);
void decodemsg_jt65(int *call1, int *call2, int *grid, const int *x);
#ifdef __cplusplus
}
#endif
#endif // _qra64_h_

File diff suppressed because it is too large Load Diff

View File

@ -1,65 +0,0 @@
// qra64_subs.c
// Fortran interface routines for QRA64
#include "qra64.h"
#include <stdio.h>
static qra64codec *pqra64codec = NULL;
void qra64_enc_(int x[], int y[])
{
if (pqra64codec==NULL) pqra64codec = qra64_init(QRA_USERAP);
qra64_encode(pqra64codec, y, x);
}
void qra64_dec_(float r[], int* nc1, int* nc2, int* ng2, int* APtype,
int* iset, int* ns0, float* b0, int* nf0,
int xdec[], float* snr, int* rc)
{
/*
APtype: AP
-----------------------------------------------------------------------
-1 0 (no AP information)
0 [CQ/QRZ ? ? ] 25/37
1 [MyCall ? ? ] 25/37
2 [ ? HisCall ? ] 25/37
3 [MyCall HisCall ? ] 49/68
4 [MyCall HisCall grid] 68
5 [CQ/QRZ HisCall ? ] 49/68
rc Message format AP APTYPE Comments
------------------------------------------------------------------------
-16 Failed sanity check
-2 Decoded but CRC failed
-1 No decode
0 [ ? ? ? ] 0 -1 Decode with no AP info
1 [CQ/QRZ ? ? ] 25 0
2 [CQ/QRZ ? _ ] 37 0
3 [MyCall ? ? ] 25 1
4 [MyCall ? _ ] 37 1
5 [MyCall HisCall ? ] 49 3
6 [ ? HisCall ? ] 25 2 Optional
7 [ ? HisCall _ ] 37 2 Optional
8 [MyCall HisCall Grid] 68 4
9 [CQ/QRZ HisCall ? ] 49 5 Optional (not needed?)
10 [CQ/QRZ HisCall _ ] 68 5 Optional
11 [CQ/QRZ HisCall Grid] 68 ? Optional
*/
float EbNodBEstimated;
int err=0;
int nSubmode=*ns0;
float b90=*b0;
int nFadingModel=*nf0;
if(pqra64codec==NULL) pqra64codec = qra64_init(QRA_USERAP);
err=qra64_apset(pqra64codec,*nc1,*nc2,*ng2,*APtype);
if(err<0) printf("ERROR: qra64_apset returned %d\n",err);
if(*iset==0) {
*rc = qra64_decode_fastfading(pqra64codec,&EbNodBEstimated,xdec,r,
nSubmode,b90,nFadingModel);
*snr = EbNodBEstimated - 31.0;
}
}

View File

@ -1,88 +0,0 @@
$ qra64_nico -h
QRA64 Mode Tests
2016, Nico Palermo - IV3NWV
---------------------------
Syntax: qra64 [-s<snrdb>] [-c<channel>] [-a<ap-type>] [-t<testtype>] [-h]
Options:
-s<snrdb> : set simulation SNR in 2500 Hz BW (default:-27.5 dB)
-c<channel> : set channel type 0=AWGN (default) 1=Rayleigh
-a<ap-type> : set decode type 0=NOAP 1=AUTOAP (default) 2=USERAP
-t<testtype>: 0=simulate seq of msgs between IV3NWV and K1JT (default)
1=simulate K1JT receiving K1JT IV3NWV JN66
2=simulate fast-fading routines (option -c ignored)
Options used only for fast-fading simulations:
-b : 90% fading bandwidth in Hz [1..230 Hz] (default = 2.5 Hz)
-m : fading model. 0=Gauss, 1=Lorentz (default = Lorentz)
-q : qra64 submode. 0=QRA64A,... 4=QRA64E (default = QRA64A)
-h: this help
#############################################################################
Usage example:
qra64 -c2 -t2 -a2 -b50 -m1 -q2 -s-26.0 -n50000
Simulate a fast-fading channel (-c2)
Evaluate decoder performance (-t2) with
USER_AP (-a2)
B90 = 50 Hz (-b50)
Lorentz model (-m1)
submode QRA64C (-q2)
Input SNR = -26.0 dB (-s-26.0)
Simulate 50000 transmissions (-n50000)
(type qra64 -h for command syntax)
Command Output:
Input SNR = -26.0dB ap-mode=USER AP
Simulating the fast-fading channel
B90=50.00 Hz - Fading Model=Lorentz - Submode=QRA64C
Decoder metric = Matched to fast-fading signal
Encoding msg [K1JT IV3NWV JN66]
50000 transmissions will be simulated
K1JT decoder enabled for [CQ ? ?/blank]
K1JT decoder enabled for [K1JT ? ?/blank]
K1JT decoder enabled for [? IV3NWV ?/blank]
K1JT decoder enabled for [K1JT IV3NWV ?]
K1JT decoder enabled for [K1JT IV3NWV JN66]
K1JT decoder enabled for [CQ IV3NWV ?/b/JN66]
Now decoding with K1JT's decoder...
5.5 %
Undetected error with rc=6
13.1 %
Undetected error with rc=7
70.8 %
Undetected error with rc=1
75.8 %
Undetected error with rc=9
88.9 %
Undetected error with rc=6
100.0 %
Msgs transmitted:50000
Msg decoded:
rc= 0 0 with [? ? ?] AP0
rc= 1 0 with [CQ ? ?] AP27
rc= 2 0 with [CQ ? ] AP42
rc= 3 145 with [CALL ? ?] AP29
rc= 4 0 with [CALL ? ] AP44
rc= 5 12085 with [CALL CALL ?] AP57
rc= 6 0 with [? CALL ?] AP29
rc= 7 0 with [? CALL ] AP44
rc= 8 24307 with [CALL CALL G] AP72
rc= 9 0 with [CQ CALL ?] AP55
rc=10 0 with [CQ CALL ] AP70
rc=11 0 with [CQ CALL G] AP70
Total: 36537/50000 (5 undetected errors)
Estimated SNR (average in dB) = -26.26 dB

View File

@ -1,201 +0,0 @@
program qra64sim
! Generate simulated QRA64 data for testing the decoder.
use wavhdr
use packjt
parameter (NMAX=54*12000) ! = 648,000
parameter (NFFT=10*65536,NH=NFFT/2)
type(hdr) h !Header for .wav file
integer*2 iwave(NMAX) !Generated waveform
integer*4 itone(84) !Channel symbols (values 0-63)
real*4 xnoise(NMAX) !Generated random noise
real*4 dat(NMAX) !Generated real data
complex cdat(NMAX) !Generated complex waveform
complex cspread(0:NFFT-1) !Complex amplitude for Rayleigh fading
complex z
complex c00(0:720000) !Analytic signal for dat()
real*8 f0,dt,twopi,phi,dphi,baud,fsample,freq
character msg*22,fname*11,csubmode*1,arg*12,cd*1
character msgsent*22
logical lsync
data lsync/.false./
nargs=iargc()
if(nargs.ne.8) then
print*,'Usage: qra64sim "msg" A-E Nsigs fDop DT Nfiles Sync SNR'
print*,'Example qra64sim "K1ABC W9XYZ EN37" A 10 0.2 0.0 1 T -26'
print*,'Sync = T to include sync test.'
go to 999
endif
call getarg(1,msg)
call getarg(2,csubmode)
mode64=2**(ichar(csubmode)-ichar('A'))
call getarg(3,arg)
read(arg,*) nsigs
call getarg(4,arg)
read(arg,*) fspread
call getarg(5,arg)
read(arg,*) xdt
call getarg(6,arg)
read(arg,*) nfiles
call getarg(7,arg)
if(arg(1:1).eq.'T' .or. arg(1:1).eq.'1') lsync=.true.
call getarg(8,arg)
read(arg,*) snrdb
if(mode64.ge.8) nsigs=1
rms=100.
fsample=12000.d0 !Sample rate (Hz)
dt=1.d0/fsample !Sample interval (s)
twopi=8.d0*atan(1.d0)
npts=54*12000 !Total samples in .wav file
nsps=6912
baud=12000.d0/nsps !Keying rate = 1.7361111111
nsym=84 !Number of channel symbols
h=default_header(12000,npts)
dfsig=2000.0/nsigs !Freq spacing between sigs in file (Hz)
ichk=0
write(*,1000)
1000 format('File Sig Freq A-E S/N DT Dop Message'/60('-'))
nsync=0
do ifile=1,nfiles !Loop over requested number of files
write(fname,1002) ifile !Output filename
1002 format('000000_',i4.4)
open(10,file=fname//'.wav',access='stream',status='unknown')
xnoise=0.
cdat=0.
if(snrdb.lt.90) then
do i=1,npts
xnoise(i)=gran() !Generate gaussian noise
enddo
endif
do isig=1,nsigs !Generate requested number of sigs
if(mod(nsigs,2).eq.0) f0=1500.0 + dfsig*(isig-0.5-nsigs/2)
if(mod(nsigs,2).eq.1) f0=1500.0 + dfsig*(isig-(nsigs+1)/2)
if(nsigs.eq.1) f0=1000.0
xsnr=snrdb
if(snrdb.eq.0.0) xsnr=-20 - isig
call genqra64(msg,ichk,msgsent,itone,itype)
bandwidth_ratio=2500.0/6000.0
sig=sqrt(2*bandwidth_ratio)*10.0**(0.05*xsnr)
if(xsnr.gt.90.0) sig=1.0
write(*,1020) ifile,isig,f0,csubmode,xsnr,xdt,fspread,msg
1020 format(i4,i4,f10.3,2x,a1,2x,f5.1,f6.2,f6.1,1x,a22)
phi=0.d0
dphi=0.d0
k=(xdt+1.0)*12000 !Start audio at t = xdt + 1.0 s
isym0=-99
do i=1,npts !Add this signal into cdat()
isym=i/nsps + 1
if(isym.gt.nsym) exit
if(isym.ne.isym0) then
freq=f0 + itone(isym)*baud*mode64
dphi=twopi*freq*dt
isym0=isym
endif
phi=phi + dphi
if(phi.gt.twopi) phi=phi-twopi
xphi=phi
z=cmplx(cos(xphi),sin(xphi))
k=k+1
if(k.ge.1) cdat(k)=cdat(k) + sig*z
enddo
enddo
if(fspread.ne.0) then !Apply specified Doppler spread
df=12000.0/nfft
twopi=8*atan(1.0)
cspread(0)=1.0
cspread(NH)=0.
b=6.0 !Use truncated Lorenzian shape for fspread
do i=1,NH
f=i*df
x=b*f/fspread
z=0.
a=0.
if(x.lt.3.0) then !Cutoff beyond x=3
a=sqrt(1.111/(1.0+x*x)-0.1) !Lorentzian
call random_number(r1)
phi1=twopi*r1
z=a*cmplx(cos(phi1),sin(phi1))
endif
cspread(i)=z
z=0.
if(x.lt.50.0) then
call random_number(r2)
phi2=twopi*r2
z=a*cmplx(cos(phi2),sin(phi2))
endif
cspread(NFFT-i)=z
enddo
! do i=0,NFFT-1
! f=i*df
! if(i.gt.NH) f=(i-nfft)*df
! s=real(cspread(i))**2 + aimag(cspread(i))**2
! write(13,3000) i,f,s,cspread(i)
!3000 format(i5,f10.3,3f12.6)
! enddo
! s=real(cspread(0))**2 + aimag(cspread(0))**2
! write(13,3000) 1024,0.0,s,cspread(0)
call four2a(cspread,NFFT,1,1,1) !Transform to time domain
sum=0.
do i=0,NFFT-1
p=real(cspread(i))**2 + aimag(cspread(i))**2
sum=sum+p
enddo
avep=sum/NFFT
fac=sqrt(1.0/avep)
cspread=fac*cspread !Normalize to constant avg power
cdat=cspread(1:npts)*cdat !Apply Rayleigh fading
! do i=0,NFFT-1
! p=real(cspread(i))**2 + aimag(cspread(i))**2
! write(14,3010) i,p,cspread(i)
!3010 format(i8,3f12.6)
! enddo
endif
dat=aimag(cdat) + xnoise !Add the generated noise
fac=32767.0/nsigs
if(snrdb.ge.90.0) iwave(1:npts)=nint(fac*dat(1:npts))
if(snrdb.lt.90.0) iwave(1:npts)=nint(rms*dat(1:npts))
write(10) h,iwave(1:npts) !Save the .wav file
close(10)
if(lsync) then
cd=' '
if(ifile.eq.nfiles) cd='d'
nf1=200
nf2=3000
nfqso=nint(f0)
ntol=100
minsync=0
emedelay=0.0
call ana64(dat,npts,c00)
call sync64(c00,nf1,nf2,nfqso,ntol,minsync,mode64,emedelay,xdt2,f02, &
jpk0,sync,sync2,width)
terr=1.01/(8.0*baud)
ferr=1.01*mode64*baud
if(abs(xdt2-xdt).lt.terr .and. abs(f02-f0).lt.ferr) nsync=nsync+1
open(40,file='sync64.out',status='unknown',position='append')
write(40,1030) ifile,64,csubmode,snrdb,fspread,xdt2-xdt,f02-f0, &
width,sync,sync2,nsync,cd
1030 format(i4,i3,1x,a1,2f7.1,f7.2,4f8.1,i5,1x,a1)
close(40)
endif
enddo
if(lsync) write(*,1040) snrdb,nfiles,nsync
1040 format('SNR:',f6.1,' nfiles:',i5,' nsynced:',i5)
999 end program qra64sim

View File

@ -1,137 +0,0 @@
subroutine qra_loops(c00,npts2,nsps,mode,mode64,nsubmode,nFadingModel, &
ndepth,nc1,nc2,ng2,naptype,jpk0,xdt,f0,width,snr2,irc,dat4)
use packjt
use timer_module, only: timer
parameter (LN=2176*63) !LN=LL*NN; LL = 64*(mode64+2)
character*37 decoded
complex c00(0:npts2-1) !Analytic representation of dd(), 6000 Hz
complex ,allocatable :: c0(:) !Ditto, with freq shift
real a(3) !twkfreq params f,f1,f2
real s3(LN) !Symbol spectra
real s3avg(LN) !Averaged symbol spectra
integer dat4(12),dat4x(12) !Decoded message (as 12 integers)
integer nap(0:11) !AP return codes
data nap/0,2,3,2,3,4,2,3,6,4,6,6/,nsave/0/
save nsave,s3avg
allocate(c0(0:npts2-1))
irc=-99
s3lim=20.
ibwmax=11
if(mode64.le.4) ibwmax=9
ibwmin=ibwmax
idtmax=3
call qra_params(ndepth,maxaptype,idfmax,idtmax,ibwmin,ibwmax,maxdist)
LL=64*(mode64+2)
NN=63
napmin=99
ncall=0
do iavg=0,1
if(iavg.eq.1) then
idfmax=1
idtmax=1
endif
do idf=1,idfmax
ndf=idf/2
if(mod(idf,2).eq.0) ndf=-ndf
a=0.
a(1)=-(f0+0.4*ndf)
call twkfreq(c00,c0,npts2,6000.0,a)
do idt=1,idtmax
ndt=idt/2
if(iavg.eq.0) then
if(mod(idt,2).eq.0) ndt=-ndt
jpk=jpk0 + 240*ndt !240/6000 = 0.04 s = tsym/32
if(jpk.lt.0) jpk=0
call timer('spec64 ',0)
call spec64(c0,nsps,mode,mode64,jpk,s3,LL,NN)
call timer('spec64 ',1)
call pctile(s3,LL*NN,40,base)
s3=s3/base
where(s3(1:LL*NN)>s3lim) s3(1:LL*NN)=s3lim
else
s3(1:LL*NN)=s3avg(1:LL*NN)
endif
do ibw=ibwmax,ibwmin,-2
ndist=ndf**2 + ndt**2 + ((ibwmax-ibw)/2)**2
if(ndist.gt.maxdist) cycle
b90=1.728**ibw
if(b90.gt.230.0) cycle
if(b90.lt.0.15*width) exit
ncall=ncall+1
call timer('qra64_de',0)
call qra64_dec(s3,nc1,nc2,ng2,naptype,0,nSubmode,b90, &
nFadingModel,dat4,snr2,irc)
call timer('qra64_de',1)
if(irc.eq.0) go to 200
if(irc.gt.0) call badmsg(irc,dat4,nc1,nc2,ng2)
iirc=max(0,min(irc,11))
if(irc.gt.0 .and. nap(iirc).lt.napmin) then
dat4x=dat4
b90x=b90
snr2x=snr2
napmin=nap(iirc)
irckeep=irc
xdtkeep=jpk/6000.0 - 1.0
f0keep=-a(1)
idfkeep=idf
idtkeep=idt
ibwkeep=ibw
ndistx=ndist
go to 100 !###
endif
enddo ! ibw (b90 loop)
!### if(iand(ndepth,3).lt.3 .and. irc.ge.0) go to 100
enddo ! idt (DT loop)
enddo ! idf (f0 loop)
! if(iavg.eq.0 .and. abs(jpk0-4320).le.1300) then
if(iavg.eq.0) then
a=0.
a(1)=-f0
call twkfreq(c00,c0,npts2,6000.0,a)
jpk=3000 !### These definitions need work ###
! if(nsps.ge.3600) jpk=4080 !###
if(nsps.ge.3600) jpk=6000 !###
call spec64(c0,nsps,mode,mode64,jpk,s3,LL,NN)
call pctile(s3,LL*NN,40,base)
s3=s3/base
where(s3(1:LL*NN)>s3lim) s3(1:LL*NN)=s3lim
s3avg(1:LL*NN)=s3avg(1:LL*NN)+s3(1:LL*NN)
nsave=nsave+1
endif
if(iavg.eq.0 .and. nsave.lt.2) exit
enddo ! iavg
100 if(napmin.ne.99) then
dat4=dat4x
b90=b90x
snr2=snr2x
irc=irckeep
xdt=xdtkeep
f0=f0keep
idt=idtkeep
idf=idfkeep
ibw=ibwkeep
ndist=ndistx
endif
200 if(mode.eq.65 .and. nsps.eq.7200/2) xdt=xdt+0.4 !### Empirical -- WHY ??? ###
if(irc.ge.0) then
navg=nsave
if(iavg.eq.0) navg=0
!### For tests only:
open(53,file='fort.53',status='unknown',position='append')
call unpackmsg(dat4,decoded) !Unpack the user message
write(53,3053) idf,idt,ibw,b90,xdt,f0,snr2,ndist,irc,navg,decoded(1:22)
3053 format(3i5,f7.1,f7.2,2f7.1,3i4,2x,a22)
close(53)
!###
nsave=0
s3avg=0.
irc=irc + 100*navg
endif
return
end subroutine qra_loops

View File

@ -140,20 +140,20 @@ subroutine chk_samples(ihsym,k,nstop)
call system_clock(count0,clkfreq)
maxhsym=0
endif
if((mod(ihsym,100).eq.0 .or. ihsym.ge.nstop-100) .and. &
k0.ne.99999999) then
call system_clock(count1,clkfreq)
dtime=dfloat(count1-count0)/dfloat(clkfreq)
if(dtime.lt.28.0) return
if(dtime.gt.1.d-6) fsample=(k-3456)/dtime
call date_and_time(values=itime)
sec=itime(7)+0.001*itime(8)
write(ctime,3000) itime(5)-itime(4)/60,itime(6),sec
3000 format(i2.2,':',i2.2,':',f6.3)
write(33,3033) ctime,dtime,ihsym,nstop,k,fsample
3033 format(a12,f12.6,2i7,i10,f15.3)
flush(33)
endif
! if((mod(ihsym,100).eq.0 .or. ihsym.ge.nstop-100) .and. &
! k0.ne.99999999) then
! call system_clock(count1,clkfreq)
! dtime=dfloat(count1-count0)/dfloat(clkfreq)
! if(dtime.lt.28.0) return
! if(dtime.gt.1.d-6) fsample=(k-3456)/dtime
! call date_and_time(values=itime)
! sec=itime(7)+0.001*itime(8)
! write(ctime,3000) itime(5)-itime(4)/60,itime(6),sec
!3000 format(i2.2,':',i2.2,':',f6.3)
! write(33,3033) ctime,dtime,ihsym,nstop,k,fsample
!3033 format(a12,f12.6,2i7,i10,f15.3)
! flush(33)
! endif
k0=k
return

View File

@ -29,7 +29,7 @@ subroutine sync4(dat,jz,ntol,nfqso,mode,mode4,minwidth,dtx,dfx,snrx, &
df=0.5*11025.0/nfft
ftop=nfqso + 7*mode4*df
if(ftop.gt.11025.0/4.0) then
print*,'*** Rx Freq is set too high for this sybmode ***'
print*,'*** Rx Freq is set too high for this submode ***'
go to 900
endif
@ -85,7 +85,7 @@ subroutine sync4(dat,jz,ntol,nfqso,mode,mode4,minwidth,dtx,dfx,snrx, &
enddo
if(syncbest.lt.-1.e29) go to 900
ccfred=red
call pctile(ccfred(iaa:ibb),ibb-iaa+1,45,base)
call pctile(ccfred(ia:ib),ib-ia+1,45,base)
ccfred=ccfred-base
dfx=ipk*df

View File

@ -1,185 +0,0 @@
subroutine synciscat(cdat,npts,nh,npct,s0,jsym,df,ntol, &
mousebutton,mode4,nafc,psavg,xsync,sig,ndf0,msglen, &
ipk,jpk,idf,df1)
! Synchronize an ISCAT signal
! cdat() is the downsampled analytic signal.
! Sample rate = fsample = BW = 11025 * (9/32) = 3100.78125 Hz
! npts, nsps, etc., are all reduced by 9/32
parameter (NMAX=30*3101)
parameter (NSZ=4*1400)
complex cdat(NMAX)
complex c(288)
real s0(288,NSZ)
real fs0(288,96) !108 = 96 + 3*4
real savg(288)
real sref(288)
real psavg(72) !Average spectrum of whole file
integer icos(4)
data icos/0,1,3,2/
data nsync/4/,nlen/2/,ndat/18/
! Silence compiler warnings:
sigbest=-20.0
ndf0best=0
msglenbest=0
ipkbest=0
jpkbest=0
ipk2=0
idfbest=mousebutton
fsample=3100.78125 !New sample rate
nsps=144/mode4
nsym=npts/nsps - 1
nblk=nsync+nlen+ndat
nfft=2*nsps !FFTs at twice the symbol length,
kstep=nsps/4 ! stepped by 1/4 symbol
df=fsample/nfft
fac=1.0/1000.0 !Somewhat arbitrary
savg=0.
s0=0.
ia=1-kstep
do j=1,4*nsym !Compute symbol spectra
ia=ia+kstep
ib=ia+nsps-1
if(ib.gt.npts) exit
c(1:nsps)=fac*cdat(ia:ib)
c(nsps+1:nfft)=0.
call four2a(c,nfft,1,-1,1)
do i=1,nfft
s0(i,j)=real(c(i))**2 + aimag(c(i))**2
savg(i)=savg(i) + s0(i,j) !Accumulate avg spectrum
enddo
i0=40
enddo
jsym=4*nsym
savg=savg/jsym
do i=1,71 !Compute spectrum in dB, for plot
if(mode4.eq.1) then
psavg(i)=2*db(savg(4*i)+savg(4*i-1)+savg(4*i-2)+savg(4*i-3)) + 1.0
else
psavg(i)=2*db(savg(2*i)+savg(2*i-1)) + 7.0
endif
enddo
do i=nh+1,nfft-nh
call pctile(savg(i-nh),2*nh+1,npct,sref(i))
enddo
sref(1:nh)=sref(nh+11)
sref(nfft-nh+1:nfft)=sref(nfft-nh)
do i=1,nfft !Normalize the symbol spectra
fac=1.0/sref(i)
if(i.lt.11) fac=1.0/savg(11)
do j=1,jsym
s0(i,j)=fac*s0(i,j)
enddo
enddo
nfold=jsym/96
jb=96*nfold
ttot=npts/fsample !Length of record (s)
df1=df/ttot !Step size for f1=fdot
idf1=int(-25.0/df1)
idf2=int(5.0/df1)
if(nafc.eq.0) then
idf1=0
idf2=0
else if(mod(-idf1,2).eq.1) then
idf1=idf1-1
endif
xsyncbest=0.
do idf=idf1,idf2 !Loop over fdot
fs0=0.
do j=1,jb !Fold s0 into fs0, modulo 4*nblk
k=mod(j-1,4*nblk)+1
ii=nint(idf*float(j-jb/2)/float(jb))
ia=max(1-ii,1)
ib=min(nfft-ii,nfft)
do i=ia,ib
fs0(i,k)=fs0(i,k) + s0(i+ii,j)
enddo
enddo
ref=nfold*4
i0=27
if(mode4.eq.1) i0=95
ia=i0-nint(ntol/df)
ib=i0+nint(ntol/df)
if(ia.lt.1) ia=1
if(ib.gt.nfft-3) ib=nfft-3
smax=0.
ipk=1
jpk=1
do j=0,4*nblk-1 !Find sync pattern: lags 0-95
do i=ia,ib !Search specified freq range
ss=0.
do n=1,4 !Sum over 4 sync tones
k=j+4*n-3
if(k.gt.96) k=k-96
ss=ss + fs0(i+2*icos(n),k)
enddo
if(ss.gt.smax) then
smax=ss
ipk=i !Frequency offset, DF
jpk=j+1 !Time offset, DT
endif
enddo
enddo
xsync=smax/ref - 1.0
if(nfold.lt.26) xsync=xsync * sqrt(nfold/26.0)
xsync=xsync-0.5 !Empirical
sig=db(smax/ref - 1.0) - 15.0
if(mode4.eq.1) sig=sig-5.0
! if(sig.lt.-20 .or. xsync.lt.1.0) sig=-20.0
! if(sig.lt.-20) sig=-20.0
ndf0=nint(df*(ipk-i0))
smax=0.
ja=jpk+16
if(ja.gt.4*nblk) ja=ja-4*nblk
jj=jpk+20
if(jj.gt.4*nblk) jj=jj-4*nblk
do i=ipk,ipk+60,2 !Find User's message length
ss=fs0(i,ja) + fs0(i+10,jj)
if(ss.gt.smax) then
smax=ss
ipk2=i
endif
enddo
msglen=(ipk2-ipk)/2
if(msglen.lt.2 .or. msglen.gt.29) cycle
if(xsync.ge.xsyncbest) then
xsyncbest=xsync
sigbest=sig
ndf0best=ndf0
msglenbest=msglen
ipkbest=ipk
jpkbest=jpk
idfbest=idf
endif
enddo
xsync=xsyncbest
sig=sigbest
ndf0=ndf0best
msglen=msglenbest
ipk=ipkbest
jpk=jpkbest
idf=idfbest
if(nafc.eq.0) idf=0
return
end subroutine synciscat

View File

@ -103,7 +103,7 @@ program test_q65
dterr=tsym/4.0
nferr=max(1,nint(0.5*baud),nint(fdop/3.0))
ndec1z=nfiles
do nsnr=ia,ib,-1
snr1=nsnr
if(ia.eq.99) snr1=snr

View File

@ -225,8 +225,7 @@ int main(int argc, char *argv[])
// disallow multiple instances with same instance key
QLockFile instance_lock {temp_dir.absoluteFilePath (a.applicationName () + ".lock")};
instance_lock.setStaleLockTime (0);
bool lock_ok {false};
while (!(lock_ok = instance_lock.tryLock ()))
while (!instance_lock.tryLock ())
{
if (QLockFile::LockFailedError == instance_lock.error ())
{
@ -249,6 +248,10 @@ int main(int argc, char *argv[])
throw std::runtime_error {"Multiple instances must have unique rig names"};
}
}
else
{
throw std::runtime_error {"Failed to access lock file"};
}
}
// load UI translations

View File

@ -19,7 +19,6 @@ namespace
"JT4",
"WSPR",
"Echo",
"ISCAT",
"MSK144",
"FreqCal",
"FT8",

View File

@ -44,7 +44,6 @@ public:
JT4,
WSPR,
Echo,
ISCAT,
MSK144,
FreqCal,
FT8,

View File

@ -1,6 +1,10 @@
set (SAMPLE_FILES
FT4/000000_000002.wav
FT8/181201_180245.wav
FST4+FST4W/210115_0058.wav
FST4+FST4W/201230_0300.wav
MSK144/181211_120500.wav
MSK144/181211_120800.wav
ISCAT/ISCAT-A/VK7MO_110401_235515.wav
ISCAT/ISCAT-B/K0AWU_100714_115000.wav
JT4/JT4A/DF2ZC_070926_040700.WAV
@ -19,9 +23,22 @@ set (SAMPLE_FILES
MSK144/181211_120800.wav
QRA64/QRA64C/161113_0111.wav
WSPR/150426_0918.wav
Q65/30A_Ionoscatter_6m/201203_022700.wav
Q65/30A_Ionoscatter_6m/201203_022800.wav
Q65/30A_Ionoscatter_6m/201203_022900.wav
Q65/30A_Ionoscatter_6m/201203_024000.wav
Q65/60A_EME_6m/210106_1621.wav
Q65/60B_1296_Troposcatter/210109_0007.wav
Q65/60B_1296_Troposcatter/210109_0147.wav
Q65/60B_1296_Troposcatter/210109_0151.wav
Q65/60D_EME_10GHz/201212_1838.wav
Q65/120D_Rainscatter_10_GHz/210117_0920.wav
Q65/120E_Ionoscatter_6m/210130_1438.wav
Q65/120E_Ionoscatter_6m/210130_1442.wav
Q65/300A_Optical_Scatter/201210_0505.wav
)
set (contents_file_name contents_${WSJTX_VERSION_MAJOR}.${WSJTX_VERSION_MINOR}.json)
set (contents_file_name contents_${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.json)
set (contents_file ${CMAKE_CURRENT_BINARY_DIR}/${contents_file_name})
set (web_tree ${CMAKE_CURRENT_BINARY_DIR}/web)
set_source_files_properties (${contents_file} PROPERTIES GENERATED ON)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More