Merge branch 'release-2.5.0'
@ -26,7 +26,7 @@ if (WIN32)
|
||||
add_custom_command (
|
||||
OUTPUT ${outfile}.h ${outfile}.cpp
|
||||
COMMAND ${DUMPCPP_Executable}
|
||||
ARGS ${AX_SERVER_options} -o "${outfile}" "${infile}"
|
||||
ARGS ${ax_server_options} -o "${outfile}" "${infile}"
|
||||
MAIN_DEPENDENCY ${infile} VERBATIM)
|
||||
list (APPEND ${outfiles} ${outfile}.cpp)
|
||||
endforeach()
|
||||
|
@ -71,7 +71,7 @@ message (STATUS "******************************************************")
|
||||
|
||||
include (set_build_type)
|
||||
# RC 0 or omitted is a development build, GA is a General Availability release build
|
||||
set_build_type (RC 3)
|
||||
set_build_type (RC 4)
|
||||
set (wsjtx_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}${BUILD_TYPE_REVISION}")
|
||||
|
||||
#
|
||||
|
@ -2735,6 +2735,7 @@ bool Configuration::impl::open_rig (bool force)
|
||||
|
||||
ui_->test_CAT_push_button->setStyleSheet ({});
|
||||
rig_active_ = true;
|
||||
LOG_TRACE ("emitting startup_transceiver");
|
||||
Q_EMIT start_transceiver (++transceiver_command_number_); // start rig on its thread
|
||||
result = true;
|
||||
}
|
||||
@ -2782,6 +2783,7 @@ void Configuration::impl::transceiver_frequency (Frequency f)
|
||||
cached_rig_state_.frequency (apply_calibration (f + current_offset_));
|
||||
|
||||
// qDebug () << "Configuration::impl::transceiver_frequency: n:" << transceiver_command_number_ + 1 << "f:" << f;
|
||||
LOG_TRACE ("emitting set_transceiver: requested state:" << cached_rig_state_);
|
||||
Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_);
|
||||
}
|
||||
|
||||
@ -2808,6 +2810,7 @@ void Configuration::impl::transceiver_tx_frequency (Frequency f)
|
||||
}
|
||||
|
||||
// qDebug () << "Configuration::impl::transceiver_tx_frequency: n:" << transceiver_command_number_ + 1 << "f:" << f;
|
||||
LOG_TRACE ("emitting set_transceiver: requested state:" << cached_rig_state_);
|
||||
Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_);
|
||||
}
|
||||
}
|
||||
@ -2817,6 +2820,7 @@ void Configuration::impl::transceiver_mode (MODE m)
|
||||
cached_rig_state_.online (true); // we want the rig online
|
||||
cached_rig_state_.mode (m);
|
||||
// qDebug () << "Configuration::impl::transceiver_mode: n:" << transceiver_command_number_ + 1 << "m:" << m;
|
||||
LOG_TRACE ("emitting set_transceiver: requested state:" << cached_rig_state_);
|
||||
Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_);
|
||||
}
|
||||
|
||||
@ -2826,6 +2830,7 @@ void Configuration::impl::transceiver_ptt (bool on)
|
||||
set_cached_mode ();
|
||||
cached_rig_state_.ptt (on);
|
||||
// qDebug () << "Configuration::impl::transceiver_ptt: n:" << transceiver_command_number_ + 1 << "on:" << on;
|
||||
LOG_TRACE ("emitting set_transceiver: requested state:" << cached_rig_state_);
|
||||
Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_);
|
||||
}
|
||||
|
||||
@ -2909,6 +2914,7 @@ void Configuration::impl::close_rig ()
|
||||
if (rig_active_)
|
||||
{
|
||||
ui_->test_CAT_push_button->setStyleSheet ("QPushButton {background-color: red;}");
|
||||
LOG_TRACE ("emitting stop_transceiver");
|
||||
Q_EMIT stop_transceiver ();
|
||||
for (auto const& connection: rig_connections_)
|
||||
{
|
||||
|
@ -6,7 +6,7 @@ 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 or later, of WSJT-X or you have upgraded macOS.
|
||||
are moving from v2.3 to v2.4 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.
|
||||
|
||||
@ -25,7 +25,7 @@ change has been made by typing:
|
||||
|
||||
sysctl -a | grep sysv.shm
|
||||
|
||||
If shmmax is not shown as 52428800 then contact me since WSJT-X will fail to load with
|
||||
If shmmax is not shown as 52428800 then contact me since WSJT-X might fail to load with
|
||||
an error message: "Unable to create shared memory segment".
|
||||
|
||||
You can now close the Terminal window. It will not be necessary to repeat this procedure
|
||||
@ -72,7 +72,9 @@ Please email me if you have problems.
|
||||
|
||||
--- John G4KLA (g4kla@rmnjmn.co.uk)
|
||||
|
||||
Addendum: Information about com.wsjtx.sysctl.plist and multiple instances of WSJT-X.
|
||||
Additional Notes:
|
||||
|
||||
1. 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
|
||||
@ -87,7 +89,8 @@ simultaneously, the shmall parameter in the com.wsjtx.sysctl.plist file needs to
|
||||
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.
|
||||
Remember to reboot your Mac afterwards.
|
||||
Replace your new version of this file in /Library/LaunchDaemons and 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
|
||||
@ -96,4 +99,15 @@ be changed.
|
||||
If two instances of WSJT-X are running, it is likely that you might need additional
|
||||
audio devices, from two rigs for example. Visit Audio MIDI Setup and create an Aggregate Device
|
||||
which will allow you to specify more than one interface. I recommend you consult Apple's guide
|
||||
on combining multiple audio interfaces which is at https://support.apple.com/en-us/HT202000.
|
||||
on combining multiple audio interfaces which is at https://support.apple.com/en-us/HT202000.
|
||||
|
||||
2. Preventing WSJT-X from being put into 'sleep' mode (App Nap).
|
||||
|
||||
In normal circumstances an application which has not been directly accessed for a while can be
|
||||
subject to App Nap which means it is suspended until such time as its windows are accessed. If
|
||||
it is intended that WSJT-X should be submitting continued reports to, for example, PSK Reporter
|
||||
then reporting will be interrupted. App Nap can be disabled as follows, but first quit WSJT-X:
|
||||
|
||||
Open a Terminal window and type: defaults write org.k1jt.wsjtx NSAppSleepDisable -bool YES
|
||||
If you type: defaults read org.k1jt.wsjtx then the response will be: NSAppSleepDisable = 1;
|
||||
Close the Terminal window and launch WSJT-X. (If you 'Hide' WSJT-X, this scheme will be suspended.)
|
||||
|
20
NEWS
@ -12,6 +12,26 @@
|
||||
Copyright 2001 - 2021 by Joe Taylor, K1JT.
|
||||
|
||||
|
||||
Release: WSJT-X 2.5.0-rc4
|
||||
Aug 2, 2021
|
||||
-------------------------
|
||||
|
||||
Remember that the WSJT-X 2.5.0 package includes MAP65 3.0.0. Changes
|
||||
in the package since WSJT-X 2.5.0-rc3 include the following
|
||||
enhancements and defect repairs:
|
||||
|
||||
MAP65:
|
||||
- Suppress display of duplicate decodes
|
||||
- Increase the length of .tf2 & .iq files to 56 s
|
||||
- Implements an early decoding pass at 52 s
|
||||
|
||||
WSJT-X:
|
||||
- Repair a defect in CALL3.TXT lookups that incorrectly matched
|
||||
partial calls
|
||||
- Instructions in macOS ReadMe.txt to suppress App Nap energy saving
|
||||
- Revised User Guide using FT8 mode for the basic tutorial
|
||||
- Allow contest and FD operating in Q65 mode
|
||||
|
||||
Release: WSJT-X 2.5.0-rc3
|
||||
Jul 5, 2021
|
||||
-------------------------
|
||||
|
26
Radio.cpp
@ -42,6 +42,15 @@ namespace Radio
|
||||
value = v.toDouble ();
|
||||
if (ok) *ok = true;
|
||||
}
|
||||
if (ok && !*ok)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
return frequency (value, scale, ok);
|
||||
}
|
||||
|
||||
Frequency frequency (double value, int scale, bool * ok)
|
||||
{
|
||||
value *= std::pow (10., scale);
|
||||
if (ok)
|
||||
{
|
||||
@ -50,6 +59,10 @@ namespace Radio
|
||||
value = 0.;
|
||||
*ok = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ok = true;
|
||||
}
|
||||
}
|
||||
return std::llround (value);
|
||||
}
|
||||
@ -66,6 +79,15 @@ namespace Radio
|
||||
value = v.toDouble ();
|
||||
if (ok) *ok = true;
|
||||
}
|
||||
if (ok && !*ok)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
return frequency_delta (value, scale, ok);
|
||||
}
|
||||
|
||||
FrequencyDelta frequency_delta (double value, int scale, bool * ok)
|
||||
{
|
||||
value *= std::pow (10., scale);
|
||||
if (ok)
|
||||
{
|
||||
@ -75,6 +97,10 @@ namespace Radio
|
||||
value = 0.;
|
||||
*ok = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ok = true;
|
||||
}
|
||||
}
|
||||
return std::llround (value);
|
||||
}
|
||||
|
@ -34,10 +34,12 @@ namespace Radio
|
||||
// QVariant argument is convertible to double and is assumed to
|
||||
// be scaled by (10 ** -scale).
|
||||
//
|
||||
Frequency UDP_EXPORT frequency (QVariant const&, int scale,
|
||||
Frequency UDP_EXPORT frequency (QVariant const&, int scale = 0,
|
||||
bool * ok = nullptr, QLocale const& = QLocale ());
|
||||
FrequencyDelta UDP_EXPORT frequency_delta (QVariant const&, int scale,
|
||||
FrequencyDelta UDP_EXPORT frequency_delta (QVariant const&, int scale = 0,
|
||||
bool * ok = nullptr, QLocale const& = QLocale ());
|
||||
Frequency UDP_EXPORT frequency (double, int scale = 0, bool * ok = nullptr);
|
||||
FrequencyDelta UDP_EXPORT frequency_delta (double, int scale = 0, bool * ok = nullptr);
|
||||
|
||||
//
|
||||
// Frequency type formatting
|
||||
|
@ -12,6 +12,27 @@
|
||||
Copyright 2001 - 2021 by Joe Taylor, K1JT.
|
||||
|
||||
|
||||
Release: WSJT-X 2.5.0-rc4
|
||||
Aug 2, 2021
|
||||
-------------------------
|
||||
|
||||
Remember that the WSJT-X 2.5.0 package includes MAP65 3.0.0. Changes
|
||||
in the package since WSJT-X 2.5.0-rc3 include the following
|
||||
enhancements and defect repairs:
|
||||
|
||||
MAP65:
|
||||
- Suppress display of duplicate decodes
|
||||
- Increase the length of .tf2 & .iq files to 56 s
|
||||
- Implement an early decoding pass at 52 s
|
||||
- Clean up the output written to map65_rx.log
|
||||
|
||||
WSJT-X:
|
||||
- Repair a defect in CALL3.TXT lookups that incorrectly matched
|
||||
partial calls
|
||||
- Instructions in macOS ReadMe.txt to suppress App Nap energy saving
|
||||
- Revised User Guide using FT8 mode for the basic tutorial
|
||||
- Allow contest and FD operating in Q65 mode
|
||||
|
||||
Release: WSJT-X 2.5.0-rc3
|
||||
Jul 5, 2021
|
||||
-------------------------
|
||||
|
@ -1128,7 +1128,7 @@ void HamlibTransceiver::do_poll ()
|
||||
{
|
||||
m_->error_check (rig_get_freq (m_->rig_.data (), RIG_VFO_CURR, &f), tr ("getting current VFO frequency"));
|
||||
f = std::round (f);
|
||||
CAT_TRACE ("rig_get_freq frequency=" << f);
|
||||
CAT_TRACE ("rig_get_freq frequency=" << Radio::frequency (f));
|
||||
update_rx_frequency (f);
|
||||
}
|
||||
|
||||
|
@ -96,11 +96,11 @@ void OmniRigTransceiver::register_transceivers (logger_type *,
|
||||
};
|
||||
}
|
||||
|
||||
OmniRigTransceiver::OmniRigTransceiver (logger_type * logger,
|
||||
OmniRigTransceiver::OmniRigTransceiver (logger_type * the_logger,
|
||||
std::unique_ptr<TransceiverBase> wrapped,
|
||||
RigNumber n, TransceiverFactory::PTTMethod ptt_type,
|
||||
QString const& ptt_port, QObject * parent)
|
||||
: TransceiverBase {logger, parent}
|
||||
: TransceiverBase {the_logger, parent}
|
||||
, wrapped_ {std::move (wrapped)}
|
||||
, use_for_ptt_ {TransceiverFactory::PTT_method_CAT == ptt_type || ("CAT" == ptt_port && (TransceiverFactory::PTT_method_RTS == ptt_type || TransceiverFactory::PTT_method_DTR == ptt_type))}
|
||||
, ptt_type_ {ptt_type}
|
||||
@ -111,173 +111,131 @@ OmniRigTransceiver::OmniRigTransceiver (logger_type * logger,
|
||||
, reversed_ {false}
|
||||
{
|
||||
CoInitializeEx (nullptr, 0 /*COINIT_APARTMENTTHREADED*/); // required because Qt only does this for GUI thread
|
||||
CAT_TRACE ("constructed");
|
||||
}
|
||||
|
||||
OmniRigTransceiver::~OmniRigTransceiver ()
|
||||
{
|
||||
CAT_TRACE ("destroying");
|
||||
CoUninitialize ();
|
||||
}
|
||||
|
||||
// returns false on time out
|
||||
bool OmniRigTransceiver::await_notification_with_timeout (int timeout)
|
||||
{
|
||||
QEventLoop el;
|
||||
connect (this, &OmniRigTransceiver::notified, &el, [&el] () {el.exit (1);});
|
||||
QTimer::singleShot (timeout, Qt::CoarseTimer, &el, [&el] () {el.exit (0);});
|
||||
return 1 == el.exec (); // wait for notify or timer
|
||||
}
|
||||
|
||||
int OmniRigTransceiver::do_start ()
|
||||
{
|
||||
CAT_TRACE ("starting");
|
||||
|
||||
if (wrapped_) wrapped_->start (0);
|
||||
|
||||
omni_rig_.reset (new OmniRig::OmniRigX {this});
|
||||
if (omni_rig_->isNull ())
|
||||
try
|
||||
{
|
||||
CAT_ERROR ("failed to start COM server");
|
||||
throw_qstring (tr ("Failed to start OmniRig COM server"));
|
||||
}
|
||||
if (wrapped_) wrapped_->start (0);
|
||||
|
||||
// COM/OLE exceptions get signaled
|
||||
connect (&*omni_rig_, SIGNAL (exception (int, QString, QString, QString)), this, SLOT (handle_COM_exception (int, QString, QString, QString)));
|
||||
|
||||
// IOmniRigXEvent interface signals
|
||||
connect (&*omni_rig_, SIGNAL (VisibleChange ()), this, SLOT (handle_visible_change ()));
|
||||
connect (&*omni_rig_, SIGNAL (RigTypeChange (int)), this, SLOT (handle_rig_type_change (int)));
|
||||
connect (&*omni_rig_, SIGNAL (StatusChange (int)), this, SLOT (handle_status_change (int)));
|
||||
connect (&*omni_rig_, SIGNAL (ParamsChange (int, int)), this, SLOT (handle_params_change (int, int)));
|
||||
connect (&*omni_rig_
|
||||
, SIGNAL (CustomReply (int, QVariant const&, QVariant const&))
|
||||
, this, SLOT (handle_custom_reply (int, QVariant const&, QVariant const&)));
|
||||
|
||||
CAT_INFO ("OmniRig s/w version: " << omni_rig_->SoftwareVersion ()
|
||||
<< "i/f version: " << omni_rig_->InterfaceVersion ());
|
||||
|
||||
// fetch the interface of the RigX CoClass and instantiate a proxy object
|
||||
switch (rig_number_)
|
||||
{
|
||||
case One: rig_.reset (new OmniRig::RigX (omni_rig_->Rig1 ())); break;
|
||||
case Two: rig_.reset (new OmniRig::RigX (omni_rig_->Rig2 ())); break;
|
||||
}
|
||||
|
||||
Q_ASSERT (rig_);
|
||||
Q_ASSERT (!rig_->isNull ());
|
||||
|
||||
// COM/OLE exceptions get signaled
|
||||
connect (&*rig_, SIGNAL (exception (int, QString, QString, QString)), this, SLOT (handle_COM_exception (int, QString, QString, QString)));
|
||||
|
||||
offline_timer_.reset (new QTimer); // instantiate here as
|
||||
// constructor runs in wrong
|
||||
// thread
|
||||
offline_timer_->setSingleShot (true);
|
||||
connect (offline_timer_.data (), &QTimer::timeout, [this] () {offline ("Rig went offline");});
|
||||
|
||||
if (use_for_ptt_ && (TransceiverFactory::PTT_method_DTR == ptt_type_ || TransceiverFactory::PTT_method_RTS == ptt_type_))
|
||||
{
|
||||
// fetch the interface for the serial port if we need it for PTT
|
||||
port_.reset (new OmniRig::PortBits (rig_->PortBits ()));
|
||||
|
||||
Q_ASSERT (port_);
|
||||
Q_ASSERT (!port_->isNull ());
|
||||
omni_rig_.reset (new OmniRig::OmniRigX {this});
|
||||
if (omni_rig_->isNull ())
|
||||
{
|
||||
CAT_ERROR ("failed to start COM server");
|
||||
throw_qstring (tr ("Failed to start OmniRig COM server"));
|
||||
}
|
||||
|
||||
// COM/OLE exceptions get signaled
|
||||
connect (&*port_, SIGNAL (exception (int, QString, QString, QString)), this, SLOT (handle_COM_exception (int, QString, QString, QString)));
|
||||
connect (&*omni_rig_, SIGNAL (exception (int, QString, QString, QString)), this, SLOT (handle_COM_exception (int, QString, QString, QString)));
|
||||
|
||||
CAT_TRACE ("OmniRig RTS state: " << port_->Rts ());
|
||||
// IOmniRigXEvent interface signals
|
||||
connect (&*omni_rig_, SIGNAL (VisibleChange ()), this, SLOT (handle_visible_change ()));
|
||||
connect (&*omni_rig_, SIGNAL (RigTypeChange (int)), this, SLOT (handle_rig_type_change (int)));
|
||||
connect (&*omni_rig_, SIGNAL (StatusChange (int)), this, SLOT (handle_status_change (int)));
|
||||
connect (&*omni_rig_, SIGNAL (ParamsChange (int, int)), this, SLOT (handle_params_change (int, int)));
|
||||
connect (&*omni_rig_
|
||||
, SIGNAL (CustomReply (int, QVariant const&, QVariant const&))
|
||||
, this, SLOT (handle_custom_reply (int, QVariant const&, QVariant const&)));
|
||||
|
||||
// remove locking because it doesn't seem to work properly
|
||||
// if (!port_->Lock ()) // try to take exclusive use of the OmniRig serial port for PTT
|
||||
// {
|
||||
// CAT_WARNING ("Failed to get exclusive use of serial port for PTT from OmniRig");
|
||||
// }
|
||||
CAT_INFO ("OmniRig s/w version: " << static_cast<quint16> (omni_rig_->SoftwareVersion () >> 16)
|
||||
<< '.' << static_cast<quint16> (omni_rig_->SoftwareVersion () & 0xffff)
|
||||
<< " i/f version: " << static_cast<int> (omni_rig_->InterfaceVersion () >> 8 & 0xff)
|
||||
<< '.' << static_cast<int> (omni_rig_->InterfaceVersion () && 0xff));
|
||||
|
||||
// start off so we don't accidentally key the radio
|
||||
if (TransceiverFactory::PTT_method_DTR == ptt_type_)
|
||||
// fetch the interface of the RigX CoClass and instantiate a proxy object
|
||||
switch (rig_number_)
|
||||
{
|
||||
port_->SetDtr (false);
|
||||
case One: rig_.reset (new OmniRig::RigX (omni_rig_->Rig1 ())); break;
|
||||
case Two: rig_.reset (new OmniRig::RigX (omni_rig_->Rig2 ())); break;
|
||||
}
|
||||
else // RTS
|
||||
{
|
||||
port_->SetRts (false);
|
||||
}
|
||||
}
|
||||
|
||||
rig_type_ = rig_->RigType ();
|
||||
readable_params_ = rig_->ReadableParams ();
|
||||
writable_params_ = rig_->WriteableParams ();
|
||||
Q_ASSERT (rig_);
|
||||
Q_ASSERT (!rig_->isNull ());
|
||||
|
||||
CAT_INFO (QString {"OmniRig initial rig type: %1 readable params=0x%2 writable params=0x%3 for rig %4"}
|
||||
.arg (rig_type_)
|
||||
.arg (readable_params_, 8, 16, QChar ('0'))
|
||||
.arg (writable_params_, 8, 16, QChar ('0'))
|
||||
.arg (rig_number_));
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
if (OmniRig::ST_ONLINE == rig_->Status ())
|
||||
// COM/OLE exceptions get signaled
|
||||
connect (&*rig_, SIGNAL (exception (int, QString, QString, QString)), this, SLOT (handle_COM_exception (int, QString, QString, QString)));
|
||||
|
||||
offline_timer_.reset (new QTimer); // instantiate here as constructor runs in wrong thread
|
||||
offline_timer_->setSingleShot (true);
|
||||
connect (offline_timer_.data (), &QTimer::timeout, [this] () {offline ("Rig went offline");});
|
||||
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
break;
|
||||
// leave some time for Omni-Rig to do its first poll
|
||||
QThread::msleep (250);
|
||||
if (OmniRig::ST_ONLINE == rig_->Status ())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
await_notification_with_timeout (1000);
|
||||
}
|
||||
if (OmniRig::ST_ONLINE != rig_->Status ())
|
||||
{
|
||||
throw_qstring ("OmniRig: " + rig_->StatusStr ());
|
||||
}
|
||||
QThread::msleep (500); // leave some time for Omni-Rig to get
|
||||
// the rig status for the 1st. time
|
||||
auto f = rig_->GetRxFrequency ();
|
||||
for (int i = 0; (f == 0) && (i < 5); ++i)
|
||||
{
|
||||
await_notification_with_timeout (1000);
|
||||
f = rig_->GetRxFrequency ();
|
||||
}
|
||||
update_rx_frequency (f);
|
||||
int resolution {0};
|
||||
if (OmniRig::PM_UNKNOWN == rig_->Vfo ()
|
||||
&& (writable_params_ & (OmniRig::PM_VFOA | OmniRig::PM_VFOB))
|
||||
== (OmniRig::PM_VFOA | OmniRig::PM_VFOB))
|
||||
{
|
||||
// start with VFO A (probably MAIN) on rigs that we
|
||||
// can't query VFO but can set explicitly
|
||||
rig_->SetVfo (OmniRig::PM_VFOA);
|
||||
}
|
||||
f = state ().frequency ();
|
||||
if (f % 10) return resolution; // 1Hz resolution
|
||||
auto test_frequency = f - f % 100 + 55;
|
||||
if (OmniRig::PM_FREQ & writable_params_)
|
||||
{
|
||||
rig_->SetFreq (test_frequency);
|
||||
}
|
||||
else if (reversed_ && (OmniRig::PM_FREQB & writable_params_))
|
||||
{
|
||||
rig_->SetFreqB (test_frequency);
|
||||
}
|
||||
else if (!reversed_ && (OmniRig::PM_FREQA & writable_params_))
|
||||
{
|
||||
rig_->SetFreqA (test_frequency);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw_qstring (tr ("OmniRig: don't know how to set rig frequency"));
|
||||
}
|
||||
if (!await_notification_with_timeout (1000))
|
||||
{
|
||||
CAT_ERROR ("do_start 1: wait timed out");
|
||||
throw_qstring (tr ("OmniRig: timeout waiting for update from rig"));
|
||||
}
|
||||
switch (rig_->GetRxFrequency () - test_frequency)
|
||||
{
|
||||
case -5: resolution = -1; break; // 10Hz truncated
|
||||
case 5: resolution = 1; break; // 10Hz rounded
|
||||
case -15: resolution = -2; break; // 20Hz truncated
|
||||
case -55: resolution = -2; break; // 100Hz truncated
|
||||
case 45: resolution = 2; break; // 100Hz rounded
|
||||
}
|
||||
if (1 == resolution) // may be 20Hz rounded
|
||||
{
|
||||
test_frequency = f - f % 100 + 51;
|
||||
|
||||
if (OmniRig::ST_ONLINE != rig_->Status ())
|
||||
{
|
||||
CAT_ERROR ("rig not online");
|
||||
throw_qstring ("OmniRig: " + rig_->StatusStr ());
|
||||
}
|
||||
|
||||
if (use_for_ptt_ && (TransceiverFactory::PTT_method_DTR == ptt_type_ || TransceiverFactory::PTT_method_RTS == ptt_type_))
|
||||
{
|
||||
// fetch the interface for the serial port if we need it for PTT
|
||||
port_.reset (new OmniRig::PortBits (rig_->PortBits ()));
|
||||
|
||||
Q_ASSERT (port_);
|
||||
Q_ASSERT (!port_->isNull ());
|
||||
|
||||
// COM/OLE exceptions get signaled
|
||||
connect (&*port_, SIGNAL (exception (int, QString, QString, QString)), this, SLOT (handle_COM_exception (int, QString, QString, QString)));
|
||||
|
||||
CAT_TRACE ("OmniRig RTS state: " << port_->Rts ());
|
||||
|
||||
// remove locking because it doesn't seem to work properly
|
||||
// if (!port_->Lock ()) // try to take exclusive use of the OmniRig serial port for PTT
|
||||
// {
|
||||
// CAT_WARNING ("Failed to get exclusive use of serial port for PTT from OmniRig");
|
||||
// }
|
||||
|
||||
// start off so we don't accidentally key the radio
|
||||
if (TransceiverFactory::PTT_method_DTR == ptt_type_)
|
||||
{
|
||||
port_->SetDtr (false);
|
||||
}
|
||||
else // RTS
|
||||
{
|
||||
port_->SetRts (false);
|
||||
}
|
||||
}
|
||||
|
||||
rig_type_ = rig_->RigType ();
|
||||
readable_params_ = rig_->ReadableParams ();
|
||||
writable_params_ = rig_->WriteableParams ();
|
||||
|
||||
CAT_INFO (QString {"OmniRig initial rig type: %1 readable params=0x%2 writable params=0x%3 for rig %4"}
|
||||
.arg (rig_type_)
|
||||
.arg (readable_params_, 8, 16, QChar ('0'))
|
||||
.arg (writable_params_, 8, 16, QChar ('0'))
|
||||
.arg (rig_number_));
|
||||
update_rx_frequency (rig_->GetRxFrequency ());
|
||||
int resolution {0};
|
||||
if (OmniRig::PM_UNKNOWN == rig_->Vfo ()
|
||||
&& (writable_params_ & (OmniRig::PM_VFOA | OmniRig::PM_VFOB))
|
||||
== (OmniRig::PM_VFOA | OmniRig::PM_VFOB))
|
||||
{
|
||||
// start with VFO A (probably MAIN) on rigs that we
|
||||
// can't query VFO but can set explicitly
|
||||
rig_->SetVfo (OmniRig::PM_VFOA);
|
||||
}
|
||||
auto f = state ().frequency ();
|
||||
if (f % 10) return resolution; // 1Hz resolution
|
||||
auto test_frequency = f - f % 100 + 55;
|
||||
if (OmniRig::PM_FREQ & writable_params_)
|
||||
{
|
||||
rig_->SetFreq (test_frequency);
|
||||
@ -290,34 +248,65 @@ int OmniRigTransceiver::do_start ()
|
||||
{
|
||||
rig_->SetFreqA (test_frequency);
|
||||
}
|
||||
if (!await_notification_with_timeout (2000))
|
||||
else
|
||||
{
|
||||
CAT_ERROR ("do_start 2: wait timed out");
|
||||
throw_qstring (tr ("OmniRig: timeout waiting for update from rig"));
|
||||
throw_qstring (tr ("OmniRig: don't know how to set rig frequency"));
|
||||
}
|
||||
if (9 == rig_->GetRxFrequency () - test_frequency)
|
||||
switch (rig_->GetRxFrequency () - test_frequency)
|
||||
{
|
||||
resolution = 2; // 20Hz rounded
|
||||
case -5: resolution = -1; break; // 10Hz truncated
|
||||
case 5: resolution = 1; break; // 10Hz rounded
|
||||
case -15: resolution = -2; break; // 20Hz truncated
|
||||
case -55: resolution = -2; break; // 100Hz truncated
|
||||
case 45: resolution = 2; break; // 100Hz rounded
|
||||
}
|
||||
if (1 == resolution) // may be 20Hz rounded
|
||||
{
|
||||
test_frequency = f - f % 100 + 51;
|
||||
if (OmniRig::PM_FREQ & writable_params_)
|
||||
{
|
||||
rig_->SetFreq (test_frequency);
|
||||
}
|
||||
else if (reversed_ && (OmniRig::PM_FREQB & writable_params_))
|
||||
{
|
||||
rig_->SetFreqB (test_frequency);
|
||||
}
|
||||
else if (!reversed_ && (OmniRig::PM_FREQA & writable_params_))
|
||||
{
|
||||
rig_->SetFreqA (test_frequency);
|
||||
}
|
||||
if (9 == rig_->GetRxFrequency () - test_frequency)
|
||||
{
|
||||
resolution = 2; // 20Hz rounded
|
||||
}
|
||||
}
|
||||
if (OmniRig::PM_FREQ & writable_params_)
|
||||
{
|
||||
rig_->SetFreq (f);
|
||||
}
|
||||
else if (reversed_ && (OmniRig::PM_FREQB & writable_params_))
|
||||
{
|
||||
rig_->SetFreqB (f);
|
||||
}
|
||||
else if (!reversed_ && (OmniRig::PM_FREQA & writable_params_))
|
||||
{
|
||||
rig_->SetFreqA (f);
|
||||
}
|
||||
update_rx_frequency (f);
|
||||
CAT_TRACE ("started");
|
||||
|
||||
return resolution;
|
||||
}
|
||||
if (OmniRig::PM_FREQ & writable_params_)
|
||||
catch (...)
|
||||
{
|
||||
rig_->SetFreq (f);
|
||||
CAT_TRACE ("start threw exception");
|
||||
throw;
|
||||
}
|
||||
else if (reversed_ && (OmniRig::PM_FREQB & writable_params_))
|
||||
{
|
||||
rig_->SetFreqB (f);
|
||||
}
|
||||
else if (!reversed_ && (OmniRig::PM_FREQA & writable_params_))
|
||||
{
|
||||
rig_->SetFreqA (f);
|
||||
}
|
||||
update_rx_frequency (f);
|
||||
return resolution;
|
||||
}
|
||||
|
||||
void OmniRigTransceiver::do_stop ()
|
||||
{
|
||||
CAT_TRACE ("stopping");
|
||||
QThread::msleep (200); // leave some time for pending
|
||||
// commands at the server end
|
||||
|
||||
@ -337,6 +326,7 @@ void OmniRigTransceiver::do_stop ()
|
||||
{
|
||||
rig_->clear ();
|
||||
rig_.reset ();
|
||||
CAT_TRACE ("rig_ reset");
|
||||
}
|
||||
omni_rig_->clear ();
|
||||
omni_rig_.reset ();
|
||||
@ -396,7 +386,6 @@ void OmniRigTransceiver::handle_status_change (int rig_number)
|
||||
else
|
||||
{
|
||||
offline_timer_->stop (); // good to go again
|
||||
Q_EMIT notified ();
|
||||
}
|
||||
// else
|
||||
// {
|
||||
@ -467,7 +456,6 @@ void OmniRigTransceiver::handle_params_change (int rig_number, int params)
|
||||
|
||||
if (params & OmniRig::PM_FREQ)
|
||||
{
|
||||
CAT_TRACE ("FREQ");
|
||||
need_frequency = true;
|
||||
}
|
||||
if (params & OmniRig::PM_FREQA)
|
||||
@ -653,7 +641,6 @@ void OmniRigTransceiver::handle_params_change (int rig_number, int params)
|
||||
}
|
||||
CAT_TRACE ("OmniRig params change: state after:" << state ());
|
||||
}
|
||||
Q_EMIT notified ();
|
||||
}
|
||||
|
||||
void OmniRigTransceiver::handle_custom_reply (int rig_number, QVariant const& command, QVariant const& reply)
|
||||
@ -710,7 +697,7 @@ void OmniRigTransceiver::do_ptt (bool on)
|
||||
|
||||
void OmniRigTransceiver::do_frequency (Frequency f, MODE m, bool /*no_ignore*/)
|
||||
{
|
||||
CAT_TRACE (f << state ());
|
||||
CAT_TRACE (f << ' ' << state ());
|
||||
if (!rig_ || rig_->isNull ()) return;
|
||||
if (UNK != m)
|
||||
{
|
||||
@ -739,7 +726,7 @@ void OmniRigTransceiver::do_frequency (Frequency f, MODE m, bool /*no_ignore*/)
|
||||
|
||||
void OmniRigTransceiver::do_tx_frequency (Frequency tx, MODE m, bool /*no_ignore*/)
|
||||
{
|
||||
CAT_TRACE (tx << state ());
|
||||
CAT_TRACE (tx << ' ' << state ());
|
||||
if (!rig_ || rig_->isNull ()) return;
|
||||
bool split {tx != 0};
|
||||
if (split)
|
||||
@ -804,7 +791,7 @@ void OmniRigTransceiver::do_tx_frequency (Frequency tx, MODE m, bool /*no_ignore
|
||||
|
||||
void OmniRigTransceiver::do_mode (MODE mode)
|
||||
{
|
||||
CAT_TRACE (mode << state ());
|
||||
CAT_TRACE (mode << ' ' << state ());
|
||||
if (!rig_ || rig_->isNull ()) return;
|
||||
// TODO: G4WJS OmniRig doesn't seem to have any capability of tracking/setting VFO B mode
|
||||
auto mapped = map_mode (mode);
|
||||
|
@ -44,9 +44,6 @@ public:
|
||||
void do_ptt (bool on) override;
|
||||
|
||||
private:
|
||||
bool await_notification_with_timeout (int timeout);
|
||||
Q_SIGNAL void notified () const;
|
||||
// Q_SLOT void timeout_check ();
|
||||
Q_SLOT void handle_COM_exception (int, QString, QString, QString);
|
||||
Q_SLOT void handle_visible_change ();
|
||||
Q_SLOT void handle_rig_type_change (int rig_number);
|
||||
|
@ -23,6 +23,12 @@ QDebug operator << (QDebug d, Transceiver::TransceiverState const& s)
|
||||
}
|
||||
#endif
|
||||
|
||||
std::ostream& operator << (std::ostream& os, Transceiver::MODE m)
|
||||
{
|
||||
auto const& mo = Transceiver::staticMetaObject; \
|
||||
return os << mo.enumerator (mo.indexOfEnumerator ("MODE")).valueToKey (static_cast<int> (m)); \
|
||||
}
|
||||
|
||||
std::ostream& operator << (std::ostream& os, Transceiver::TransceiverState const& s)
|
||||
{
|
||||
return os
|
||||
|
@ -169,6 +169,7 @@ Q_DECLARE_METATYPE (Transceiver::TransceiverState);
|
||||
QDebug operator << (QDebug, Transceiver::TransceiverState const&);
|
||||
#endif
|
||||
|
||||
std::ostream& operator << (std::ostream&, Transceiver::MODE);
|
||||
std::ostream& operator << (std::ostream&, Transceiver::TransceiverState const&);
|
||||
|
||||
ENUM_QDATASTREAM_OPS_DECL (Transceiver, MODE);
|
||||
|
@ -16,6 +16,8 @@ namespace
|
||||
|
||||
void TransceiverBase::start (unsigned sequence_number) noexcept
|
||||
{
|
||||
CAT_TRACE ("#: " << sequence_number);
|
||||
|
||||
QString message;
|
||||
try
|
||||
{
|
||||
@ -26,10 +28,12 @@ void TransceiverBase::start (unsigned sequence_number) noexcept
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
CAT_TRACE ("#: " << sequence_number << " what: " << e.what ());
|
||||
message = e.what ();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
CAT_TRACE ("#: " << sequence_number);
|
||||
message = unexpected;
|
||||
}
|
||||
if (!message.isEmpty ())
|
||||
@ -41,7 +45,7 @@ void TransceiverBase::start (unsigned sequence_number) noexcept
|
||||
void TransceiverBase::set (TransceiverState const& s,
|
||||
unsigned sequence_number) noexcept
|
||||
{
|
||||
CAT_TRACE ("#: " << sequence_number << " " << s);
|
||||
CAT_TRACE ("#: " << s);
|
||||
|
||||
QString message;
|
||||
try
|
||||
@ -119,10 +123,12 @@ void TransceiverBase::set (TransceiverState const& s,
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
CAT_TRACE ("#: " << sequence_number << " what: " << e.what ());
|
||||
message = e.what ();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
CAT_TRACE ("#: " << sequence_number << " " << sequence_number);
|
||||
message = unexpected;
|
||||
}
|
||||
if (!message.isEmpty ())
|
||||
@ -133,6 +139,7 @@ void TransceiverBase::set (TransceiverState const& s,
|
||||
|
||||
void TransceiverBase::startup ()
|
||||
{
|
||||
CAT_TRACE ("startup");
|
||||
QString message;
|
||||
try
|
||||
{
|
||||
@ -144,10 +151,12 @@ void TransceiverBase::startup ()
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
CAT_TRACE ("startup" << " what: " << e.what ());
|
||||
message = e.what ();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
CAT_TRACE ("startup");
|
||||
message = unexpected;
|
||||
}
|
||||
if (!message.isEmpty ())
|
||||
@ -158,6 +167,7 @@ void TransceiverBase::startup ()
|
||||
|
||||
void TransceiverBase::shutdown ()
|
||||
{
|
||||
CAT_TRACE ("shutdown");
|
||||
may_update u {this};
|
||||
if (requested_.online ())
|
||||
{
|
||||
@ -177,6 +187,7 @@ void TransceiverBase::shutdown ()
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
CAT_TRACE ("shutdown");
|
||||
// don't care about exceptions
|
||||
}
|
||||
}
|
||||
@ -186,6 +197,7 @@ void TransceiverBase::shutdown ()
|
||||
|
||||
void TransceiverBase::stop () noexcept
|
||||
{
|
||||
CAT_TRACE ("stop");
|
||||
QString message;
|
||||
try
|
||||
{
|
||||
@ -193,10 +205,12 @@ void TransceiverBase::stop () noexcept
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
CAT_TRACE ("stop" << " what: " << e.what ());
|
||||
message = e.what ();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
CAT_TRACE ("stop");
|
||||
message = unexpected;
|
||||
}
|
||||
if (!message.isEmpty ())
|
||||
@ -211,6 +225,7 @@ void TransceiverBase::stop () noexcept
|
||||
|
||||
void TransceiverBase::update_rx_frequency (Frequency rx)
|
||||
{
|
||||
CAT_TRACE ("frequency: " << rx);
|
||||
if (rx)
|
||||
{
|
||||
actual_.frequency (rx);
|
||||
@ -220,28 +235,35 @@ void TransceiverBase::update_rx_frequency (Frequency rx)
|
||||
|
||||
void TransceiverBase::update_other_frequency (Frequency tx)
|
||||
{
|
||||
CAT_TRACE ("frequency: " << tx);
|
||||
actual_.tx_frequency (tx);
|
||||
}
|
||||
|
||||
void TransceiverBase::update_split (bool state)
|
||||
{
|
||||
CAT_TRACE ("state: " << state);
|
||||
actual_.split (state);
|
||||
}
|
||||
|
||||
void TransceiverBase::update_mode (MODE m)
|
||||
{
|
||||
CAT_TRACE ("mode: " << m);
|
||||
actual_.mode (m);
|
||||
requested_.mode (m); // track rig changes
|
||||
}
|
||||
|
||||
void TransceiverBase::update_PTT (bool state)
|
||||
{
|
||||
CAT_TRACE ("state: " << state);
|
||||
actual_.ptt (state);
|
||||
}
|
||||
|
||||
void TransceiverBase::update_complete (bool force_signal)
|
||||
{
|
||||
if ((do_pre_update () && actual_ != last_) || force_signal)
|
||||
CAT_TRACE ("force signal: " << force_signal);
|
||||
if ((do_pre_update ()
|
||||
&& actual_ != last_)
|
||||
|| force_signal)
|
||||
{
|
||||
Q_EMIT update (actual_, last_sequence_number_);
|
||||
last_ = actual_;
|
||||
@ -250,6 +272,7 @@ void TransceiverBase::update_complete (bool force_signal)
|
||||
|
||||
void TransceiverBase::offline (QString const& reason)
|
||||
{
|
||||
CAT_TRACE ("reason: " << reason);
|
||||
Q_EMIT failure (reason);
|
||||
try
|
||||
{
|
||||
@ -257,6 +280,7 @@ void TransceiverBase::offline (QString const& reason)
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
CAT_TRACE ("reason: " << reason);
|
||||
// don't care
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ JT4 11101000000011000011000000000000000000
|
||||
JT4/VHF 11111001001011011011110000000000000000
|
||||
JT9 11101000000011100001000000000000100000
|
||||
JT9/VHF 11111010100011111001000000000000000000
|
||||
JT9+JT65 11101000000111100001000000000000100000
|
||||
JT65 11101000000011100001000000000000100000
|
||||
JT65/VHF 11111001000011011010110001000000000000
|
||||
Q65 11111101011011010011100000010000000011
|
||||
|
@ -49,12 +49,11 @@ set (UG_SRCS
|
||||
system-requirements.adoc
|
||||
transceiver-setup.adoc
|
||||
tutorial-example1.adoc
|
||||
tutorial-example2.adoc
|
||||
tutorial-example3.adoc
|
||||
tutorial-example4.adoc
|
||||
tutorial-example5.adoc
|
||||
tutorial-example6.adoc
|
||||
tutorial-main-window.adoc
|
||||
tutorial-download-samples.adoc
|
||||
tutorial-wide-graph-settings.adoc
|
||||
utilities.adoc
|
||||
vhf-features.adoc
|
||||
@ -63,7 +62,6 @@ set (UG_SRCS
|
||||
)
|
||||
|
||||
set (UG_IMGS
|
||||
images/130610_2343-wav-80.png
|
||||
images/AstroData_2.png
|
||||
images/Astronomical_data.png
|
||||
images/auto-seq.png
|
||||
@ -72,7 +70,6 @@ set (UG_IMGS
|
||||
images/colors.png
|
||||
images/config-menu.png
|
||||
images/decode-menu.png
|
||||
images/decodes.png
|
||||
images/download_samples.png
|
||||
images/echo_144.png
|
||||
images/EME_Deep_0.png
|
||||
|
@ -1,11 +1,9 @@
|
||||
// Status=edited
|
||||
|
||||
The following controls appear at the bottom of the Wide Graph window.
|
||||
Decoding occurs only in the displayed frequency range; otherwise, with
|
||||
the exceptions of *Start NNN Hz* and of *JT65 nnnn JT9* when operating
|
||||
in JT9+JT65 mode, controls on the Wide Graph window have no effect on
|
||||
the decoding process.
|
||||
|
||||
Decoding occurs only in the displayed frequency range; otherwise,
|
||||
controls on the Wide Graph window have no effect on the decoding
|
||||
process.
|
||||
image::wide-graph-controls.png[align="center",alt="Wide Graph Controls"]
|
||||
|
||||
- *Bins/Pixel* controls the displayed frequency resolution. Set this
|
||||
@ -13,11 +11,6 @@ value to 1 for the highest possible resolution, or to higher numbers
|
||||
to compress the spectral display. Normal operation with a convenient
|
||||
window size works well at 2 to 8 bins per pixel.
|
||||
|
||||
- *JT65 nnnn JT9* sets the dividing point (blue marker) for wide-band
|
||||
decoding of JT65 and JT9 signals in *JT9+JT65* mode. The decoder
|
||||
looks for JT65 signals everywhere, but JT9 signals only above this
|
||||
frequency. This setting is stored separately for each band.
|
||||
|
||||
- *Start nnn Hz* sets the low-frequency starting point of the
|
||||
waterfall frequency scale.
|
||||
|
||||
|
Before Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 133 KiB |
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 112 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 171 KiB |
@ -1,5 +1,13 @@
|
||||
=== Documentation Conventions
|
||||
|
||||
We include screen shots that illustrate many of the settings and
|
||||
features of _WSJT-X_. Keep in mind that _WSJT-X_ is a multi-platform
|
||||
application: the detailed appearance of windows and user controls may
|
||||
be significantly different in Windows, Linux, or macOS environments.
|
||||
The underlying functionality is the same on all operating systems,
|
||||
however. Where desirable we call special attention to important
|
||||
platform differences.
|
||||
|
||||
In this manual the following icons call attention to particular types
|
||||
of information:
|
||||
|
||||
|
@ -39,7 +39,7 @@ image::RadioTab.png[align="center",alt="Radio Tab"]
|
||||
+
|
||||
|
||||
NOTE: A special value of *USB* is available for custom USB devices
|
||||
like those used by some SDR kits. This is not the same a virtual
|
||||
like those used by some SDR kits. This is not the same as the virtual
|
||||
serial port provided by USB connected transceivers and CAT
|
||||
interfaces, for those use the COM or serial port name that
|
||||
refers to them.
|
||||
|
16
doc/user_guide/en/tutorial-download-samples.adoc
Normal file
@ -0,0 +1,16 @@
|
||||
// Status=review
|
||||
|
||||
[[DOWNLOAD_SAMPLES]]
|
||||
=== Download Samples
|
||||
|
||||
The following steps will download sample audio Wave files that were originally recorded
|
||||
by WSJT-X. These files can be read in and processed by WSJT-X to simulate realtime
|
||||
operation.
|
||||
|
||||
- Select *Download samples...* from the *Help* menu.
|
||||
|
||||
- Download some or all of the available sample files using checkboxes
|
||||
on the screen shown below. For this tutorial you will need at least
|
||||
the FT8 files.
|
||||
|
||||
image::download_samples.png[width=400,align="center",alt="Download Samples"]
|
@ -1,121 +0,0 @@
|
||||
// Status=review
|
||||
.Main Window:
|
||||
- Select *JT9+JT65* on the *Mode* menu.
|
||||
- Toggle the *Tx mode* button to read *Tx JT65 #*, and set the Tx and Rx
|
||||
frequencies to 1718 Hz.
|
||||
- Double-click on *Erase* to clear both text windows.
|
||||
|
||||
.Wide Graph Settings:
|
||||
|
||||
- *Bins/Pixel* = 7
|
||||
- *JT65 .... JT9* = 2500
|
||||
- Adjust the width of the Wide Graph window so that the upper
|
||||
frequency limit is approximately 4000 Hz.
|
||||
|
||||
.Open a Wave File:
|
||||
|
||||
- Select *File | Open* and navigate to +...\save\samples\JT9+JT65\130610_2343.wav+.
|
||||
The waterfall should look something like this:
|
||||
|
||||
//.130610_2343.wav Decode
|
||||
[[X14]]
|
||||
image::130610_2343-wav-80.png[align="left",alt="Wide Graph Decode 130610_2343"]
|
||||
|
||||
The position of the blue marker on the waterfall scale is
|
||||
set by the spinner control *JT65 nnnn JT9*, where nnnn is an audio
|
||||
frequency in Hz. In *JT9+JT65* mode the program will automatically
|
||||
decode JT9 signals only above this frequency. JT65 signals will be
|
||||
decoded over the full displayed frequency range.
|
||||
|
||||
JT9 signals appear in the *Cumulative* spectrum as nearly rectangular
|
||||
shapes about 16 Hz wide. They have no clearly visible sync tone like
|
||||
the one at the low-frequency edge of all JT65 signals. By convention
|
||||
the nominal frequency of both JT9 and JT65 signals is taken to be that
|
||||
of the lowest tone, at the left edge of its spectrum.
|
||||
|
||||
This sample file contains 17 decodable signals — nine in JT65 mode
|
||||
(flagged with the character # in the decoded text windows), and eight
|
||||
in JT9 mode (flagged with @). On multi-core computers the decoders
|
||||
for JT9 and JT65 modes run simultaneously, so their results will be
|
||||
interspersed. The *Band Activity* window contains all decodes (you
|
||||
might need to scroll back in the window to see some of them). A
|
||||
signal at the frequency specified by the green marker is given
|
||||
decoding priority, and its message is displayed also in the *Rx
|
||||
Frequency* window.
|
||||
|
||||
[[FigDecodes]]
|
||||
image::decodes.png[align="center"]
|
||||
|
||||
- Confirm that mouse-click behavior is similar to that described
|
||||
earlier, in <<TUT_EX1,Example 1>>. _WSJT-X_ automatically determines
|
||||
the mode of each JT9 or JT65 message.
|
||||
|
||||
+
|
||||
|
||||
TIP: When you double-click on a signal in the waterfall it will be
|
||||
properly decoded even if on the "`wrong`" side of the *JT65 nnnn JT9*
|
||||
marker. The Tx mode automatically switches to that of the decoded
|
||||
signal and the Rx and Tx frequency markers on the waterfall scale
|
||||
resize themselves accordingly. When selecting a JT65 signal, click on
|
||||
the sync tone at its left edge.
|
||||
|
||||
- Double-click on the waterfall near 815 Hz: a JT65 message
|
||||
originating from W7VP will be decoded and appear in the *Rx Frequency*
|
||||
window. Between the *UTC* and *Freq* columns on the decoded text line
|
||||
you will find *dB*, the measured signal-to-noise ratio, and *DT*, the
|
||||
signal's time offset in seconds relative to your computer clock.
|
||||
|
||||
[width="80%",align="center",cols="^10,2*^8,2*^10,54",options="header"]
|
||||
|===
|
||||
|UTC|dB|DT|Freq|Mode|Message
|
||||
|+2343+|+-7+|+0.3+|+815+|+#+|+KK4DSD W7VP -16+
|
||||
|===
|
||||
|
||||
- Double-click on the waterfall at 3196 Hz. The program will decode a
|
||||
JT9 message from IZ0MIT:
|
||||
|
||||
[width="80%",align="center",cols="^10,2*^8,2*^10,54",options="header"]
|
||||
|===
|
||||
|UTC|dB|DT|Freq|Mode|Message
|
||||
|+2343+|+-8+|+0.3+|+3196+|+@+|+WB8QPG IZ0MIT -11+
|
||||
|===
|
||||
|
||||
- Scroll back in the *Band Activity* window and double-click on the
|
||||
message `CQ DL7ACA JO40`. The program will set *Tx mode* to JT65 and
|
||||
the Rx frequency to that of DL7ACA, 975 Hz. If you hold down the
|
||||
*Ctrl* key, both Rx and Tx frequencies will be moved. If you had
|
||||
checked *Double-click on call sets Tx Enable* on the *Setup* menu, the
|
||||
program would configure itself to begin a transmission and start a QSO
|
||||
with DL7ACA.
|
||||
|
||||
- Hold *Ctrl* down and double-click on the decoded JT65 message `CQ
|
||||
TA4A KM37`. The program will set Tx mode to JT9 and the Rx and Tx
|
||||
frequencies to 3567 Hz. The program is now configured properly for a
|
||||
JT9 QSO with TA4A.
|
||||
|
||||
.Reopen the First Sample File:
|
||||
- Select *File | Open* and navigate to `...\save\samples\130418_1742.wav`.
|
||||
|
||||
Taking full advantage of the wide-band, dual-mode capability of
|
||||
_WSJT-X_ requires a receiver bandwidth of at least 4 kHz. These
|
||||
data were recorded with a much narrower Rx bandwidth, roughly 200 to
|
||||
2400 Hz. If you have no Rx filter wider than about 2.7 kHz, you will
|
||||
be using data like this. For best viewing, adjust *Bins/Pixel* and the
|
||||
width of the Wide Graph so that only the active part of the spectrum
|
||||
shows, say 200 to 2400 Hz. Re-open the example file after any change of
|
||||
*Bins/Pixel* or Wide Graph width, to refresh the waterfall.
|
||||
|
||||
The signals in this file are all JT9 signals. To decode them
|
||||
automatically in *JT9+JT65* mode you’ll need to move the *JT65 nnnn JT9*
|
||||
delimiter down to 1000 Hz or less.
|
||||
|
||||
.Waterfall Controls
|
||||
|
||||
Now is a good time to experiment with the *Start* control and the
|
||||
sliders controlling gain and zero-point of the waterfall and spectrum
|
||||
plots. *Start* determines the frequency displayed at the left side of
|
||||
the waterfall scale. Sliders set the baseline level and gain for the
|
||||
waterfall and the several types of spectra. Good starting values
|
||||
should be close to mid-scale. You might want to uncheck *Flatten*
|
||||
when adjusting the sliders. Re-open the wave file after each change,
|
||||
to see the new results.
|
@ -1,27 +1,92 @@
|
||||
// Status=review
|
||||
.Main Window:
|
||||
- Select *FT8* on the *Mode* menu.
|
||||
- Click the *Stop* button on the main window to halt any data acquisition.
|
||||
- Select *FT8* from the *Mode* menu and *Deep* from the *Decode* menu.
|
||||
- Double-click on *Erase* to clear both text windows.
|
||||
|
||||
.Wide Graph Settings:
|
||||
|
||||
- *Bins/Pixel* = 5, *Start* = 100 Hz, *N Avg* = 2
|
||||
- Adjust the width of the Wide Graph window so that the upper
|
||||
frequency limit is approximately 3300 Hz.
|
||||
|
||||
.Open a Wave File:
|
||||
|
||||
- Select *File | Open* and navigate to
|
||||
+...\save\samples\FT8\181201_180245.wav+. The waterfall and Band
|
||||
Activity window should look something like the following screen shots.
|
||||
(This recording was made during the "FT8 Roundup" contest, so most
|
||||
transmissions happen to be using *RTTY Roundup* message formats.)
|
||||
- Select *File | Open log directory* and navigate to
|
||||
+...\save\samples\FT8\210703_133430.wav+. The waterfall and Band
|
||||
Activity/Rx Frequency windows should look something like the following screen shots:
|
||||
|
||||
- You may want to pretend you are K1JT
|
||||
by entering that callsign temporarily as *My Call* on the
|
||||
*Settings | General* tab. Your results should then be identical to
|
||||
those shown in the screen shot below. Don't forget to change *My Call*
|
||||
back to your own call when you are done!
|
||||
|
||||
[[X15]]
|
||||
image::FT8_waterfall.png[align="left",alt="Wide Graph Decode 170709_135615"]
|
||||
image::FT8_waterfall.png[align="left",alt="Wide Graph Decode 210703_133430"]
|
||||
|
||||
image::ft8_decodes.png[align="left"]
|
||||
|
||||
|
||||
.Decoding Overview
|
||||
|
||||
Decoding takes place at the end of a receive sequence. With *Decode* set
|
||||
to *Deep*, three decoding passes will be done and the *Decode* button on the
|
||||
mainwindow will illuminate three times, once for each pass.
|
||||
The first decoding attempt in each decoding pass is done at the selected Rx frequency,
|
||||
indicated by the U-shaped green marker on the waterfall frequency
|
||||
scale. All decodes appear in the left (*Band Activity*) window. The right
|
||||
(*Rx Frequency*) text window displays any decodes obtained at the current
|
||||
Rx frequency along with any decodes addressed to *My Call* (K1JT in this case).
|
||||
The red marker on the waterfall scale indicates your
|
||||
Tx frequency.
|
||||
|
||||
Twenty one FT8 signals are decoded from the example file. The number
|
||||
of decodes is shown in a box at the bottom of the main window.
|
||||
When this file was recorded HA5WA was finishing a QSO with K1JT, and
|
||||
his 73 message is shown in red because it is addressed to *My Call* (in this case K1JT).
|
||||
By default, lines containing `CQ`
|
||||
are highlighted in green, and lines with *My Call* (K1JT)
|
||||
in red. Notice that K1JT has two callers; HA0DU and EA3AGB.
|
||||
|
||||
[[X13]]
|
||||
.Decoding Controls
|
||||
|
||||
To gain some feeling for controls frequently used when making QSOs,
|
||||
try double-clicking with the mouse on the decoded text lines and on the
|
||||
waterfall spectral display. You should be able to confirm the
|
||||
following behavior:
|
||||
|
||||
- Double-click on one of the decoded *CQ* messages highlighted in
|
||||
green. These actions produce the following results:
|
||||
|
||||
** Callsign and locator of the station calling CQ are copied to the *DX
|
||||
Call* and *DX Grid* entry fields.
|
||||
|
||||
** Messages are generated for a standard minimal QSO.
|
||||
|
||||
** The *Tx even* box is checked or cleared appropriately, so that you
|
||||
will transmit in the proper (odd or even) minutes.
|
||||
|
||||
** The Rx frequency marker is moved to the frequency of the CQing
|
||||
station.
|
||||
|
||||
** You can modify the double-click behavior by holding down the
|
||||
*Shift* key to move only the Tx frequency or the *Ctrl* key to move
|
||||
both Rx and Tx frequencies. (On a Mac computer, use the *command* key
|
||||
instead of *Ctrl*).
|
||||
|
||||
** In addition, if *Double-click on call sets Tx enable* is checked on the
|
||||
*Settings | General* tab then *Enable Tx* will be activated
|
||||
so that a transmission will start automatically at the proper time.
|
||||
|
||||
|
||||
+
|
||||
|
||||
NOTE: You can prevent your Tx frequency from being changed by checking the
|
||||
box *Hold Tx Freq*.
|
||||
|
||||
- Double-click on the decoded message `K1JT HA0DU KN07`, highlighted
|
||||
in red. Results will be similar to those in the previous step. The Tx
|
||||
frequency (red marker) is not moved unless *Shift* or *Ctrl* is held
|
||||
down. Messages highlighted in red are usually in response to your own
|
||||
CQ or from a tail-ender, and you probably want your Tx frequency to
|
||||
stay where it was.
|
||||
|
||||
- Click with the mouse anywhere on the waterfall display. The green Rx
|
||||
frequency marker will jump to your selected frequency, and the Rx
|
||||
frequency control on the main window will be updated accordingly.
|
||||
@ -38,11 +103,12 @@ things just described and also invokes the decoder in a small range
|
||||
around the Rx frequency. To decode a particular signal, double-click
|
||||
near the left edge of its waterfall trace.
|
||||
|
||||
- Now double-click on any of the lines of decoded text in the Band
|
||||
Activity window. Any line will show the same behavior, setting
|
||||
Rx frequency to that of the selected message and leaving Tx frequency
|
||||
unchanged. To change both Rx and Tx frequencies, hold *Ctrl* down
|
||||
when double-clicking.
|
||||
- Ctrl-double-click on a signal to set both Rx and Tx frequencies and
|
||||
decode at the new frequency.
|
||||
|
||||
- Click *Erase* to clear the right window.
|
||||
|
||||
- Double-click *Erase* to clear both text windows.
|
||||
|
||||
TIP: To avoid QRM from competing callers, it is usually best
|
||||
to answer a CQ on a different frequency from that of the CQing
|
||||
@ -53,6 +119,11 @@ box *Hold Tx Freq*.
|
||||
TIP: Keyboard shortcuts *Shift+F11* and *Shift+F12* provide an easy
|
||||
way to move your Tx frequency down or up in 60 Hz steps.
|
||||
|
||||
TIP: Sliders and spinner controls respond to *Arrow* key presses
|
||||
and *Page Up/Down* key presses, with the *Page* keys moving the
|
||||
controls in larger steps. You can also type numbers directly into
|
||||
the spinner controls or use the mouse wheel.
|
||||
|
||||
TIP: An online {ft8_tips} by ZL2IFB offers many additional tips on
|
||||
operating procedures.
|
||||
|
||||
|
@ -1,25 +0,0 @@
|
||||
// Status=review
|
||||
|
||||
- Click the *Stop* button on the main window to halt any data acquisition.
|
||||
|
||||
- Select *JT9* from the *Mode* menu and *Deep* from the *Decode* menu.
|
||||
|
||||
- Set the audio frequencies to *Tx 1224 Hz* and *Rx 1224 Hz*.
|
||||
|
||||
+
|
||||
|
||||
TIP: Sliders and spinner controls respond to *Arrow* key presses
|
||||
and *Page Up/Down* key presses, with the *Page* keys moving the
|
||||
controls in larger steps. You can also type numbers directly into
|
||||
the spinner controls or use the mouse wheel.
|
||||
|
||||
[[DOWNLOAD_SAMPLES]]
|
||||
=== Download Samples
|
||||
|
||||
- Select *Download samples...* from the *Help* menu.
|
||||
|
||||
- Download some or all of the available sample files using checkboxes
|
||||
on the screen shown below. For this tutorial you will need at least
|
||||
the JT9 and JT9+JT65 files.
|
||||
|
||||
image::download_samples.png[align="center",alt="Downlod Samples"]
|
@ -1,13 +1,46 @@
|
||||
// Status=review
|
||||
|
||||
- *Bins/Pixel* = 4
|
||||
- *Start* = 200 Hz
|
||||
- *N Avg* = 5
|
||||
- *Palette* = Digipan
|
||||
- *Flatten* = checked
|
||||
- Select *Cumulative* for data display
|
||||
- *Gain* and *Zero* sliders for waterfall and spectrum set near midscale
|
||||
- *Spec* = 25%
|
||||
The WSJT-X Wide Graph window displays the frequency spectrum of the received audio. Usually, the
|
||||
upper portion of the window shows a waterfall plot of the frequency spectrum (a spectrogram) and
|
||||
a line plot of the current or average spectrum. Controls at the bottom of the window are used to
|
||||
set up the displayed audio frequency range, color palette, and scaling of the spectrum displays.
|
||||
A control on the bottom right of the Wide Graph (displayed as *Spec nn%*) lets you control
|
||||
the vertical fraction of the window occupied by the spectrum line plot.
|
||||
It is important to set appropriate lower and upper
|
||||
audio frequency limits for the Wide Graph because these limits define the FT8 decoder's search window.
|
||||
For this tutorial, the limits will be set to cover 100-3300 Hz:
|
||||
|
||||
- Set *Start* = 100 Hz.
|
||||
- Set *Bins/Pixel* = 5. Smaller/larger values make the Wide Graph cover a smaller/larger
|
||||
frequency range.
|
||||
- Use the mouse to grab the left or right edge of the *Wide Graph*, and
|
||||
adjust its width so that the upper frequency limit is about 2400 Hz.
|
||||
adjust its width so that the upper frequency limit is about 3300 Hz.
|
||||
|
||||
The *N Avg* setting controls how many spectra are averaged to produce each line in the spectrogram.
|
||||
Smaller values make the spectrogram update more frequently, resulting in signals being more spread
|
||||
out in the vertical (time) direction.
|
||||
On the other hand, larger values make it easier to detect very weak signals:
|
||||
|
||||
- Set *N Avg* = 2.
|
||||
|
||||
The *Palette* setting controls the color scheme used for the spectrogram:
|
||||
|
||||
- Set *Palette* = Fldigi
|
||||
|
||||
When *Flatten* is checked, WSJT-X attempts to correct for slope or curvature in the receiver's
|
||||
passband shape.
|
||||
|
||||
- *Flatten* = checked
|
||||
|
||||
The line plot can be set to display the current (un-averaged) spectrum or the cumulative (averaged)
|
||||
spectrum:
|
||||
|
||||
- Select *Cumulative* for data display
|
||||
- Set the *Gain* and *Zero* sliders for the waterfall and spectrum to near midscale
|
||||
|
||||
The *Spec nn%* setting determines what fraction of the vertical extent of the Wide Graph will
|
||||
be used for the line plot of the spectrum. Setting *Spec* to 0 will eliminate the line plot and
|
||||
a setting of 100 will eliminate the spectrogram and show only the line plot:
|
||||
|
||||
- Set *Spec* = 50%
|
||||
|
||||
|
@ -141,31 +141,20 @@ include::transceiver-setup.adoc[]
|
||||
== Basic Operating Tutorial
|
||||
|
||||
This section introduces the basic user controls and program behavior
|
||||
of _WSJT-X_, with particular emphasis on the JT9, JT65, and FT8 modes.
|
||||
of _WSJT-X_, with particular emphasis on the FT8 mode.
|
||||
We suggest that new users should go through the full HF-oriented
|
||||
tutorial, preferably while at your radio. Note that as of late 2018,
|
||||
digital usage on the HF bands has mostly moved from JT65 and JT9 to FT8. So
|
||||
you may wish to pay particular attention to *FT8*, in Section 6.6.
|
||||
tutorial, preferably while at your radio.
|
||||
|
||||
Subsequent sections cover additional details on <<MAKE_QSOS,Making
|
||||
QSOs>>, <<WSPR,WSPR mode>> and <<VHF_AND_UP,VHF+ Features>>.
|
||||
|
||||
[[TUT_MAIN]]
|
||||
=== Main Window Settings
|
||||
include::tutorial-main-window.adoc[]
|
||||
[[TUT_SAMPLES]]
|
||||
include::tutorial-download-samples.adoc[]
|
||||
|
||||
[[TUT_WIDE_GRAPH]]
|
||||
=== Wide Graph Settings
|
||||
include::tutorial-wide-graph-settings.adoc[]
|
||||
|
||||
[[TUT_EX1]]
|
||||
=== JT9
|
||||
include::tutorial-example1.adoc[]
|
||||
|
||||
[[TUT_EX2]]
|
||||
=== JT9+JT65
|
||||
include::tutorial-example2.adoc[]
|
||||
|
||||
[[TUT_EX3]]
|
||||
=== FT8
|
||||
include::tutorial-example3.adoc[]
|
||||
|
@ -1118,7 +1118,7 @@ subroutine pack77_1(nwords,w,i3,n3,c77)
|
||||
irpt=irpt+35
|
||||
else if(c2.eq.'R+' .or. c2.eq.'R-') then
|
||||
ir=1
|
||||
read(w(nwords)(2:),*) irpt
|
||||
read(w(nwords)(2:),*,err=900) irpt
|
||||
if(irpt.ge.-50 .and. irpt.le.-31) irpt=irpt+101
|
||||
irpt=irpt+35
|
||||
else if(trim(w(nwords)).eq.'RRR') then
|
||||
@ -1274,6 +1274,7 @@ subroutine pack77_4(nwords,w,i3,n3,c77)
|
||||
if(call_1(1:1).eq.'<') call_1=w(1)(2:len(trim(w(1)))-1)
|
||||
call_2=w(2)
|
||||
if(call_2(1:1).eq.'<') call_2=w(2)(2:len(trim(w(2)))-1)
|
||||
if(call_1(1:1).ne.'<' .and. call_2(1:1).ne.'<') goto 900
|
||||
call chkcall(call_1,bcall_1,ok1)
|
||||
call chkcall(call_2,bcall_2,ok2)
|
||||
icq=0
|
||||
|
@ -55,7 +55,8 @@ subroutine jt9a()
|
||||
if(.not.ok) call abort
|
||||
call flush(6)
|
||||
call timer('decoder ',0)
|
||||
if(local_params%nmode.eq.8 .and. local_params%ndiskdat) then
|
||||
if(local_params%nmode.eq.8 .and. local_params%ndiskdat .and. &
|
||||
.not. local_params%nagain) then
|
||||
! Early decoding pass, FT8 only, when wsjtx reads from disk
|
||||
nearly=41
|
||||
local_params%nzhsym=nearly
|
||||
|
@ -157,12 +157,17 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
! Try list decoding via "Deep Likelihood".
|
||||
call timer('ccf_85 ',0)
|
||||
! Try to synchronize using all 85 symbols
|
||||
call q65_ccf_85(s1,iz,jz,nfqso,ia,ia2,ipk,jpk,f0,xdt,imsg_best,ccf1)
|
||||
call q65_ccf_85(s1,iz,jz,nfqso,ia,ia2,ipk,jpk,f0,xdt,imsg_best, &
|
||||
better,ccf1)
|
||||
call timer('ccf_85 ',1)
|
||||
|
||||
call timer('list_dec',0)
|
||||
call q65_dec_q3(s1,iz,jz,s3,LL,ipk,jpk,snr2,dat4,idec,decoded)
|
||||
call timer('list_dec',1)
|
||||
if(better.ge.1.10 .or. mode_q65.ge.8) then
|
||||
call timer('list_dec',0)
|
||||
call q65_dec_q3(s1,iz,jz,s3,LL,ipk,jpk,snr2,dat4,idec,decoded)
|
||||
call timer('list_dec',1)
|
||||
! if(idec.ge.0) write(70,3070) idec,mode_q65,better,trim(decoded)
|
||||
!3070 format(i3,i5,f8.2,2x,a)
|
||||
endif
|
||||
! If idec=3 we have a q3 decode. Continue to compute sync curve for plotting.
|
||||
endif
|
||||
|
||||
@ -359,18 +364,21 @@ subroutine q65_dec_q012(s3,LL,snr2,dat4,idec,decoded)
|
||||
100 return
|
||||
end subroutine q65_dec_q012
|
||||
|
||||
subroutine q65_ccf_85(s1,iz,jz,nfqso,ia,ia2,ipk,jpk,f0,xdt,imsg_best,ccf1)
|
||||
subroutine q65_ccf_85(s1,iz,jz,nfqso,ia,ia2,ipk,jpk,f0,xdt,imsg_best, &
|
||||
better,ccf1)
|
||||
|
||||
! Attempt synchronization using all 85 symbols, in advance of an
|
||||
! attempt at q3 decoding. Return ccf1 for the "red sync curve".
|
||||
|
||||
real s1(iz,jz)
|
||||
real, allocatable :: ccf(:,:) !CCF(freq,lag)
|
||||
real, allocatable :: best(:) !best(imsg) -- for checking 2nd best
|
||||
real ccf1(-ia2:ia2)
|
||||
integer ijpk(2)
|
||||
integer itone(85)
|
||||
|
||||
allocate(ccf(-ia2:ia2,-53:214))
|
||||
allocate(best(ncw))
|
||||
ipk=0
|
||||
jpk=0
|
||||
ccf_best=0.
|
||||
@ -415,8 +423,15 @@ subroutine q65_ccf_85(s1,iz,jz,nfqso,ia,ia2,ipk,jpk,f0,xdt,imsg_best,ccf1)
|
||||
imsg_best=imsg
|
||||
ccf1=ccf(:,jpk)
|
||||
endif
|
||||
best(imsg)=ccfmax
|
||||
enddo ! imsg
|
||||
|
||||
deallocate(ccf)
|
||||
better=0.
|
||||
if(imsg_best.gt.0) then
|
||||
best(imsg_best)=0.
|
||||
better=ccf_best/maxval(best)
|
||||
endif
|
||||
|
||||
return
|
||||
end subroutine q65_ccf_85
|
||||
|
@ -34,11 +34,14 @@ extern struct { //This is "common/datcom/..." in Fortran
|
||||
int nfast; //No longer used
|
||||
int nsave; //Number of s3(64,63) spectra saved
|
||||
int max_drift; //Maximum Q65 drift: units symbol_rate/TxT
|
||||
int nhsym; //Number of available JT65 half-symbols
|
||||
char mycall[12];
|
||||
char mygrid[6];
|
||||
char hiscall[12];
|
||||
char hisgrid[6];
|
||||
char datetime[20];
|
||||
int junk1; //Used to test extent of copy to shared memory
|
||||
int junk2;
|
||||
} datcom_;
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@ extern qint16 id[4*60*96000];
|
||||
|
||||
void getfile(QString fname, bool xpol, int dbDgrd)
|
||||
{
|
||||
int npts=2*52*96000;
|
||||
int npts=2*56*96000;
|
||||
if(xpol) npts=2*npts;
|
||||
|
||||
// Degrade S/N by dbDgrd dB -- for tests only!!
|
||||
@ -56,7 +56,7 @@ void getfile(QString fname, bool xpol, int dbDgrd)
|
||||
|
||||
void savetf2(QString fname, bool xpol)
|
||||
{
|
||||
int npts=2*52*96000;
|
||||
int npts=2*56*96000;
|
||||
if(xpol) npts=2*npts;
|
||||
|
||||
qint16* buf=(qint16*)malloc(2*npts);
|
||||
|
@ -136,8 +136,8 @@ target_link_libraries (m65 m65impl ${FFTW3_LIBRARIES})
|
||||
add_executable (mapsim mapsim.f90)
|
||||
target_link_libraries (mapsim m65impl ${FFTW3_LIBRARIES})
|
||||
|
||||
add_executable (synctest synctest.f90)
|
||||
target_link_libraries (synctest m65impl ${FFTW3_LIBRARIES})
|
||||
#add_executable (synctest synctest.f90)
|
||||
#target_link_libraries (synctest m65impl ${FFTW3_LIBRARIES})
|
||||
|
||||
if (WIN32)
|
||||
install (
|
||||
|
@ -6,18 +6,21 @@ subroutine decode0(dd,ss,savg,nstandalone)
|
||||
real*4 dd(4,NSMAX),ss(4,322,NFFT),savg(4,NFFT)
|
||||
real*8 fcenter
|
||||
integer hist(0:32768)
|
||||
logical ldecoded
|
||||
character mycall*12,hiscall*12,mygrid*6,hisgrid*6,datetime*20
|
||||
character mycall0*12,hiscall0*12,hisgrid0*6
|
||||
common/npar/fcenter,nutc,idphi,mousedf,mousefqso,nagain, &
|
||||
ndepth,ndiskdat,neme,newdat,nfa,nfb,nfcal,nfshift, &
|
||||
mcall3,nkeep,ntol,nxant,nrxlog,nfsample,nxpol,nmode, &
|
||||
nfast,nsave,max_drift,mycall,mygrid,hiscall,hisgrid,datetime
|
||||
nfast,nsave,max_drift,nhsym,mycall,mygrid,hiscall,hisgrid,datetime
|
||||
common/early/nhsym1,nhsym2,ldecoded(32768)
|
||||
data neme0/-99/,mcall3b/1/
|
||||
save
|
||||
|
||||
call sec0(0,tquick)
|
||||
call timer('decode0 ',0)
|
||||
if(newdat.ne.0) then
|
||||
nz=52*96000
|
||||
nz=96000*nhsym/5.3833
|
||||
hist=0
|
||||
do i=1,nz
|
||||
j1=min(abs(dd(1,i)),32768.0)
|
||||
@ -36,7 +39,6 @@ subroutine decode0(dd,ss,savg,nstandalone)
|
||||
enddo
|
||||
10 rmsdd=1.5*i
|
||||
endif
|
||||
nhsym=279
|
||||
ndphi=0
|
||||
if(iand(nrxlog,8).ne.0) ndphi=1
|
||||
|
||||
@ -52,12 +54,16 @@ subroutine decode0(dd,ss,savg,nstandalone)
|
||||
call map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
|
||||
mousedf,mousefqso,nagain,ndecdone,nfshift,ndphi,max_drift, &
|
||||
nfcal,nkeep,mcall3b,nsum,nsave,nxant,mycall,mygrid, &
|
||||
neme,ndepth,nstandalone,hiscall,hisgrid,nhsym,nfsample,nxpol,nmode)
|
||||
neme,ndepth,nstandalone,hiscall,hisgrid,nhsym,nfsample, &
|
||||
ndiskdat,nxpol,nmode)
|
||||
call timer('map65a ',1)
|
||||
call timer('decode0 ',1)
|
||||
|
||||
write(*,1010) nsum,nsave
|
||||
1010 format('<DecodeFinished>',2i4)
|
||||
call sec0(1,tdec)
|
||||
if(nhsym.eq.nhsym1) write(*,1010) nsum,nsave,nstandalone,nhsym,tdec
|
||||
1010 format('<EarlyFinished>',3i4,i6,f6.2)
|
||||
if(nhsym.eq.nhsym2) write(*,1012) nsum,nsave,nstandalone,nhsym,tdec
|
||||
1012 format('<DecodeFinished>',3i4,i6,f6.2)
|
||||
flush(6)
|
||||
|
||||
return
|
||||
|
@ -3,14 +3,15 @@ subroutine display(nkeep,ftol)
|
||||
parameter (MAXLINES=400,MX=400,MAXCALLS=500)
|
||||
integer indx(MAXLINES),indx2(MX)
|
||||
character*83 line(MAXLINES),line2(MX),line3(MAXLINES)
|
||||
character out*52,cfreq0*3,livecq*58
|
||||
character out*52,out0*52,cfreq0*3,livecq*58
|
||||
character*6 callsign,callsign0
|
||||
character*12 freqcall(MAXCALLS)
|
||||
real freqkHz(MAXLINES)
|
||||
integer utc(MAXLINES),utc2(MX),utcz
|
||||
real*8 f0
|
||||
|
||||
rewind 26
|
||||
out0=' '
|
||||
rewind(26)
|
||||
|
||||
do i=1,MAXLINES
|
||||
read(26,1010,end=10) line(i)
|
||||
@ -45,7 +46,7 @@ subroutine display(nkeep,ftol)
|
||||
enddo
|
||||
20 i0=i
|
||||
nz=nz-i0+1
|
||||
rewind 26
|
||||
rewind(26)
|
||||
if(nz.lt.1) go to 999
|
||||
do i=1,nz
|
||||
j=i+i0-1
|
||||
@ -132,8 +133,14 @@ subroutine display(nkeep,ftol)
|
||||
index(livecq,' QRT ').gt.0 .or. index(livecq,' CQV ').gt.0 .or. &
|
||||
index(livecq,' CQH ').gt.0) write(19,1029) livecq
|
||||
1029 format(a58)
|
||||
write(*,1030) out !Messages
|
||||
1030 format('@',a52)
|
||||
|
||||
! Suppress listing duplicate (same time, same decoded message)
|
||||
if(out(14:17).ne.out0(14:17) .or. out(26:50).ne.out0(26:50)) then
|
||||
write(*,1030) out !Messages
|
||||
1030 format('@',a52)
|
||||
out0=out
|
||||
endif
|
||||
|
||||
i1=index(out(26:),' ')
|
||||
callsign=out(i1+26:)
|
||||
i2=index(callsign,' ')
|
||||
|
@ -26,21 +26,23 @@ program m65
|
||||
use timer_module, only: timer
|
||||
use timer_impl, only: init_timer, fini_timer
|
||||
|
||||
include 'njunk.f90'
|
||||
parameter (NFFT=32768)
|
||||
parameter (NSMAX=60*96000)
|
||||
parameter (NREAD=2048)
|
||||
integer*2 i2(NREAD)
|
||||
real*8 hsym
|
||||
real*4 ssz5a(NFFT)
|
||||
logical*1 lstrong(0:1023)
|
||||
logical*1 lstrong(0:1023),ldecoded,eof
|
||||
real*8 fc0,fcenter
|
||||
character*80 arg,infile
|
||||
character mycall*12,hiscall*12,mygrid*6,hisgrid*6,datetime*20
|
||||
common/datcom/dd(4,5760000),ss(4,322,NFFT),savg(4,NFFT),fc0,nutc0,junk(37)
|
||||
common/datcom/dd(4,5760000),ss(4,322,NFFT),savg(4,NFFT),fc0,nutc0,junk(NJUNK)
|
||||
common/npar/fcenter,nutc,idphi,mousedf,mousefqso,nagain, &
|
||||
ndepth,ndiskdat,neme,newdat,nfa,nfb,nfcal,nfshift, &
|
||||
mcall3,nkeep,ntol,nxant,nrxlog,nfsample,nxpol,nmode, &
|
||||
nfast,nsave,max_drift,mycall,mygrid,hiscall,hisgrid,datetime
|
||||
nfast,nsave,max_drift,nhsym,mycall,mygrid,hiscall,hisgrid,datetime
|
||||
common/early/nhsym1,nhsym2,ldecoded(32768)
|
||||
|
||||
nargs=iargc()
|
||||
if(nargs.ne.1 .and. nargs.lt.5) then
|
||||
@ -52,6 +54,9 @@ program m65
|
||||
print*,' (Gets data from MAP65, via shared memory region.)'
|
||||
go to 999
|
||||
endif
|
||||
nstandalone=1
|
||||
nhsym1=280
|
||||
nhsym2=302
|
||||
call getarg(1,arg)
|
||||
if(arg(1:2).eq.'-s') then
|
||||
call m65a
|
||||
@ -124,9 +129,12 @@ program m65
|
||||
|
||||
nch=2
|
||||
if(nxpol.eq.1) nch=4
|
||||
|
||||
eof=.false.
|
||||
do irec=1,9999999
|
||||
read(10,end=10) i2
|
||||
if(.not.eof) read(10,end=4) i2
|
||||
go to 6
|
||||
4 eof=.true.
|
||||
6 if(eof) i2=0
|
||||
do i=1,NREAD,nch
|
||||
k=k+1
|
||||
if(k.gt.60*96000) exit
|
||||
@ -156,15 +164,18 @@ program m65
|
||||
rejecty,pxdb,pydb,ssz5a,nkhz,ihsym,nzap,slimit,lstrong)
|
||||
call timer('symspec ',1)
|
||||
nhsym0=nhsym
|
||||
|
||||
nutc=nutc0
|
||||
if(nhsym.eq.nhsym1) call decode0(dd,ss,savg,nstandalone)
|
||||
if(nhsym.eq.nhsym2) then
|
||||
call decode0(dd,ss,savg,nstandalone)
|
||||
exit
|
||||
endif
|
||||
endif
|
||||
enddo ! irec
|
||||
|
||||
10 continue
|
||||
if(iqadjust.ne.0) write(*,3002) rejectx,rejecty
|
||||
3002 format('Image rejection:',2f7.1,' dB')
|
||||
nutc=nutc0
|
||||
nstandalone=1
|
||||
call decode0(dd,ss,savg,nstandalone)
|
||||
enddo ! ifile
|
||||
|
||||
call timer('m65 ',1)
|
||||
@ -175,5 +186,10 @@ program m65
|
||||
print*,infile
|
||||
|
||||
999 call fini_timer()
|
||||
if(arg(1:2).eq.'-s') then
|
||||
write(21,1999) datetime(:17)
|
||||
1999 format('Subprocess m65 terminated normally at UTC ',a17)
|
||||
close(21)
|
||||
endif
|
||||
|
||||
end program m65
|
||||
|
@ -1,5 +1,5 @@
|
||||
subroutine m65a
|
||||
|
||||
|
||||
use timer_module, only: timer
|
||||
use timer_impl, only: init_timer !, limtrace
|
||||
use, intrinsic :: iso_c_binding, only: C_NULL_CHAR
|
||||
@ -70,27 +70,35 @@ subroutine m65b(m65com,nbytes)
|
||||
end subroutine m65b
|
||||
|
||||
subroutine m65c(dd,ss,savg,nparams0)
|
||||
|
||||
include 'njunk.f90'
|
||||
real*4 dd(4,5760000),ss(4,322,32768),savg(4,32768)
|
||||
real*8 fcenter
|
||||
integer nparams0(40),nparams(40)
|
||||
integer nparams0(NJUNK+2),nparams(NJUNK+2)
|
||||
logical ldecoded
|
||||
character*12 mycall,hiscall
|
||||
character*6 mygrid,hisgrid
|
||||
character*20 datetime
|
||||
common/npar/fcenter,nutc,idphi,mousedf,mousefqso,nagain, &
|
||||
ndepth,ndiskdat,neme,newdat,nfa,nfb,nfcal,nfshift, &
|
||||
mcall3,nkeep,ntol,nxant,nrxlog,nfsample,nxpol,nmode, &
|
||||
nfast,nsave,max_drift,mycall,mygrid,hiscall,hisgrid,datetime
|
||||
nfast,nsave,max_drift,nhsym,mycall,mygrid,hiscall,hisgrid, &
|
||||
datetime,junk1,junk2
|
||||
common/early/nhsym1,nhsym2,ldecoded(32768)
|
||||
equivalence (nparams,fcenter)
|
||||
|
||||
nparams=nparams0 !Copy parameters into common/npar/
|
||||
npatience=1
|
||||
if(iand(nrxlog,1).ne.0) then
|
||||
if(nhsym.eq.nhsym1 .and. iand(nrxlog,1).ne.0) then
|
||||
write(21,1000) datetime(:17)
|
||||
1000 format(/'UTC Date: 'a17/78('-'))
|
||||
flush(21)
|
||||
endif
|
||||
if(iand(nrxlog,2).ne.0) rewind 21
|
||||
if(iand(nrxlog,4).ne.0) rewind 26
|
||||
if(iand(nrxlog,2).ne.0) rewind(21)
|
||||
if(iand(nrxlog,4).ne.0) then
|
||||
if(nhsym.eq.nhsym1) rewind(26)
|
||||
if(nhsym.eq.nhsym2) backspace(26)
|
||||
endif
|
||||
|
||||
nstandalone=0
|
||||
if(sum(nparams).ne.0) call decode0(dd,ss,savg,nstandalone)
|
||||
|
@ -1,7 +1,8 @@
|
||||
subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
|
||||
mousedf,mousefqso,nagain,ndecdone,nfshift,ndphi,max_drift, &
|
||||
nfcal,nkeep,mcall3b,nsum,nsave,nxant,mycall,mygrid, &
|
||||
neme,ndepth,nstandalone,hiscall,hisgrid,nhsym,nfsample,nxpol,nmode)
|
||||
neme,ndepth,nstandalone,hiscall,hisgrid,nhsym,nfsample, &
|
||||
ndiskdat,nxpol,nmode)
|
||||
|
||||
! Processes timf2 data from Linrad to find and decode JT65 signals.
|
||||
|
||||
@ -24,6 +25,7 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
|
||||
logical done(MAXMSG)
|
||||
logical xpol,bq65,q65b_called
|
||||
logical candec(MAX_CANDIDATES)
|
||||
logical ldecoded
|
||||
character decoded*22,blank*22,cmode*2
|
||||
real short(3,NFFT) !SNR dt ipol for potential shorthands
|
||||
real qphi(12)
|
||||
@ -31,35 +33,44 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
|
||||
|
||||
common/c3com/ mcall3a
|
||||
common/testcom/ifreq
|
||||
|
||||
common/early/nhsym1,nhsym2,ldecoded(32768)
|
||||
|
||||
data blank/' '/,cm/'#'/
|
||||
data shmsg0/'ATT','RO ','RRR','73 '/
|
||||
data nfile/0/,nutc0/-999/,nid/0/,ip000/1/,ip001/1/,mousefqso0/-999/
|
||||
save
|
||||
|
||||
call sec0(0,tquick)
|
||||
! Clean start for Q65 at early decode
|
||||
if(nhsym.eq.nhsym1 .or. nagain.ne.0) ldecoded=.false.
|
||||
|
||||
nkhz_center=nint(1000.0*(fcenter-int(fcenter)))
|
||||
mfa=nfa-nkhz_center+48
|
||||
mfb=nfb-nkhz_center+48
|
||||
mode65=mod(nmode,10)
|
||||
if(mode65.eq.3) mode65=4
|
||||
mode_q65=nmode/10
|
||||
xpol=(nxpol.ne.0)
|
||||
|
||||
nts_jt65=2**(mode65-1) !JT65 tone separation factor
|
||||
nts_q65=2**(mode_q65) !Q65 tone separation factor
|
||||
nts_q65=2**(mode_q65-1) !Q65 tone separation factor
|
||||
xpol=(nxpol.ne.0)
|
||||
|
||||
! No second decode for JT65?
|
||||
! if(nhsym.eq.nhsym2 .and. (nstandalone.eq.1 .or. ndiskdat.eq.0)) mode65=0
|
||||
if(nhsym.eq.nhsym2 .and. nagain.eq.0) mode65=0
|
||||
! print*,'=a',nhsym,nagain,mode65
|
||||
|
||||
if(nagain.eq.0) then
|
||||
call timer('get_cand',0)
|
||||
call get_candidates(ss,savg,xpol,mfa,mfb,nts_jt65,nts_q65,cand,ncand)
|
||||
call get_candidates(ss,savg,xpol,nhsym,mfa,mfb,nts_jt65,nts_q65,cand,ncand)
|
||||
call timer('get_cand',1)
|
||||
candec=.false.
|
||||
endif
|
||||
!###
|
||||
! do k=1,ncand
|
||||
! freq=cand(k)%f+nkhz_center-48.0-1.27046
|
||||
! write(70,3010) nutc,k,cand(k)%snr,cand(k)%f,freq,cand(k)%xdt, &
|
||||
! cand(k)%ipol,cand(k)%iflip
|
||||
!3010 format(i4.4,i5,f10.1,3f10.3,2i3)
|
||||
! ipk=cand(k)%indx
|
||||
! write(*,3010) nutc,k,db(cand(k)%snr),freq,cand(k)%xdt, &
|
||||
! cand(k)%ipol,cand(k)%iflip,ipk,ldecoded(ipk)
|
||||
!3010 format('=a',i5.4,i5,f8.2,f10.3,f8.2,2i3,i6,L4)
|
||||
! enddo
|
||||
!###
|
||||
|
||||
@ -111,7 +122,9 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
|
||||
short=0. !Zero the whole short array
|
||||
jpz=1
|
||||
if(xpol) jpz=4
|
||||
if(mode65.eq.0) go to 50
|
||||
|
||||
! First steps for JT65 decoding
|
||||
do i=ia,ib !Search over freq range
|
||||
freq=0.001*(i-16385)*df
|
||||
! Find the local base level for each polarization; update every 10 bins.
|
||||
@ -278,8 +291,9 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
|
||||
endif
|
||||
enddo !i=ia,ib
|
||||
|
||||
if(nqd.eq.1) then
|
||||
50 if(nqd.eq.1) then
|
||||
nwrite=0
|
||||
if(mode65.eq.0) km=0
|
||||
do k=1,km
|
||||
decoded=msg(k)
|
||||
if(decoded.ne.' ') then
|
||||
@ -350,7 +364,7 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
|
||||
call timer('q65b ',0)
|
||||
call q65b(nutc,nqd,nxant,fcenter,nfcal,nfsample,ikhz,mousedf, &
|
||||
ntol,xpol,mycall,mygrid, hiscall,hisgrid,mode_q65,f0,fqso, &
|
||||
newdat,nagain,max_drift,idec)
|
||||
newdat,nagain,max_drift,nhsym,idec)
|
||||
call timer('q65b ',1)
|
||||
if(idec.ge.0) candec(icand)=.true.
|
||||
enddo
|
||||
@ -361,7 +375,7 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
|
||||
call timer('q65b ',0)
|
||||
call q65b(nutc,nqd,nxant,fcenter,nfcal,nfsample,ikhz,mousedf, &
|
||||
ntol,xpol,mycall,mygrid,hiscall,hisgrid,mode_q65,f0,fqso, &
|
||||
newdat,nagain,max_drift,idec)
|
||||
newdat,nagain,max_drift,nhsym,idec)
|
||||
call timer('q65b ',1)
|
||||
endif
|
||||
endif
|
||||
@ -379,15 +393,17 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
|
||||
|
||||
if(ndphi.eq.1 .and.iloop.eq.12) call getdphi(qphi)
|
||||
if(nqd.eq.1) then
|
||||
write(*,1013) nsum,nsave
|
||||
1013 format('<QuickDecodeDone>',2i4)
|
||||
call sec0(1,tdec)
|
||||
write(*,1013) nsum,nsave,nstandalone,nhsym,tdec
|
||||
1013 format('<QuickDecodeDone>',3i4,i6,f6.2)
|
||||
flush(6)
|
||||
call sec0(1,tquick)
|
||||
open(16,file='tquick.dat',status='unknown',access='append')
|
||||
write(16,1016) nutc,tquick
|
||||
write(16,1016) nutc,tdec
|
||||
1016 format(i4.4,f7.1)
|
||||
close(16)
|
||||
endif
|
||||
call sec0(1,tsec0)
|
||||
if(nhsym.eq.nhsym1 .and. tsec0.gt.3.0) go to 700
|
||||
if(nqd.eq.1 .and. nagain.eq.1) go to 900
|
||||
|
||||
if(nqd.eq.0 .and. bq65) then
|
||||
@ -403,21 +419,19 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
|
||||
call timer('q65b ',0)
|
||||
call q65b(nutc,nqd,nxant,fcenter,nfcal,nfsample,ikhz,mousedf,ntol, &
|
||||
xpol,mycall,mygrid,hiscall,hisgrid,mode_q65,f0,fqso,newdat, &
|
||||
nagain,max_drift,idec)
|
||||
nagain,max_drift,nhsym,idec)
|
||||
call timer('q65b ',1)
|
||||
if(idec.ge.0) candec(icand)=.true.
|
||||
enddo ! icand
|
||||
endif
|
||||
call sec0(1,tsec0)
|
||||
|
||||
enddo ! nqd
|
||||
|
||||
! Trim the list and produce a sorted index and sizes of groups.
|
||||
! (Should trimlist remove all but best SNR for given UTC and message content?)
|
||||
call trimlist(sig,km,ftol,indx,nsiz,nz)
|
||||
|
||||
do i=1,km
|
||||
done(i)=.false.
|
||||
enddo
|
||||
700 call trimlist(sig,km,ftol,indx,nsiz,nz)
|
||||
done(1:km)=.false.
|
||||
j=0
|
||||
ilatest=-1
|
||||
do n=1,nz
|
||||
@ -490,11 +504,8 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
|
||||
write(21,1100) f0,ndf,dt,npol,nsync2,nutc,decoded,cp, &
|
||||
cmode(1:1),cmode(2:2)
|
||||
1100 format(f8.3,i5,f5.1,2i4,i5.4,2x,a22,2x,a1,3x,a1,1x,a1)
|
||||
|
||||
! write(21,1014) f0,ndf,ndf0,ndf1,ndf2,dt,npol,nsync1, &
|
||||
! nutc,decoded,cp,cmode
|
||||
|
||||
endif
|
||||
|
||||
endif
|
||||
j=j+nsiz(n)
|
||||
enddo !i=1,km
|
||||
|
1
map65/libm65/njunk.f90
Normal file
@ -0,0 +1 @@
|
||||
parameter(NJUNK=40)
|
@ -1,6 +1,6 @@
|
||||
subroutine q65b(nutc,nqd,nxant,fcenter,nfcal,nfsample,ikhz,mousedf,ntol,xpol, &
|
||||
mycall0,mygrid,hiscall0,hisgrid,mode_q65,f0,fqso,newdat,nagain, &
|
||||
max_drift,idec)
|
||||
max_drift,nhsym,idec)
|
||||
|
||||
! This routine provides an interface between MAP65 and the Q65 decoder
|
||||
! in WSJT-X. All arguments are input data obtained from the MAP65 GUI.
|
||||
@ -22,17 +22,20 @@ subroutine q65b(nutc,nqd,nxant,fcenter,nfcal,nfsample,ikhz,mousedf,ntol,xpol, &
|
||||
integer*2 iwave(60*12000)
|
||||
complex ca(MAXFFT1),cb(MAXFFT1) !FFTs of raw x,y data
|
||||
complex cx(0:MAXFFT2-1),cy(0:MAXFFT2-1),cz(0:MAXFFT2)
|
||||
logical xpol
|
||||
logical xpol,ldecoded
|
||||
integer ipk1(1)
|
||||
real*8 fcenter,freq0,freq1
|
||||
character*12 mycall0,hiscall0
|
||||
character*12 mycall,hiscall
|
||||
character*6 mygrid,hisgrid
|
||||
character*4 grid4
|
||||
character*28 msg00
|
||||
character*80 line
|
||||
character*80 wsjtx_dir
|
||||
character*1 cp,cmode*2
|
||||
common/cacb/ca,cb
|
||||
common/early/nhsym1,nhsym2,ldecoded(32768)
|
||||
data nutc00/-1/,msg00/' '/
|
||||
save
|
||||
|
||||
open(9,file='wsjtx_dir.txt',status='old')
|
||||
@ -50,8 +53,8 @@ subroutine q65b(nutc,nqd,nxant,fcenter,nfcal,nfsample,ikhz,mousedf,ntol,xpol, &
|
||||
ib=nint(ifreq+ntol/df3)
|
||||
ipk1=maxloc(sync(ia:ib)%ccfmax)
|
||||
ipk=ia+ipk1(1)-1
|
||||
if(ldecoded(ipk)) go to 900
|
||||
snr1=sync(ipk)%ccfmax
|
||||
|
||||
ipol=1
|
||||
if(xpol) ipol=sync(ipk)%ipol
|
||||
|
||||
@ -141,6 +144,7 @@ subroutine q65b(nutc,nqd,nxant,fcenter,nfcal,nfsample,ikhz,mousedf,ntol,xpol, &
|
||||
freq0=MHz + 0.001d0*ikhz
|
||||
|
||||
if(nsnr0.gt.-99) then
|
||||
ldecoded(ipk)=.true.
|
||||
nq65df=nint(1000*(0.001*k0*df+nkhz_center-48.0+1.000-1.27046-ikhz))-nfcal
|
||||
nq65df=nq65df + nfreq0 - 1000
|
||||
npol=nint(poldeg)
|
||||
@ -163,7 +167,6 @@ subroutine q65b(nutc,nqd,nxant,fcenter,nfcal,nfsample,ikhz,mousedf,ntol,xpol, &
|
||||
endif
|
||||
|
||||
! Write to lu 26, for Messages and Band Map windows
|
||||
|
||||
cmode=': '
|
||||
cmode(2:2)=char(ichar('A') + mode_q65-1)
|
||||
freq1=freq0 + 0.001d0*(ikhz1-ikhz)
|
||||
@ -171,9 +174,14 @@ subroutine q65b(nutc,nqd,nxant,fcenter,nfcal,nfsample,ikhz,mousedf,ntol,xpol, &
|
||||
':',cp,cmode
|
||||
1014 format(f8.3,i5,3i3,f5.1,i4,i3,i4,i5.4,4x,a22,1x,2a1,2x,a2)
|
||||
|
||||
! Suppress writing duplicates (same time, same decoded message) to map65_rx.log
|
||||
if(nutc.ne.nutc00 .or. msg0(1:28).ne.msg00) then
|
||||
! Write to file map65_rx.log:
|
||||
write(21,1110) freq1,ndf,xdt0,npol,nsnr0,nutc,msg0(1:28),cq0
|
||||
1110 format(f8.3,i5,f5.1,2i4,i5.4,2x,a28,': A',2x,a3)
|
||||
write(21,1110) freq1,ndf,xdt0,npol,nsnr0,nutc,msg0(1:28),cq0
|
||||
1110 format(f8.3,i5,f5.1,2i4,i5.4,2x,a28,': A',2x,a3)
|
||||
nutc00=nutc
|
||||
msg00=msg0(1:28)
|
||||
endif
|
||||
endif
|
||||
|
||||
900 close(13)
|
||||
|
@ -2,6 +2,7 @@ subroutine recvpkt(nsam,nblock2,userx_no,k,buf4,buf8,buf16)
|
||||
|
||||
! Reformat timf2 data from Linrad and stuff data into r*4 array dd().
|
||||
|
||||
include 'njunk.f90'
|
||||
parameter (NSMAX=60*96000) !Total sample intervals per minute
|
||||
parameter (NFFT=32768)
|
||||
integer*1 userx_no
|
||||
@ -11,7 +12,8 @@ subroutine recvpkt(nsam,nblock2,userx_no,k,buf4,buf8,buf16)
|
||||
integer*2 jd(4),kd(2),nblock2
|
||||
real*4 xd(4),yd(2)
|
||||
real*8 fcenter
|
||||
common/datcom/dd(4,5760000),ss(4,322,NFFT),savg(4,NFFT),fcenter,nutc,junk(36)
|
||||
common/datcom/dd(4,5760000),ss(4,322,NFFT),savg(4,NFFT),fcenter,nutc, &
|
||||
junk(NJUNK)
|
||||
equivalence (kd,d4)
|
||||
equivalence (jd,d8,yd)
|
||||
equivalence (xd,c16)
|
||||
|
@ -18,11 +18,13 @@ subroutine symspec(k,nxpol,ndiskdat,nb,nbslider,idphi,nfsample, &
|
||||
! ihsym index number of this half-symbol (1-322)
|
||||
! nzap number of samples zero'ed by noise blanker
|
||||
|
||||
include 'njunk.f90'
|
||||
parameter (NSMAX=60*96000) !Total sample intervals per minute
|
||||
parameter (NFFT=32768) !Length of FFTs
|
||||
real*8 ts,hsym
|
||||
real*8 fcenter
|
||||
common/datcom/dd(4,5760000),ss(4,322,NFFT),savg(4,NFFT),fcenter,nutc,junk(36)
|
||||
common/datcom/dd(4,5760000),ss(4,322,NFFT),savg(4,NFFT),fcenter,nutc, &
|
||||
junk(NJUNK)
|
||||
real*4 ssz5a(NFFT),w(NFFT),w2a(NFFT),w2b(NFFT)
|
||||
complex z,zfac
|
||||
complex zsumx,zsumy
|
||||
|
@ -41,7 +41,7 @@ program synctest
|
||||
call timer('synctest',0)
|
||||
|
||||
call timer('get_cand',0)
|
||||
call get_candidates(ss,savg,.true.,nfa,nfb,nts_jt65,nts_q65,cand,ncand)
|
||||
call get_candidates(ss,savg,302,.true.,nfa,nfb,nts_jt65,nts_q65,cand,ncand)
|
||||
call timer('get_cand',1)
|
||||
|
||||
do k=1,ncand
|
||||
|
@ -7,6 +7,7 @@ module wideband_sync
|
||||
real :: pol !Polarization angle, degrees
|
||||
integer :: ipol !Polarization angle, 1 to 4 ==> 0, 45, 90, 135 deg
|
||||
integer :: iflip !Sync type: JT65 = +/- 1, Q65 = 0
|
||||
integer :: indx
|
||||
end type candidate
|
||||
type sync_dat
|
||||
real :: ccfmax
|
||||
@ -25,25 +26,21 @@ module wideband_sync
|
||||
|
||||
contains
|
||||
|
||||
subroutine get_candidates(ss,savg,xpol,nfa,nfb,nts_jt65,nts_q65,cand,ncand)
|
||||
subroutine get_candidates(ss,savg,xpol,jz,nfa,nfb,nts_jt65,nts_q65,cand,ncand)
|
||||
|
||||
! Search symbol spectra ss() over frequency range nfa to nfb (in kHz) for
|
||||
! JT65 and Q65 sync patterns. The nts_* variables are the submode tone
|
||||
! spacings: 1 2 4 8 16 for A B C D E. Birdies are detected and
|
||||
! excised. Candidates are returned in the structure array cand().
|
||||
|
||||
parameter (MAX_PEAKS=300)
|
||||
parameter (MAX_PEAKS=100)
|
||||
real ss(4,322,NFFT),savg(4,NFFT)
|
||||
real pavg(-20:20)
|
||||
integer indx(NFFT)
|
||||
logical xpol,skip
|
||||
logical xpol,skip,ldecoded
|
||||
type(candidate) :: cand(MAX_CANDIDATES)
|
||||
common/early/nhsym1,nhsym2,ldecoded(32768)
|
||||
|
||||
do j=322,1,-1 !Find end of data in ss()
|
||||
if(sum(ss(1,j,1:NFFT)).gt.0.0) exit
|
||||
enddo
|
||||
jz=j
|
||||
|
||||
call wb_sync(ss,savg,xpol,jz,nfa,nfb)
|
||||
|
||||
tstep=2048.0/11025.0 !0.185760 s: 0.5*tsym_jt65, 0.3096*tsym_q65
|
||||
@ -87,11 +84,11 @@ subroutine get_candidates(ss,savg,xpol,nfa,nfb,nts_jt65,nts_q65,cand,ncand)
|
||||
diffhz=1000.0*(f0-cand(m)%f)
|
||||
bw=nts_q65*110.0
|
||||
if(cand(m)%iflip.ne.0) bw=nts_jt65*178.0
|
||||
if(diffhz.gt.-20.0 .and. diffhz.lt.bw+20.0) skip=.true.
|
||||
! write(*,3301) i,k,m,f0,cand(m)%f,diffhz,snr1,skip
|
||||
!3301 format('=',3i5,f10.1,3f10.3,L3)
|
||||
if(diffhz.gt.-0.03*bw .and. diffhz.lt.1.03*bw) skip=.true.
|
||||
enddo
|
||||
if(skip) cycle
|
||||
! write(*,3301) i,k,m,f0,diffhz,bw,db(snr1)
|
||||
!3301 format('=A',3i5,f8.3,2f8.0,f8.2)
|
||||
k=k+1
|
||||
cand(k)%snr=snr1
|
||||
cand(k)%f=f0
|
||||
@ -99,6 +96,7 @@ subroutine get_candidates(ss,savg,xpol,nfa,nfb,nts_jt65,nts_q65,cand,ncand)
|
||||
cand(k)%pol=sync(n)%pol
|
||||
cand(k)%ipol=sync(n)%ipol
|
||||
cand(k)%iflip=nint(flip)
|
||||
cand(k)%indx=n
|
||||
if(k.ge.MAX_CANDIDATES) exit
|
||||
enddo
|
||||
ncand=k
|
||||
|
@ -19,7 +19,7 @@ int main(int argc, char *argv[])
|
||||
QApplication a {argc, argv};
|
||||
// Override programs executable basename as application name.
|
||||
a.setApplicationName ("MAP65");
|
||||
a.setApplicationVersion ("3.0.0-rc3");
|
||||
a.setApplicationVersion ("3.0.0-rc4");
|
||||
// switch off as we share an Info.plist file with WSJT-X
|
||||
a.setAttribute (Qt::AA_DontUseNativeMenuBar);
|
||||
MainWindow w;
|
||||
|
@ -520,6 +520,7 @@ void MainWindow::dataSink(int k)
|
||||
static int nkhz;
|
||||
static int nfsample=96000;
|
||||
static int nxpol=0;
|
||||
static int iRxState=0;
|
||||
static float fgreen;
|
||||
static int ndiskdat;
|
||||
static int nb;
|
||||
@ -530,7 +531,6 @@ void MainWindow::dataSink(int k)
|
||||
static float rejecty;
|
||||
static float slimit;
|
||||
|
||||
|
||||
if(m_diskData) {
|
||||
ndiskdat=1;
|
||||
datcom_.ndiskdat=1;
|
||||
@ -620,10 +620,23 @@ void MainWindow::dataSink(int k)
|
||||
n=0;
|
||||
}
|
||||
|
||||
// if(ihsym == 280) { //For JT65, decode at t=52 s (also for old *.tf2/*.iq disk files)
|
||||
if(ihsym == 302) { //For Q65, decode at t=56 s
|
||||
if(ihsym<280) iRxState=0;
|
||||
|
||||
if(iRxState==0 and ihsym>=280) { //Early decode, t=52 s
|
||||
iRxState=1;
|
||||
datcom_.newdat=1;
|
||||
datcom_.nagain=0;
|
||||
datcom_.nhsym=ihsym;
|
||||
QDateTime t = QDateTime::currentDateTimeUtc();
|
||||
m_dateTime=t.toString("yyyy-MMM-dd hh:mm");
|
||||
decode(); //Start the decoder
|
||||
}
|
||||
|
||||
if(iRxState<=1 and ihsym>=302) { //Decode at t=56 s (for Q65 and data from disk)
|
||||
iRxState=2;
|
||||
datcom_.newdat=1;
|
||||
datcom_.nagain=0;
|
||||
datcom_.nhsym=ihsym;
|
||||
QDateTime t = QDateTime::currentDateTimeUtc();
|
||||
m_dateTime=t.toString("yyyy-MMM-dd hh:mm");
|
||||
decode(); //Start the decoder
|
||||
@ -636,6 +649,7 @@ void MainWindow::dataSink(int k)
|
||||
watcher2->setFuture(*future2);
|
||||
}
|
||||
}
|
||||
|
||||
soundInThread.m_dataSinkBusy=false;
|
||||
}
|
||||
|
||||
@ -1107,15 +1121,14 @@ void MainWindow::diskDat() //diskDat()
|
||||
m_diskData=true;
|
||||
datcom_.newdat=1;
|
||||
|
||||
// if(g_pWideGraph->m_bForceCenterFreq) datcom_.fcenter=g_pWideGraph->m_dForceCenterFreq;
|
||||
// qDebug() << "aa" << datcom_.fcenter << g_pWideGraph->m_dForceCenterFreq
|
||||
// << g_pWideGraph->m_bForceCenterFreq;
|
||||
|
||||
if(m_fs96000) hsym=2048.0*96000.0/11025.0; //Samples per JT65 half-symbol
|
||||
if(!m_fs96000) hsym=2048.0*95238.1/11025.0;
|
||||
for(int i=0; i<304; i++) { // Do the half-symbol FFTs
|
||||
int k = i*hsym + 2048.5;
|
||||
dataSink(k);
|
||||
while(m_decoderBusy) {
|
||||
qApp->processEvents();
|
||||
}
|
||||
if(i%10 == 0) qApp->processEvents(); //Keep the GUI responsive
|
||||
}
|
||||
}
|
||||
@ -1248,6 +1261,9 @@ void MainWindow::freezeDecode(int n) //freezeDecode()
|
||||
void MainWindow::decode() //decode()
|
||||
{
|
||||
ui->DecodeButton->setStyleSheet(m_pbdecoding_style1);
|
||||
|
||||
// QFile f("mockRTfiles.txt");
|
||||
// if(datcom_.nagain==0 && (!m_diskData) && !f.exists()) {
|
||||
if(datcom_.nagain==0 && (!m_diskData)) {
|
||||
qint64 ms = QDateTime::currentMSecsSinceEpoch() % 86400000;
|
||||
int imin=ms/60000;
|
||||
@ -1282,7 +1298,7 @@ void MainWindow::decode() //decode()
|
||||
datcom_.ntol=m_tol;
|
||||
datcom_.nxant=0;
|
||||
if(m_xpolx) datcom_.nxant=1;
|
||||
if(datcom_.nutc < m_nutc0) m_map65RxLog |= 1; //Date and Time to all65.txt
|
||||
if(datcom_.nutc < m_nutc0) m_map65RxLog |= 1; //Date and Time to map65_rx.log
|
||||
m_nutc0=datcom_.nutc;
|
||||
datcom_.map65RxLog=m_map65RxLog;
|
||||
datcom_.nfsample=96000;
|
||||
@ -1303,7 +1319,9 @@ void MainWindow::decode() //decode()
|
||||
memcpy(datcom_.mygrid, mgrid.toLatin1(), 6);
|
||||
memcpy(datcom_.hiscall, hcall.toLatin1(), 12);
|
||||
memcpy(datcom_.hisgrid, hgrid.toLatin1(), 6);
|
||||
memcpy(datcom_.datetime, m_dateTime.toLatin1(), 20);
|
||||
memcpy(datcom_.datetime, m_dateTime.toLatin1(), 17);
|
||||
datcom_.junk1=1234;
|
||||
datcom_.junk2=5678;
|
||||
|
||||
//newdat=1 ==> this is new data, must do the big FFT
|
||||
//nagain=1 ==> decode only at fQSO +/- Tol
|
||||
@ -1317,9 +1335,10 @@ void MainWindow::decode() //decode()
|
||||
from += noffset;
|
||||
size -= noffset;
|
||||
}
|
||||
memcpy(to, from, qMin(mem_m65.size(), size));
|
||||
memcpy(to, from, qMin(mem_m65.size(), size-8));
|
||||
datcom_.nagain=0;
|
||||
datcom_.ndiskdat=0;
|
||||
m_map65RxLog=0;
|
||||
m_call3Modified=false;
|
||||
|
||||
QFile lockFile(m_appDir + "/.lock"); // Allow m65 to start
|
||||
@ -1371,7 +1390,8 @@ void MainWindow::readFromStdout() //readFromStdout
|
||||
lab7->setText (QString {"Avg: %1"}.arg (m_nsum));
|
||||
if(m_modeQ65>0) m_wide_graph_window->setDecodeFinished();
|
||||
}
|
||||
if(t.indexOf("<DecodeFinished>") >= 0) {
|
||||
|
||||
if((t.indexOf("<EarlyFinished>") >= 0) or (t.indexOf("<DecodeFinished>") >= 0)) {
|
||||
if(m_widebandDecode) {
|
||||
m_messages_window->setText(m_messagesText,m_bandmapText);
|
||||
m_band_map_window->setText(m_bandmapText);
|
||||
@ -1379,10 +1399,12 @@ void MainWindow::readFromStdout() //readFromStdout
|
||||
}
|
||||
QFile lockFile(m_appDir + "/.lock");
|
||||
lockFile.open(QIODevice::ReadWrite);
|
||||
if(t.indexOf("<DecodeFinished>") >= 0) {
|
||||
m_map65RxLog=0;
|
||||
m_startAnother=m_loopall;
|
||||
}
|
||||
ui->DecodeButton->setStyleSheet("");
|
||||
decodeBusy(false);
|
||||
m_map65RxLog=0;
|
||||
m_startAnother=m_loopall;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1531,11 +1553,13 @@ void MainWindow::guiUpdate()
|
||||
msgsent[22]=0;
|
||||
|
||||
if(m_restart) {
|
||||
QString t=" Tx " + m_modeTx + " ";
|
||||
t=t.left(11);
|
||||
QFile f("map65_tx.log");
|
||||
f.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append);
|
||||
QTextStream out(&f);
|
||||
out << QDateTime::currentDateTimeUtc().toString("yyyy-MMM-dd hh:mm")
|
||||
<< " Tx message: " << QString::fromLatin1(msgsent)
|
||||
<< t << QString::fromLatin1(msgsent)
|
||||
#if QT_VERSION >= QT_VERSION_CHECK (5, 15, 0)
|
||||
<< Qt::endl
|
||||
#else
|
||||
@ -1560,11 +1584,13 @@ void MainWindow::guiUpdate()
|
||||
m_transmitting=true;
|
||||
m_wide_graph_window->enableSetRxHardware(false);
|
||||
|
||||
QString t=" Tx " + m_modeTx + " ";
|
||||
t=t.left(11);
|
||||
QFile f("map65_tx.log");
|
||||
f.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append);
|
||||
QTextStream out(&f);
|
||||
out << QDateTime::currentDateTimeUtc().toString("yyyy-MMM-dd hh:mm")
|
||||
<< " Tx message: " << QString::fromLatin1(msgsent)
|
||||
<< t << QString::fromLatin1(msgsent)
|
||||
#if QT_VERSION >= QT_VERSION_CHECK (5, 15, 0)
|
||||
<< Qt::endl
|
||||
#else
|
||||
|
@ -1,6 +1,6 @@
|
||||
set (SAMPLE_FILES
|
||||
FT4/000000_000002.wav
|
||||
FT8/181201_180245.wav
|
||||
FT8/210703_133430.wav
|
||||
FST4+FST4W/210115_0058.wav
|
||||
FST4+FST4W/201230_0300.wav
|
||||
MSK144/181211_120500.wav
|
||||
@ -17,7 +17,6 @@ set (SAMPLE_FILES
|
||||
JT65/JT65B/000000_0005.wav
|
||||
JT65/JT65B/000000_0006.wav
|
||||
JT65/JT65B/000000_0007.wav
|
||||
JT9+JT65/130610_2343.wav
|
||||
JT9/130418_1742.wav
|
||||
MSK144/181211_120500.wav
|
||||
MSK144/181211_120800.wav
|
||||
|
BIN
samples/FT8/210703_133430.wav
Normal file
@ -453,10 +453,6 @@ void DisplayText::displayDecodedText(DecodedText const& decodedText, QString con
|
||||
// if enabled add the DXCC entity and B4 status to the end of the
|
||||
// preformated text line t1
|
||||
auto currentMode = mode;
|
||||
if ("JT9+JT65" == mode)
|
||||
{
|
||||
currentMode = decodedText.isJT65 () ? "JT65" : "JT9";
|
||||
}
|
||||
message = appendWorkedB4 (message, decodedText.CQersCall(), dxGrid, &bg, &fg
|
||||
, logBook, currentBand, currentMode, extra);
|
||||
}
|
||||
|
@ -1028,9 +1028,9 @@ void MainWindow::not_GA_warning_message ()
|
||||
MessageBox::critical_message (this,
|
||||
"This is a pre-release version of WSJT-X 2.5.0 made\n"
|
||||
"available for testing purposes. By design it will\n"
|
||||
"be nonfunctional after Aug 31, 2021.");
|
||||
"be nonfunctional after Sept 30, 2021.");
|
||||
auto now = QDateTime::currentDateTimeUtc ();
|
||||
if (now >= QDateTime {{2021, 8, 31}, {23, 59, 59, 999}, Qt::UTC}) {
|
||||
if (now >= QDateTime {{2021, 9, 30}, {23, 59, 59, 999}, Qt::UTC}) {
|
||||
Q_EMIT finished ();
|
||||
}
|
||||
}
|
||||
@ -4942,12 +4942,13 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie
|
||||
return;
|
||||
}
|
||||
|
||||
bool bContestOK=(m_mode=="FT4" or m_mode=="FT8" or m_mode=="Q65" or m_mode=="MSK144");
|
||||
if(message_words.size () > 3 // enough fields for a normal message
|
||||
&& (message_words.at(1).contains(m_baseCall) || "DE" == message_words.at(1))
|
||||
&& (message_words.at(2).contains(qso_partner_base_call) or m_bDoubleClicked
|
||||
or bEU_VHF_w2 or (m_QSOProgress==CALLING))) {
|
||||
if(message_words.at(3).contains(grid_regexp) and SpecOp::EU_VHF!=m_config.special_op_id()) {
|
||||
if(SpecOp::NA_VHF==m_config.special_op_id() or SpecOp::WW_DIGI==m_config.special_op_id()){
|
||||
if((SpecOp::NA_VHF==m_config.special_op_id() or SpecOp::WW_DIGI==m_config.special_op_id()) and bContestOK){
|
||||
setTxMsg(3);
|
||||
m_QSOProgress=ROGER_REPORT;
|
||||
} else {
|
||||
@ -5604,8 +5605,8 @@ void MainWindow::lookup()
|
||||
break;
|
||||
}
|
||||
QString t=QString(c);
|
||||
if(t.indexOf(hisCall)==0) {
|
||||
int i1=t.indexOf(",");
|
||||
int i1=t.indexOf(",");
|
||||
if(t.left(i1)==hisCall) {
|
||||
QString hisgrid=t.mid(i1+1,6);
|
||||
i1=hisgrid.indexOf(",");
|
||||
if(i1>0) {
|
||||
@ -6454,13 +6455,21 @@ void MainWindow::on_actionQ65_triggered()
|
||||
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("");
|
||||
|
||||
if (SpecOp::NONE < m_config.special_op_id () && SpecOp::FOX > m_config.special_op_id ()) {
|
||||
QString t0="";
|
||||
if(SpecOp::NA_VHF==m_config.special_op_id()) t0="NA VHF";
|
||||
if(SpecOp::EU_VHF==m_config.special_op_id()) t0="EU VHF";
|
||||
if(SpecOp::FIELD_DAY==m_config.special_op_id()) t0="Field Day";
|
||||
if(t0=="") {
|
||||
ui->labDXped->setVisible(false);
|
||||
} else {
|
||||
ui->labDXped->setVisible(true);
|
||||
ui->labDXped->setText(t0);
|
||||
}
|
||||
on_contest_log_action_triggered();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::on_actionMSK144_triggered()
|
||||
|
@ -530,9 +530,8 @@ void CPlotter::DrawOverlay() //DrawOverlay()
|
||||
int yh=5;
|
||||
int yTxTop=12;
|
||||
int yRxBottom=yTxTop + 2*yh + 4;
|
||||
if(m_mode=="JT9" or m_mode=="JT65" or m_mode=="JT9+JT65"
|
||||
or m_mode=="Q65" or m_mode=="FT8" or m_mode=="FT4"
|
||||
or m_mode.startsWith("FST4")) {
|
||||
if(m_mode=="JT9" or m_mode=="JT65" or m_mode=="Q65" or m_mode=="FT8"
|
||||
or m_mode=="FT4" or m_mode.startsWith("FST4")) {
|
||||
|
||||
if(m_mode=="FST4" and !m_bSingleDecode) {
|
||||
x1=XfromFreq(m_nfa);
|
||||
@ -580,9 +579,8 @@ void CPlotter::DrawOverlay() //DrawOverlay()
|
||||
}
|
||||
}
|
||||
|
||||
if(m_mode=="JT9" or m_mode=="JT65" or m_mode=="JT9+JT65" or
|
||||
m_mode.mid(0,4)=="WSPR" or m_mode=="Q65" or m_mode=="FT8"
|
||||
or m_mode=="FT4" or m_mode.startsWith("FST4")) {
|
||||
if(m_mode=="JT9" or m_mode=="JT65" or m_mode.mid(0,4)=="WSPR" or m_mode=="Q65"
|
||||
or m_mode=="FT8" or m_mode=="FT4" or m_mode.startsWith("FST4")) {
|
||||
painter0.setPen(penRed);
|
||||
x1=XfromFreq(m_txFreq);
|
||||
x2=XfromFreq(m_txFreq+bw);
|
||||
@ -597,15 +595,6 @@ void CPlotter::DrawOverlay() //DrawOverlay()
|
||||
painter0.drawLine(x2,yTxTop,x2,yTxTop+yh);
|
||||
}
|
||||
|
||||
if(m_mode=="JT9+JT65") {
|
||||
QPen pen2(Qt::blue, 3); //Mark the JT65 | JT9 divider
|
||||
painter0.setPen(pen2);
|
||||
x1=XfromFreq(m_fMin);
|
||||
if(x1<2) x1=2;
|
||||
x2=x1+30;
|
||||
painter0.drawLine(x1,8,x1,28);
|
||||
}
|
||||
|
||||
if(m_dialFreq>10.13 and m_dialFreq< 10.15 and m_mode.mid(0,4)!="WSPR") {
|
||||
float f1=1.0e6*(10.1401 - m_dialFreq);
|
||||
float f2=f1+200.0;
|
||||
|
@ -292,7 +292,7 @@ void WideGraph::setTxFreq(int n) //setTxFreq
|
||||
void WideGraph::setMode(QString mode) //setMode
|
||||
{
|
||||
m_mode=mode;
|
||||
ui->fSplitSpinBox->setEnabled(m_mode=="JT9+JT65" or m_mode.startsWith("FST4"));
|
||||
ui->fSplitSpinBox->setEnabled(m_mode.startsWith("FST4"));
|
||||
ui->widePlot->setMode(mode);
|
||||
ui->widePlot->DrawOverlay();
|
||||
ui->widePlot->update();
|
||||
@ -363,7 +363,7 @@ void WideGraph::setRxBand (QString const& band)
|
||||
else
|
||||
{
|
||||
ui->fSplitSpinBox->setValue (m_fMinPerBand.value (band, 2500).toUInt ());
|
||||
ui->fSplitSpinBox->setEnabled (m_mode=="JT9+JT65" or m_mode.startsWith("FST4"));
|
||||
ui->fSplitSpinBox->setEnabled (m_mode.startsWith("FST4"));
|
||||
}
|
||||
ui->widePlot->setRxBand(band);
|
||||
setRxRange ();
|
||||
|