Tagging WSJT-X v2.4.0 Release Candidate two
-----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEUELwYiy7vDRM+hTD2GSwbR6BYY8FAmBBI9YACgkQ2GSwbR6B YY9o6gf+Lel+ypXoyWJBGVgIo8IhJLSoytXFs0aZF1uy6yQjxoeVdnjWfIV7PR/T AGRmYghiUvou+LVXgFekr6nwC2cnT+qm9b+P6+gStZxcmmLWwGSmDPw/uh73epnT NOYsK/A6pLeEXoeR93r/5gHZSHpayFm7naLq2GzaAZJIC+DZiab8quuqOK790g9H z1XI3P7imE3iNJI2ASCmZoVGJqjU9Mw07Fn8bDvQ/00yK+hmX7yWVPtKJ4oe7Z24 czCjQ7W+yZJFBjeKQ7cZnXfgHfZrEYFeCcU5k2ljPFyZ5l3CI7JK/B/BYryV5+7k PihM7K2n25h7pBS0Dx7SMqWWvm4mEw== =taXS -----END PGP SIGNATURE----- gpgsig -----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEUELwYiy7vDRM+hTD2GSwbR6BYY8FAmBBJGUACgkQ2GSwbR6B YY9/eAgAgY+/ALXG48FPIrVMNe0mjcg+Hy/zgPkUw8qMUMsNwPe1cp8ZSRMrU7zv SFzrEb61j9L07mw6dsf0isbRyGNkK8CpiMkn0kBbqmqsLcth0+n5dGC3d4uqQq55 WYG79oseXitPDYGXMgFKwwWySyUY8gYZ9hoCDUo0BROrVX6g3YR+IaY7tnQV6i1K fFb0UEMgvWrkKUbUDdsXf4zZx1htyKSWTvdwJMNUV/0xCa6kWw8DHVsYJ1DpneGf fgwavRL3y5EPEIz3QIV0ldAe7fzTCfkTphqWwldilHqqOMuLRgGJ6WdYaktNmccP Pk1dsvIUngxUx8i9az2SxAH5LYmzig== =cadP -----END PGP SIGNATURE----- Merge tag 'wsjtx-2.4.0-rc2' into develop Tagging WSJT-X v2.4.0 Release Candidate two
@ -424,7 +424,6 @@ set (wsjt_FSRCS
|
|||||||
lib/gen4.f90
|
lib/gen4.f90
|
||||||
lib/gen65.f90
|
lib/gen65.f90
|
||||||
lib/gen9.f90
|
lib/gen9.f90
|
||||||
lib/geniscat.f90
|
|
||||||
lib/genwave.f90
|
lib/genwave.f90
|
||||||
lib/ft8/genft8.f90
|
lib/ft8/genft8.f90
|
||||||
lib/qra/q65/genq65.f90
|
lib/qra/q65/genq65.f90
|
||||||
@ -456,7 +455,6 @@ set (wsjt_FSRCS
|
|||||||
lib/interleave63.f90
|
lib/interleave63.f90
|
||||||
lib/interleave9.f90
|
lib/interleave9.f90
|
||||||
lib/inter_wspr.f90
|
lib/inter_wspr.f90
|
||||||
lib/iscat.f90
|
|
||||||
lib/jplsubs.f
|
lib/jplsubs.f
|
||||||
lib/jt9fano.f90
|
lib/jt9fano.f90
|
||||||
lib/jtmsg.f90
|
lib/jtmsg.f90
|
||||||
@ -538,7 +536,6 @@ set (wsjt_FSRCS
|
|||||||
lib/sync9.f90
|
lib/sync9.f90
|
||||||
lib/sync9f.f90
|
lib/sync9f.f90
|
||||||
lib/sync9w.f90
|
lib/sync9w.f90
|
||||||
lib/synciscat.f90
|
|
||||||
lib/timf2.f90
|
lib/timf2.f90
|
||||||
lib/tweak1.f90
|
lib/tweak1.f90
|
||||||
lib/twkfreq.f90
|
lib/twkfreq.f90
|
||||||
|
@ -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.
|
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:
|
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
|
sudo sysctl -w kern.sysv.shmall=25600
|
||||||
|
|
||||||
It is important to note that these parameter settings will not survive a reboot. If you
|
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
|
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".
|
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
|
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
|
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
|
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
|
simultaneously, the shmall parameter in the sysctl.conf file needs to be modified as follows.
|
||||||
requirements and I will provide a replacement sysctl.conf to suit.
|
|
||||||
|
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
|
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
|
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.
|
on combining multiple audio interfaces which is at https://support.apple.com/en-us/HT202000.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
kern.sysv.shmmax=104857600
|
kern.sysv.shmmax=52428800
|
||||||
kern.sysv.shmmin=1
|
kern.sysv.shmmin=1
|
||||||
kern.sysv.shmmni=128
|
kern.sysv.shmmni=128
|
||||||
kern.sysv.shmseg=32
|
kern.sysv.shmseg=32
|
||||||
|
@ -16,11 +16,15 @@ namespace
|
|||||||
|
|
||||||
DecodedText::DecodedText (QString const& the_string)
|
DecodedText::DecodedText (QString const& the_string)
|
||||||
: string_ {the_string.left (the_string.indexOf (QChar::Nbsp))} // discard appended info
|
: string_ {the_string.left (the_string.indexOf (QChar::Nbsp))} // discard appended info
|
||||||
|
, clean_string_ {string_}
|
||||||
, padding_ {string_.indexOf (" ") > 4 ? 2 : 0} // allow for
|
, padding_ {string_.indexOf (" ") > 4 ? 2 : 0} // allow for
|
||||||
// seconds
|
// seconds
|
||||||
, message_ {string_.mid (column_qsoText + padding_).trimmed ()}
|
, message_ {string_.mid (column_qsoText + padding_).trimmed ()}
|
||||||
, is_standard_ {false}
|
, 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);
|
// qDebug () << "DecodedText: the_string:" << the_string << "Nbsp pos:" << the_string.indexOf (QChar::Nbsp);
|
||||||
if (message_.length() >= 1)
|
if (message_.length() >= 1)
|
||||||
{
|
{
|
||||||
|
@ -32,6 +32,7 @@ public:
|
|||||||
explicit DecodedText (QString const& message);
|
explicit DecodedText (QString const& message);
|
||||||
|
|
||||||
QString string() const { return string_; };
|
QString string() const { return string_; };
|
||||||
|
QString clean_string() const { return clean_string_; };
|
||||||
QStringList messageWords () const;
|
QStringList messageWords () const;
|
||||||
int indexOf(QString s) const { return string_.indexOf(s); };
|
int indexOf(QString s) const { return string_.indexOf(s); };
|
||||||
int indexOf(QString s, int i) const { return string_.indexOf(s,i); };
|
int indexOf(QString s, int i) const { return string_.indexOf(s,i); };
|
||||||
@ -76,6 +77,7 @@ private:
|
|||||||
column_qsoText = 22 };
|
column_qsoText = 22 };
|
||||||
|
|
||||||
QString string_;
|
QString string_;
|
||||||
|
QString clean_string_;
|
||||||
int padding_;
|
int padding_;
|
||||||
QString message_;
|
QString message_;
|
||||||
QString message0_;
|
QString message0_;
|
||||||
|
@ -576,20 +576,28 @@ void MultiSettings::impl::select_configuration (QString const& target_name)
|
|||||||
{
|
{
|
||||||
if (main_window_ && target_name != current_)
|
if (main_window_ && target_name != current_)
|
||||||
{
|
{
|
||||||
|
bool changed {false};
|
||||||
{
|
{
|
||||||
auto const& current_group = settings_.group ();
|
auto const& current_group = settings_.group ();
|
||||||
if (current_group.size ()) settings_.endGroup ();
|
if (current_group.size ()) settings_.endGroup ();
|
||||||
// position to the alternative settings
|
// position to the alternative settings
|
||||||
SettingsGroup alternatives {&settings_, multi_settings_root_group};
|
SettingsGroup alternatives {&settings_, multi_settings_root_group};
|
||||||
// save the target settings
|
if (settings_.childGroups ().contains (target_name))
|
||||||
SettingsGroup target_group {&settings_, target_name};
|
{
|
||||||
new_settings_ = get_settings ();
|
changed = true;
|
||||||
|
// save the target settings
|
||||||
|
SettingsGroup target_group {&settings_, target_name};
|
||||||
|
new_settings_ = get_settings ();
|
||||||
|
}
|
||||||
if (current_group.size ()) settings_.beginGroup (current_group);
|
if (current_group.size ()) settings_.beginGroup (current_group);
|
||||||
}
|
}
|
||||||
// and set up the restart
|
if (changed)
|
||||||
current_ = target_name;
|
{
|
||||||
Q_EMIT parent_->configurationNameChanged (unescape_ampersands (current_));
|
// and set up the restart
|
||||||
restart (RepositionType::save_and_replace);
|
current_ = target_name;
|
||||||
|
Q_EMIT parent_->configurationNameChanged (unescape_ampersands (current_));
|
||||||
|
restart (RepositionType::save_and_replace);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
88
NEWS
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
__ __ ______ _____ ________ __ __
|
__ __ ______ _____ ________ __ __
|
||||||
| \ _ | \ / \ | \| \ | \ | \
|
| \ _ | \ / \ | \| \ | \ | \
|
||||||
| $$ / \ | $$| $$$$$$\ \$$$$$ \$$$$$$$$ | $$ | $$
|
| $$ / \ | $$| $$$$$$\ \$$$$$ \$$$$$$$$ | $$ | $$
|
||||||
@ -13,6 +12,91 @@
|
|||||||
Copyright 2001 - 2021 by Joe Taylor, K1JT.
|
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
|
Release: WSJT-X 2.4.0-rc1
|
||||||
Feb 3, 2021
|
Feb 3, 2021
|
||||||
-------------------------
|
-------------------------
|
||||||
@ -351,7 +435,7 @@ prior v2.2.0 release. Here is a brief summary;
|
|||||||
|
|
||||||
- Italian UI translation, tnx Marco, PY1ZRJ.
|
- 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
|
Release: WSJT-X 2.2
|
||||||
|
@ -9,10 +9,94 @@
|
|||||||
\$$ \$$ \$$$$$$ \$$$$$$ \$$ \$$ \$$
|
\$$ \$$ \$$$$$$ \$$$$$$ \$$ \$$ \$$
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Copyright 2001 - 2021 by Joe Taylor, K1JT.
|
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
|
Release: WSJT-X 2.4.0-rc1
|
||||||
Feb 3, 2021
|
Feb 3, 2021
|
||||||
-------------------------
|
-------------------------
|
||||||
@ -352,7 +436,7 @@ prior v2.2.0 release. Here is a brief summary;
|
|||||||
|
|
||||||
- Italian UI translation, tnx Marco, PY1ZRJ.
|
- 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
|
Release: WSJT-X 2.2
|
||||||
|
@ -117,7 +117,7 @@ SampleDownloader::impl::impl (QSettings * settings
|
|||||||
main_layout_.addLayout (&left_layout_, 0, 0);
|
main_layout_.addLayout (&left_layout_, 0, 0);
|
||||||
main_layout_.addWidget (&button_box_, 0, 1);
|
main_layout_.addWidget (&button_box_, 0, 1);
|
||||||
main_layout_.addWidget (&details_widget_, 1, 0, 1, 2);
|
main_layout_.addWidget (&details_widget_, 1, 0, 1, 2);
|
||||||
main_layout_.setRowStretch (1, 2);
|
main_layout_.setRowStretch (0, 2);
|
||||||
setLayout (&main_layout_);
|
setLayout (&main_layout_);
|
||||||
|
|
||||||
connect (&button_box_, &QDialogButtonBox::clicked, this, &SampleDownloader::impl::button_clicked);
|
connect (&button_box_, &QDialogButtonBox::clicked, this, &SampleDownloader::impl::button_clicked);
|
||||||
|
@ -49,6 +49,8 @@ Directory::Directory (Configuration const * configuration
|
|||||||
|
|
||||||
setColumnCount (2);
|
setColumnCount (2);
|
||||||
setHeaderLabels ({tr ("File"), tr ("Progress")});
|
setHeaderLabels ({tr ("File"), tr ("Progress")});
|
||||||
|
headerItem ()->setTextAlignment (0, Qt::AlignHCenter);
|
||||||
|
headerItem ()->setTextAlignment (1, Qt::AlignHCenter);
|
||||||
header ()->setSectionResizeMode (QHeaderView::ResizeToContents);
|
header ()->setSectionResizeMode (QHeaderView::ResizeToContents);
|
||||||
setItemDelegate (&item_delegate_);
|
setItemDelegate (&item_delegate_);
|
||||||
|
|
||||||
@ -294,14 +296,15 @@ void Directory::update (QTreeWidgetItem * item)
|
|||||||
int counted {0};
|
int counted {0};
|
||||||
|
|
||||||
// get the count, progress and size of children
|
// 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
|
// estimate size of items not yet downloaded as average of
|
||||||
// those actually present
|
// those actually present
|
||||||
if (counted)
|
// if (counted)
|
||||||
{
|
// {
|
||||||
max += (items - counted) * max / counted;
|
// max += (items - counted) * max / counted;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// save as our progress
|
// save as our progress
|
||||||
item->setData (1, Qt::UserRole, max);
|
item->setData (1, Qt::UserRole, max);
|
||||||
|
@ -14,28 +14,42 @@ void DirectoryDelegate::paint (QPainter * painter, QStyleOptionViewItem const& o
|
|||||||
{
|
{
|
||||||
if (1 == index.column ())
|
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 ();
|
auto progress = index.data ().toLongLong ();
|
||||||
|
qint64 percent;
|
||||||
if (progress > 0)
|
if (progress > 0)
|
||||||
{
|
{
|
||||||
auto percent = int (progress * 100 / index.data (Qt::UserRole).toLongLong ());
|
percent = int (progress * 100 / index.data (Qt::UserRole).toLongLong ());
|
||||||
progress_bar_option.progress = percent;
|
}
|
||||||
progress_bar_option.text = QString::number (percent) + '%';
|
#if !defined (Q_OS_DARWIN)
|
||||||
progress_bar_option.textVisible = true;
|
QStyleOptionProgressBar progress_option;
|
||||||
progress_bar_option.textAlignment = Qt::AlignCenter;
|
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
|
else
|
||||||
{
|
{
|
||||||
// not started
|
// 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
|
else
|
||||||
{
|
{
|
||||||
|
@ -27,7 +27,12 @@ FileNode::FileNode (QTreeWidgetItem * parent
|
|||||||
|
|
||||||
void FileNode::error (QString const& title, QString const& message)
|
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)
|
bool FileNode::sync (bool local)
|
||||||
|
@ -436,7 +436,11 @@ HamlibTransceiver::HamlibTransceiver (logger_type * logger,
|
|||||||
{
|
{
|
||||||
m_->set_conf ("ptt_type", "RTS");
|
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,
|
HamlibTransceiver::HamlibTransceiver (logger_type * logger,
|
||||||
@ -453,51 +457,6 @@ HamlibTransceiver::HamlibTransceiver (logger_type * logger,
|
|||||||
|
|
||||||
// m_->rig_->state.obj = this;
|
// 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_)
|
if (!m_->is_dummy_)
|
||||||
{
|
{
|
||||||
switch (rig_get_caps_int (m_->model_, RIG_CAPS_PORT_TYPE))
|
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_type", "RTS");
|
||||||
}
|
}
|
||||||
|
m_->set_conf ("ptt_share", "1");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make Icom CAT split commands less glitchy
|
// Make Icom CAT split commands less glitchy
|
||||||
m_->set_conf ("no_xchg", "1");
|
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
|
// 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);
|
// rig_set_freq_callback (m_->rig_.data (), &frequency_change_callback, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
HamlibTransceiver::~HamlibTransceiver () = default;
|
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 ()
|
int HamlibTransceiver::do_start ()
|
||||||
{
|
{
|
||||||
CAT_TRACE ("starting: " << rig_get_caps_cptr (m_->model_, RIG_CAPS_MFG_NAME_CPTR)
|
CAT_TRACE ("starting: " << rig_get_caps_cptr (m_->model_, RIG_CAPS_MFG_NAME_CPTR)
|
||||||
|
@ -24,6 +24,7 @@ public:
|
|||||||
~HamlibTransceiver ();
|
~HamlibTransceiver ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void load_user_settings ();
|
||||||
int do_start () override;
|
int do_start () override;
|
||||||
void do_stop () override;
|
void do_stop () override;
|
||||||
void do_frequency (Frequency, MODE, bool no_ignore) override;
|
void do_frequency (Frequency, MODE, bool no_ignore) override;
|
||||||
|
108
UnitTests.txt
@ -5,23 +5,37 @@ RxFreq: 1000/10
|
|||||||
|
|
||||||
Commit No_AP MyCall BothCalls
|
Commit No_AP MyCall BothCalls
|
||||||
-----------------------------------------------
|
-----------------------------------------------
|
||||||
ef4787: 3 10 6 14 30 33
|
767f53: 1 1 5 116 6 10 85 21 32 59 RC1
|
||||||
ada5a6: 3 6 6 10 29 36
|
767f53: 2 2 7 301 6 10 241 21 33 168
|
||||||
10f574: 2 7 97.6 6 10 95.4 21 33 80.7
|
767f53: 3 2 7 334 6 10 283 21 33 194
|
||||||
b8ea4c: 2 7 100.5 6 10 96.9 21 33 81.0
|
|
||||||
|
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
|
Mode: Q65-30A
|
||||||
Data: 30A_N0AN_6m_Ionoscatter (69 files, 6m ionoscatter)
|
Data: 30A_N0AN_6m_Ionoscatter (69 files, 6m ionoscatter)
|
||||||
Message: "N0AN K1JT -19"
|
Message: "N0AN K1JT -19"
|
||||||
RxFreq: 1500/10
|
RxFreq: 1500/10
|
||||||
|
|
||||||
Commit No_AP MyCall BothCalls
|
Commit No_AP MyCall BothCalls
|
||||||
------------------------------------------------
|
-----------------------------------------------
|
||||||
ef4787: 7 14 16 22 38 40
|
767f53: 1 8 16 76 15 23 70 33 42 48
|
||||||
70a348: 38 43
|
767f53: 2 10 16 225 15 24 217 34 44 134
|
||||||
ada5a6: 10 17 11 23 40 46
|
767f53: 3 10 16 266 15 24 260 34 44 155
|
||||||
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
|
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
|
Mode: Q65-60B
|
||||||
Data: 60B_1296_Troposcatter (75 files)
|
Data: 60B_1296_Troposcatter (75 files)
|
||||||
@ -30,10 +44,18 @@ RxFreq: 1000/10
|
|||||||
|
|
||||||
Commit No_AP MyCall BothCalls
|
Commit No_AP MyCall BothCalls
|
||||||
--------------------------------------------------
|
--------------------------------------------------
|
||||||
ef4787: 1 2 11 23 64 67
|
767f53: 1 1 5 115 12 27 105 68 69 22 RC1
|
||||||
ada5a6: 1 5 14 28 64 67
|
767f53: 2 1 5 322 12 28 304 65 67 53
|
||||||
10f574: 1 5 142.7 11 27 129.8 65 67 36.8
|
767f53: 3 1 5 401 12 28 354 65 67 63
|
||||||
b8ea4c: 1 5 144.3 11 27 132.2 65 67 39.3
|
|
||||||
|
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
|
Mode: Q65-60D
|
||||||
Data: MsgAvg (22 files, simulated fDop = 50 Hz)
|
Data: MsgAvg (22 files, simulated fDop = 50 Hz)
|
||||||
@ -42,10 +64,17 @@ RxFreq: 1000/10
|
|||||||
|
|
||||||
Commit No_AP MyCall BothCalls
|
Commit No_AP MyCall BothCalls
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
ef4787: 0 10 21 21 22 22
|
767f53: 1 0 11 39 19 19 28 22 22 7
|
||||||
ada5a6 0 11 21 21 22 22
|
767f53: 2 0 11 103 21 21 70 22 22 7
|
||||||
10f574: 0 11 47.7 21 21 33.9 22 22 11.6
|
767f53: 3 0 11 106 21 21 73 22 22 7
|
||||||
b8ea4c: 0 11 46.4 21 21 33.8 22 22 11.9
|
|
||||||
|
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
|
Mode: Q65-60D
|
||||||
Data: 60D_2 (21 files, 1296 troposcatter)
|
Data: 60D_2 (21 files, 1296 troposcatter)
|
||||||
@ -54,18 +83,36 @@ RxFreq: 1000/20
|
|||||||
|
|
||||||
Commit No_AP MyCall BothCalls
|
Commit No_AP MyCall BothCalls
|
||||||
----------------------------------------------
|
----------------------------------------------
|
||||||
10f574: 5 5 33.6 7 8 31.8 12 14 25.1
|
767f53: 1 2 4 36 6 8 35 13 14 22
|
||||||
b8ea4v: 5 5 39.1 7 8 38.0 13 14 30.8
|
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
|
Mode: Q65-120D
|
||||||
Data: 120D (14 files, 10 GHz troposcatter)
|
Data: 120D (14 files, 10 GHz troposcatter)
|
||||||
Message: "VK7MO VK3WE QF32"
|
Message: "VK7MO VK3WE QF32", "VK7MO VK3WE R-18"
|
||||||
RxFreq: 1000/20
|
RxFreq: 1000/20
|
||||||
|
|
||||||
Commit No_AP MyCall BothCalls
|
Commit No_AP MyCall BothCalls
|
||||||
----------------------------------------------
|
----------------------------------------------
|
||||||
10f574: 0 0 24.9 0 0 25.0 1 4 25.0
|
767f53: 1 0 0 33 0 0 34 1 5 31 RC1
|
||||||
b8ea4v: 0 0 39.1 0 0 25.4 1 5 40.1
|
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
|
Mode: Q65-60D
|
||||||
Data: 60D_10_GHz_EME (14 files)
|
Data: 60D_10_GHz_EME (14 files)
|
||||||
@ -74,5 +121,14 @@ RxFreq: 1000/50
|
|||||||
|
|
||||||
Commit No_AP MyCall BothCalls
|
Commit No_AP MyCall BothCalls
|
||||||
----------------------------------------------
|
----------------------------------------------
|
||||||
10f574: 9 10 13.6 10 11 12.7 14 14 7.1
|
767f53: 1 8 9 13 9 10 12 14 14 6 RC1
|
||||||
b8ea4v: 9 10 13.7 10 11 12.6 14 14 7.5
|
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
|
||||||
|
@ -192,7 +192,7 @@ WSJTXLogging::WSJTXLogging ()
|
|||||||
(
|
(
|
||||||
sinks::file::make_collector
|
sinks::file::make_collector
|
||||||
(
|
(
|
||||||
keywords::max_size = 40 * 1024 * 1024
|
keywords::max_size = 5 * 1024 * 1024
|
||||||
, keywords::min_free_space = 1024 * 1024 * 1024
|
, keywords::min_free_space = 1024 * 1024 * 1024
|
||||||
, keywords::max_files = 12
|
, keywords::max_files = 12
|
||||||
, keywords::target = app_data.absoluteFilePath ("logs").toStdWString ()
|
, keywords::target = app_data.absoluteFilePath ("logs").toStdWString ()
|
||||||
|
@ -10,8 +10,7 @@ JT9/VHF 1111101010001111100100000000000000000
|
|||||||
JT9+JT65 1110100000011110000100000000000010000
|
JT9+JT65 1110100000011110000100000000000010000
|
||||||
JT65 1110100000001110000100000000000010000
|
JT65 1110100000001110000100000000000010000
|
||||||
JT65/VHF 1111100100001101101011000100000000000
|
JT65/VHF 1111100100001101101011000100000000000
|
||||||
QRA64 1111100101101101100000000010000000000
|
Q65 1111110101101101001110000001000000001
|
||||||
Q65 1111110101101101001110000011000000001
|
|
||||||
ISCAT 1001110000000001100000000000000000000
|
ISCAT 1001110000000001100000000000000000000
|
||||||
MSK144 1011111101000000000100010000000000000
|
MSK144 1011111101000000000100010000000000000
|
||||||
WSPR 0000000000000000010100000000000000000
|
WSPR 0000000000000000010100000000000000000
|
||||||
|
@ -166,9 +166,9 @@ function (document)
|
|||||||
COMMAND ${ASCIIDOCTOR_EXECUTABLE} ${_args_ASCIIDOCTOR_OPTIONS}
|
COMMAND ${ASCIIDOCTOR_EXECUTABLE} ${_args_ASCIIDOCTOR_OPTIONS}
|
||||||
-b html5
|
-b html5
|
||||||
-a nofooter
|
-a nofooter
|
||||||
-a VERSION_MAJOR=${WSJTX_VERSION_MAJOR}
|
-a VERSION_MAJOR=${PROJECT_VERSION_MAJOR}
|
||||||
-a VERSION_MINOR=${WSJTX_VERSION_MINOR}
|
-a VERSION_MINOR=${PROJECT_VERSION_MINOR}
|
||||||
-a VERSION_PATCH=${WSJTX_VERSION_PATCH}
|
-a VERSION_PATCH=${PROJECT_VERSION_PATCH}
|
||||||
-a VERSION=${wsjtx_VERSION}
|
-a VERSION=${wsjtx_VERSION}
|
||||||
--out-file=${_html_file} ${_source_name}
|
--out-file=${_html_file} ${_source_name}
|
||||||
DEPENDS ${_args_DEPENDS}
|
DEPENDS ${_args_DEPENDS}
|
||||||
@ -195,9 +195,9 @@ function (document)
|
|||||||
COMMAND ${ASCIIDOCTOR_EXECUTABLE} ARGS ${_args_ASCIIDOCTOR_OPTIONS}
|
COMMAND ${ASCIIDOCTOR_EXECUTABLE} ARGS ${_args_ASCIIDOCTOR_OPTIONS}
|
||||||
-b docbook
|
-b docbook
|
||||||
-a data-uri!
|
-a data-uri!
|
||||||
-a VERSION_MAJOR=${WSJTX_VERSION_MAJOR}
|
-a VERSION_MAJOR=${wsjtx_VERSION_MAJOR}
|
||||||
-a VERSION_MINOR=${WSJTX_VERSION_MINOR}
|
-a VERSION_MINOR=${wsjtx_VERSION_MINOR}
|
||||||
-a VERSION_PATCH=${WSJTX_VERSION_PATCH}${BUILD_TYPE_REVISION}
|
-a VERSION_PATCH=${wsjtx_VERSION_PATCH}${BUILD_TYPE_REVISION}
|
||||||
-a VERSION=${wsjtx_VERSION}
|
-a VERSION=${wsjtx_VERSION}
|
||||||
-D ${CMAKE_CURRENT_BINARY_DIR}
|
-D ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
-o ${_docbook_file} ${_source_name}
|
-o ${_docbook_file} ${_source_name}
|
||||||
|
@ -27,9 +27,10 @@ our work under terms of the GNU General Public License must display
|
|||||||
the following copyright notice prominently:
|
the following copyright notice prominently:
|
||||||
|
|
||||||
*The algorithms, source code, look-and-feel of _{prog}_ and related
|
*The algorithms, source code, look-and-feel of _{prog}_ and related
|
||||||
programs, and protocol specifications for the modes FSK441, FT4, FT8,
|
programs, and protocol specifications for the modes FSK441, FST4,
|
||||||
JT4, JT6M, JT9, JT65, JTMS, QRA64, ISCAT, and MSK144 are Copyright (C)
|
FST4W, FT4, FT8, JT4, JT6M, JT9, JT44, JT65, JTMS, Q65, QRA64, ISCAT,
|
||||||
2001-2020 by one or more of the following authors: Joseph Taylor,
|
and MSK144 are Copyright (C) 2001-2021 by one or more of the following
|
||||||
K1JT; Bill Somerville, G4WJS; Steven Franke, K9AN; Nico Palermo,
|
authors: Joseph Taylor, K1JT; Bill Somerville, G4WJS; Steven Franke,
|
||||||
IV3NWV; Greg Beam, KI7MT; Michael Black, W9MDB; Edson Pereira, PY2SDR;
|
K9AN; Nico Palermo, IV3NWV; Greg Beam, KI7MT; Michael Black, W9MDB;
|
||||||
Philip Karn, KA9Q; and other members of the WSJT Development Group.*
|
Edson Pereira, PY2SDR; Philip Karn, KA9Q; and other members of the
|
||||||
|
WSJT Development Group.*
|
||||||
|
@ -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]
|
:sourceforge-jtsdk: https://sourceforge.net/projects/jtsdk[SourceForge JTSDK]
|
||||||
:ubuntu_sdk: https://launchpad.net/~ubuntu-sdk-team/+archive/ppa[Ubuntu SDK Notice]
|
: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]
|
: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]
|
: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_1h.msi[Win64 OpenSSL Light Package]
|
:win64_openssl: https://slproweb.com/download/Win64OpenSSL_Light-1_1_1j.msi[Win64 OpenSSL Light Package]
|
||||||
:writelog: https://writelog.com/[Writelog]
|
:writelog: https://writelog.com/[Writelog]
|
||||||
:wsjtx_group: https://groups.io/g/WSJTX[WSJTX Group]
|
:wsjtx_group: https://groups.io/g/WSJTX[WSJTX Group]
|
||||||
:wsjtx: https://physics.princeton.edu/pulsar/K1JT/wsjtx.html[WSJT-X]
|
:wsjtx: https://physics.princeton.edu/pulsar/K1JT/wsjtx.html[WSJT-X]
|
||||||
|
@ -42,7 +42,7 @@ control. The *Sync* control sets a minimum threshold for establishing
|
|||||||
time and frequency synchronization with a received signal.
|
time and frequency synchronization with a received signal.
|
||||||
|
|
||||||
* Spinner control *T/R xx s* sets sequence lengths for transmission
|
* 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
|
* With *Split operation* activated on the *File -> Settings -> Radio* tab, in
|
||||||
MSK144 and the fast JT9 submodes you can activate the spinner control
|
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
|
* Checkboxes at bottom center of the main window control special
|
||||||
features for particular operating modes:
|
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
|
** *Fast* enables fast JT9 submodes
|
||||||
|
|
||||||
@ -69,4 +69,5 @@ features for particular operating modes:
|
|||||||
** *Call 1st* enables automatic response to the first decoded
|
** *Call 1st* enables automatic response to the first decoded
|
||||||
responder to your CQ
|
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
|
@ -37,6 +37,12 @@ examples for configurations `FT8` and `Echo`:
|
|||||||
==== View Menu
|
==== View Menu
|
||||||
image::view-menu.png[align="left",alt="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]]
|
||||||
==== Mode Menu
|
==== Mode Menu
|
||||||
image::mode-menu.png[align="left",alt="Mode Menu"]
|
image::mode-menu.png[align="left",alt="Mode Menu"]
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
// Status=edited
|
// Status=edited
|
||||||
|
|
||||||
Two arrangements of controls are provided for generating and selecting
|
Controls familiar to users of program _WSJT_ appear on *Tab 1*,
|
||||||
Tx messages. Controls familiar to users of program _WSJT_
|
providing six fields for message entry. Pre-formatted messages for
|
||||||
appear on *Tab 1*, providing six fields for message entry.
|
the standard minimal QSO are generated when you click *Generate Std
|
||||||
Pre-formatted messages for the standard minimal QSO are generated when
|
Msgs* or double-click on an appropriate line in one of the decoded
|
||||||
you click *Generate Std Msgs* or double-click on an appropriate line
|
text windows.
|
||||||
in one of the decoded text windows.
|
|
||||||
|
|
||||||
//.Traditional Message Menu
|
//.Traditional Message Menu
|
||||||
image::traditional-msg-box.png[align="center",alt="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
|
Pressing *Enter* on a modified message #5 automatically adds that
|
||||||
message to the stored macros.
|
message to the stored macros.
|
||||||
|
|
||||||
* In some circumstances it may be desirable to make your QSOs as
|
* In some circumstances it may be desirable to make your QSOs as short
|
||||||
short as possible. To configure the program to start contacts with
|
as possible. To configure the program to start contacts with message
|
||||||
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
|
#2, disable message #1 by double-clicking its radio-button in the
|
||||||
rather than RRR for message #4, double-click one of its buttons.
|
*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
|
||||||
The second arrangement of controls for generating and selecting
|
buttons.
|
||||||
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.
|
|
||||||
|
|
||||||
+
|
+
|
||||||
|
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
=== AP Decoding
|
=== 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
|
procedures that use naturally accumulating information during a
|
||||||
minimal QSO. This _a priori_ (AP) information increases sensitivity
|
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
|
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
|
false decodes. AP is optional in FT8 and JT65, but is always enabled
|
||||||
enabled for FT4.
|
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
|
For example: when you decide to answer a CQ, you already know your own
|
||||||
callsign and that of your potential QSO partner. The software
|
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.
|
hypothetically known information.
|
||||||
|
|
||||||
[[FT8_AP_INFO_TABLE]]
|
[[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"]
|
[width="35%",cols="h10,<m20",frame=topbot,options="header"]
|
||||||
|===============================================
|
|===============================================
|
||||||
|aP | Message components
|
|aP | Message components
|
||||||
@ -47,7 +47,9 @@ forwarded to {pskreporter}.
|
|||||||
|
|
||||||
Table 2 lists the six possible QSO states that are tracked by the
|
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
|
_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]]
|
[[FT8_AP_DECODING_TYPES_TABLE]]
|
||||||
.FT4 and FT8 AP decoding types for each QSO state
|
.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"]
|
[width="50%",cols="h,3*^",frame=topbot,options="header"]
|
||||||
|===========================================
|
|===========================================
|
||||||
|Mode |Mode character|Sync character|End of line information
|
|Mode |Mode character|Sync character|End of line information
|
||||||
|
|FST4 | ` | | ?   aP
|
||||||
|FT4 | ~ | | ?   aP
|
|FT4 | ~ | | ?   aP
|
||||||
|FT8 | ~ | | ?   aP
|
|FT8 | ~ | | ?   aP
|
||||||
|JT4 | $ | *, # | f, fN, dCN
|
|JT4 | $ | *, # | f, fN, dCN
|
||||||
|JT9 | @ | |
|
|JT9 | @ | |
|
||||||
|JT65 | # | |
|
|JT65 | # | |
|
||||||
|JT65 VHF| # | *, # | f, fN, dCN
|
|JT65 VHF| # | *, # | f, fN, dCN
|
||||||
|QRA64 | : | * | R
|
|Q65 | : | | qP
|
||||||
|ISCAT | | * | M N C T
|
|
||||||
|MSK144 | & | |
|
|MSK144 | & | |
|
||||||
|===========================================
|
|===========================================
|
||||||
Sync character::
|
Sync character::
|
||||||
@ -126,32 +128,20 @@ Sync character::
|
|||||||
End of line information::
|
End of line information::
|
||||||
`?` - Decoded with lower confidence +
|
`?` - Decoded with lower confidence +
|
||||||
`a` - Decoded with aid of some _a priori_ (AP) information +
|
`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 +
|
`d` - Deep Search algorithm +
|
||||||
`f` - Franke-Taylor or Fano algorithm +
|
`f` - Franke-Taylor or Fano algorithm +
|
||||||
`M` - Message length (characters) +
|
|
||||||
`N` - Number of Rx intervals or frames averaged +
|
`N` - Number of Rx intervals or frames averaged +
|
||||||
`P` - Number indicating type of AP information (Table 1, above) +
|
`P` - Number indicating type of AP information (Table 1 or Table 6) +
|
||||||
`R` - Return code from QRA64 decoder +
|
|
||||||
`T` - Length of analyzed region (s)
|
|
||||||
|
|
||||||
Table 6 below shows the meaning of the return codes R in QRA64 mode.
|
[[Q65_AP_INFO_TABLE]]
|
||||||
|
.Q65 end-of-line codes
|
||||||
[[QRA64_AP_INFO_TABLE]]
|
[width="45%",cols="h10,<m20",frame=topbot,options="header"]
|
||||||
.QRA64 AP return codes
|
|
||||||
[width="35%",cols="h10,<m20",frame=topbot,options="header"]
|
|
||||||
|===============================================
|
|===============================================
|
||||||
|rc | Message components
|
| | Message components
|
||||||
|0 | ?     ?     ?
|
|q0 | ?     ?     ?
|
||||||
|1 | CQ     ?     ?
|
|q1 | CQ     ?     ?
|
||||||
|2 | CQ     ?
|
|q2 | MyCall     ?     ?
|
||||||
|3 | MyCall     ?     ?
|
|q3 | MyCall DxCall     ?
|
||||||
|4 | MyCall     ?
|
|q4 | MyCall DxCall     [<blank> \| RRR \| RR73 \| 73]
|
||||||
|5 | MyCall DxCall     ?
|
|
||||||
|6 | ?     DxCall     ?
|
|
||||||
|7 | ?     DxCall
|
|
||||||
|8 | MyCall DxCall DxGrid
|
|
||||||
|9 | CQ DxCall     ?
|
|
||||||
|10 | CQ DxCall
|
|
||||||
|11 | CQ DxCall DxGrid
|
|
||||||
|===============================================
|
|===============================================
|
||||||
|
Before Width: | Height: | Size: 230 KiB After Width: | Height: | Size: 134 KiB |
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 5.9 KiB |
BIN
doc/user_guide/en/images/FST4-1.png
Normal file
After Width: | Height: | Size: 477 KiB |
BIN
doc/user_guide/en/images/FST4W-1.png
Normal file
After Width: | Height: | Size: 389 KiB |
Before Width: | Height: | Size: 161 KiB After Width: | Height: | Size: 175 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 8.7 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 98 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 5.5 KiB |
@ -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
|
2001. Bill Somerville, G4WJS, and Steve Franke, K9AN, have been major
|
||||||
contributors to development of _WSJT-X_ since 2013 and 2015, respectively.
|
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*,
|
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
|
first seven are designed for making reliable QSOs under weak-signal
|
||||||
conditions. They use nearly identical message structure and source
|
conditions. They use nearly identical message structure and source
|
||||||
encoding. JT65 and QRA64 were designed for EME ("`moonbounce`") on
|
encoding. JT65 was designed for EME ("`moonbounce`") on VHF and
|
||||||
the VHF/UHF bands and have also proven very effective for worldwide
|
higher bands and is mostly used for that purpose today. Q65 replaces
|
||||||
QRP communication on the HF bands. QRA64 has some advantages over
|
an earlier mode, QRA64. Q65 is particularly effective for tropospheric
|
||||||
JT65, including better performance for EME on the higher microwave
|
scatter, rain scatter, ionospheric scatter, TEP, and EME on VHF and
|
||||||
bands. JT9 was originally designed for the HF and lower bands. Its
|
higher bands, as well as other types of fast-fading signals. JT9 was
|
||||||
submode JT9A is 1 dB more sensitive than JT65 while using less than
|
originally designed for the HF and lower bands. Its submode JT9A is 1
|
||||||
10% of the bandwidth. JT4 offers a wide variety of tone spacings and
|
dB more sensitive than JT65 while using less than 10% of the
|
||||||
has proven highly effective for EME on microwave bands up to 24 GHz.
|
bandwidth. JT4 offers a wide variety of tone spacings and has proven
|
||||||
These four "`slow`" modes use one-minute timed sequences of
|
highly effective for EME on microwave bands up to 24 GHz. These four
|
||||||
alternating transmission and reception, so a minimal QSO takes four to
|
"`slow`" modes use one-minute timed sequences of alternating
|
||||||
six minutes — two or three transmissions by each station, one sending
|
transmission and reception, so a minimal QSO takes four to six minutes
|
||||||
in odd UTC minutes and the other even. FT8 is operationally similar
|
— two or three transmissions by each station, one sending in odd UTC
|
||||||
but four times faster (15-second T/R sequences) and less sensitive by
|
minutes and the other even. FT8 is operationally similar but four
|
||||||
a few dB. FT4 is faster still (7.5 s T/R sequences) and especially
|
times faster (15-second T/R sequences) and less sensitive by a few dB.
|
||||||
well-suited for radio contesting. FST4 was added to _WSJT-X_ in
|
FT4 is faster still (7.5 s T/R sequences) and especially well-suited
|
||||||
version 2.3.0. It is intended especially for use on the LF and MF
|
for radio contesting. FST4 was added to _WSJT-X_ in version 2.3.0.
|
||||||
bands, and already during its first few months of testing
|
It is intended especially for use on the LF and MF bands, and already
|
||||||
intercontinental paths have been spanned many times on the 2200 and
|
during its first few months of testing intercontinental paths have
|
||||||
630 m bands. Further details can be found in the following section,
|
been spanned many times on the 2200 and 630 m bands. Further details
|
||||||
<<NEW_FEATURES,New Features in Version 2.3.0>>. On the HF bands,
|
can be found in the following section, <<NEW_FEATURES,New Features in
|
||||||
world-wide QSOs are possible with any of these modes using power
|
Version 2.4.0>>. On the HF bands, world-wide QSOs are possible with
|
||||||
levels of a few watts (or even milliwatts) and compromise antennas.
|
any of these modes using power levels of a few watts (or even
|
||||||
On VHF bands and higher, QSOs are possible (by EME and other
|
milliwatts) and compromise antennas. On VHF bands and higher, QSOs
|
||||||
propagation types) at signal levels 10 to 15 dB below those required
|
are possible (by EME, scatter, and other propagation types) at signal
|
||||||
for CW.
|
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
|
protocols designed to take advantage of brief signal enhancements from
|
||||||
ionized meteor trails, aircraft scatter, and other types of scatter
|
ionized meteor trails, aircraft scatter, and other types of scatter
|
||||||
propagation. These modes use timed sequences of 5, 10, 15, or 30 s
|
propagation. These modes use timed sequences of 5, 10, 15, or 30 s
|
||||||
duration. User messages are transmitted repeatedly at high rate (up
|
duration. User messages are transmitted repeatedly at high rate (up
|
||||||
to 250 characters per second for MSK144) to make good use of the
|
to 250 characters per second for MSK144) to make good use of the
|
||||||
shortest meteor-trail reflections or "`pings`". ISCAT uses free-form
|
shortest meteor-trail reflections or "`pings`". MSK144 uses the same
|
||||||
messages up to 28 characters long, while MSK144 uses the same
|
|
||||||
structured messages as the slow modes and optionally an abbreviated
|
structured messages as the slow modes and optionally an abbreviated
|
||||||
format with hashed callsigns.
|
format with hashed callsigns.
|
||||||
|
|
||||||
|
@ -60,12 +60,10 @@ or rag-chewing.
|
|||||||
|
|
||||||
=== Auto-Sequencing
|
=== Auto-Sequencing
|
||||||
|
|
||||||
The 15-second T/R cycles of FT8 allow only about two seconds to inspect
|
The T/R cycles of many _WSJT-X_ modes allow only a few seconds to
|
||||||
decoded messages and decide how to reply, which is often not enough.
|
inspect decoded messages and decide how to reply. Often this is not
|
||||||
The slow modes JT4, JT9, JT65, and QRA64 allow nearly 10 seconds
|
enough time, so for FST4, FT4, FT8, MSK144, and Q65 the program
|
||||||
for this task, but operators may find that this is still insufficient
|
offers a basic auto-sequencing feature.
|
||||||
when workload is high, especially on EME. For these reasons a basic
|
|
||||||
auto-sequencing feature is offered.
|
|
||||||
|
|
||||||
Check *Auto Seq* on the main window to enable this 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*
|
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
|
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_MSGS]]
|
||||||
=== Contest Messages
|
=== Contest Messages
|
||||||
@ -160,7 +159,7 @@ guidelines for contest logging with FT4, FT8, and MSK144:
|
|||||||
[[COMP-CALL]]
|
[[COMP-CALL]]
|
||||||
=== Nonstandard Callsigns
|
=== Nonstandard Callsigns
|
||||||
|
|
||||||
*FT4, FT8, and MSK144*
|
*FST4, FT4, FT8, MSK144, and Q65*
|
||||||
|
|
||||||
Compound callsigns like xx/K1ABC or K1ABC/x and special event
|
Compound callsigns like xx/K1ABC or K1ABC/x and special event
|
||||||
callsigns like YW18FIFA are supported for normal QSOs but not for
|
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
|
prevents including your locator in standard messages, which
|
||||||
necessarily impairs the usefulness of tools like PSK Reporter.
|
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
|
In the 72-bit modes, compound callsigns are handled in one of two
|
||||||
possible ways:
|
possible ways:
|
||||||
|
@ -1,34 +1,15 @@
|
|||||||
[[NEW_FEATURES]]
|
[[NEW_FEATURES]]
|
||||||
=== New in Version {VERSION}
|
=== New in Version {VERSION}
|
||||||
|
|
||||||
_WSJT-X 2.3.0_ introduces *FST4* and *FST4W*, new digital protocols
|
_WSJT-X 2.4.0_ introduces *Q65*, a new digital protocol designed for
|
||||||
designed particularly for the LF and MF bands. Decoders for these
|
minimal two-way QSOs over especially difficult propagation paths. On
|
||||||
modes can take advantage of the very small Doppler spreads present at
|
paths with Doppler spread more than a few Hz, the weak-signal
|
||||||
these frequencies, even over intercontinental distances. As a
|
performance of Q65 is the best among all WSJT-X modes.
|
||||||
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.
|
|
||||||
|
|
||||||
The new modes use 4-GFSK modulation and share common software for
|
Q65 uses message formats and sequencing identical to those used in
|
||||||
encoding and decoding messages. FST4 offers T/R sequence lengths of
|
FST4, FT4, FT8, and MSK144. Submodes are provided with a wide variety
|
||||||
15, 30, 60, 120, 300, 900, and 1800 seconds, while FST4W omits the
|
of tone spacings and T/R sequence lengths 15, 30, 60, 120, and 300 s.
|
||||||
lengths shorter than 120 s. Submodes are given names like FST4-60,
|
A new, highly reliable list-decoding technique is used for messages
|
||||||
FST4W-300, etc., the appended numbers indicating sequence length in
|
that contain previously copied message fragments. Message averaging
|
||||||
seconds. Message payloads contain either 77 bits, as in FT4, FT8, and
|
is provided for situations where single transmissions are too weak or
|
||||||
MSK144, or 50 bits for the WSPR-like messages of FST4W. Message
|
signal enhancements too sparse for a signal to be decoded.
|
||||||
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.
|
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
[[PROTOCOL_OVERVIEW]]
|
[[PROTOCOL_OVERVIEW]]
|
||||||
=== Overview
|
=== Overview
|
||||||
|
|
||||||
All QSO modes except ISCAT use structured messages that compress
|
All QSO modes use structured messages that compress
|
||||||
user-readable information into fixed-length packets. JT4, JT9, JT65,
|
user-readable information into fixed-length packets. JT4, JT9, and JT65
|
||||||
and QRA64 use 72-bit payloads. Standard messages consist of two
|
use 72-bit payloads. Standard messages consist of two
|
||||||
28-bit fields normally used for callsigns and a 15-bit field for a
|
28-bit fields normally used for callsigns and a 15-bit field for a
|
||||||
grid locator, report, acknowledgment, or 73. An additional bit flags
|
grid locator, report, acknowledgment, or 73. An additional bit flags
|
||||||
a message containing arbitrary free text, up to 13 characters.
|
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
|
aim is to compress the most common messages used for minimally valid
|
||||||
QSOs into a fixed 72-bit length.
|
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
|
The 5 additional bits are used to flag special message types used for
|
||||||
nonstandard callsigns, contest exchanges, FT8 DXpedition Mode, and a
|
nonstandard callsigns, contest exchanges, FT8 DXpedition Mode, and a
|
||||||
few other possibilities. Full details have been published in QEX, see
|
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
|
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.
|
= 2, 3, 4 used to convey the messages RO, RRR, and 73, respectively.
|
||||||
|
|
||||||
[[QRA64_PROTOCOL]]
|
[[Q65_PROTOCOL]]
|
||||||
==== QRA64
|
==== Q65
|
||||||
|
|
||||||
QRA64 is intended for EME and other extreme weak-signal applications.
|
Q65 is intended for scatter, EME, and other extreme weak-signal
|
||||||
Its internal code was designed by IV3NWV. The protocol uses a (63,12)
|
applications. Forward error correction (FEC) uses a specially
|
||||||
**Q**-ary **R**epeat **A**ccumulate code that is inherently better
|
designed (65,15) block code with six-bit symbols. Two symbols are
|
||||||
than the Reed Solomon (63,12) code used in JT65, yielding a 1.3 dB
|
“punctured” from the code, yielding an effective (63,13) code with a
|
||||||
advantage. A new synchronizing scheme is based on three 7 x 7 Costas
|
payload of k = 13 information symbols conveyed by n = 63 channel
|
||||||
arrays. This change yields another 1.9 dB advantage.
|
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
|
For each T/R sequence length, submodes A - E have tone spacings and
|
||||||
similar to JT65. QRA64 does not use two-tone shorthand messages, and
|
occupied bandwidths 1, 2, 4, 8, and 16 times those specified in the
|
||||||
it makes no use of a callsign database. Rather, additional
|
above table. Full submode designations include a number for sequence
|
||||||
sensitivity is gained by making use of already known information as a
|
length and a letter for tone spacing, as in Q65-15A, Q65-120C, etc.
|
||||||
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.
|
|
||||||
|
|
||||||
[[WSPR_PROTOCOL]]
|
[[WSPR_PROTOCOL]]
|
||||||
==== WSPR
|
==== 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
|
|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
|
|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
|
|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
|
|JT65A |RS|(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
|
|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
|
| 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-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
|
|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
|
|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.
|
circumstances that may require them, such as significant Doppler spread.
|
||||||
Table 8 summarizes the tone spacings, bandwidths, and approximate
|
Table 8 summarizes the tone spacings, bandwidths, and approximate
|
||||||
threshold sensitivities of the various submodes when spreading is
|
threshold sensitivities of the various submodes when spreading is
|
||||||
comparable to tone spacing.
|
comparable to tone spacing.
|
||||||
|
|
||||||
[[SLOW_SUBMODES]]
|
[[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"]
|
[width="50%",cols="h,3*^",frame=topbot,options="header"]
|
||||||
|=====================================
|
|=====================================
|
||||||
|Mode |Tone Spacing |BW (Hz)|S/N (dB)
|
|Mode |Tone Spacing |BW (Hz)|S/N (dB)
|
||||||
@ -315,56 +323,22 @@ comparable to tone spacing.
|
|||||||
|JT65A |2.692| 177.6 |-25
|
|JT65A |2.692| 177.6 |-25
|
||||||
|JT65B |5.383| 352.6 |-25
|
|JT65B |5.383| 352.6 |-25
|
||||||
|JT65C |10.767| 702.5 |-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
|
.Parameters of Q65 Submodes
|
||||||
|QRA64D|13.889| 876.7 |-23
|
[width="100%",cols="h,5*^",frame=topbot,options="header"]
|
||||||
|QRA64E|27.778|1751.7 |-22
|
|=====================================
|
||||||
|
|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     4.33|13.33     867|26.67     1733|N/A|N/A
|
||||||
|
|30|3.33     217|6.67     433|13.33     867| 26.67     1733| N/A
|
||||||
|
|60|1.67     108|3.33     217|6.67     433|13.33     867|26.67     1733
|
||||||
|
|120|0.75     49|1.50     98|3.00     195|6.00     390| 12.00     780
|
||||||
|
|300|0.29     19|0.58     38|1.16     75|2.31     150|4.63     301
|
||||||
|=====================================
|
|=====================================
|
||||||
|
|
||||||
[[FAST_MODES]]
|
[[FAST_MODES]]
|
||||||
=== 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
|
==== JT9
|
||||||
|
|
||||||
The JT9 slow modes all use keying rate 12000/6912 = 1.736 baud. By contrast, with
|
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)
|
|Mode |FEC Type |(n,k) | Q|Modulation Type|Keying rate (Baud)
|
||||||
|Bandwidth (Hz)|Sync Energy|Tx Duration (s)
|
|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
|
|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
|
|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
|
|JT9G |K=32, r=1/2|(206,72)| 8| 9-FSK|100.0 | 900 | 0.19| 0.850
|
||||||
|
@ -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
|
* Check *Highlight by Mode* if you wish worked before status to be per
|
||||||
<<INTRO,mode>>.
|
<<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
|
* Worked before status is calculated from your _WSJT-X_ ADIF
|
||||||
<<LOGGING, Logging>> file, you may replace ADIF log file with one
|
<<LOGGING, Logging>> file, you may replace ADIF log file with one
|
||||||
exported from your station logging application, *Rescan ADIF Log*
|
exported from your station logging application, *Rescan ADIF Log*
|
||||||
|
@ -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
|
Failure of the CAT-control test turns the button red and displays an
|
||||||
error message. After a successful CAT test, toggle the *Test PTT*
|
error message. After a successful CAT test, toggle the *Test PTT*
|
||||||
button to confirm that your selected method of T/R control is working
|
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.)
|
switching later by using the *Tune* button on the main window.)
|
||||||
|
@ -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:
|
at the top of this file in our source code repository:
|
||||||
https://sourceforge.net/p/wsjt/wsjtx/ci/master/tree/Network/NetworkMessage.hpp
|
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
|
Programs like _JTAlert_ use the _UDP Server_ feature to obtain
|
||||||
information about running _WSJT-X_ instances. If you are using
|
information about running _WSJT-X_ instances. If you are using
|
||||||
_JTAlert_ to control _WSJT-X_, be sure to check the
|
_JTAlert_ to control _WSJT-X_, be sure to check the
|
||||||
|
@ -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
|
- You can reorder your macro messages by using drag-and-drop. The
|
||||||
new order will be preserved when _WSJT-X_ is restarted.
|
new order will be preserved when _WSJT-X_ is restarted.
|
||||||
|
|
||||||
- Messages can also be added from the main window's *Tx5* field on Tab
|
- Messages can also be added from the main window's *Tx5*
|
||||||
1 or the *Free msg* field on Tab 2. Simply hit [Enter] after the
|
field. Simply hit [Enter] after the message has been entered.
|
||||||
message has been entered.
|
|
||||||
|
@ -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.
|
conventional JT65 and JT9 sub-bands simultaneously on most HF bands.
|
||||||
Further details are provided in the <<TUTORIAL,Basic Operating
|
Further details are provided in the <<TUTORIAL,Basic Operating
|
||||||
Tutorial>>. A wider displayed bandwidth may also be helpful at VHF
|
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.
|
much wider ranges of frequencies.
|
||||||
|
|
||||||
- If you have only a standard SSB filter you won’t be able to display
|
- If you have only a standard SSB filter you won’t be able to display
|
||||||
|
@ -1,5 +1,19 @@
|
|||||||
Do not confuse FST4 with FT4, which has a very different purpose!
|
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
|
Operation with FST4 is similar to that with other _WSJT-X_ modes: most
|
||||||
on-screen controls, auto-sequencing, and other features behave in
|
on-screen controls, auto-sequencing, and other features behave in
|
||||||
familiar ways. However, operating conventions on the 2200 and 630 m
|
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
|
further limit the decoding range to the setting of *F Tol* on
|
||||||
either side of *Rx Freq*.
|
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"]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
FST4W is used in the same way as WSPR, but FST4W has significant
|
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
|
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
|
decoding range is 1400 to 1600 Hz. However, for added flexibility you
|
||||||
can select different center frequencies and *F Tol* values. We expect
|
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.
|
a fixed sequence with no two stations transmitting simultaneously.
|
||||||
Sequence 1 is the first sequence after 00:00 UTC. For WSPR-like
|
Sequence 1 is the first sequence after 00:00 UTC. For WSPR-like
|
||||||
scheduling behavior, you should select *Random* with this control.
|
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.
|
||||||
|
@ -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
|
controls in larger steps. You can also type numbers directly into
|
||||||
the spinner controls or use the mouse wheel.
|
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]]
|
||||||
=== Download Samples
|
=== Download Samples
|
||||||
|
|
||||||
|
@ -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
|
other possible JT65 message in at least 52 of the 63
|
||||||
information-carrying channel symbols.
|
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
|
Execution of any of these utility programs with "-t" as the only
|
||||||
command-line argument produces examples of all supported message
|
command-line argument produces examples of all supported message
|
||||||
types. For example, using `jt65code -t`:
|
types. For example, using `jt65code -t`:
|
||||||
|
@ -11,12 +11,11 @@ higher bands. These features include:
|
|||||||
|
|
||||||
- *JT65*, widely used for EME on VHF and higher bands
|
- *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
|
- *MSK144*, for meteor scatter
|
||||||
|
|
||||||
- *ISCAT*, for aircraft scatter and other types of scatter propagation
|
|
||||||
|
|
||||||
- *Echo* mode, for detecting and measuring your own lunar echoes
|
- *Echo* mode, for detecting and measuring your own lunar echoes
|
||||||
|
|
||||||
- *Doppler tracking*, which becomes increasingly important for EME
|
- *Doppler tracking*, which becomes increasingly important for EME
|
||||||
@ -174,55 +173,33 @@ RO, RRR, and 73.
|
|||||||
|
|
||||||
image::JT65B.png[align="center",alt="JT65B"]
|
image::JT65B.png[align="center",alt="JT65B"]
|
||||||
|
|
||||||
=== QRA64
|
=== Q65
|
||||||
|
|
||||||
QRA64 is designed for EME on VHF and higher bands; its
|
Q65 is designed for propagation paths that produce fast fading
|
||||||
operation is generally similar to JT4 and JT65. The following screen
|
signals: tropospheric scatter, rain scatter, ionospheric scatter,
|
||||||
shot shows an example of a QRA64C transmission from DL7YC recorded at
|
trans-equatorial propagation (TEP), EME, and the like. The following
|
||||||
G3WDG over the EME path at 24 GHz. Doppler spread on the path was 78
|
screen shot shows an example with submode Q65-30A on a 6-meter
|
||||||
Hz, so although the signal is reasonably strong its tones are
|
ionospheric scatter path of about 1100 km.
|
||||||
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.
|
|
||||||
|
|
||||||
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
|
takes advantage of _a priori_ (AP) information such as one's own
|
||||||
callsign and the encoded form of message word `CQ`. In normal usage,
|
callsign and the message word `CQ`. In normal usage, as a QSO
|
||||||
as a QSO progresses the available AP information increases to include
|
progresses the available AP information increases to include the
|
||||||
the callsign of the station being worked and perhaps also his/her
|
callsign of the station being worked and perhaps also his/her 4-digit
|
||||||
4-digit grid locator. The decoder always begins by attempting to
|
grid locator. The decoder takes advantage of whatever AP information
|
||||||
decode the full message using no AP information. If this attempt
|
is available.
|
||||||
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.
|
|
||||||
|
|
||||||
For EME QSOs some operators use short-form QRA64 messages consisting
|
For Q65 EME QSOs, particularly on the micriowave bands, some operators
|
||||||
of a single tone. To activate automatic generation of these messages,
|
use short-form messages consisting of a single tone. To activate
|
||||||
check the box labeled *Sh*. This also enables the generation of a
|
automatic generation of these messages, check the box labeled *Sh*.
|
||||||
single tone at 1000Hz by selecting Tx6, to assist in finding signals
|
This also enables the generation of a single tone at 1000Hz by
|
||||||
initially, as the QRA64 tones are often not visible on the waterfall.
|
selecting Tx6, to assist in finding signals initially. The box
|
||||||
The box labeled *Tx6* switches the Tx6 message from 1000Hz to 1250Hz
|
labeled *Tx6* switches the Tx6 message from 1000Hz to 1250Hz to
|
||||||
to indicate to the other station that you are ready to receive messages.
|
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
|
// TIP: G3WDG has prepared a more detailed tutorial on using {QRA64_EME}.
|
||||||
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.
|
|
||||||
|
|
||||||
=== MSK144
|
=== MSK144
|
||||||
|
|
||||||
@ -335,21 +312,28 @@ image::echo_144.png[align="center",alt="Echo 144 MHz"]
|
|||||||
|
|
||||||
=== Tips for EME
|
=== Tips for EME
|
||||||
|
|
||||||
Current conventions dictate that digital EME is usually done with
|
Until the advent of Q65, digital EME has mostly been done using JT65A
|
||||||
JT65A on the 50 MHz band, JT65B on 144 and 432 MHz, and JT65C on 1296
|
on the 50 MHz band, JT65B on 144 and 432 MHz, and JT65C on 1296 MHz.
|
||||||
MHz. On higher microwave bands typical choices are JT65C or one of
|
On higher microwave bands typical choices have been JT65C or one of
|
||||||
the wider QRA64 or JT4 submodes, depending on the expected amount of
|
the wider QRA64 or JT4 submodes, depending on the expected amount of
|
||||||
Doppler spread. JT4 and JT65 offer message *Averaging* -- the
|
Doppler spread. We now recommend a suitable submodes of Q65 for EME
|
||||||
summation of subsequent transmissions that convey the same message --
|
on all bands: for example, Q65-60A on 50 and 144 MHz, -60B on
|
||||||
to enable decodes at signal-to-noise ratios several dB below the
|
432 MHz, -60C on 1296 MHz, and -60D on 10 GHz.
|
||||||
threshold for single transmissions. These modes also allow *Deep
|
|
||||||
Search* decoding, in which the decoder hypothesizes messages
|
JT4, JT65, and Q65 offer *Message Averaging* -- the summation of
|
||||||
containing known or previously decoded callsigns and tests them for
|
subsequent transmissions that convey the same message -- to enable
|
||||||
reliability using a correlation algorithm. Finally, JT65 and QRA64
|
decodes at signal-to-noise ratios several dB below the threshold for
|
||||||
offer _a priori_ (AP) decoding, which takes advantage of naturally
|
single transmissions. JT4 and JT65 also allow *Deep Search* decoding,
|
||||||
accumulating information during a QSO. The following tutorial aims to
|
in which the decoder hypothesizes messages containing known or
|
||||||
familiarize you with these program features, all of which are of
|
previously decoded callsigns and tests them for reliability using a
|
||||||
special interest for EME and other extreme weak-signal conditions.
|
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:
|
As a starting point, configure _WSJT-X_ as follows:
|
||||||
|
|
||||||
@ -381,7 +365,7 @@ decode*, *Decode after EME delay*
|
|||||||
|
|
||||||
.Wide Graph:
|
.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
|
- Adjust the width of the window so that the frequency range extends
|
||||||
up to at least 2400 Hz.
|
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
|
options of the *Decode* menu on and off. For best sensitivity, most
|
||||||
users will want to use *Deep* decoding with *Enable averaging*,
|
users will want to use *Deep* decoding with *Enable averaging*,
|
||||||
*Enable deep search*, and *Enable AP* all turned on.
|
*Enable deep search*, and *Enable AP* all turned on.
|
||||||
|
|
||||||
|
////
|
@ -119,6 +119,15 @@ In macOS, enter the following command from a terminal:
|
|||||||
|
|
||||||
open /Applications/wsjtx.app --args -stylesheet :/qdarkstyle/style.qss
|
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
|
Depending on your operating system, the main _WSJT-X_ window will look
|
||||||
something like this:
|
something like this:
|
||||||
|
|
||||||
@ -193,7 +202,7 @@ include::wspr.adoc[]
|
|||||||
include::controls-functions-menus.adoc[]
|
include::controls-functions-menus.adoc[]
|
||||||
|
|
||||||
[[CONTROLS_MAIN]]
|
[[CONTROLS_MAIN]]
|
||||||
=== Button Row
|
=== Button Row
|
||||||
include::controls-functions-main-window.adoc[]
|
include::controls-functions-main-window.adoc[]
|
||||||
|
|
||||||
[[CONTROLS_LEFT]]
|
[[CONTROLS_LEFT]]
|
||||||
|
@ -7,7 +7,7 @@ TargetFileName="${AppLocalDataLocation}/logs/wsjtx_syslog_%Y-%m.log"
|
|||||||
RotationTimePoint="01 00:00:00"
|
RotationTimePoint="01 00:00:00"
|
||||||
Append=true
|
Append=true
|
||||||
EnableFinalRotation=false
|
EnableFinalRotation=false
|
||||||
MaxSize=41943040
|
MaxSize=52428800
|
||||||
MinFreeSpace=1073741824
|
MinFreeSpace=1073741824
|
||||||
MaxFiles=12
|
MaxFiles=12
|
||||||
Target="${AppLocalDataLocation}/logs"
|
Target="${AppLocalDataLocation}/logs"
|
||||||
|
@ -368,7 +368,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
|
|||||||
endif
|
endif
|
||||||
if(params%nmode.ne.8 .or. params%nzhsym.eq.50 .or. &
|
if(params%nmode.ne.8 .or. params%nzhsym.eq.50 .or. &
|
||||||
.not.params%ndiskdat) then
|
.not.params%ndiskdat) then
|
||||||
|
|
||||||
write(*,1010) nsynced,ndecoded,navg0
|
write(*,1010) nsynced,ndecoded,navg0
|
||||||
1010 format('<DecodeFinished>',2i4,i9)
|
1010 format('<DecodeFinished>',2i4,i9)
|
||||||
call flush(6)
|
call flush(6)
|
||||||
@ -806,7 +806,7 @@ contains
|
|||||||
|
|
||||||
select type(this)
|
select type(this)
|
||||||
type is (counting_q65_decoder)
|
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
|
end select
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -86,13 +86,6 @@ subroutine fast_decode(id2,narg,trperiod,line,mycall_12, &
|
|||||||
endif
|
endif
|
||||||
jz=ib-ia+1
|
jz=ib-ia+1
|
||||||
line(1:100)(1:1)=char(0)
|
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
|
900 return
|
||||||
end subroutine fast_decode
|
end subroutine fast_decode
|
||||||
|
@ -614,7 +614,7 @@ contains
|
|||||||
endif
|
endif
|
||||||
call this%callback(nutc,smax1,nsnr,xdt,fsig,msg, &
|
call this%callback(nutc,smax1,nsnr,xdt,fsig,msg, &
|
||||||
iaptype,qual,ntrperiod,lwspr,fmid,w50)
|
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
|
goto 800
|
||||||
endif
|
endif
|
||||||
enddo ! metrics
|
enddo ! metrics
|
||||||
|
@ -65,7 +65,8 @@ program ft4code
|
|||||||
if(i3.eq.2) msgtype="EU VHF Contest"
|
if(i3.eq.2) msgtype="EU VHF Contest"
|
||||||
if(i3.eq.3) msgtype="ARRL RTTY Roundup"
|
if(i3.eq.3) msgtype="ARRL RTTY Roundup"
|
||||||
if(i3.eq.4) msgtype="Nonstandard calls"
|
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(i3.ge.1) n3=-1
|
||||||
bad=" "
|
bad=" "
|
||||||
comment=' '
|
comment=' '
|
||||||
|
@ -64,7 +64,8 @@ program ft8code
|
|||||||
if(i3.eq.2) msgtype="EU VHF Contest"
|
if(i3.eq.2) msgtype="EU VHF Contest"
|
||||||
if(i3.eq.3) msgtype="ARRL RTTY Roundup"
|
if(i3.eq.3) msgtype="ARRL RTTY Roundup"
|
||||||
if(i3.eq.4) msgtype="Nonstandard call"
|
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
|
if(i3.ge.1) n3=-1
|
||||||
bad=" "
|
bad=" "
|
||||||
comment=' '
|
comment=' '
|
||||||
|
@ -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
|
|
206
lib/iscat.f90
@ -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
|
|
@ -206,6 +206,12 @@ program jt9
|
|||||||
go to 999
|
go to 999
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if(mycall.eq.'b') mycall=' '
|
||||||
|
if(hiscall.eq.'b') then
|
||||||
|
hiscall=' '
|
||||||
|
hisgrid=' '
|
||||||
|
endif
|
||||||
|
|
||||||
if (mode .eq. 241) then
|
if (mode .eq. 241) then
|
||||||
ntol = min (ntol, 100)
|
ntol = min (ntol, 100)
|
||||||
else if (mode .eq. 65 + 9 .and. .not. have_ntol) then
|
else if (mode .eq. 65 + 9 .and. .not. have_ntol) then
|
||||||
|
@ -51,7 +51,8 @@ program msk144code
|
|||||||
if(i3.eq.2) msgtype="EU VHF Contest"
|
if(i3.eq.2) msgtype="EU VHF Contest"
|
||||||
if(i3.eq.3) msgtype="ARRL RTTY Roundup"
|
if(i3.eq.3) msgtype="ARRL RTTY Roundup"
|
||||||
if(i3.eq.4) msgtype="Nonstandard calls"
|
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(i3.ge.1) n3=-1
|
||||||
if(i4tone(41).lt.0) then
|
if(i4tone(41).lt.0) then
|
||||||
msgtype="Sh msg"
|
msgtype="Sh msg"
|
||||||
|
@ -100,7 +100,7 @@ subroutine msk144decodeframe(c,softbits,msgreceived,nsuccess)
|
|||||||
nsuccess=1
|
nsuccess=1
|
||||||
write(c77,'(77i1)') decoded77
|
write(c77,'(77i1)') decoded77
|
||||||
read(c77(72:77),'(2b3)') n3,i3
|
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
|
nsuccess=0
|
||||||
else
|
else
|
||||||
call unpack77(c77,1,msgreceived,unpk77_success)
|
call unpack77(c77,1,msgreceived,unpk77_success)
|
||||||
|
@ -67,10 +67,10 @@ contains
|
|||||||
integer dat4(13) !Decoded message as 12 6-bit integers
|
integer dat4(13) !Decoded message as 12 6-bit integers
|
||||||
integer dgen(13)
|
integer dgen(13)
|
||||||
logical lclearave,lnewdat0,lapcqonly,unpk77_success
|
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 :: c00(:) !Analytic signal, 6000 Sa/s
|
||||||
complex, allocatable :: c0(:) !Analytic signal, 6000 Sa/s
|
complex, allocatable :: c0(:) !Analytic signal, 6000 Sa/s
|
||||||
|
|
||||||
! Start by setting some parameters and allocating storage for large arrays
|
! Start by setting some parameters and allocating storage for large arrays
|
||||||
call sec0(0,tdecode)
|
call sec0(0,tdecode)
|
||||||
nfa=nfa0
|
nfa=nfa0
|
||||||
@ -79,7 +79,7 @@ contains
|
|||||||
idec=-1
|
idec=-1
|
||||||
idf=0
|
idf=0
|
||||||
idt=0
|
idt=0
|
||||||
irc=0
|
nrc=-2
|
||||||
mode_q65=2**nsubmode
|
mode_q65=2**nsubmode
|
||||||
npts=ntrperiod*12000
|
npts=ntrperiod*12000
|
||||||
nfft1=ntrperiod*12000
|
nfft1=ntrperiod*12000
|
||||||
@ -98,9 +98,8 @@ contains
|
|||||||
allocate (c00(0:nfft1-1))
|
allocate (c00(0:nfft1-1))
|
||||||
allocate (c0(0:nfft1-1))
|
allocate (c0(0:nfft1-1))
|
||||||
|
|
||||||
if(ntrperiod.eq.15) then
|
nsps=1800
|
||||||
nsps=1800
|
if(ntrperiod.eq.30) then
|
||||||
else if(ntrperiod.eq.30) then
|
|
||||||
nsps=3600
|
nsps=3600
|
||||||
else if(ntrperiod.eq.60) then
|
else if(ntrperiod.eq.60) then
|
||||||
nsps=7200
|
nsps=7200
|
||||||
@ -108,23 +107,26 @@ contains
|
|||||||
nsps=16000
|
nsps=16000
|
||||||
else if(ntrperiod.eq.300) then
|
else if(ntrperiod.eq.300) then
|
||||||
nsps=41472
|
nsps=41472
|
||||||
else
|
|
||||||
stop 'Invalid TR period'
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
baud=12000.0/nsps
|
baud=12000.0/nsps
|
||||||
this%callback => callback
|
this%callback => callback
|
||||||
nFadingModel=1
|
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)
|
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
|
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)
|
ibwb=min(10,ibwa+5)
|
||||||
else if(iand(ndepth,3).eq.3) then
|
else if(iand(ndepth,3).eq.3) then
|
||||||
ibwa=max(1,ibwa-1)
|
ibwa=max(1,ibwa-1)
|
||||||
ibwb=min(10,ibwb+1)
|
ibwb=min(10,ibwb+1)
|
||||||
|
maxiters=100
|
||||||
endif
|
endif
|
||||||
|
|
||||||
! Generate codewords for full-AP list decoding
|
! Generate codewords for full-AP list decoding
|
||||||
call q65_set_list(mycall,hiscall,hisgrid,codewords,ncw)
|
call q65_set_list(mycall,hiscall,hisgrid,codewords,ncw)
|
||||||
dgen=0
|
dgen=0
|
||||||
@ -175,7 +177,6 @@ contains
|
|||||||
call timer('q65loops',0)
|
call timer('q65loops',0)
|
||||||
call q65_loops(c00,npts/2,nsps/2,nsubmode,ndepth,jpk0, &
|
call q65_loops(c00,npts/2,nsps/2,nsubmode,ndepth,jpk0, &
|
||||||
xdt,f0,iaptype,xdt1,f1,snr2,dat4,idec)
|
xdt,f0,iaptype,xdt1,f1,snr2,dat4,idec)
|
||||||
! idec=-1 !### TEMPORARY ###
|
|
||||||
call timer('q65loops',1)
|
call timer('q65loops',1)
|
||||||
if(idec.ge.0) then
|
if(idec.ge.0) then
|
||||||
dtdec=xdt1
|
dtdec=xdt1
|
||||||
@ -229,6 +230,7 @@ contains
|
|||||||
write(c77,1000) dat4(1:12),dat4(13)/2
|
write(c77,1000) dat4(1:12),dat4(13)/2
|
||||||
1000 format(12b6.6,b5.5)
|
1000 format(12b6.6,b5.5)
|
||||||
call unpack77(c77,0,decoded,unpk77_success) !Unpack to get msgsent
|
call unpack77(c77,0,decoded,unpk77_success) !Unpack to get msgsent
|
||||||
|
call q65_snr(dat4,dtdec,f0dec,mode_q65,nused,snr2)
|
||||||
nsnr=nint(snr2)
|
nsnr=nint(snr2)
|
||||||
call this%callback(nutc,snr1,nsnr,dtdec,f0dec,decoded, &
|
call this%callback(nutc,snr1,nsnr,dtdec,f0dec,decoded, &
|
||||||
idec,nused,ntrperiod)
|
idec,nused,ntrperiod)
|
||||||
@ -244,21 +246,22 @@ contains
|
|||||||
if(c6.eq.' ') c6='<b> '
|
if(c6.eq.' ') c6='<b> '
|
||||||
c4=hisgrid(1:4)
|
c4=hisgrid(1:4)
|
||||||
if(c4.eq.' ') c4='<b> '
|
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)'
|
'1x,a6,1x,a6,1x,a4,1x,a)'
|
||||||
if(ntrperiod.le.30) fmt(5:5)='6'
|
if(ntrperiod.le.30) fmt(5:5)='6'
|
||||||
write(22,fmt) nutc,cmode,nQSOprogress,idec,idf,idt,ibw,nused, &
|
if(idec.eq.3) nrc=0
|
||||||
icand,ncand,xdt,f0,snr1,snr2,tdecode,mycall(1:6),c6,c4, &
|
write(22,fmt) nutc,cmode,nQSOprogress,idec,idfbest,idtbest,ibw, &
|
||||||
trim(decoded)
|
ndistbest,nused,icand,ncand,nrc,ndepth,xdt,f0,snr2,tdecode, &
|
||||||
|
mycall(1:6),c6,c4,trim(decoded)
|
||||||
close(22)
|
close(22)
|
||||||
endif
|
endif
|
||||||
else
|
! else
|
||||||
! Report snr1, even if no decode.
|
! Report snr1, even if no decode.
|
||||||
nsnr=db(snr1) - 35.0
|
! nsnr=db(snr1) - 35.0
|
||||||
if(nsnr.lt.-35) nsnr=-35
|
! if(nsnr.lt.-35) nsnr=-35
|
||||||
idec=-1
|
! idec=-1
|
||||||
call this%callback(nutc,snr1,nsnr,xdt,f0,decoded, &
|
! call this%callback(nutc,snr1,nsnr,xdt,f0,decoded, &
|
||||||
idec,0,ntrperiod)
|
! idec,0,ntrperiod)
|
||||||
endif
|
endif
|
||||||
navg0=1000*navg(0) + navg(1)
|
navg0=1000*navg(0) + navg(1)
|
||||||
if(single_decode .or. lagain) go to 900
|
if(single_decode .or. lagain) go to 900
|
||||||
@ -309,6 +312,7 @@ contains
|
|||||||
! Unpack decoded message for display to user
|
! Unpack decoded message for display to user
|
||||||
write(c77,1000) dat4(1:12),dat4(13)/2
|
write(c77,1000) dat4(1:12),dat4(13)/2
|
||||||
call unpack77(c77,0,decoded,unpk77_success) !Unpack to get msgsent
|
call unpack77(c77,0,decoded,unpk77_success) !Unpack to get msgsent
|
||||||
|
call q65_snr(dat4,dtdec,f0dec,mode_q65,nused,snr2)
|
||||||
nsnr=nint(snr2)
|
nsnr=nint(snr2)
|
||||||
call this%callback(nutc,snr1,nsnr,dtdec,f0dec,decoded, &
|
call this%callback(nutc,snr1,nsnr,dtdec,f0dec,decoded, &
|
||||||
idec,nused,ntrperiod)
|
idec,nused,ntrperiod)
|
||||||
@ -324,12 +328,13 @@ contains
|
|||||||
if(c6.eq.' ') c6='<b> '
|
if(c6.eq.' ') c6='<b> '
|
||||||
c4=hisgrid(1:4)
|
c4=hisgrid(1:4)
|
||||||
if(c4.eq.' ') c4='<b> '
|
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)'
|
'1x,a6,1x,a6,1x,a4,1x,a)'
|
||||||
if(ntrperiod.le.30) fmt(5:5)='6'
|
if(ntrperiod.le.30) fmt(5:5)='6'
|
||||||
write(22,fmt) nutc,cmode,nQSOprogress,idec,idf,idt,ibw,nused, &
|
if(idec.eq.3) nrc=0
|
||||||
icand,ncand,xdt,f0,snr1,snr2,tdecode,mycall(1:6),c6,c4, &
|
write(22,fmt) nutc,cmode,nQSOprogress,idec,idfbest,idtbest,ibw, &
|
||||||
trim(decoded)
|
ndistbest,nused,icand,ncand,nrc,ndepth,xdt,f0,snr2,tdecode, &
|
||||||
|
mycall(1:6),c6,c4,trim(decoded)
|
||||||
close(22)
|
close(22)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
@ -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;
|
const qracode *pQraCode;
|
||||||
float *ix, *ex;
|
float *ix, *ex;
|
||||||
@ -579,7 +581,7 @@ int q65_decode(q65_codec_ds *pCodec, int* pDecodedCodeword, int *pDecodedMsg, co
|
|||||||
rc = qra_extrinsic( pQraCode,
|
rc = qra_extrinsic( pQraCode,
|
||||||
ex,
|
ex,
|
||||||
ix,
|
ix,
|
||||||
100,
|
maxiters,
|
||||||
pCodec->qra_v2cmsg,
|
pCodec->qra_v2cmsg,
|
||||||
pCodec->qra_c2vmsg);
|
pCodec->qra_c2vmsg);
|
||||||
|
|
||||||
|
@ -11,13 +11,15 @@ module q65
|
|||||||
38,46,50,55,60,62,66,69,74,76,85/)
|
38,46,50,55,60,62,66,69,74,76,85/)
|
||||||
integer codewords(63,206)
|
integer codewords(63,206)
|
||||||
integer ibwa,ibwb,ncw,nsps,mode_q65,nfa,nfb
|
integer ibwa,ibwb,ncw,nsps,mode_q65,nfa,nfb
|
||||||
integer idf,idt,ibw
|
integer idfbest,idtbest,ibw,ndistbest,maxiters
|
||||||
integer istep,nsmo,lag1,lag2,npasses,nused,iseq,ncand
|
integer istep,nsmo,lag1,lag2,npasses,nused,iseq,ncand,nrc
|
||||||
integer i0,j0
|
integer i0,j0
|
||||||
integer navg(0:1)
|
integer navg(0:1)
|
||||||
logical lnewdat
|
logical lnewdat
|
||||||
real candidates(20,3) !snr, xdt, and f0 of top candidates
|
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 sync(85) !sync vector
|
||||||
real df,dtstep,dtdec,f0dec,ftol
|
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
|
! width Estimated Doppler spread
|
||||||
! dat4(13) Decoded message as 13 six-bit integers
|
! dat4(13) Decoded message as 13 six-bit integers
|
||||||
! snr2 Estimated SNR of decoded signal
|
! snr2 Estimated SNR of decoded signal
|
||||||
! idec Flag for decing results
|
! idec Flag for decoding results
|
||||||
! -1 No decode
|
! -1 No decode
|
||||||
! 0 No AP
|
! 0 No AP
|
||||||
! 1 "CQ ? ?"
|
! 1 "CQ ? ?"
|
||||||
@ -60,7 +62,6 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
|||||||
integer dat4(13)
|
integer dat4(13)
|
||||||
character*37 decoded
|
character*37 decoded
|
||||||
logical first,lclearave
|
logical first,lclearave
|
||||||
real, allocatable :: s1(:,:) !Symbol spectra, 1/8-symbol steps
|
|
||||||
real, allocatable :: s3(:,:) !Data-symbol energies s3(LL,63)
|
real, allocatable :: s3(:,:) !Data-symbol energies s3(LL,63)
|
||||||
real, allocatable :: ccf1(:) !CCF(freq) at fixed lag (red)
|
real, allocatable :: ccf1(:) !CCF(freq) at fixed lag (red)
|
||||||
real, allocatable :: ccf2(:) !Max CCF(freq) at any lag (orange)
|
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
|
! Set some parameters and allocate storage for large arrays
|
||||||
irc=-2
|
irc=-2
|
||||||
|
nrc=-2
|
||||||
idec=-1
|
idec=-1
|
||||||
snr1=0.
|
snr1=0.
|
||||||
dat4=0
|
dat4=0
|
||||||
@ -94,13 +96,17 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
|||||||
enddo
|
enddo
|
||||||
endif
|
endif
|
||||||
|
|
||||||
allocate(s1(iz,jz))
|
|
||||||
allocate(s3(-64:LL-65,63))
|
allocate(s3(-64:LL-65,63))
|
||||||
allocate(ccf1(-ia2:ia2))
|
allocate(ccf1(-ia2:ia2))
|
||||||
allocate(ccf2(iz))
|
allocate(ccf2(iz))
|
||||||
if(LL.ne.LL0 .or. iz.ne.iz0 .or. jz.ne.jz0 .or. lclearave) then
|
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)
|
if(allocated(s1a)) deallocate(s1a)
|
||||||
allocate(s1a(iz,jz,0:1))
|
allocate(s1a(iz,jz,0:1))
|
||||||
|
s1=0.
|
||||||
s1a=0.
|
s1a=0.
|
||||||
navg=0
|
navg=0
|
||||||
LL0=LL
|
LL0=LL
|
||||||
@ -127,8 +133,9 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
|||||||
|
|
||||||
i0=nint(nfqso/df) !Target QSO frequency
|
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
|
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
|
s1=s1/base
|
||||||
|
s1raw=s1
|
||||||
|
|
||||||
! Apply fast AGC to the symbol spectra
|
! Apply fast AGC to the symbol spectra
|
||||||
s1max=20.0 !Empirical choice
|
s1max=20.0 !Empirical choice
|
||||||
@ -233,9 +240,11 @@ subroutine q65_symspec(iwave,nmax,iz,jz,s1)
|
|||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
if(lnewdat) then
|
if(lnewdat) then
|
||||||
s1a(:,:,iseq)=s1a(:,:,iseq) + s1
|
|
||||||
navg(iseq)=navg(iseq) + 1
|
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
|
return
|
||||||
end subroutine q65_symspec
|
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
|
b90=1.72**ibw
|
||||||
b90ts=b90/baud
|
b90ts=b90/baud
|
||||||
call q65_dec1(s3,nsubmode,b90ts,esnodb,irc,dat4,decoded)
|
call q65_dec1(s3,nsubmode,b90ts,esnodb,irc,dat4,decoded)
|
||||||
|
nrc=irc
|
||||||
if(irc.ge.0) then
|
if(irc.ge.0) then
|
||||||
snr2=esnodb - db(2500.0/baud) + 3.0 !Empirical adjustment
|
snr2=esnodb - db(2500.0/baud) + 3.0 !Empirical adjustment
|
||||||
idec=3
|
idec=3
|
||||||
@ -314,6 +324,7 @@ subroutine q65_dec_q012(s3,LL,snr2,dat4,idec,decoded)
|
|||||||
b90=1.72**ibw
|
b90=1.72**ibw
|
||||||
b90ts=b90/baud
|
b90ts=b90/baud
|
||||||
call q65_dec2(s3,nsubmode,b90ts,esnodb,irc,dat4,decoded)
|
call q65_dec2(s3,nsubmode,b90ts,esnodb,irc,dat4,decoded)
|
||||||
|
nrc=irc
|
||||||
if(irc.ge.0) then
|
if(irc.ge.0) then
|
||||||
snr2=esnodb - db(2500.0/baud) + 3.0 !Empirical adjustment
|
snr2=esnodb - db(2500.0/baud) + 3.0 !Empirical adjustment
|
||||||
idec=iaptype
|
idec=iaptype
|
||||||
@ -486,6 +497,7 @@ subroutine q65_dec1(s3,nsubmode,b90ts,esnodb,irc,dat4,decoded)
|
|||||||
else
|
else
|
||||||
irc=-1
|
irc=-1
|
||||||
endif
|
endif
|
||||||
|
nrc=irc
|
||||||
|
|
||||||
return
|
return
|
||||||
end subroutine q65_dec1
|
end subroutine q65_dec1
|
||||||
@ -504,8 +516,9 @@ subroutine q65_dec2(s3,nsubmode,b90ts,esnodb,irc,dat4,decoded)
|
|||||||
nFadingModel=1
|
nFadingModel=1
|
||||||
decoded=' '
|
decoded=' '
|
||||||
call q65_intrinsics_ff(s3,nsubmode,b90ts,nFadingModel,s3prob)
|
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
|
if(sum(dat4).le.0) irc=-2
|
||||||
|
nrc=irc
|
||||||
if(irc.ge.0) then
|
if(irc.ge.0) then
|
||||||
write(c77,1000) dat4(1:12),dat4(13)/2
|
write(c77,1000) dat4(1:12),dat4(13)/2
|
||||||
1000 format(12b6.6,b5.5)
|
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)
|
if(j.ge.1 .and. j.le.jz) s3(-64:LL-65,n)=s1(i1:i2,j)
|
||||||
enddo
|
enddo
|
||||||
endif
|
endif
|
||||||
|
call q65_bzap(s3,LL) !Zap birdies
|
||||||
|
|
||||||
return
|
return
|
||||||
end subroutine q65_s1_to_s3
|
end subroutine q65_s1_to_s3
|
||||||
|
|
||||||
@ -589,4 +603,88 @@ subroutine q65_sync_curve(ccf1,ia,ib,rms1)
|
|||||||
return
|
return
|
||||||
end subroutine q65_sync_curve
|
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
|
end module q65
|
||||||
|
@ -75,11 +75,12 @@ int q65_intrinsics_fastfading(q65_codec_ds *pCodec,
|
|||||||
|
|
||||||
|
|
||||||
int q65_decode(q65_codec_ds *pCodec,
|
int q65_decode(q65_codec_ds *pCodec,
|
||||||
int* pDecodedCodeword,
|
int* pDecodedCodeword,
|
||||||
int *pDecodedMsg,
|
int *pDecodedMsg,
|
||||||
const float *pIntrinsics,
|
const float *pIntrinsics,
|
||||||
const int *pAPMask,
|
const int *pAPMask,
|
||||||
const int *pAPSymbols);
|
const int *pAPSymbols,
|
||||||
|
const int maxiters);
|
||||||
|
|
||||||
int q65_decode_fullaplist(q65_codec_ds *codec,
|
int q65_decode_fullaplist(q65_codec_ds *codec,
|
||||||
int *ydec,
|
int *ydec,
|
||||||
|
@ -38,6 +38,9 @@ subroutine q65_loops(c00,npts2,nsps2,nsubmode,ndepth,jpk0, &
|
|||||||
napmin=99
|
napmin=99
|
||||||
xdt1=xdt0
|
xdt1=xdt0
|
||||||
f1=f0
|
f1=f0
|
||||||
|
idfbest=0
|
||||||
|
idtbest=0
|
||||||
|
ndistbest=0
|
||||||
|
|
||||||
do idf=1,idfmax
|
do idf=1,idfmax
|
||||||
ndf=idf/2
|
ndf=idf/2
|
||||||
@ -56,6 +59,7 @@ subroutine q65_loops(c00,npts2,nsps2,nsubmode,ndepth,jpk0, &
|
|||||||
call pctile(s3,LL*NN,40,base)
|
call pctile(s3,LL*NN,40,base)
|
||||||
s3=s3/base
|
s3=s3/base
|
||||||
where(s3(1:LL*NN)>s3lim) s3(1:LL*NN)=s3lim
|
where(s3(1:LL*NN)>s3lim) s3(1:LL*NN)=s3lim
|
||||||
|
call q65_bzap(s3,LL) !Zap birdies
|
||||||
do ibw=ibwa,ibwb
|
do ibw=ibwa,ibwb
|
||||||
ndist=ndf**2 + ndt**2 + (ibw-ibw0)**2
|
ndist=ndf**2 + ndt**2 + (ibw-ibw0)**2
|
||||||
if(ndist.gt.maxdist) cycle
|
if(ndist.gt.maxdist) cycle
|
||||||
@ -69,7 +73,13 @@ subroutine q65_loops(c00,npts2,nsps2,nsubmode,ndepth,jpk0, &
|
|||||||
! -1 = invalid params
|
! -1 = invalid params
|
||||||
! -2 = decode failed
|
! -2 = decode failed
|
||||||
! -3 = CRC mismatch
|
! -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 ! ibw (b90 loop)
|
||||||
enddo ! idt (DT loop)
|
enddo ! idt (DT loop)
|
||||||
enddo ! idf (f0 loop)
|
enddo ! idf (f0 loop)
|
||||||
|
@ -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[],
|
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
|
/* Input: s3[LL,NN] Symbol spectra
|
||||||
@ -93,8 +93,9 @@ void q65_dec_(float s3[], float s3prob[], int APmask[], int APsymbols[],
|
|||||||
int rc;
|
int rc;
|
||||||
int ydec[63];
|
int ydec[63];
|
||||||
float esnodb;
|
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;
|
*rc0=rc;
|
||||||
// rc = -1: Invalid params
|
// rc = -1: Invalid params
|
||||||
// rc = -2: Decode failed
|
// rc = -2: Decode failed
|
||||||
|
@ -9,10 +9,13 @@ program q65sim
|
|||||||
integer*2 iwave(NMAX) !Generated waveform
|
integer*2 iwave(NMAX) !Generated waveform
|
||||||
integer itone(85) !Channel symbols (values 0-65)
|
integer itone(85) !Channel symbols (values 0-65)
|
||||||
integer y(63) !Codeword
|
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 xnoise(NMAX) !Generated random noise
|
||||||
real*4 dat(NMAX) !Generated real data
|
real*4 dat(NMAX) !Generated real data
|
||||||
complex cdat(NMAX) !Generated complex waveform
|
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
|
complex z
|
||||||
real*8 f0,dt,twopi,phi,dphi,baud,fsample,freq
|
real*8 f0,dt,twopi,phi,dphi,baud,fsample,freq
|
||||||
character msg*37,fname*17,csubmode*1,arg*12
|
character msg*37,fname*17,csubmode*1,arg*12
|
||||||
@ -22,10 +25,13 @@ program q65sim
|
|||||||
if(nargs.ne.10) then
|
if(nargs.ne.10) then
|
||||||
print*,'Usage: q65sim "msg" A-E freq fDop DT f1 Stp TRp Nfile SNR'
|
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 "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*,' fDop = Doppler spread'
|
||||||
print*,' f1 = Drift or Doppler rate (Hz/min)'
|
print*,' f1 = Drift or Doppler rate (Hz/min)'
|
||||||
print*,' Stp = Step size (Hz)'
|
print*,' Stp = Step size (Hz)'
|
||||||
print*,' Stp = 0 implies no Doppler tracking'
|
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
|
go to 999
|
||||||
endif
|
endif
|
||||||
call getarg(1,msg)
|
call getarg(1,msg)
|
||||||
@ -94,14 +100,17 @@ program q65sim
|
|||||||
h=default_header(12000,npts)
|
h=default_header(12000,npts)
|
||||||
|
|
||||||
write(*,1004)
|
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
|
do ifile=1,nfiles !Loop over requested number of files
|
||||||
if(ntrperiod.lt.60) then
|
istart = (ifile*ntrperiod*2) - (ntrperiod*2)
|
||||||
write(fname,1005) ifile !Output filename
|
if(ntrperiod.lt.30) then !wdg was 60
|
||||||
1005 format('000000_',i6.6,'.wav')
|
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
|
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')
|
1106 format('000000_',i4.4,'.wav')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -118,7 +127,7 @@ program q65sim
|
|||||||
sig=sqrt(2*bandwidth_ratio)*10.0**(0.05*snrdb)
|
sig=sqrt(2*bandwidth_ratio)*10.0**(0.05*snrdb)
|
||||||
if(snrdb.gt.90.0) sig=1.0
|
if(snrdb.gt.90.0) sig=1.0
|
||||||
write(*,1020) ifile,ntrperiod,f0,csubmode,snrdb,fspread,xdt,f1,nstp,trim(msgsent)
|
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
|
phi=0.d0
|
||||||
dphi=0.d0
|
dphi=0.d0
|
||||||
k=(xdt+0.5)*12000 !Start audio at t=xdt+0.5 s (TR=15 and 30 s)
|
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
|
if(isym.ne.isym0) then
|
||||||
freq_drift=f1*i*dt/60.0
|
freq_drift=f1*i*dt/60.0
|
||||||
if(nstp.ne.0) freq_drift=freq_drift - nstp*nint(freq_drift/nstp)
|
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
|
dphi=twopi*freq*dt
|
||||||
isym0=isym
|
isym0=isym
|
||||||
endif
|
endif
|
||||||
|
@ -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
|
|
@ -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
|
|
||||||
};
|
|
@ -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
|
|
||||||
};
|
|
@ -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;
|
|
||||||
}
|
|
@ -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_
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -140,20 +140,20 @@ subroutine chk_samples(ihsym,k,nstop)
|
|||||||
call system_clock(count0,clkfreq)
|
call system_clock(count0,clkfreq)
|
||||||
maxhsym=0
|
maxhsym=0
|
||||||
endif
|
endif
|
||||||
if((mod(ihsym,100).eq.0 .or. ihsym.ge.nstop-100) .and. &
|
! if((mod(ihsym,100).eq.0 .or. ihsym.ge.nstop-100) .and. &
|
||||||
k0.ne.99999999) then
|
! k0.ne.99999999) then
|
||||||
call system_clock(count1,clkfreq)
|
! call system_clock(count1,clkfreq)
|
||||||
dtime=dfloat(count1-count0)/dfloat(clkfreq)
|
! dtime=dfloat(count1-count0)/dfloat(clkfreq)
|
||||||
if(dtime.lt.28.0) return
|
! if(dtime.lt.28.0) return
|
||||||
if(dtime.gt.1.d-6) fsample=(k-3456)/dtime
|
! if(dtime.gt.1.d-6) fsample=(k-3456)/dtime
|
||||||
call date_and_time(values=itime)
|
! call date_and_time(values=itime)
|
||||||
sec=itime(7)+0.001*itime(8)
|
! sec=itime(7)+0.001*itime(8)
|
||||||
write(ctime,3000) itime(5)-itime(4)/60,itime(6),sec
|
! write(ctime,3000) itime(5)-itime(4)/60,itime(6),sec
|
||||||
3000 format(i2.2,':',i2.2,':',f6.3)
|
!3000 format(i2.2,':',i2.2,':',f6.3)
|
||||||
write(33,3033) ctime,dtime,ihsym,nstop,k,fsample
|
! write(33,3033) ctime,dtime,ihsym,nstop,k,fsample
|
||||||
3033 format(a12,f12.6,2i7,i10,f15.3)
|
!3033 format(a12,f12.6,2i7,i10,f15.3)
|
||||||
flush(33)
|
! flush(33)
|
||||||
endif
|
! endif
|
||||||
k0=k
|
k0=k
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -29,7 +29,7 @@ subroutine sync4(dat,jz,ntol,nfqso,mode,mode4,minwidth,dtx,dfx,snrx, &
|
|||||||
df=0.5*11025.0/nfft
|
df=0.5*11025.0/nfft
|
||||||
ftop=nfqso + 7*mode4*df
|
ftop=nfqso + 7*mode4*df
|
||||||
if(ftop.gt.11025.0/4.0) then
|
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
|
go to 900
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ subroutine sync4(dat,jz,ntol,nfqso,mode,mode4,minwidth,dtx,dfx,snrx, &
|
|||||||
enddo
|
enddo
|
||||||
if(syncbest.lt.-1.e29) go to 900
|
if(syncbest.lt.-1.e29) go to 900
|
||||||
ccfred=red
|
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
|
ccfred=ccfred-base
|
||||||
|
|
||||||
dfx=ipk*df
|
dfx=ipk*df
|
||||||
|
@ -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
|
|
@ -103,7 +103,7 @@ program test_q65
|
|||||||
dterr=tsym/4.0
|
dterr=tsym/4.0
|
||||||
nferr=max(1,nint(0.5*baud),nint(fdop/3.0))
|
nferr=max(1,nint(0.5*baud),nint(fdop/3.0))
|
||||||
ndec1z=nfiles
|
ndec1z=nfiles
|
||||||
|
|
||||||
do nsnr=ia,ib,-1
|
do nsnr=ia,ib,-1
|
||||||
snr1=nsnr
|
snr1=nsnr
|
||||||
if(ia.eq.99) snr1=snr
|
if(ia.eq.99) snr1=snr
|
||||||
|
7
main.cpp
@ -225,8 +225,7 @@ int main(int argc, char *argv[])
|
|||||||
// disallow multiple instances with same instance key
|
// disallow multiple instances with same instance key
|
||||||
QLockFile instance_lock {temp_dir.absoluteFilePath (a.applicationName () + ".lock")};
|
QLockFile instance_lock {temp_dir.absoluteFilePath (a.applicationName () + ".lock")};
|
||||||
instance_lock.setStaleLockTime (0);
|
instance_lock.setStaleLockTime (0);
|
||||||
bool lock_ok {false};
|
while (!instance_lock.tryLock ())
|
||||||
while (!(lock_ok = instance_lock.tryLock ()))
|
|
||||||
{
|
{
|
||||||
if (QLockFile::LockFailedError == instance_lock.error ())
|
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"};
|
throw std::runtime_error {"Multiple instances must have unique rig names"};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw std::runtime_error {"Failed to access lock file"};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// load UI translations
|
// load UI translations
|
||||||
|
@ -19,7 +19,6 @@ namespace
|
|||||||
"JT4",
|
"JT4",
|
||||||
"WSPR",
|
"WSPR",
|
||||||
"Echo",
|
"Echo",
|
||||||
"ISCAT",
|
|
||||||
"MSK144",
|
"MSK144",
|
||||||
"FreqCal",
|
"FreqCal",
|
||||||
"FT8",
|
"FT8",
|
||||||
|
@ -44,7 +44,6 @@ public:
|
|||||||
JT4,
|
JT4,
|
||||||
WSPR,
|
WSPR,
|
||||||
Echo,
|
Echo,
|
||||||
ISCAT,
|
|
||||||
MSK144,
|
MSK144,
|
||||||
FreqCal,
|
FreqCal,
|
||||||
FT8,
|
FT8,
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
set (SAMPLE_FILES
|
set (SAMPLE_FILES
|
||||||
FT4/000000_000002.wav
|
FT4/000000_000002.wav
|
||||||
FT8/181201_180245.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-A/VK7MO_110401_235515.wav
|
||||||
ISCAT/ISCAT-B/K0AWU_100714_115000.wav
|
ISCAT/ISCAT-B/K0AWU_100714_115000.wav
|
||||||
JT4/JT4A/DF2ZC_070926_040700.WAV
|
JT4/JT4A/DF2ZC_070926_040700.WAV
|
||||||
@ -19,9 +23,22 @@ set (SAMPLE_FILES
|
|||||||
MSK144/181211_120800.wav
|
MSK144/181211_120800.wav
|
||||||
QRA64/QRA64C/161113_0111.wav
|
QRA64/QRA64C/161113_0111.wav
|
||||||
WSPR/150426_0918.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 (contents_file ${CMAKE_CURRENT_BINARY_DIR}/${contents_file_name})
|
||||||
set (web_tree ${CMAKE_CURRENT_BINARY_DIR}/web)
|
set (web_tree ${CMAKE_CURRENT_BINARY_DIR}/web)
|
||||||
set_source_files_properties (${contents_file} PROPERTIES GENERATED ON)
|
set_source_files_properties (${contents_file} PROPERTIES GENERATED ON)
|
||||||
|