mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-25 13:48:42 -05:00
Merge branch 'master' into develop
This commit is contained in:
commit
f0945282dd
@ -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
|
||||
)
|
||||
|
@ -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
|
||||
|
18
Darwin/com.wsjtx.sysctl.plist
Normal file
18
Darwin/com.wsjtx.sysctl.plist
Normal 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>
|
@ -1,5 +0,0 @@
|
||||
kern.sysv.shmmax=52428800
|
||||
kern.sysv.shmmin=1
|
||||
kern.sysv.shmmni=128
|
||||
kern.sysv.shmseg=32
|
||||
kern.sysv.shmall=25600
|
@ -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)
|
||||
|
@ -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
41
NEWS
@ -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
|
||||
|
@ -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
|
||||
|
117
WSJTXLogging.cpp
117
WSJTXLogging.cpp
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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 program’s design, code, testing, and/or documentation to its
|
||||
present state.
|
||||
|
||||
|
@ -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 |
BIN
doc/user_guide/en/images/Q65_6m_ionoscatter.png
Normal file
BIN
doc/user_guide/en/images/Q65_6m_ionoscatter.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 229 KiB |
Binary file not shown.
Before Width: | Height: | Size: 88 KiB |
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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 won’t be able to display
|
||||
more than about 2.7 kHz bandwidth. Depending on the exact dial
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
164
lib/sync64.f90
164
lib/sync64.f90
@ -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
|
@ -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
|
||||
|
@ -21,7 +21,7 @@ CAboutDlg::CAboutDlg(QWidget *parent) :
|
||||
"© 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 />"
|
||||
|
@ -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") {
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user