Merge branch 'master' into develop

This commit is contained in:
Bill Somerville 2021-03-14 16:40:56 +00:00
commit f0945282dd
No known key found for this signature in database
GPG Key ID: D864B06D1E81618F
31 changed files with 1094 additions and 1099 deletions

View File

@ -526,7 +526,6 @@ set (wsjt_FSRCS
lib/symspec2.f90
lib/symspec65.f90
lib/sync4.f90
lib/sync64.f90
lib/sync65.f90
lib/ft4/getcandidates4.f90
lib/ft4/get_ft4_bitmetrics.f90
@ -1603,7 +1602,7 @@ install (DIRECTORY
if (APPLE)
install (FILES
Darwin/ReadMe.txt
Darwin/sysctl.conf
Darwin/com.wsjtx.sysctl.plist
DESTINATION .
#COMPONENT runtime
)

View File

@ -1,42 +1,21 @@
Notes on WSJT-X Installation for Mac OS X
-----------------------------------------
Important: If you are using the new Mac with the M1 chip then please read
the section marked: BEGIN M1. Otherwise BEGIN INTEL applies.
If you have already downloaded a previous version of WSJT-X then I suggest
you change the name in the Applications folder from WSJT-X to WSJT-X_previous
before proceeding.
I recommend that you follow the installation instructions especially if you
are moving from v2.2 to v2.3 of WSJT-X or you have upgraded macOS.
BEGIN M1:
are moving from v2.2 to v2.3 or later, of WSJT-X or you have upgraded macOS.
Double-click on the wsjtx-...-Darwin.dmg file you have downloaded from K1JT's web-site.
Now open a Terminal window by going to Applications->Utilities and clicking on Terminal.
There are two system variables that must be set manually since the M1 Macs do not recognise
automatic parameter settings by means of the sysctl.conf file present in the download.
Type these commands - you will be asked for your password which will not be echoed:
sudo sysctl -w kern.sysv.shmmax=52428800
sudo sysctl -w kern.sysv.shmall=25600
It is important to note that these parameter settings will not survive a reboot. If you
need to reboot your Mac, then these commands must be re-entered. Now proceed to NEXT.
BEGIN INTEL:
Double-click on the wsjtx-...-Darwin.dmg file you have downloaded from K1JT's web-site.
Now open a Terminal window by going to Applications->Utilities and clicking on Terminal.
Along with this ReadMe file there is a file: sysctl.conf which must be copied to a
Along with this ReadMe file there is a file: com.wsjtx.sysctl.plist which must be copied to a
system area by typing this line in the Terminal window and then pressing the Return key.
sudo cp /Volumes/WSJT-X/sysctl.conf /etc
sudo cp /Volumes/WSJT-X/com.wsjtx.sysctl.plist /Library/LaunchDaemons
you will be asked for your normal password because authorisation is needed to copy this file.
(Your password will not be echoed but press the Return key when completed.)
@ -53,8 +32,6 @@ You can now close the Terminal window. It will not be necessary to repeat this
again, even when you download an updated version of WSJT-X. It might be necessary if you
upgrade macOS.
NEXT:
Drag the WSJT-X app to your preferred location, such as Applications.
You need to configure your sound card. Visit Applications > Utilities > Audio MIDI
@ -95,27 +72,22 @@ Please email me if you have problems.
--- John G4KLA (g4kla@rmnjmn.co.uk)
Addendum: Information about sysctl.conf and multiple instances of WSJT-X.
Addendum: Information about com.wsjtx.sysctl.plist and multiple instances of WSJT-X.
WSJT-X makes use of a block of memory which is shared between different parts of
the code. The normal allocation of shared memory on a Mac is insufficient and this
has to be increased. The sysctl.conf file is used for this purpose. You can
use a Mac editor to examine sysctl.conf. (Do not use another editor - the file
has to be increased. The com.wsjtx.sysctl.plist file is used for this purpose. You can
use a Mac editor to examine the file. (Do not use another editor - the file
would probably be corrupted.)
It is possible to run two instances of WSJT-X simultaneously. See "Section 16.2
Frequently asked Questions" in the User Guide. If you wish to run more than two instances
simultaneously, the shmall parameter in the sysctl.conf file needs to be modified as follows.
simultaneously, the shmall parameter in the com.wsjtx.sysctl.plist file needs to be modified as follows.
The shmall parameter determines the amount of shared memory which is allocated in 4096 byte pages
with 50MB (52428800) required for each instance. The shmall parameter is calculated as:
(n * 52428800)/4096 where 'n' is the number of instances required to run simultaneously. If
you are using an Intel Mac, modify the shmall parameter in the sysctl.conf file using a Mac editor
and then install in the /etc directory using the installation procedure described above for an
Intel Mac. Remember to reboot your Mac afterwards.
If you are using an M1 Mac, then simply issue the sudo sysctl -w kern.sysv.shmall=xxx command where
xxx is the new value of shmall that is required.
(n * 52428800)/4096 where 'n' is the number of instances required to run simultaneously.
Remember to reboot your Mac afterwards.
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

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.wsjtx.sysctl</string>
<key>Program</key>
<string>/usr/sbin/sysctl</string>
<key>ProgramArguments</key>
<array>
<string>/usr/sbin/sysctl</string>
<string>kern.sysv.shmmax=52428800</string>
<string>kern.sysv.shmall=25600</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>

View File

@ -1,5 +0,0 @@
kern.sysv.shmmax=52428800
kern.sysv.shmmin=1
kern.sysv.shmmni=128
kern.sysv.shmseg=32
kern.sysv.shmall=25600

View File

@ -23,7 +23,7 @@ DecodedText::DecodedText (QString const& the_string)
, is_standard_ {false}
{
// discard appended AP info
clean_string_.replace (QRegularExpression {R"(^(.*)(?:(?:\?\s)?a[0-9].*)$)"}, "\\1");
clean_string_.replace (QRegularExpression {R"(^(.*?)(?:\?\s)?a[0-9].*$)"}, "\\1");
// qDebug () << "DecodedText: the_string:" << the_string << "Nbsp pos:" << the_string.indexOf (QChar::Nbsp);
if (message_.length() >= 1)

View File

@ -142,8 +142,8 @@ namespace Logger
err += e.what ();
// Since we cannot be sure of boost log state, output to cerr and cout.
std::cerr << "ERROR: " << err << std::endl;
std::cout << "ERROR: " << err << std::endl;
LOG_ERROR (err);
throw;
}
}

41
NEWS
View File

@ -12,6 +12,41 @@
Copyright 2001 - 2021 by Joe Taylor, K1JT.
Release: WSJT-X 2.4.0-rc3
Mar 16, 2021
-------------------------
WSJT-X 2.4.0 Release Candidate 3 adds new Q65 mode functionality and
decoder optimizations; repairs defects and regressions discovered in
the RC2 and v2.3.0 GA releases.
- Repaired a memory corruption related to display of Q65_Sync,
particularly nasty on macOS.
- Q65 now dissplays two sync curves: orange for the current sequence,
red for the accumulated average.
- Behavior of "Save decoded" has been corrected.
- Repaied a defect that caused crash when displaying the Wide Graph
with lower frequency limit set to 0.
- Program no longer terminates a transmission when Settings is
closed.
- Program no longer forces TxFreq to 700 or 1000 Hz when entering Q65
mode or closing Settings. Instead, it highlights TxFreq with red
background when its value should be 700 Hz but is not.
- Program displays a warning label if a contest mode is active in Q65
mode.
- Many updates to User Guide, mostly related to Q65.
- Repaired a regression that disallowed a new QSO initiation after an
abandoned QSO.
Release: WSJT-X 2.4.0-rc2
Mar 6, 2021
-------------------------
@ -63,7 +98,7 @@ the RC1 release.
Release: WSJT-X 2.3.1
Mar 8, 2021
Mar 18, 2021
---------------------
WSJT-X 2.3.1 General Availability release updates the User Guide to
@ -96,6 +131,10 @@ below.
- Repair a defect that could caused incorrect log entry fields when
using FT4 mode and a priori (AP) decoding.
- Repair defects saving .WAV files for periods with decodes.
- Offer a new scheme for adjusting macOS shared memory parameters.
Release: WSJT-X 2.4.0-rc1
Feb 3, 2021

View File

@ -12,6 +12,41 @@
Copyright 2001 - 2021 by Joe Taylor, K1JT.
Release: WSJT-X 2.4.0-rc3
Mar 16, 2021
-------------------------
WSJT-X 2.4.0 Release Candidate 3 adds new Q65 mode functionality and
decoder optimizations; repairs defects and regressions discovered in
the RC2 and v2.3.0 GA releases.
- Repaired a memory corruption related to display of Q65_Sync,
particularly nasty on macOS.
- Q65 now dissplays two sync curves: orange for the current sequence,
red for the accumulated average.
- Behavior of "Save decoded" has been corrected.
- Repaied a defect that caused crash when displaying the Wide Graph
with lower frequency limit set to 0.
- Program no longer terminates a transmission when Settings is
closed.
- Program no longer forces TxFreq to 700 or 1000 Hz when entering Q65
mode or closing Settings. Instead, it highlights TxFreq with red
background when its value should be 700 Hz but is not.
- Program displays a warning label if a contest mode is active in Q65
mode.
- Many updates to User Guide, mostly related to Q65.
- Repaired a regression that disallowed a new QSO initiation after an
abandoned QSO.
Release: WSJT-X 2.4.0-rc2
Mar 6, 2021
-------------------------
@ -63,7 +98,7 @@ the RC1 release.
Release: WSJT-X 2.3.1
Mar 8, 2021
Mar 18, 2021
---------------------
WSJT-X 2.3.1 General Availability release updates the User Guide to
@ -96,6 +131,10 @@ below.
- Repair a defect that could caused incorrect log entry fields when
using FT4 mode and a priori (AP) decoding.
- Repair defects saving .WAV files for periods with decodes.
- Offer a new scheme for adjusting macOS shared memory parameters.
Release: WSJT-X 2.4.0-rc1
Feb 3, 2021

View File

@ -104,59 +104,11 @@ namespace
<< context.category << ": " << msg.toStdWString ();
}
}
}
WSJTXLogging::WSJTXLogging ()
void default_log_config ()
{
auto core = logging::core::get ();
// Catch relevant exceptions from logging.
core->set_exception_handler
(
logging::make_exception_handler<std::runtime_error, std::logic_error> (exception_handler {})
);
// Check for a user-defined logging configuration settings file.
QFile log_config {QStandardPaths::locate (QStandardPaths::ConfigLocation, "wsjtx_log_config.ini")};
if (log_config.exists () && log_config.open (QFile::ReadOnly) && log_config.isReadable ())
{
QTextStream ts {&log_config};
auto config = ts.readAll ();
// Substitution variables.
container::flat_map<QString, QString> replacements =
{
{"DesktopLocation", QStandardPaths::writableLocation (QStandardPaths::DesktopLocation)},
{"DocumentsLocation", QStandardPaths::writableLocation (QStandardPaths::DocumentsLocation)},
{"TempLocation", QStandardPaths::writableLocation (QStandardPaths::TempLocation)},
{"HomeLocation", QStandardPaths::writableLocation (QStandardPaths::HomeLocation)},
{"CacheLocation", QStandardPaths::writableLocation (QStandardPaths::CacheLocation)},
{"GenericCacheLocation", QStandardPaths::writableLocation (QStandardPaths::GenericCacheLocation)},
{"GenericDataLocation", QStandardPaths::writableLocation (QStandardPaths::GenericDataLocation)},
{"AppDataLocation", QStandardPaths::writableLocation (QStandardPaths::AppDataLocation)},
{"AppLocalDataLocation", QStandardPaths::writableLocation (QStandardPaths::AppLocalDataLocation)},
};
// Parse the configration settings substituting the variable if found.
QString new_config;
int pos {0};
QRegularExpression subst_vars {R"(\${([^}]+)})"};
auto iter = subst_vars.globalMatch (config);
while (iter.hasNext ())
{
auto match = iter.next ();
auto const& name = match.captured (1);
auto repl_iter = replacements.find (name);
auto repl = repl_iter != replacements.end () ? repl_iter->second : "${" + name + "}";
new_config += config.mid (pos, match.capturedStart (1) - 2 - pos) + repl;
pos = match.capturedEnd (0);
}
new_config += config.mid (pos);
std::wstringbuf buffer {new_config.toStdWString (), std::ios_base::in};
std::wistream stream {&buffer};
Logger::init_from_config (stream);
LOG_INFO ("Read logging configuration file: " << log_config.fileName ());
}
else // Default setup
{
//
// Define sinks, filters, and formatters using expression
// templates for efficiency.
@ -219,10 +171,75 @@ WSJTXLogging::WSJTXLogging ()
);
core->add_sink (sys_sink);
}
// Indicate start of logging
LOG_INFO ("Log Start");
}
}
WSJTXLogging::WSJTXLogging ()
{
auto core = logging::core::get ();
// Catch relevant exceptions from logging.
core->set_exception_handler
(
logging::make_exception_handler<std::runtime_error, std::logic_error> (exception_handler {})
);
// Check for a user-defined logging configuration settings file.
QFile log_config {QStandardPaths::locate (QStandardPaths::ConfigLocation, "wsjtx_log_config.ini")};
if (log_config.exists () && log_config.open (QFile::ReadOnly) && log_config.isReadable ())
{
QTextStream ts {&log_config};
auto config = ts.readAll ();
// Substitution variables.
container::flat_map<QString, QString> replacements =
{
{"DesktopLocation", QStandardPaths::writableLocation (QStandardPaths::DesktopLocation)},
{"DocumentsLocation", QStandardPaths::writableLocation (QStandardPaths::DocumentsLocation)},
{"TempLocation", QStandardPaths::writableLocation (QStandardPaths::TempLocation)},
{"HomeLocation", QStandardPaths::writableLocation (QStandardPaths::HomeLocation)},
{"CacheLocation", QStandardPaths::writableLocation (QStandardPaths::CacheLocation)},
{"GenericCacheLocation", QStandardPaths::writableLocation (QStandardPaths::GenericCacheLocation)},
{"GenericDataLocation", QStandardPaths::writableLocation (QStandardPaths::GenericDataLocation)},
{"AppDataLocation", QStandardPaths::writableLocation (QStandardPaths::AppDataLocation)},
{"AppLocalDataLocation", QStandardPaths::writableLocation (QStandardPaths::AppLocalDataLocation)},
};
// Parse the configration settings substituting the variable if found.
QString new_config;
int pos {0};
QRegularExpression subst_vars {R"(\${([^}]+)})"};
auto iter = subst_vars.globalMatch (config);
while (iter.hasNext ())
{
auto match = iter.next ();
auto const& name = match.captured (1);
auto repl_iter = replacements.find (name);
auto repl = repl_iter != replacements.end () ? repl_iter->second : "${" + name + "}";
new_config += config.mid (pos, match.capturedStart (1) - 2 - pos) + repl;
pos = match.capturedEnd (0);
}
new_config += config.mid (pos);
std::wstringbuf buffer {new_config.toStdWString (), std::ios_base::in};
std::wistream stream {&buffer};
try
{
Logger::init_from_config (stream);
LOG_INFO ("Read logging configuration file: " << log_config.fileName ());
}
catch (std::exception const& e)
{
default_log_config ();
LOG_ERROR ("Reading logging configuration file: " << log_config.fileName () << " - " << e.what ());
LOG_INFO ("Reverting to default logging configuration");
}
}
else // Default setup
{
default_log_config ();
}
::qInstallMessageHandler (&qt_log_handler);
}

1307
cty.dat

File diff suppressed because it is too large Load Diff

View File

@ -95,7 +95,7 @@ set (UG_IMGS
images/JT65B.png
images/keyboard-shortcuts.png
images/MSK144.png
images/QRA64.png
images/Q65_6m_ionoscatter.png
images/WSPR_WideGraphControls.png
images/WSPR_1a.png
images/WSPR_2.png
@ -224,7 +224,7 @@ foreach (lang ${LANGUAGES})
SOURCE user_guide/wsjtx-main.adoc
LANG "${lang}"
OUTPUT html
ASCIIDOCTOR_OPTIONS -d book -a data-uri -a toc=left -a max-width=1024px
ASCIIDOCTOR_OPTIONS -d book -a data-uri -a toc=left
DEPENDS ${common_SRCS} ${_sources}
)
document(

View File

@ -2,18 +2,20 @@
The _WSJT_ project was started by *K1JT* in 2001. Since 2005 it has
been an Open Source project, which now includes the programs _WSJT_,
_MAP65_, _WSPR_, _WSJT-X_, and _WSPR-X_. *G4WJS* (since 2013) and
*K9AN* (since 2015) have made major contributions to _WSJT-X_.
Together with K1JT they now form the core development team.
_MAP65_, _WSPR_, _WSJT-X_, and _WSPR-X_. *G4WJS* (since 2013), *K9AN*
(since 2015), and *IV3NWV* (since 2016) have made major contributions
to _WSJT-X_. Together with K1JT they now form the core development
team. *G4WJS* and *W9MDB* have made major contributiions to _hamlib_,
on which _WSJT-X_ depends for rig control.
All code in the _WSJT_ project is licensed under the GNU Public
License (GPL). Many users of these programs, too numerous to mention
here individually, have contributed suggestions and advice that have
greatly aided the development of _WSJT_ and its sister programs. For
_WSJT-X_ in particular, we acknowledge contributions from *AC6SL,
AE4JY, DJ0OT, G3WDG, G4KLA, IV3NWV, IW3RAB, K3WYC, KA6MAL, KA9Q,
AE4JY, DF2ET, DJ0OT, G3WDG, G4KLA, IW3RAB, K3WYC, KA1GT, KA6MAL, KA9Q,
KB1ZMX, KD6EKQ, KI7MT, KK1D, ND0B, PY2SDR, VE1SKY, VK3ACF, VK4BDJ,
VK7MO, W4TI, W4TV, and W9MDB*. Each of these amateurs has helped to
VK7MO, W3DJS, W4TI, W4TV, and W9MDB*. Each of these amateurs has helped to
bring the programs design, code, testing, and/or documentation to its
present state.

View File

@ -20,6 +20,7 @@ sky background temperature in the direction of the moon, scaled to the
operating frequency; *Dpol*, the spatial polarization offset in
degrees; *MNR*, the maximum non-reciprocity of the EME path in dB,
owing to a combination of Faraday rotation and spatial polarization;
*Dist*, the distance from your location to the moon, in km;
and finally *Dgrd*, an estimate of the signal degradation in dB,
relative to the best possible time with the moon at perigee in a cold
part of the sky.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

View File

@ -5,39 +5,38 @@ radio communication using very weak signals. The first four letters in
the program name stand for "`**W**eak **S**ignal communication by
K1**JT**,`" while the suffix "`*-X*`" indicates that _WSJT-X_ started
as an extended branch of an earlier program, _WSJT_, first released in
2001. Bill Somerville, G4WJS, and Steve Franke, K9AN, have been major
contributors to development of _WSJT-X_ since 2013 and 2015, respectively.
2001. Bill Somerville, G4WJS, Steve Franke, K9AN, and Nico Palermo,
IV3NWV, have been major contributors to development of _WSJT-X_ since
2013, 2015, and 2016, respectively.
_WSJT-X_ Version {VERSION_MAJOR}.{VERSION_MINOR} offers eleven
different protocols or modes: *FST4*, *FT4*, *FT8*, *JT4*, *JT9*,
*JT65*, *Q65*, *MSK144*, *WSPR*, *FST4W*, and *Echo*. The
first seven are designed for making reliable QSOs under weak-signal
*JT65*, *Q65*, *MSK144*, *WSPR*, *FST4W*, and *Echo*. The first seven
are designed for making reliable QSOs under weak-signal
conditions. They use nearly identical message structure and source
encoding. JT65 was designed for EME ("`moonbounce`") on VHF and
higher bands and is mostly used for that purpose today. Q65 replaces
an earlier mode, QRA64. Q65 is particularly effective for tropospheric
scatter, rain scatter, ionospheric scatter, TEP, and EME on VHF and
higher bands, as well as other types of fast-fading signals. JT9 was
originally designed for the HF and lower bands. Its submode JT9A is 1
dB more sensitive than JT65 while using less than 10% of the
bandwidth. JT4 offers a wide variety of tone spacings and has proven
highly effective for EME on microwave bands up to 24 GHz. These four
"`slow`" modes use one-minute timed sequences of alternating
transmission and reception, so a minimal QSO takes four to six minutes
— two or three transmissions by each station, one sending in odd UTC
minutes and the other even. FT8 is operationally similar but four
times faster (15-second T/R sequences) and less sensitive by a few dB.
FT4 is faster still (7.5 s T/R sequences) and especially well-suited
for radio contesting. FST4 was added to _WSJT-X_ in version 2.3.0.
It is intended especially for use on the LF and MF bands, and already
during its first few months of testing intercontinental paths have
been spanned many times on the 2200 and 630 m bands. Further details
can be found in the following section, <<NEW_FEATURES,New Features in
Version 2.4.0>>. On the HF bands, world-wide QSOs are possible with
any of these modes using power levels of a few watts (or even
milliwatts) and compromise antennas. On VHF bands and higher, QSOs
are possible (by EME, scatter, and other propagation types) at signal
levels 10 to 15 dB below those required for CW.
higher bands and is mostly used for that purpose today. Q65 is
particularly effective for tropospheric scatter, rain scatter,
ionospheric scatter, TEP, and EME on VHF and higher bands, as well as
other types of fast-fading signals. JT9 was designed for the HF and
lower bands. Its submode JT9A is 1 dB more sensitive than JT65 while
using less than 10% of the bandwidth. JT4 offers a wide variety of
tone spacings and has proven highly effective for EME on microwave
bands up to 24 GHz. The "`slow`" modes use timed sequences of
alternating transmission and reception. JT4, JT9, and JT65 use
one-minute sequences, so a minimal QSO takes four to six minutes — two
or three transmissions by each station, one sending in odd UTC minutes
and the other even. FT8 is four times faster (15-second T/R
sequences) and less sensitive by a few dB. FT4 is faster still (7.5 s
T/R sequences) and especially well-suited for radio contesting. FST4
is designed especially for the LF and MF bands. Both FST4 and Q65
offer a wide variety of timed sequence lengths, and Q65 a range of
tone spacings for different propagation conditions. On the HF bands,
world-wide QSOs are possible with any of these modes using power
levels of a few watts (or even milliwatts) and compromise antennas.
On VHF bands and higher, QSOs are possible (by EME, scatter, and other
propagation types) at signal levels 10 to 15 dB below those required
for CW.
*MSK144*, and optionally submodes *JT9E-H* are "`fast`"
protocols designed to take advantage of brief signal enhancements from

View File

@ -75,8 +75,8 @@ responder to your CQ.
NOTE: When *Auto-Seq* is enabled, the program de-activates *Enable Tx*
at the end of each QSO. It is not intended that _WSJT-X_ should make
fully automated QSOs. *Auto-sequencing is an operator aid, not an
operator replacement.*
fully automated QSOs. Auto-sequencing is an operator aid, not an
operator replacement.
[[CONTEST_MSGS]]
=== Contest Messages
@ -159,9 +159,9 @@ guidelines for contest logging with FT4, FT8, and MSK144:
[[COMP-CALL]]
=== Nonstandard Callsigns
*FST4, FT4, FT8, MSK144, and Q65*
*Modes with 77-bit message payloads: FST4, FT4, FT8, MSK144, and Q65*
Compound callsigns like xx/K1ABC or K1ABC/x and special event
Compound callsigns like PJ4/K1ABC or K1ABC/3 and special event
callsigns like YW18FIFA are supported for normal QSOs but not for
contest-style messages. Model QSOs look something like this:
@ -195,7 +195,7 @@ the types of information that can be included in a message. It
prevents including your locator in standard messages, which
necessarily impairs the usefulness of tools like PSK Reporter.
*JT4, JT9, and JT65*
*Modes with 72-bit message payloads: JT4, JT9, and JT65*
In the 72-bit modes, compound callsigns are handled in one of two
possible ways:

View File

@ -175,19 +175,20 @@ separation is 110250/4096 = 26.92 Hz multiplied by n for JT65A, with n
Q65 is intended for scatter, EME, and other extreme weak-signal
applications. Forward error correction (FEC) uses a specially
designed (65,15) block code with six-bit symbols. Two symbols are
“punctured” from the code, yielding an effective (63,13) code with a
payload of k = 13 information symbols conveyed by n = 63 channel
symbols. The punctured symbols consist of a 12-bit CRC computed from
the 13 information symbols. The CRC is used to reduce the
false-decode rate to a very low value. A 22-symbol pseudo-random
sequence spread throughout a transmission is sent as “tone 0” and used
for synchronization. The total number of channel symbols in a Q65
transmission is thus 63 + 22 = 85.
For each T/R sequence length, submodes A - E have tone spacings and
occupied bandwidths 1, 2, 4, 8, and 16 times those specified in the
above table. Full submode designations include a number for sequence
length and a letter for tone spacing, as in Q65-15A, Q65-120C, etc.
“punctured” from the code and not transmitted, thereby yielding an
effective (63,13) code with a payload of k = 13 information symbols
conveyed by n = 63 channel symbols. The punctured symbols consist of
a 12-bit CRC computed from the 13 information symbols. The CRC is
used to reduce the false-decode rate to a very low value. A 22-symbol
pseudorandom 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. Q65 offers T/R
sequence lengths of 15, 30, 60, 120, and 300 s, and submodes A - E
have tone spacings 1, 2, 4, 8, and 16 times the symbol rate. Submode
designations include a number for sequence length and a letter for
tone spacing, as in Q65-15A, Q65-120C, etc. Occupied bandwidths are
65 times the tone spacing, ranging from 19 Hz (Q65-300A) to a maximum
of 1733 Hz (Q65-15C, Q65-30D, and Q65-60E).
[[WSPR_PROTOCOL]]
==== WSPR

View File

@ -26,13 +26,7 @@ TIP: The PC audio mixer normally has two sliders, one for each
- If your transceiver offers more than one bandwidth setting in USB
mode, it may be advantageous to choose the widest one possible, up
to about 5 kHz. This choice has the desirable effect of allowing
the *Wide Graph* (waterfall and 2D spectrum) to display the
conventional JT65 and JT9 sub-bands simultaneously on most HF bands.
Further details are provided in the <<TUTORIAL,Basic Operating
Tutorial>>. A wider displayed bandwidth may also be helpful at VHF
and above, where FT8, JT4, JT65, and Q65 signals may be found over
much wider ranges of frequencies.
to about 5 kHz.
- If you have only a standard SSB filter you wont be able to display
more than about 2.7 kHz bandwidth. Depending on the exact dial

View File

@ -1,15 +1,15 @@
_WSJT-X_ supports a number of features designed for use on the VHF and
higher bands. These features include:
- *FT4*, designed especially for contesting
- *FT4*, for contesting
- *FT8*, designed for making fast QSOs with weak, fading signals
- *FT8*, for fast QSOs with weak, fading signals
- *JT4*, particularly useful for EME on the microwave bands
- *JT4*, for EME on the microwave bands
- *JT9 fast modes*, useful for scatter propagation on VHF bands
- *JT9 fast modes*, for scatter propagation on VHF bands
- *JT65*, widely used for EME on VHF and higher bands
- *JT65*, for EME on VHF and higher bands
- *Q65*, for ionospheric scatter, tropospheric scatter, rain scatter,
TEP, and EME
@ -175,29 +175,31 @@ image::JT65B.png[align="center",alt="JT65B"]
=== Q65
Q65 is designed for propagation paths that produce fast fading
signals: tropospheric scatter, rain scatter, ionospheric scatter,
trans-equatorial propagation (TEP), EME, and the like. The following
screen shot shows an example with submode Q65-30A on a 6-meter
ionospheric scatter path of about 1100 km.
Q65 is designed for fast-fading signals: tropospheric scatter, rain
scatter, ionospheric scatter, trans-equatorial propagation (TEP), EME,
and the like. The following screen shot shows a series of ionospheric
scatter QSOs using submode Q65-30A on the 6 meter band. The received
signals were barely audible most of the time.
image::Q65_6m_ionoscatter.png[align="center",alt="Q65"]
The Q65 decoder makes no use of a callsign database. Instead, it
takes advantage of _a priori_ (AP) information such as one's own
callsign and the message word `CQ`. In normal usage, as a QSO
progresses the available AP information increases to include the
callsign of the station being worked and perhaps also his/her 4-digit
The Q65 decoder takes advantage of _a priori_ (AP) information such as
the encoded forms of one's own callsign and the message word `CQ`. In
normal usage, as a QSO progresses AP information increases to include
the callsign of the station being worked and perhaps his/her 4-digit
grid locator. The decoder takes advantage of whatever AP information
is available.
is currently available.
For Q65 EME QSOs, particularly on the micriowave bands, some operators
For Q65 EME QSOs on the microwave bands, some operators
use short-form messages consisting of a single tone. To activate
automatic generation of these messages, check the box labeled *Sh*.
This also enables the generation of a single tone at 1000Hz by
selecting Tx6, to assist in finding signals initially. The box
labeled *Tx6* switches the Tx6 message from 1000Hz to 1250Hz to
indicate to the other station that you are ready to receive messages.
These short-form messages are not decoded automatically, and
auto-sequencing will not respond to them. You must recognize and
interpret them yourself.
// TIP: G3WDG has prepared a more detailed tutorial on using {QRA64_EME}.
@ -314,11 +316,12 @@ image::echo_144.png[align="center",alt="Echo 144 MHz"]
Until the advent of Q65, digital EME has mostly been done using JT65A
on the 50 MHz band, JT65B on 144 and 432 MHz, and JT65C on 1296 MHz.
On higher microwave bands typical choices have been JT65C or one of
the wider QRA64 or JT4 submodes, depending on the expected amount of
Doppler spread. We now recommend a suitable submodes of Q65 for EME
on all bands: for example, Q65-60A on 50 and 144 MHz, -60B on
432 MHz, -60C on 1296 MHz, and -60D on 10 GHz.
On higher microwave bands typical choices have been JT65C, one of the
wider JT4 submodes, or QRA64, depending on the expected amount of
Doppler spread. We now recommend a suitable submode of Q65 (which has
replaced QRA64) for EME on any VHF or higher band: for example,
Q65-60A on 50 and 144 MHz, Q65-60B on 432 MHz, Q65-60C on 1296 MHz,
and Q65-60D on 10 GHz.
JT4, JT65, and Q65 offer *Message Averaging* -- the summation of
subsequent transmissions that convey the same message -- to enable

View File

@ -6,7 +6,7 @@ Joseph H Taylor, Jr, K1JT
// package building .deb, .rpm, etc as it exposes the IP address and the images
// are non-free, so can't be included as part of the Debian package.
// :badges:
:docinfo1:
:docinfo: shared
:imagesdir: {docdir}/images
:icons: font
:numbered:

View File

@ -87,7 +87,7 @@ contains
! Determine the T/R sequence: iseq=0 (even), or iseq=1 (odd)
n=nutc
if(ntrperiod.ge.60) n=100*n
if(ntrperiod.ge.60 .and. nutc.le.2359) n=100*n
write(cutc,'(i6.6)') n
read(cutc,'(3i2)') ih,im,is
nsec=3600*ih + 60*im + is
@ -234,7 +234,9 @@ contains
nsnr=nint(snr2)
call this%callback(nutc,snr1,nsnr,dtdec,f0dec,decoded, &
idec,nused,ntrperiod)
if(iand(ndepth,128).ne.0) call q65_clravg !AutoClrAvg after decode
! if(iand(ndepth,128).ne.0) call q65_clravg !AutoClrAvg after decode
if(iand(ndepth,128).ne.0 .and. .not.lagain .and. &
int(abs(f0dec-nfqso)).le.ntol ) call q65_clravg !AutoClrAvg
call sec0(1,tdecode)
open(22,file=trim(data_dir)//'/q65_decodes.dat',status='unknown', &
position='append',iostat=ios)
@ -246,13 +248,13 @@ contains
if(c6.eq.' ') c6='<b> '
c4=hisgrid(1:4)
if(c4.eq.' ') c4='<b> '
fmt='(i6.4,1x,a4,4i2,6i3,i4,f6.2,f7.1,f6.1,f6.2,'// &
fmt='(i6.4,1x,a4,4i2,6i3,i4,f6.2,f7.1,f6.1,f7.1,f6.2,'// &
'1x,a6,1x,a6,1x,a4,1x,a)'
if(ntrperiod.le.30) fmt(5:5)='6'
if(idec.eq.3) nrc=0
write(22,fmt) nutc,cmode,nQSOprogress,idec,idfbest,idtbest,ibw, &
ndistbest,nused,icand,ncand,nrc,ndepth,xdt,f0,snr2,tdecode, &
mycall(1:6),c6,c4,trim(decoded)
ndistbest,nused,icand,ncand,nrc,ndepth,xdt,f0,snr2,plog, &
tdecode,mycall(1:6),c6,c4,trim(decoded)
close(22)
endif
! else
@ -316,7 +318,9 @@ contains
nsnr=nint(snr2)
call this%callback(nutc,snr1,nsnr,dtdec,f0dec,decoded, &
idec,nused,ntrperiod)
if(iand(ndepth,128).ne.0) call q65_clravg !AutoClrAvg after decode
! if(iand(ndepth,128).ne.0) call q65_clravg !AutoClrAvg after decode
if(iand(ndepth,128).ne.0 .and. .not.lagain .and. &
int(abs(f0dec-nfqso)).le.ntol ) call q65_clravg !AutoClrAvg
call sec0(1,tdecode)
open(22,file=trim(data_dir)//'/q65_decodes.dat',status='unknown', &
position='append',iostat=ios)
@ -328,13 +332,13 @@ contains
if(c6.eq.' ') c6='<b> '
c4=hisgrid(1:4)
if(c4.eq.' ') c4='<b> '
fmt='(i6.4,1x,a4,4i2,6i3,i4,f6.2,f7.1,f6.1,f6.2,'// &
fmt='(i6.4,1x,a4,4i2,6i3,i4,f6.2,f7.1,f6.1,f7.1,f6.2,'// &
'1x,a6,1x,a6,1x,a4,1x,a)'
if(ntrperiod.le.30) fmt(5:5)='6'
if(idec.eq.3) nrc=0
write(22,fmt) nutc,cmode,nQSOprogress,idec,idfbest,idtbest,ibw, &
ndistbest,nused,icand,ncand,nrc,ndepth,xdt,f0,snr2,tdecode, &
mycall(1:6),c6,c4,trim(decoded)
ndistbest,nused,icand,ncand,nrc,ndepth,xdt,f0,snr2,plog, &
tdecode,mycall(1:6),c6,c4,trim(decoded)
close(22)
endif
endif

View File

@ -20,8 +20,10 @@ module q65
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, allocatable,save :: ccf2(:) !Max CCF(freq) at any lag, single seq
real, allocatable,save :: ccf2_avg(:) !Like ccf2, but for accumulated average
real sync(85) !sync vector
real df,dtstep,dtdec,f0dec,ftol
real df,dtstep,dtdec,f0dec,ftol,plog
contains
@ -64,7 +66,6 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
logical first,lclearave
real, allocatable :: s3(:,:) !Data-symbol energies s3(LL,63)
real, allocatable :: ccf1(:) !CCF(freq) at fixed lag (red)
real, allocatable :: ccf2(:) !Max CCF(freq) at any lag (orange)
data first/.true./
save first
@ -98,7 +99,6 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
allocate(s3(-64:LL-65,63))
allocate(ccf1(-ia2:ia2))
allocate(ccf2(iz))
if(LL.ne.LL0 .or. iz.ne.iz0 .or. jz.ne.jz0 .or. lclearave) then
if(allocated(s1raw)) deallocate(s1raw)
allocate(s1raw(iz,jz))
@ -106,6 +106,10 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
allocate(s1(iz,jz))
if(allocated(s1a)) deallocate(s1a)
allocate(s1a(iz,jz,0:1))
if(allocated(ccf2)) deallocate(ccf2)
allocate(ccf2(iz))
if(allocated(ccf2_avg)) deallocate(ccf2_avg)
allocate(ccf2_avg(iz))
s1=0.
s1a=0.
navg=0
@ -114,6 +118,8 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
jz0=jz
lclearave=.false.
endif
ccf1=0.
ccf2_avg=0.
dtstep=nsps/(NSTEP*12000.0) !Step size in seconds
lag1=-1.0/dtstep
lag2=1.0/dtstep + 0.9999
@ -145,7 +151,7 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
enddo
dat4=0
if(ncw.gt.0 .and. iavg.lt.2) then
if(ncw.gt.0 .and. iavg.le.1) then
! Try list decoding via "Deep Likelihood".
call timer('ccf_85 ',0)
! Try to synchronize using all 85 symbols
@ -157,8 +163,14 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
call timer('list_dec',1)
endif
! Get 2d CCF and ccf2 using sync symbols only
if(iavg.eq.0) then
call q65_ccf_22(s1,iz,jz,nfqso,ipk,jpk,f0a,xdta,ccf2)
endif
! Get 2d CCF and ccf2 using sync symbols only
if(iavg.ge.1) then
call q65_ccf_22(s1,iz,jz,nfqso,ipk,jpk,f0a,xdta,ccf2_avg)
endif
if(idec.lt.0) then
f0=f0a
xdt=xdta
@ -188,7 +200,9 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
width=df*(i2-i1)
if(ncw.eq.0) ccf1=0.
call q65_write_red(iz,ia2,xdt,ccf1,ccf2)
! write(*,3001) nutc,iavg,navg(0),sum(ccf2_avg),sum(ccf2)
!3001 format(i4.4,2i4,2f8.2)
call q65_write_red(iz,xdt,ccf2_avg,ccf2)
if(iavg.eq.2) then
call q65_dec_q012(s3,LL,snr2,dat4,idec,decoded)
@ -555,28 +569,28 @@ subroutine q65_s1_to_s3(s1,iz,jz,ipk,jpk,LL,mode_q65,sync,s3)
return
end subroutine q65_s1_to_s3
subroutine q65_write_red(iz,ia2,xdt,ccf1,ccf2)
subroutine q65_write_red(iz,xdt,ccf2_avg,ccf2)
! Write data for the red and orange sync curves to LU 17.
real ccf1(-ia2:ia2)
real ccf2_avg(iz)
real ccf2(iz)
call q65_sync_curve(ccf1,-ia2,ia2,rms1)
call q65_sync_curve(ccf2_avg,1,iz,rms1)
call q65_sync_curve(ccf2,1,iz,rms2)
rewind 17
write(17,1000) xdt
do i=1,iz
do i=max(1,nint(nfa/df)),nint(nfb/df)
freq=i*df
ii=i-i0
if(freq.ge.float(nfa) .and. freq.le.float(nfb)) then
ccf1a=-99.0
if(ii.ge.-ia2 .and. ii.le.ia2) ccf1a=ccf1(ii)
write(17,1000) freq,ccf1a,ccf2(i)
y1=ccf2_avg(i)
if(y1.gt.10.0) y1=10.0 + 2.0*log10(y1/10.0)
y2=ccf2(i)
if(y2.gt.10.0) y2=10.0 + 2.0*log10(y2/10.0)
write(17,1000) freq,y1,y2
1000 format(3f10.3)
endif
enddo
flush(17)
return
end subroutine q65_write_red
@ -596,9 +610,9 @@ subroutine q65_sync_curve(ccf1,ia,ib,rms1)
dot_product(ccf1(ib-ic:ib),ccf1(ib-ic:ib))
rms1=0.
if(nsum.gt.0) rms1=sqrt(sq/nsum)
if(rms1.gt.0.0) ccf1=2.0*ccf1/rms1
smax1=maxval(ccf1)
if(smax1.gt.10.0) ccf1=10.0*ccf1/smax1
if(rms1.gt.0.0) ccf1=ccf1/rms1
! smax1=maxval(ccf1)
! if(smax1.gt.10.0) ccf1=10.0*ccf1/smax1
return
end subroutine q65_sync_curve

View File

@ -1,164 +0,0 @@
subroutine sync64(c0,nf1,nf2,nfqso,ntol,minsync,mode64,emedelay,dtx,f0, &
jpk,sync,sync2,width)
use timer_module, only: timer
parameter (NMAX=60*12000) !Max size of raw data at 12000 Hz
parameter (NSPS=3456) !Samples per symbol at 6000 Hz
parameter (NSPC=7*NSPS) !Samples per Costas waveform
real s1(0:NSPC-1) !Power spectrum of Costas 1
real s2(0:NSPC-1) !Power spectrum of Costas 2
real s3(0:NSPC-1) !Power spectrum of Costas 3
real s0(0:NSPC-1) !Sum of s1+s2+s3
real s0a(0:NSPC-1) !Best synchromized spectrum (saved)
real s0b(0:NSPC-1) !tmp
real a(5) !Parameters of Lorentzian fit
integer icos7(0:6) !Costas 7x7 tones
integer ipk0(1)
complex cc(0:NSPC-1) !Costas waveform
complex c0(0:720000) !Complex spectrum of dd()
complex c1(0:NSPC-1) !Complex spectrum of Costas 1
complex c2(0:NSPC-1) !Complex spectrum of Costas 2
complex c3(0:NSPC-1) !Complex spectrum of Costas 3
data icos7/2,5,6,0,4,1,3/ !Costas 7x7 tone pattern
data mode64z/-1/
save
if(mode64.ne.mode64z) then
! Submode has changed, recompute the complex Costas waveform
twopi=8.0*atan(1.0)
dfgen=mode64*12000.0/6912.0
k=-1
phi=0.
do j=0,6
dphi=twopi*10.0*icos7(j)*dfgen/6000.0
do i=1,NSPS
phi=phi + dphi
if(phi.gt.twopi) phi=phi-twopi
k=k+1
cc(k)=cmplx(cos(phi),sin(phi))
enddo
enddo
mode64z=mode64
endif
nfft3=NSPC
df3=6000.0/nfft3
fa=max(nf1,nfqso-ntol)
fb=min(nf2,nfqso+ntol)
iaa=max(0,nint(fa/df3))
ibb=min(NSPC-1,nint(fb/df3))
maxtol=max(ntol,500)
fa=max(nf1,nfqso-maxtol)
fb=min(nf2,nfqso+maxtol)
ia=max(0,nint(fa/df3))
ib=min(NSPC-1,nint(fb/df3))
id=0.1*(ib-ia)
iz=ib-ia+1
sync=-1.e30
smaxall=0.
jpk=0
ja=0
! jb=(5.0+emedelay)*6000 !Bigger range than necessary?
jb=(2.0+emedelay)*6000 !Bigger range than necessary?
jstep=100
ipk=0
kpk=0
nadd=10*mode64
if(minsync.eq.-2) nadd=10 !###
if(mod(nadd,2).eq.0) nadd=nadd+1 !Make nadd odd
nskip=max(49,nadd)
do j1=ja,jb,jstep !Loop over DT
call timer('sync64_1',0)
j2=j1 + 39*NSPS
j3=j1 + 77*NSPS
c1=1.e-4*c0(j1:j1+NSPC-1) * conjg(cc)
c2=1.e-4*c0(j2:j2+NSPC-1) * conjg(cc)
c3=1.e-4*c0(j3:j3+NSPC-1) * conjg(cc)
call four2a(c1,nfft3,1,-1,1)
call four2a(c2,nfft3,1,-1,1)
call four2a(c3,nfft3,1,-1,1)
s1=0.
s2=0.
s3=0.
s0b=0.
do i=ia,ib
freq=i*df3
s1(i)=real(c1(i))**2 + aimag(c1(i))**2
s2(i)=real(c2(i))**2 + aimag(c2(i))**2
s3(i)=real(c3(i))**2 + aimag(c3(i))**2
enddo
call timer('sync64_1',1)
call timer('sync64_2',0)
s0(ia:ib)=s1(ia:ib) + s2(ia:ib) + s3(ia:ib)
s0(:ia-1)=0.
s0(ib+1:)=0.
if(nadd.ge.3) then !Smooth the spectrum
iiz=3
if(minsync.eq.-2) iiz=1
do ii=1,iiz !### Was ii=1,3
s0b(ia:ib)=s0(ia:ib)
call smo(s0b(ia:ib),iz,s0(ia:ib),nadd)
enddo
endif
call averms(s0(ia+id:ib-id),iz-2*id,nskip,ave,rms)
s=(maxval(s0(iaa:ibb))-ave)/rms
ipk0=maxloc(s0(iaa:ibb))
ip=ipk0(1) + iaa - 1
if(s.gt.sync) then
jpk=j1
s0a=(s0-ave)/rms
sync=s
dtx=jpk/6000.0 - 1.0
ipk=ip
f0=ip*df3
endif
call timer('sync64_2',1)
enddo ! j1 (DT loop)
s0a=s0a+2.0
nskip=50
call lorentzian(s0a(ia+nskip:ib-nskip),iz-2*nskip,a)
f0a=(a(3)+ia+49)*df3
w1=df3*a(4)
w2=2*nadd*df3
width=w1
if(w1.gt.1.2*w2) width=sqrt(w1**2 - w2**2)
sq=0.
do i=1,20
j=ia+nskip+1
k=ib-nskip-21+i
sq=sq + (s0a(j)-a(1))**2 + (s0a(k)-a(1))**2
enddo
rms2=sqrt(sq/40.0)
sync2=10.0*log10(a(2)/rms2)
slimit=6.0
rewind 17
write(17,1110) 0.0,0.0
rewind 17
do i=2,iz-2*nskip-1,3
x=i
z=(x-a(3))/(0.5*a(4))
yfit=a(1)
if(abs(z).lt.3.0) then
d=1.0 + z*z
yfit=a(1) + a(2)*(1.0/d - 0.1)
endif
j=i+ia+49
freq=j*df3
ss=(s0a(j-1)+s0a(j)+s0a(j+1))/3.0
if(ss.gt.slimit) write(17,1110) freq,ss
1110 format(3f10.3)
enddo
flush(17)
close(17)
return
end subroutine sync64

View File

@ -21,7 +21,6 @@ set (SAMPLE_FILES
JT9/130418_1742.wav
MSK144/181211_120500.wav
MSK144/181211_120800.wav
QRA64/QRA64C/161113_0111.wav
WSPR/150426_0918.wav
Q65/30A_Ionoscatter_6m/201203_022700.wav
Q65/30A_Ionoscatter_6m/201203_022800.wav

View File

@ -21,7 +21,7 @@ CAboutDlg::CAboutDlg(QWidget *parent) :
"&copy; 2001-2021 by Joe Taylor, K1JT, Bill Somerville, G4WJS, <br />"
"and Steve Franke, K9AN. <br /><br />"
"We gratefully acknowledge contributions from AC6SL, AE4JY,<br />"
"DF2ET, DJ0OT, G3WDG, G4KLA, IV3NWV, IW3RAB, KA1GT, K3WYC,<br />"
"DF2ET, DJ0OT, G3WDG, G4KLA, IW3RAB, K3WYC, KA1GT,<br />"
"KA6MAL, KA9Q, KB1ZMX, KD6EKQ, KI7MT, KK1D, ND0B, PY2SDR,<br />"
"VE1SKY, VK3ACF, VK4BDJ, VK7MO, W3DJS, W4TI, W4TV, and W9MDB.<br /><br />"
"WSJT-X is licensed under the terms of Version 3 <br />"

View File

@ -3293,7 +3293,6 @@ void MainWindow::to_jt9(qint32 n, qint32 istart, qint32 idone)
void MainWindow::decodeDone ()
{
if(m_mode!="FT8" or dec_data.params.nzhsym==50) m_nDecodes=0;
if(m_mode=="Q65") m_wideGraph->drawRed(0,0);
if ("FST4W" == m_mode)
{
@ -3310,11 +3309,20 @@ void MainWindow::decodeDone ()
double tdone = fmod(double(tnow.time().second()),m_TRperiod);
int mswait;
if( tdone < 0.5*m_TRperiod ) {
mswait = 1000.0 * ( 0.75 * m_TRperiod - tdone );
mswait = 1000.0 * ( 0.6 * m_TRperiod - tdone );
} else {
mswait = 1000.0 * ( 1.75 * m_TRperiod - tdone );
mswait = 1000.0 * ( 1.6 * m_TRperiod - tdone );
}
if(!m_diskData) killFileTimer.start(mswait); //Kill at 3/4 period
m_bDecoded=m_nDecodes>0;
// qDebug() << "aa 3316" << m_saveDecoded << m_saveAll << m_bDecoded << m_nDecodes
// << m_TRperiod << tdone << mswait;
if(!m_diskData and !m_saveAll) {
if(m_saveDecoded and (m_nDecodes==0)) {
// qDebug() << "bb 3319" << mswait;
killFileTimer.start(mswait); //Kill at 3/4 period
}
}
if(m_mode!="FT8" or dec_data.params.nzhsym==50) m_nDecodes=0;
dec_data.params.nagain=0;
dec_data.params.ndiskdat=0;
@ -3717,6 +3725,7 @@ void MainWindow::pskPost (DecodedText const& decodedtext)
void MainWindow::killFile ()
{
// qDebug() << "cc 3725" << m_saveDecoded << m_saveAll << m_bDecoded << m_nDecodes << m_fnameWE;
if (m_fnameWE.size () && !(m_saveAll || (m_saveDecoded && m_bDecoded))) {
QFile f1 {m_fnameWE + ".wav"};
if(f1.exists()) f1.remove();
@ -4029,8 +4038,8 @@ void MainWindow::guiUpdate()
if(m_tune or m_mode=="Echo") {
itone[0]=0;
} else {
if(m_QSOProgress==2 or m_QSOProgress==3) m_bSentReport=true;
if(m_bSentReport and (m_QSOProgress<2 or m_QSOProgress>3)) m_bSentReport=false;
if(m_QSOProgress==REPORT || m_QSOProgress==ROGER_REPORT) m_bSentReport=true;
if(m_bSentReport and (m_QSOProgress<REPORT or m_QSOProgress>ROGER_REPORT)) m_bSentReport=false;
if(m_modeTx=="JT4") gen4_(message, &ichk , msgsent, const_cast<int *> (itone),
&m_currentMessageType, 22, 22);
if(m_modeTx=="JT9") gen9_(message, &ichk, msgsent, const_cast<int *> (itone),
@ -4997,7 +5006,7 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie
auto const& word_3 = message_words.at (3);
auto word_3_as_number = word_3.toInt ();
if (("RRR" == word_3
|| word_3_as_number == 73
|| (word_3_as_number == 73 && ROGERS == m_QSOProgress)
|| "RR73" == word_3
|| ("R" == word_3 && m_QSOProgress != REPORT))) {
if(m_mode=="FT4" and "RR73" == word_3) m_dateTimeRcvdRR73=QDateTime::currentDateTimeUtc();
@ -5026,11 +5035,31 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie
m_ntx=4;
ui->txrb4->setChecked(true);
}
else
else if ((m_QSOProgress > CALLING && m_QSOProgress < ROGERS)
|| word_3.contains (QRegularExpression {"^RR(?:R|73)$"}))
{
m_ntx=5;
ui->txrb5->setChecked(true);
}
else if (ROGERS == m_QSOProgress)
{
logQSOTimer.start(0);
m_ntx=6;
ui->txrb6->setChecked(true);
}
else
{
// just work them (again)
if (ui->tx1->isEnabled ()) {
m_ntx = 1;
m_QSOProgress = REPLYING;
ui->txrb1->setChecked (true);
} else {
m_ntx=2;
m_QSOProgress = REPORT;
ui->txrb2->setChecked (true);
}
}
}
if (m_QSOProgress >= ROGER_REPORT)
{
@ -5182,10 +5211,10 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie
lookup();
m_hisGrid = ui->dxGridEntry->text();
QString rpt = message.report();
int n=rpt.toInt();
if (!m_bSentReport || base_call != qso_partner_base_call) // Don't change report within a QSO
{
auto n = message.report ().toInt ();
if(m_mode=="MSK144" and m_bShMsgs) {
int n=rpt.toInt();
if(n<=-2) n=-3;
if(n>=-1 and n<=1) n=0;
if(n>=2 and n<=4) n=3;
@ -5193,14 +5222,13 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie
if(n>=8 and n<=11) n=10;
if(n>=12 and n<=14) n=13;
if(n>=15) n=16;
rpt=QString::number(n);
}
if(!m_bSentReport) ui->rptSpinBox->setValue(n); //Don't change report within a QSO
ui->rptSpinBox->setValue (n);
}
// Don't genStdMsgs if we're already sending 73, or a "TU; " msg is queued.
m_bTUmsg=false; //### Temporary: disable use of "TU;" messages
if (!m_bSentReport and !m_nTx73 and !m_bTUmsg) {
genStdMsgs(rpt);
if (!m_nTx73 and !m_bTUmsg) {
genStdMsgs (QString::number (ui->rptSpinBox->value ()));
}
if(m_transmitting) m_restart=true;
if (ui->cbAutoSeq->isVisible () && ui->cbAutoSeq->isChecked ()
@ -6406,7 +6434,6 @@ void MainWindow::on_actionJT65_triggered()
void MainWindow::on_actionQ65_triggered()
{
// on_actionFST4_triggered();
m_mode="Q65";
m_modeTx="Q65";
ui->actionQ65->setChecked(true);
@ -6432,11 +6459,19 @@ void MainWindow::on_actionQ65_triggered()
switch_mode (Modes::Q65);
// 0123456789012345678901234567890123456
displayWidgets(nWidgets("1111110101101101001110000001000000001"));
ui->labDXped->setText("");
ui->lh_decodes_title_label->setText(tr ("Single-Period Decodes"));
ui->rh_decodes_title_label->setText(tr ("Average Decodes"));
ui->lh_decodes_headings_label->setText("UTC dB DT Freq " + tr ("Message"));
ui->rh_decodes_headings_label->setText("UTC dB DT Freq " + tr ("Message"));
statusChanged();
if(SpecOp::NONE < m_config.special_op_id()) {
ui->labDXped->setVisible(true);
ui->labDXped->setText("Contest ?");
} else {
ui->labDXped->setVisible(false);
ui->labDXped->setText("");
}
}
void MainWindow::on_actionMSK144_triggered()
@ -6684,6 +6719,16 @@ void MainWindow::on_TxFreqSpinBox_valueChanged(int n)
if(m_mode!="MSK144") {
Q_EMIT transmitFrequency (n - m_XIT);
}
if(m_mode=="Q65") {
if(((m_nSubMode==4 && m_TRperiod==60.0) || (m_nSubMode==3 && m_TRperiod==30.0) ||
(m_nSubMode==2 && m_TRperiod==15.0)) && ui->TxFreqSpinBox->value()!=700) {
ui->TxFreqSpinBox->setStyleSheet("QSpinBox{background-color:red}");
} else {
ui->TxFreqSpinBox->setStyleSheet("");
}
}
statusUpdate ();
}
@ -7562,9 +7607,7 @@ void MainWindow::on_sbTR_valueChanged(int value)
progressBar.setMaximum (value);
}
if(m_mode=="FST4") chk_FST4_freq_range();
if(m_transmitting) {
on_stopTxButton_clicked();
}
// if(m_transmitting) on_stopTxButton_clicked(); //### Is this needed or desirable? ###
on_sbSubmode_valueChanged(ui->sbSubmode->value());
statusUpdate ();
}
@ -7598,10 +7641,11 @@ void MainWindow::on_sbSubmode_valueChanged(int n)
mode_label.setText (m_mode);
}
if(m_mode=="Q65") {
if((m_nSubMode==4 && m_TRperiod==60.0) || (m_nSubMode==3 && m_TRperiod==30.0) || (m_nSubMode==2 && m_TRperiod==15.0))
{ ui->TxFreqSpinBox->setValue(700);
if(((m_nSubMode==4 && m_TRperiod==60.0) || (m_nSubMode==3 && m_TRperiod==30.0) ||
(m_nSubMode==2 && m_TRperiod==15.0)) && ui->TxFreqSpinBox->value()!=700) {
ui->TxFreqSpinBox->setStyleSheet("QSpinBox{background-color:red}");
} else {
ui->TxFreqSpinBox->setValue(1000);
ui->TxFreqSpinBox->setStyleSheet("");
}
}
if(m_mode=="JT9") {

View File

@ -239,7 +239,7 @@ void CPlotter::draw(float swide[], bool bScroll, bool bRed)
if(y2>y2max) y2max=y2;
j++;
}
if(m_bReplot) return;
if(m_bReplot and m_mode!="Q65") return;
if(swide[0]>1.0e29) m_line=0;
if(m_mode=="FT4" and m_line==34) m_line=0;
@ -274,7 +274,7 @@ void CPlotter::draw(float swide[], bool bScroll, bool bRed)
painter2D.drawText(x1-4,y,"73");
}
if(bRed and m_bQ65_Sync) { //Plot the Q65 red or orange sync curve
if(bRed and m_bQ65_Sync) { //Plot the Q65 red/orange sync curves
int k=0;
int k2=0;
std::ifstream f;
@ -283,9 +283,10 @@ void CPlotter::draw(float swide[], bool bScroll, bool bRed)
int x,y;
float freq,xdt,sync,sync2;
f >> xdt;
if(f) {
for(int i=0; i<99999; i++) {
f >> freq >> sync >> sync2;
if(f.eof()) break;
if(!f or f.eof()) break;
x=XfromFreq(freq);
if(sync > -99.0 and sync != 0.0) {
y=m_h2*(0.9 - 0.09*gain2d*sync) - m_plot2dZero - 10;
@ -298,6 +299,7 @@ void CPlotter::draw(float swide[], bool bScroll, bool bRed)
LineBuf3[k].setY(y);
k++;
}
}
f.close();
QPen pen0(Qt::red,2);
painter2D.setPen(pen0);
@ -335,6 +337,9 @@ void CPlotter::replot()
plotsave_(swide,&m_w,&m_h1,&irow);
draw(swide,false,false);
}
if(m_mode=="Q65" and m_bQ65_Sync) {
draw(swide,false,true);
}
update(); //trigger a new paintEvent
m_bReplot=false;
}
@ -623,7 +628,6 @@ void CPlotter::MakeFrequencyStrs() //MakeFrequencyStrs
int CPlotter::XfromFreq(float f) //XfromFreq()
{
// float w = m_WaterfallPixmap.width();
int x = int(m_w * (f - m_startFreq)/m_fSpan + 0.5);
if(x<0 ) return 0;
if(x>m_w) return m_w;
@ -765,6 +769,7 @@ void CPlotter::mouseReleaseEvent (QMouseEvent * event)
else {
event->ignore (); // let parent handle
}
// replot(); // ### Not needed? ###
}
void CPlotter::mouseDoubleClickEvent (QMouseEvent * event)
@ -774,8 +779,7 @@ void CPlotter::mouseDoubleClickEvent (QMouseEvent * event)
int n=2;
if(ctrl) n+=100;
emit freezeDecode1(n);
}
else {
} else {
event->ignore (); // let parent handle
}
}