Merge branch 'feat-staging' into develop

This commit is contained in:
Bill Somerville 2020-09-01 17:36:22 +01:00
commit fcc5df35d3
No known key found for this signature in database
GPG Key ID: D864B06D1E81618F
19 changed files with 312 additions and 257 deletions

View File

@ -618,6 +618,7 @@ set (wsjt_FSRCS
lib/fst4/osd240_101.f90 lib/fst4/osd240_101.f90
lib/fst4/osd240_74.f90 lib/fst4/osd240_74.f90
lib/fst4/get_crc24.f90 lib/fst4/get_crc24.f90
lib/fst4/fst4_baseline.f90
) )
# temporary workaround for a gfortran v7.3 ICE on Fedora 27 64-bit # temporary workaround for a gfortran v7.3 ICE on Fedora 27 64-bit

View File

@ -901,7 +901,7 @@ auto Configuration::special_op_id () const -> SpecialOperatingActivity
void Configuration::set_location (QString const& grid_descriptor) void Configuration::set_location (QString const& grid_descriptor)
{ {
// change the dynamic grid // change the dynamic grid
qDebug () << "Configuration::set_location - location:" << grid_descriptor; // qDebug () << "Configuration::set_location - location:" << grid_descriptor;
m_->dynamic_grid_ = grid_descriptor.trimmed (); m_->dynamic_grid_ = grid_descriptor.trimmed ();
} }
@ -2610,7 +2610,7 @@ void Configuration::impl::transceiver_frequency (Frequency f)
current_offset_ = stations_.offset (f); current_offset_ = stations_.offset (f);
cached_rig_state_.frequency (apply_calibration (f + current_offset_)); cached_rig_state_.frequency (apply_calibration (f + current_offset_));
qDebug () << "Configuration::impl::transceiver_frequency: n:" << transceiver_command_number_ + 1 << "f:" << f; // qDebug () << "Configuration::impl::transceiver_frequency: n:" << transceiver_command_number_ + 1 << "f:" << f;
Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_); Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_);
} }
@ -2636,7 +2636,7 @@ void Configuration::impl::transceiver_tx_frequency (Frequency f)
cached_rig_state_.tx_frequency (apply_calibration (f + current_tx_offset_)); cached_rig_state_.tx_frequency (apply_calibration (f + current_tx_offset_));
} }
qDebug () << "Configuration::impl::transceiver_tx_frequency: n:" << transceiver_command_number_ + 1 << "f:" << f; // qDebug () << "Configuration::impl::transceiver_tx_frequency: n:" << transceiver_command_number_ + 1 << "f:" << f;
Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_); Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_);
} }
} }
@ -2645,7 +2645,7 @@ void Configuration::impl::transceiver_mode (MODE m)
{ {
cached_rig_state_.online (true); // we want the rig online cached_rig_state_.online (true); // we want the rig online
cached_rig_state_.mode (m); cached_rig_state_.mode (m);
qDebug () << "Configuration::impl::transceiver_mode: n:" << transceiver_command_number_ + 1 << "m:" << m; // qDebug () << "Configuration::impl::transceiver_mode: n:" << transceiver_command_number_ + 1 << "m:" << m;
Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_); Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_);
} }
@ -2654,7 +2654,7 @@ void Configuration::impl::transceiver_ptt (bool on)
cached_rig_state_.online (true); // we want the rig online cached_rig_state_.online (true); // we want the rig online
set_cached_mode (); set_cached_mode ();
cached_rig_state_.ptt (on); cached_rig_state_.ptt (on);
qDebug () << "Configuration::impl::transceiver_ptt: n:" << transceiver_command_number_ + 1 << "on:" << on; // qDebug () << "Configuration::impl::transceiver_ptt: n:" << transceiver_command_number_ + 1 << "on:" << on;
Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_); Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_);
} }

View File

@ -1,7 +1,7 @@
// Status=review // Status=edited
Source code for _WSJT-X_ is available from a public repository at Source code for _WSJT-X_ is available from a public repository at
{devrepo}. To compile the program you will need to install at least the {devrepo}. To compile the program, at a minimum you must install the
following packages: following packages:
- Git - Git
@ -19,7 +19,7 @@ cd wsjtx
git checkout wsjtx-{VERSION} git checkout wsjtx-{VERSION}
===== =====
and for the current development branch, and for the current development branch:
===== =====
git clone git://git.code.sf.net/p/wsjt/wsjtx git clone git://git.code.sf.net/p/wsjt/wsjtx

View File

@ -1,16 +1,14 @@
// Status=review // Status=edited
Debian, Ubuntu, and other Debian-based systems including Raspbian: Debian, Ubuntu, and other Debian-based systems including Raspbian:
NOTE: The project team release binary installer packages for Linux NOTE: The project team release binary installer packages targeted for
when a new _WSJT-X_ release is announced. These are built to one contemporary version of a Linux distribution. Although these may
target one contemporary version of a Linux distribution. Although work on newer Linux versions or even different distributions, it is
these may work on newer Linux versions or even different unlikely that they work on older versions. Check the notes provided
distributions, it is unlikely that they will work on older with the release for details of the targeted Linux distributions and
versions. Check the notes provided with the release for details of the versions. If the binary package is not compatible with your Linux
targeted Linux distributions and versions. If the binary package is distribution or version, you must build the application from sources.
not compatible with your Linux distribution or version you must build
the application from sources.
* 32-bit: {debian32} * 32-bit: {debian32}
- To install: - To install:

View File

@ -1,12 +1,12 @@
// These instructions are up-to-date for WSJT-X v2.2 // These instructions are up-to-date for WSJT-X v2.2
*OS X 10.12* and later: Download the file {osx} to your desktop, *macOS10.13* and later: Download the file {osx} to your desktop,
double-click on it and consult its `ReadMe` file for important double-click it and consult its `ReadMe` file for important
installation notes. installation notes.
If you have already installed a previous version, you can retain it by If you have already installed a previous version, you can retain it by
changing its name in the *Applications* folder (say, from _WSJT-X_ to changing its name in the *Applications* folder (such as from _WSJT-X_ to
_WSJT-X_2.1_). You can then proceed to the installation phase. _WSJT-X_2.2_). You can then proceed to the installation phase.
Take note also of the following: Take note also of the following:

View File

@ -4,7 +4,7 @@ _WSJT-X_ is a computer program designed to facilitate basic amateur
radio communication using very weak signals. The first four letters in radio communication using very weak signals. The first four letters in
the program name stand for "`**W**eak **S**ignal communication by the program name stand for "`**W**eak **S**ignal communication by
K1**JT**,`" while the suffix "`-X`" indicates that _WSJT-X_ started as K1**JT**,`" while the suffix "`-X`" indicates that _WSJT-X_ started as
an e**Xt**ended and e**X**perimental branch of the program _WSJT_, an extended and experimental branch of the program _WSJT_,
first released in 2001. Bill Somerville, G4WJS, and Steve Franke, first released in 2001. Bill Somerville, G4WJS, and Steve Franke,
K9AN, have been major contributors to program development since 2013 K9AN, have been major contributors to program development since 2013
and 2015, respectively. and 2015, respectively.
@ -16,7 +16,7 @@ making reliable QSOs under weak-signal conditions. They use nearly
identical message structure and source encoding. JT65 and QRA64 were identical message structure and source encoding. JT65 and QRA64 were
designed for EME ("`moonbounce`") on the VHF/UHF bands and have also designed for EME ("`moonbounce`") on the VHF/UHF bands and have also
proven very effective for worldwide QRP communication on the HF bands. proven very effective for worldwide QRP communication on the HF bands.
QRA64 has a some advantages over JT65, including better performance QRA64 has some advantages over JT65, including better performance
for EME on the higher microwave bands. JT9 was originally designed for EME on the higher microwave bands. JT9 was originally designed
for the LF, MF, and lower HF bands. Its submode JT9A is 2 dB more for the LF, MF, and lower HF bands. Its submode JT9A is 2 dB more
sensitive than JT65 while using less than 10% of the bandwidth. JT4 sensitive than JT65 while using less than 10% of the bandwidth. JT4
@ -27,7 +27,7 @@ reception, so a minimal QSO takes four to six minutes — two or three
transmissions by each station, one sending in odd UTC minutes and the transmissions by each station, one sending in odd UTC minutes and the
other even. FT8 is operationally similar but four times faster other even. FT8 is operationally similar but four times faster
(15-second T/R sequences) and less sensitive by a few dB. FT4 is (15-second T/R sequences) and less sensitive by a few dB. FT4 is
faster still (7.5 s T/R sequences) and especially well suited for faster still (7.5 s T/R sequences) and especially well-suited for
radio contesting. On the HF bands, world-wide QSOs are possible with radio contesting. On the HF bands, world-wide QSOs are possible with
any of these modes using power levels of a few watts (or even any of these modes using power levels of a few watts (or even
milliwatts) and compromise antennas. On VHF bands and higher, QSOs milliwatts) and compromise antennas. On VHF bands and higher, QSOs
@ -45,7 +45,7 @@ protocols designed to take advantage of brief signal enhancements from
ionized meteor trails, aircraft scatter, and other types of scatter ionized meteor trails, aircraft scatter, and other types of scatter
propagation. These modes use timed sequences of 5, 10, 15, or 30 s propagation. These modes use timed sequences of 5, 10, 15, or 30 s
duration. User messages are transmitted repeatedly at high rate (up duration. User messages are transmitted repeatedly at high rate (up
to 250 characters per second, for MSK144) to make good use of the to 250 characters per second for MSK144) to make good use of the
shortest meteor-trail reflections or "`pings`". ISCAT uses free-form shortest meteor-trail reflections or "`pings`". ISCAT uses free-form
messages up to 28 characters long, while MSK144 uses the same messages up to 28 characters long, while MSK144 uses the same
structured messages as the slow modes and optionally an abbreviated structured messages as the slow modes and optionally an abbreviated
@ -80,4 +80,4 @@ be beta releases leading up to the final release of v2.1.0.
Release candidates should be used _only_ during a short testing Release candidates should be used _only_ during a short testing
period. They carry an implied obligation to provide feedback to the period. They carry an implied obligation to provide feedback to the
program development group. Candidate releases should not be used on program development group. Candidate releases should not be used on
the air after a full release with the same number has been made. the air after a full release with the same number is made.

View File

@ -1,7 +1,9 @@
//status: edited
A basic logging facility in _WSJT-X_ saves QSO information to files A basic logging facility in _WSJT-X_ saves QSO information to files
named `wsjtx.log` (in comma-separated text format) and `wsjtx_log.adi` named `wsjtx.log` (in comma-separated text format) and `wsjtx_log.adi`
(in standard ADIF format). These files can be imported directly into (in standard ADIF format). These files can be imported directly into
other programs, for example spreadsheets and popular logging programs. other programs (such as spreadsheets and popular logging programs).
As described in the <<INSTALL,Installation>> and <<PLATFORM,Platform As described in the <<INSTALL,Installation>> and <<PLATFORM,Platform
Dependencies>> sections, different operating systems may place your Dependencies>> sections, different operating systems may place your
local log files in different locations. You can always navigate to local log files in different locations. You can always navigate to
@ -12,30 +14,32 @@ applications like {jtalert}, which can log QSOs automatically to other
applications including {hrd}, {dxlsuite}, and {log4om}. applications including {hrd}, {dxlsuite}, and {log4om}.
The program option *Show DXCC entity and worked before status* The program option *Show DXCC entity and worked before status*
(selectable on the *Settings | General* tab) is intended mostly for (selectable on the *File | Settings | General* tab) is intended mostly for
use on non-Windows platforms, where {jtalert} is not available. When use on non-Windows platforms, where {jtalert} is not available. When
this option is checked _WSJT-X_ appends some additional information to this option is checked, _WSJT-X_ appends some additional information to
all CQ messages displayed in the _Band Activity_ window. The name of all CQ messages displayed in the _Band Activity_ window. The name of
the DXCC entity is shown, abbreviated if necessary. Your "`worked the DXCC entity is shown, abbreviated if necessary. Your "`worked
before`" status for this callsign (according to log file before`" status for this callsign (according to log file
`wsjtx_log.adi`) is indicated by highlighting colors, if that option `wsjtx_log.adi`) is indicated by highlighting colors, if that option
has been selected. is selected.
_WSJT-X_ includes a built-in `cty.dat` file containing DXCC prefix _WSJT-X_ includes a built-in `cty.dat` file containing DXCC prefix
information. Updated files can be downloaded from the {cty_dat} web information. Updated files can be downloaded from the {cty_dat} web
site when required. If an updated `cty.dat` is present in the logs site when required. If an updated and readable `cty.dat` file is
folder and readable, it will be used in preference to the built-in present in the logs folder, it is used in preference to the
one. built-in file.
The log file `wsjtx_log.adi` is updated whenever you log a QSO from The log file `wsjtx_log.adi` is updated whenever you log a QSO from
_WSJT-X_. (Keep in mind that if you erase this file you will lose all _WSJT-X_. (Keep in mind that if you erase this file, you lose all
"`worked before`" information.) You can append or overwrite the "`worked before`" information.) You can append or overwrite the
`wsjtx_log.adi` file by exporting your QSO history as an ADIF file `wsjtx_log.adi` file by exporting your QSO history as an ADIF file
from another logging program. Turning *Show DXCC entity and worked from another logging program. Turning *Show DXCC entity and worked
before status* off and then on again will cause _WSJT-X_ to re-read before status* off and then on again causes _WSJT-X_ to re-read
the log file. Very large log files may cause _WSJT-X_ to slow down the log file. Very large log files may cause _WSJT-X_ to slow down
when searching for calls. If the ADIF log file has been changed when searching for calls. If the ADIF log file has been changed
outside of _WSJT-X_ you can force _WSJT-X_ to reload the file from the outside of _WSJT-X_ you can force _WSJT-X_ to reload the file from the
*Settings | Colors* tab using the *Rescan ADIF Log* button, see *Settings | Colors* tab using the *Rescan ADIF Log* button, see
<<COLORS,Decode Highlighting>>. <<COLORS,Decode Highlighting>>.
Additional features are provided for *Contest* and *Fox* logging.
(more to come, here ...)

View File

@ -37,7 +37,7 @@ assigns more reliable numbers to relatively strong signals.
NOTE: Signals become visible on the waterfall around S/N = 26 dB and NOTE: Signals become visible on the waterfall around S/N = 26 dB and
audible (to someone with very good hearing) around 15 dB. Thresholds audible (to someone with very good hearing) around 15 dB. Thresholds
for decodability are around -20 dB for FT8, -23 dB for JT4, 25 dB for for decodability are around -20 dB for FT8, -23 dB for JT4, 25 dB for
JT65, 27 dB for JT9. JT65, and 27 dB for JT9.
NOTE: Several options are available for circumstances where fast QSOs NOTE: Several options are available for circumstances where fast QSOs
are desirable. Double-click the *Tx1* control under _Now_ or _Next_ are desirable. Double-click the *Tx1* control under _Now_ or _Next_
@ -75,7 +75,7 @@ When calling CQ you may also choose to check the box *Call 1st*.
_WSJT-X_ will then respond automatically to the first decoded _WSJT-X_ will then respond automatically to the first decoded
responder to your CQ. responder to your CQ.
NOTE: When *Auto-Seq* is enabled the program de-activates *Enable Tx* NOTE: When *Auto-Seq* is enabled, the program de-activates *Enable Tx*
at the end of each QSO. It is not intended that _WSJT-X_ should make at the end of each QSO. It is not intended that _WSJT-X_ should make
fully automated QSOs. fully automated QSOs.
@ -259,7 +259,7 @@ that a second callsign is never permissible in these messages.
NOTE: During a transmission your outgoing message is displayed in the NOTE: During a transmission your outgoing message is displayed in the
first label on the *Status Bar* and shown exactly as another station first label on the *Status Bar* and shown exactly as another station
will receive it. You can check to see that you are actually receives it. You can check to see that you are actually
transmitting the message you wish to send. transmitting the message you wish to send.
QSOs involving *Type 2* compound callsigns might look like either QSOs involving *Type 2* compound callsigns might look like either
@ -287,7 +287,7 @@ standard structured messages without callsign prefix or suffix.
TIP: If you are using a compound callsign, you may want to TIP: If you are using a compound callsign, you may want to
experiment with the option *Message generation for type 2 compound experiment with the option *Message generation for type 2 compound
callsign holders* on the *Settings | General* tab, so that messages callsign holders* on the *File | Settings | General* tab, so that messages
will be generated that best suit your needs. will be generated that best suit your needs.
=== Pre-QSO Checklist === Pre-QSO Checklist

View File

@ -1,6 +1,8 @@
//Status: edited
=== Frequency Calibration === Frequency Calibration
Many _WSJT-X_ capabilities depend on signal-detection bandwidths no Many _WSJT-X_ capabilities depend on signal-detection bandwidths of no
more than a few Hz. Frequency accuracy and stability are therefore more than a few Hz. Frequency accuracy and stability are therefore
unusually important. We provide tools to enable accurate frequency unusually important. We provide tools to enable accurate frequency
calibration of your radio, as well as precise frequency measurement of calibration of your radio, as well as precise frequency measurement of
@ -11,11 +13,11 @@ measuring the error in dial frequency for each signal.
You will probably find it convenient to define and use a special You will probably find it convenient to define and use a special
<<CONFIG-MENU,Configuration>> dedicated to frequency calibration. <<CONFIG-MENU,Configuration>> dedicated to frequency calibration.
Then complete the following steps, as appropriate for your system. Then complete the following steps, as appropriate, for your system.
- Switch to FreqCal mode - Switch to FreqCal mode
- In the _Working Frequencies_ box on the *Settings -> Frequencies* - In the _Working Frequencies_ box on the *File | Settings | Frequencies*
tab, delete any default frequencies for *FreqCal* mode that are not tab, delete any default frequencies for *FreqCal* mode that are not
relevant for your location. You may want to replace some of them with relevant for your location. You may want to replace some of them with
reliably known frequencies receivable at your location. reliably known frequencies receivable at your location.
@ -29,14 +31,14 @@ of WWV at 2.500, 5.000, 10.000, 15.000, and 20.000 MHz, and CHU at
3.330, 7.850, and 14.670 MHz. Similar shortwave signals are available 3.330, 7.850, and 14.670 MHz. Similar shortwave signals are available
in other parts of the world. in other parts of the world.
- In most cases you will want to start by deleting any existing file - In most cases, start by deleting any existing file `fmt.all` in the
`fmt.all` in the directory where your log files are kept. directory where your log files are kept.
- To cycle automatically through your chosen list of calibration - To cycle automatically through your chosen list of calibration
frequencies, check *Execute frequency calibration cycle* on the frequencies, check *Execute frequency calibration cycle* on the
*Tools* menu. _WSJT-X_ will spend 30 seconds at each *Tools* menu. _WSJT-X_ will spend 30 seconds at each
frequency. Initially no measurement data is saved to the `fmt.all` frequency. Initially no measurement data is saved to the `fmt.all`
file although it is displayed on screen, this allows you to check your file although it is displayed on screen; this allows you to check your
current calibration parameters. current calibration parameters.
- During the calibration procedure, the radio's USB dial frequency is - During the calibration procedure, the radio's USB dial frequency is
@ -61,7 +63,7 @@ the nominal frequency itself (in MHz). For example, the 20 MHz
measurement for WWV shown above produced a measured tone offset of measurement for WWV shown above produced a measured tone offset of
24.6 Hz, displayed in the _WSJT-X_ decoded text window. The resulting 24.6 Hz, displayed in the _WSJT-X_ decoded text window. The resulting
calibration constant is 24.6/20=1.23 parts per million. This number calibration constant is 24.6/20=1.23 parts per million. This number
may be entered as *Slope* on the *settings -> Frequencies* tab. may be entered as *Slope* on the *File | Settings | Frequencies* tab.
A more precise calibration can be effected by fitting the intercept A more precise calibration can be effected by fitting the intercept
and slope of a straight line to the whole sequence of calibration and slope of a straight line to the whole sequence of calibration
@ -81,19 +83,19 @@ After running *Execute frequency calibration cycle* at least once with
good results, check and edit the file `fmt.all` in the log directory good results, check and edit the file `fmt.all` in the log directory
and delete any spurious or outlier measurements. The line-fitting and delete any spurious or outlier measurements. The line-fitting
procedure can then be carried out automatically by clicking *Solve for procedure can then be carried out automatically by clicking *Solve for
calibration parameters* on the *Tools* menu. The results will be calibration parameters* on the *Tools* menu. The results are
displayed as in the following screen shot. Estimated uncertainties displayed as in the following screen shot. Estimated uncertainties
are included for slope and intercept; `N` is the number of averaged are included for slope and intercept; `N` is the number of averaged
frequency measurements included in the fit, and `StdDev` is the root frequency measurements included in the fit, and `StdDev` is the root
mean square deviation of averaged measurements from the fitted mean square deviation of averaged measurements from the fitted
straight line. If the solution seems valid you will be offered an straight line. If the solution seems valid, you are offered an
*Apply* button to push that will automatically set the calibration *Apply* button to push that automatically sets the calibration
parameters in *Settings -> Frequencies -> Frequency Calibration*. parameters in *File | Settings | Frequencies | Frequency Calibration*.
image::FreqCal_Results.png[align="center",alt="FreqCal_Results"] image::FreqCal_Results.png[align="center",alt="FreqCal_Results"]
For a quick visual check of the resulting calibration, stay in For a quick visual check of the resulting calibration, stay in
*FreqCal* mode with the *Measure* option cleared. _WSJT-X_ will show *FreqCal* mode with the *Measure* option cleared. _WSJT-X_ shows
the adjusted results directly on the waterfall and the displayed the adjusted results directly on the waterfall and the displayed
records. records.
@ -103,8 +105,8 @@ _WSJT-X_ provides a tool that can be used to determine the detailed
shape of your receiver's passband. Disconnect your antenna or tune to shape of your receiver's passband. Disconnect your antenna or tune to
a quiet frequency with no signals. With _WSJT-X_ running in one of a quiet frequency with no signals. With _WSJT-X_ running in one of
the slow modes, select *Measure reference spectrum* from the *Tools* the slow modes, select *Measure reference spectrum* from the *Tools*
menu. Wait for about a minute and then hit the *Stop* button. A file menu. Wait for about a minute and then click *Stop*. A file
named `refspec.dat` will appear in your log directory. When you check named `refspec.dat` appears in your log directory. When you check
*Ref Spec* on the *Wide Graph*, the recorded reference spectrum will *Ref Spec* on the *Wide Graph*, the recorded reference spectrum will
then be used to flatten your overall effective passband. then be used to flatten your overall effective passband.
@ -122,39 +124,39 @@ response* generates an undistorted audio waveform equal to the one
generated by the transmitting station. Its Fourier transform is then generated by the transmitting station. Its Fourier transform is then
used as a frequency-dependent phase reference to compare with the used as a frequency-dependent phase reference to compare with the
phase of the received frame's Fourier coefficients. Phase differences phase of the received frame's Fourier coefficients. Phase differences
between the reference spectrum and received spectrum will include between the reference spectrum and received spectrum include
contributions from the originating station's transmit filter, the contributions from the originating station's transmit filter, the
propagation channel, and filters in the receiver. If the received propagation channel, and filters in the receiver. If the received
frame originates from a station known to transmit signals having frame originates from a station known to transmit signals having
little phase distortion (say, a station known to use a properly little phase distortion (such as a station known to use a properly
adjusted software-defined-transceiver) and if the received signal is adjusted software-defined transceiver), and if the received signal is
relatively free from multipath distortion so that the channel phase is relatively free from multipath distortion so that the channel phase is
close to linear, the measured phase differences will be representative close to linear, the measured phase differences will be representative
of the local receiver's phase response. of the local receiver's phase response.
Complete the following steps to generate a phase equalization curve: Complete the following steps to generate a phase equalization curve:
- Record a number of wav files that contain decodable signals from - Record a number of `wav` files that contain decodable signals from
your chosen reference station. Best results will be obtained when the your chosen reference station. Best results are obtained when the
signal-to-noise ratio of the reference signals is 10 dB or greater. signal-to-noise ratio of the reference signals is 10 dB or greater.
- Enter the callsign of the reference station in the DX Call box. - Enter the callsign of the reference station in the DX Call box.
- Select *Measure phase response* from the *Tools* menu, and open each - Select *Measure phase response* from the *Tools* menu, and open each
of the wav files in turn. The mode character on decoded text lines of the `wav` files in turn. The mode character on decoded text lines
will change from `&` to `^` while _WSJT-X_ is measuring the phase changes from `&` to `^` while _WSJT-X_ is measuring the phase
response, and it will change back to `&` after the measurement is response, and it changes back to `&` after the measurement is
completed. The program needs to average a number of high-SNR frames to completed. The program needs to average a number of high-SNR frames to
accurately estimate the phase, so it may be necessary to process accurately estimate the phase, so it may be necessary to process
several wav files. The measurement can be aborted at any time by several `wav` files. The measurement can be aborted at any time by
selecting *Measure phase response* again to toggle the phase selecting *Measure phase response* again to toggle the phase
measurement off. measurement off.
+ +
When the measurement is complete _WSJT-X_ will save the measured When the measurement is complete, _WSJT-X_ saves the measured
phase response in the *Log directory*, in a file with suffix phase response in the *Log directory*, in a file with suffix
".pcoeff". The filename will contain the callsign of the reference ".pcoeff". The filename contains the callsign of the reference
station and a timestamp, for example `K0TPP_170923_112027.pcoeff`. station and a timestamp, for example `K0TPP_170923_112027.pcoeff`.
- Select *Equalization tools ...* under the *Tools* menu and click the - Select *Equalization tools ...* under the *Tools* menu and click the
@ -165,23 +167,23 @@ the proposed phase equalization curve. It's a good idea to repeat the
phase measurement several times, using different wav files for each phase measurement several times, using different wav files for each
measurement, to ensure that your measurements are repeatable. measurement, to ensure that your measurements are repeatable.
- Once you are satisfied with a fitted curve, push the *Apply* button - Once you are satisfied with a fitted curve, click the *Apply* button
to save the proposed response. The red curve will be replaced with a to save the proposed response. The red curve is replaced with a
light green curve labeled "Current" to indicate that the phase light green curve labeled "Current" to indicate that the phase
equalization curve is now being applied to the received data. Another equalization curve is now being applied to the received data. Another
curve labeled "Group Delay" will appear. The "Group Delay" curve shows curve labeled "Group Delay" appears. The "Group Delay" curve shows
the group delay variation across the passband, in ms. Click the the group delay variation across the passband, in ms. Click the
*Discard Measured* button to remove the captured data from the plot, *Discard Measured* button to remove the captured data from the plot,
leaving only the applied phase equalization curve and corresponding leaving only the applied phase equalization curve and corresponding
group delay curve. group delay curve.
- To revert to no phase equalization, push the *Restore Defaults* - To revert to no phase equalization, click the *Restore Defaults*
button followed by the *Apply* button. button followed by the *Apply* button.
The three numbers printed at the end of each MSK144 decode line can be The three numbers printed at the end of each MSK144 decode line can be
used to assess the improvement provided by equalization. These numbers used to assess the improvement provided by equalization. These numbers
are: `N` = Number of frames averaged, `H` = Number of hard bit errors are: `N` = Number of frames averaged, `H` = Number of hard bit errors
corrected, `E` = Size of MSK eye diagram opening. corrected, and `E` = Size of MSK eye diagram opening.
Here is a decode of K0TPP obtained while *Measure phase response* was measuring Here is a decode of K0TPP obtained while *Measure phase response* was measuring
the phase response: the phase response:
@ -196,7 +198,7 @@ scale. Here's how the same decode looks after phase equalization:
103900 17 6.5 1493 & WA8CLT K0TPP +07 1 0 1.6 103900 17 6.5 1493 & WA8CLT K0TPP +07 1 0 1.6
In this case, equalization has increased the eye opening from 1.2 to In this case, equalization has increased the eye-opening from 1.2 to
1.6. Larger positive eye openings are associated with reduced 1.6. Larger positive eye openings are associated with reduced
likelihood of bit errors and higher likelihood that a frame will be likelihood of bit errors and higher likelihood that a frame will be
successfully decoded. In this case, the larger eye-opening tells us successfully decoded. In this case, the larger eye-opening tells us
@ -206,7 +208,7 @@ equalization curve is going to improve decoding of signals other than
those from the reference station, K0TPP. those from the reference station, K0TPP.
It's a good idea to carry out before and after comparisons using a It's a good idea to carry out before and after comparisons using a
large number of saved wav files with signals from many different large number of saved `wav` files with signals from many different
stations, to help decide whether your equalization curve improves stations, to help decide whether your equalization curve improves
decoding for most signals. When doing such comparisons, keep in mind decoding for most signals. When doing such comparisons, keep in mind
that equalization may cause _WSJT-X_ to successfully decode a frame that equalization may cause _WSJT-X_ to successfully decode a frame

View File

@ -1,3 +1,5 @@
//status: edited
[[PROTOCOL_OVERVIEW]] [[PROTOCOL_OVERVIEW]]
=== Overview === Overview
@ -30,17 +32,17 @@ of 4-digit Maidenhead grid locators on earth is 180×180 = 32,400,
which is less than 2^15^ = 32,768; so a grid locator requires 15 bits. which is less than 2^15^ = 32,768; so a grid locator requires 15 bits.
Some 6 million of the possible 28-bit values are not needed for Some 6 million of the possible 28-bit values are not needed for
callsigns. A few of these slots have been assigned to special message callsigns. A few of these slots are assigned to special message
components such as `CQ`, `DE`, and `QRZ`. `CQ` may be followed by three components such as `CQ`, `DE`, and `QRZ`. `CQ` may be followed by three
digits to indicate a desired callback frequency. (If K1ABC transmits digits to indicate a desired callback frequency. (If K1ABC transmits
on a standard calling frequency, say 50.280, and sends `CQ 290 K1ABC on a standard calling frequency such as 50.280, and sends `CQ 290 K1ABC
FN42`, it means that s/he will listen on 50.290 and respond there to FN42`, it means that s/he will listen on 50.290 and respond there to
any replies.) A numerical signal report of the form `nn` or any replies.) A numerical signal report of the form `nn` or
`Rnn` can be sent in place of a grid locator. (As originally `Rnn` can be sent in place of a grid locator. (As originally
defined, numerical signal reports `nn` were required to fall between -01 defined, numerical signal reports `nn` were required to fall between -01
and -30 dB. Program versions 2.3 and later accommodate reports between and -30 dB. Recent program versions 2.3 and later accommodate reports between
-50 and +50 dB.) A country prefix or portable suffix may be -50 and +49 dB.) A country prefix or portable suffix may be
attached to one of the callsigns. When this feature is used the attached to one of the callsigns. When this feature is used, the
additional information is sent in place of the grid locator or by additional information is sent in place of the grid locator or by
encoding additional information into some of the 6 million available encoding additional information into some of the 6 million available
slots mentioned above. slots mentioned above.
@ -147,7 +149,8 @@ following pseudo-random sequence:
The synchronizing tone is normally sent in each interval having a The synchronizing tone is normally sent in each interval having a
"`1`" in the sequence. Modulation is 65-FSK at 11025/4096 = 2.692 "`1`" in the sequence. Modulation is 65-FSK at 11025/4096 = 2.692
baud. Frequency spacing between tones is equal to the keying rate for baud. Frequency spacing between tones is equal to the keying rate for
JT65A, and 2 and 4 times larger for JT65B and JT65C. For EME QSOs the JT65A, and 2 and 4 times larger for JT65B and JT65C, respectively.
For EME QSOs the
signal report OOO is sometimes used instead of numerical signal signal report OOO is sometimes used instead of numerical signal
reports. It is conveyed by reversing sync and data positions in the reports. It is conveyed by reversing sync and data positions in the
transmitted sequence. Shorthand messages for RO, RRR, and 73 dispense transmitted sequence. Shorthand messages for RO, RRR, and 73 dispense
@ -155,7 +158,7 @@ with the sync vector entirely and use time intervals of 16384/11025 =
1.486 s for pairs of alternating tones. The lower frequency is the 1.486 s for pairs of alternating tones. The lower frequency is the
same as that of the sync tone used in long messages, and the frequency same as that of the sync tone used in long messages, and the frequency
separation is 110250/4096 = 26.92 Hz multiplied by n for JT65A, with n separation is 110250/4096 = 26.92 Hz multiplied by n for JT65A, with n
= 2, 3, 4 used to convey the messages RO, RRR, and 73. = 2, 3, 4 used to convey the messages RO, RRR, and 73, respectively.
[[QRA64_PROTOCOL]] [[QRA64_PROTOCOL]]
==== QRA64 ==== QRA64
@ -225,7 +228,7 @@ the sync bit.
[[SLOW_SUMMARY]] [[SLOW_SUMMARY]]
==== Summary ==== Summary
Table 7 provides a brief summary parameters for the slow modes in Table 7 provides a brief summary of parameters for the slow modes in
_WSJT-X_. Parameters K and r specify the constraint length and rate _WSJT-X_. Parameters K and r specify the constraint length and rate
of the convolutional codes; n and k specify the sizes of the of the convolutional codes; n and k specify the sizes of the
(equivalent) block codes; Q is the alphabet size for the (equivalent) block codes; Q is the alphabet size for the
@ -305,7 +308,7 @@ available character set is:
Transmissions consist of sequences of 24 symbols: a synchronizing Transmissions consist of sequences of 24 symbols: a synchronizing
pattern of four symbols at tone numbers 0, 1, 3, and 2, followed by pattern of four symbols at tone numbers 0, 1, 3, and 2, followed by
two symbols with tone number corresponding to (message length) and two symbols with tone number corresponding to (message length) and
(message length + 5), and finally 18 symbols conveying the user's (message length + 5), and, finally, 18 symbols conveying the user's
message, sent repeatedly character by character. The message always message, sent repeatedly character by character. The message always
starts with `@`, the beginning-of-message symbol, which is not starts with `@`, the beginning-of-message symbol, which is not
displayed to the user. The sync pattern and message-length indicator displayed to the user. The sync pattern and message-length indicator

View File

@ -278,6 +278,7 @@ subroutine unpack77(c77,nrx,msg,unpk77_success)
read(c77(72:77),'(2b3)') n3,i3 read(c77(72:77),'(2b3)') n3,i3
msg=repeat(' ',37) msg=repeat(' ',37)
if(i3.eq.0 .and. n3.eq.0) then if(i3.eq.0 .and. n3.eq.0) then
! 0.0 Free text ! 0.0 Free text
call unpacktext77(c77(1:71),msg(1:13)) call unpacktext77(c77(1:71),msg(1:13))
@ -422,6 +423,9 @@ subroutine unpack77(c77,nrx,msg,unpk77_success)
msg=trim(call_1)//' '//grid6 msg=trim(call_1)//' '//grid6
endif endif
else if(i3.eq.0 .and. n3.gt.6) then
unpk77_success=.false.
else if(i3.eq.1 .or. i3.eq.2) then else if(i3.eq.1 .or. i3.eq.2) then
! Type 1 (standard message) or Type 2 ("/P" form for EU VHF contest) ! Type 1 (standard message) or Type 2 ("/P" form for EU VHF contest)
read(c77,1000) n28a,ipa,n28b,ipb,ir,igrid4,i3 read(c77,1000) n28a,ipa,n28b,ipb,ir,igrid4,i3

View File

@ -196,7 +196,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
params%nQSOProgress,params%nfqso,params%nfa,params%nfb, & params%nQSOProgress,params%nfqso,params%nfa,params%nfb, &
params%nsubmode,ndepth,params%ntr,params%nexp_decode, & params%nsubmode,ndepth,params%ntr,params%nexp_decode, &
params%ntol,params%emedelay, & params%ntol,params%emedelay, &
logical(params%lapcqonly),mycall,hiscall,params%nfsplit,iwspr) logical(params%lapcqonly),mycall,hiscall,iwspr)
call timer('dec240 ',1) call timer('dec240 ',1)
go to 800 go to 800
endif endif
@ -210,7 +210,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
params%nQSOProgress,params%nfqso,params%nfa,params%nfb, & params%nQSOProgress,params%nfqso,params%nfa,params%nfb, &
params%nsubmode,ndepth,params%ntr,params%nexp_decode, & params%nsubmode,ndepth,params%ntr,params%nexp_decode, &
params%ntol,params%emedelay, & params%ntol,params%emedelay, &
logical(params%lapcqonly),mycall,hiscall,params%nfsplit,iwspr) logical(params%lapcqonly),mycall,hiscall,iwspr)
call timer('dec240 ',1) call timer('dec240 ',1)
go to 800 go to 800
endif endif

View File

@ -140,8 +140,9 @@ subroutine decode240_101(llr,Keff,maxosd,norder,apmask,message101,cw,ntype,nhard
hdec=0 hdec=0
where(llr .ge. 0) hdec=1 where(llr .ge. 0) hdec=1
nxor=ieor(hdec,cw) nxor=ieor(hdec,cw)
nharderror=sum(nxor) ! re-calculate nharderror based on input llrs
dmin=sum(nxor*abs(llr)) dmin=sum(nxor*abs(llr))
ntype=2 ntype=1+i
return return
endif endif
enddo enddo

View File

@ -140,8 +140,9 @@ subroutine decode240_74(llr,Keff,maxosd,norder,apmask,message74,cw,ntype,nharder
hdec=0 hdec=0
where(llr .ge. 0) hdec=1 where(llr .ge. 0) hdec=1
nxor=ieor(hdec,cw) nxor=ieor(hdec,cw)
nharderror=sum(nxor) ! nharderror based on input llrs
dmin=sum(nxor*abs(llr)) dmin=sum(nxor*abs(llr))
ntype=2 ntype=1+i
return return
endif endif
enddo enddo

View File

@ -0,0 +1,48 @@
subroutine fst4_baseline(s,np,ia,ib,npct,sbase)
! Fit baseline to spectrum (for FST4)
! Input: s(npts) Linear scale in power
! Output: sbase(npts) Baseline
implicit real*8 (a-h,o-z)
real*4 s(np),sw(np)
real*4 sbase(np)
real*4 base
real*8 x(1000),y(1000),a(5)
data nseg/8/
do i=ia,ib
sw(i)=10.0*log10(s(i)) !Convert to dB scale
enddo
nterms=3
nlen=(ib-ia+1)/nseg !Length of test segment
i0=(ib-ia+1)/2 !Midpoint
k=0
do n=1,nseg !Loop over all segments
ja=ia + (n-1)*nlen
jb=ja+nlen-1
call pctile(sw(ja),nlen,npct,base) !Find lowest npct of points
do i=ja,jb
if(sw(i).le.base) then
if (k.lt.1000) k=k+1 !Save all "lower envelope" points
x(k)=i-i0
y(k)=sw(i)
endif
enddo
enddo
kz=k
a=0.
call polyfit(x,y,y,kz,nterms,0,a,chisqr) !Fit a low-order polynomial
sbase=0.0
do i=ia,ib
t=i-i0
sbase(i)=a(1)+t*(a(2)+t*(a(3))) + 0.2
! write(51,3051) i,sw(i),sbase(i)
!3051 format(i8,2f12.3)
enddo
sbase=10**(sbase/10.0)
return
end subroutine fst4_baseline

View File

@ -1,5 +1,6 @@
subroutine get_fst4_bitmetrics(cd,nss,hmod,nmax,nhicoh,bitmetrics,s4,badsync) subroutine get_fst4_bitmetrics(cd,nss,hmod,nmax,nhicoh,bitmetrics,s4,nsync_qual,badsync)
use timer_module, only: timer
include 'fst4_params.f90' include 'fst4_params.f90'
complex cd(0:NN*nss-1) complex cd(0:NN*nss-1)
complex cs(0:3,NN) complex cs(0:3,NN)
@ -11,6 +12,7 @@ subroutine get_fst4_bitmetrics(cd,nss,hmod,nmax,nhicoh,bitmetrics,s4,badsync)
integer graymap(0:3) integer graymap(0:3)
integer ip(1) integer ip(1)
integer hmod integer hmod
integer hbits(2*NN)
logical one(0:65535,0:15) ! 65536 8-symbol sequences, 16 bits logical one(0:65535,0:15) ! 65536 8-symbol sequences, 16 bits
logical first logical first
logical badsync logical badsync
@ -52,7 +54,7 @@ subroutine get_fst4_bitmetrics(cd,nss,hmod,nmax,nhicoh,bitmetrics,s4,badsync)
do itone=0,3 do itone=0,3
cs(itone,k)=sum(csymb*conjg(c1(:,itone))) cs(itone,k)=sum(csymb*conjg(c1(:,itone)))
enddo enddo
s4(0:3,k)=abs(cs(0:3,k)) s4(0:3,k)=abs(cs(0:3,k))**2
enddo enddo
! Sync quality check ! Sync quality check
@ -83,8 +85,10 @@ subroutine get_fst4_bitmetrics(cd,nss,hmod,nmax,nhicoh,bitmetrics,s4,badsync)
return return
endif endif
call timer('seqcorrs',0)
bitmetrics=0.0 bitmetrics=0.0
do nseq=1,nmax !Try coherent sequences of 1, 2, and 4 symbols do nseq=1,nmax !Try coherent sequences of 1,2,3,4 or 1,2,4,8 symbols
if(nseq.eq.1) nsym=1 if(nseq.eq.1) nsym=1
if(nseq.eq.2) nsym=2 if(nseq.eq.2) nsym=2
if(nhicoh.eq.0) then if(nhicoh.eq.0) then
@ -99,11 +103,14 @@ subroutine get_fst4_bitmetrics(cd,nss,hmod,nmax,nhicoh,bitmetrics,s4,badsync)
s2=0 s2=0
do i=0,nt-1 do i=0,nt-1
csum=0 csum=0
cterm=1 ! cterm=1 ! hmod.ne.1
term=1
do j=0,nsym-1 do j=0,nsym-1
ntone=mod(i/4**(nsym-1-j),4) ntone=mod(i/4**(nsym-1-j),4)
csum=csum+cs(graymap(ntone),ks+j)*cterm csum=csum+cs(graymap(ntone),ks+j)*term
cterm=cterm*conjg(cp(graymap(ntone))) term=-term
! csum=csum+cs(graymap(ntone),ks+j)*cterm ! hmod.ne.1
! cterm=cterm*conjg(cp(graymap(ntone))) ! hmod.ne.1
enddo enddo
s2(i)=abs(csum) s2(i)=abs(csum)
enddo enddo
@ -121,11 +128,30 @@ subroutine get_fst4_bitmetrics(cd,nss,hmod,nmax,nhicoh,bitmetrics,s4,badsync)
enddo enddo
enddo enddo
enddo enddo
call timer('seqcorrs',1)
hbits=0
where(bitmetrics(:,1).ge.0) hbits=1
ns1=count(hbits( 1: 16).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/))
ns2=count(hbits( 77: 92).eq.(/1,1,1,0,0,1,0,0,1,0,1,1,0,0,0,1/))
ns3=count(hbits(153:168).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/))
ns4=count(hbits(229:244).eq.(/1,1,1,0,0,1,0,0,1,0,1,1,0,0,0,1/))
ns5=count(hbits(305:320).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/))
nsync_qual=ns1+ns2+ns3+ns4+ns5
if(nsync_qual.lt. 46) then
badsync=.true.
return
endif
call normalizebmet(bitmetrics(:,1),2*NN) call normalizebmet(bitmetrics(:,1),2*NN)
call normalizebmet(bitmetrics(:,2),2*NN) call normalizebmet(bitmetrics(:,2),2*NN)
call normalizebmet(bitmetrics(:,3),2*NN) call normalizebmet(bitmetrics(:,3),2*NN)
call normalizebmet(bitmetrics(:,4),2*NN) call normalizebmet(bitmetrics(:,4),2*NN)
scalefac=2.83
bitmetrics=scalefac*bitmetrics
return return
end subroutine get_fst4_bitmetrics end subroutine get_fst4_bitmetrics

View File

@ -1,4 +1,4 @@
subroutine get_fst4_bitmetrics2(cd,nss,hmod,nsizes,bitmetrics,s4hmod,badsync) subroutine get_fst4_bitmetrics2(cd,nss,hmod,nsizes,bitmetrics,s4snr,badsync)
include 'fst4_params.f90' include 'fst4_params.f90'
complex cd(0:NN*nss-1) complex cd(0:NN*nss-1)
@ -15,7 +15,7 @@ subroutine get_fst4_bitmetrics2(cd,nss,hmod,nsizes,bitmetrics,s4hmod,badsync)
logical badsync logical badsync
real bitmetrics(2*NN,4) real bitmetrics(2*NN,4)
real s2(0:65535) real s2(0:65535)
real s4(0:3,NN,4),s4hmod(0:3,NN) real s4(0:3,NN,4),s4snr(0:3,NN)
data isyncword1/0,1,3,2,1,0,2,3/ data isyncword1/0,1,3,2,1,0,2,3/
data isyncword2/2,3,1,0,3,2,0,1/ data isyncword2/2,3,1,0,3,2,0,1/
data graymap/0,1,3,2/ data graymap/0,1,3,2/
@ -49,21 +49,21 @@ subroutine get_fst4_bitmetrics2(cd,nss,hmod,nsizes,bitmetrics,s4hmod,badsync)
i1=(k-1)*NSS i1=(k-1)*NSS
csymb=cd(i1:i1+NSS-1) csymb=cd(i1:i1+NSS-1)
do itone=0,3 do itone=0,3
s4(itone,k,1)=abs(sum(csymb*conjg(c1(:,itone)))) s4(itone,k,1)=abs(sum(csymb*conjg(c1(:,itone))))**2
s4(itone,k,2)=abs(sum(csymb( 1:nss/2)*conjg(c1( 1:nss/2,itone)))) + & s4(itone,k,2)=abs(sum(csymb( 1:nss/2)*conjg(c1( 1:nss/2,itone))))**2 + &
abs(sum(csymb(nss/2+1: nss)*conjg(c1(nss/2+1: nss,itone)))) abs(sum(csymb(nss/2+1: nss)*conjg(c1(nss/2+1: nss,itone))))**2
s4(itone,k,3)=abs(sum(csymb( 1: nss/4)*conjg(c1( 1: nss/4,itone)))) + & s4(itone,k,3)=abs(sum(csymb( 1: nss/4)*conjg(c1( 1: nss/4,itone))))**2 + &
abs(sum(csymb( nss/4+1: nss/2)*conjg(c1( nss/4+1: nss/2,itone)))) + & abs(sum(csymb( nss/4+1: nss/2)*conjg(c1( nss/4+1: nss/2,itone))))**2 + &
abs(sum(csymb( nss/2+1:3*nss/4)*conjg(c1( nss/2+1:3*nss/4,itone)))) + & abs(sum(csymb( nss/2+1:3*nss/4)*conjg(c1( nss/2+1:3*nss/4,itone))))**2 + &
abs(sum(csymb(3*nss/4+1: nss)*conjg(c1(3*nss/4+1: nss,itone)))) abs(sum(csymb(3*nss/4+1: nss)*conjg(c1(3*nss/4+1: nss,itone))))**2
s4(itone,k,4)=abs(sum(csymb( 1: nss/8)*conjg(c1( 1: nss/8,itone)))) + & s4(itone,k,4)=abs(sum(csymb( 1: nss/8)*conjg(c1( 1: nss/8,itone))))**2 + &
abs(sum(csymb( nss/8+1: nss/4)*conjg(c1( nss/8+1: nss/4,itone)))) + & abs(sum(csymb( nss/8+1: nss/4)*conjg(c1( nss/8+1: nss/4,itone))))**2 + &
abs(sum(csymb( nss/4+1:3*nss/8)*conjg(c1( nss/4+1:3*nss/8,itone)))) + & abs(sum(csymb( nss/4+1:3*nss/8)*conjg(c1( nss/4+1:3*nss/8,itone))))**2 + &
abs(sum(csymb(3*nss/8+1: nss/2)*conjg(c1(3*nss/8+1: nss/2,itone)))) + & abs(sum(csymb(3*nss/8+1: nss/2)*conjg(c1(3*nss/8+1: nss/2,itone))))**2 + &
abs(sum(csymb( nss/2+1:5*nss/8)*conjg(c1( nss/2+1:5*nss/8,itone)))) + & abs(sum(csymb( nss/2+1:5*nss/8)*conjg(c1( nss/2+1:5*nss/8,itone))))**2 + &
abs(sum(csymb(5*nss/8+1:3*nss/4)*conjg(c1(5*nss/8+1:3*nss/4,itone)))) + & abs(sum(csymb(5*nss/8+1:3*nss/4)*conjg(c1(5*nss/8+1:3*nss/4,itone))))**2 + &
abs(sum(csymb(3*nss/4+1:7*nss/8)*conjg(c1(3*nss/4+1:7*nss/8,itone)))) + & abs(sum(csymb(3*nss/4+1:7*nss/8)*conjg(c1(3*nss/4+1:7*nss/8,itone))))**2 + &
abs(sum(csymb(7*nss/8+1: nss)*conjg(c1(7*nss/8+1: nss,itone)))) abs(sum(csymb(7*nss/8+1: nss)*conjg(c1(7*nss/8+1: nss,itone))))**2
enddo enddo
enddo enddo
@ -121,11 +121,8 @@ subroutine get_fst4_bitmetrics2(cd,nss,hmod,nsizes,bitmetrics,s4hmod,badsync)
call normalizebmet(bitmetrics(:,3),2*NN) call normalizebmet(bitmetrics(:,3),2*NN)
call normalizebmet(bitmetrics(:,4),2*NN) call normalizebmet(bitmetrics(:,4),2*NN)
! Return the s4 array corresponding to N=1/hmod. Will be used for SNR calculation ! Return the s4 array corresponding to N=1. Will be used for SNR calculation
if(hmod.eq.1) s4hmod(:,:)=s4(:,:,1) s4snr(:,:)=s4(:,:,1)
if(hmod.eq.2) s4hmod(:,:)=s4(:,:,2)
if(hmod.eq.4) s4hmod(:,:)=s4(:,:,3)
if(hmod.eq.8) s4hmod(:,:)=s4(:,:,4)
return return
end subroutine get_fst4_bitmetrics2 end subroutine get_fst4_bitmetrics2

View File

@ -31,7 +31,7 @@ contains
subroutine decode(this,callback,iwave,nutc,nQSOProgress,nfqso, & subroutine decode(this,callback,iwave,nutc,nQSOProgress,nfqso, &
nfa,nfb,nsubmode,ndepth,ntrperiod,nexp_decode,ntol, & nfa,nfb,nsubmode,ndepth,ntrperiod,nexp_decode,ntol, &
emedelay,lapcqonly,mycall,hiscall,nfsplit,iwspr) emedelay,lapcqonly,mycall,hiscall,iwspr)
use timer_module, only: timer use timer_module, only: timer
use packjt77 use packjt77
@ -48,8 +48,8 @@ contains
complex, allocatable :: c2(:) complex, allocatable :: c2(:)
complex, allocatable :: cframe(:) complex, allocatable :: cframe(:)
complex, allocatable :: c_bigfft(:) !Complex waveform complex, allocatable :: c_bigfft(:) !Complex waveform
real llr(240),llra(240),llrb(240),llrc(240),llrd(240) real llr(240),llrs(240,4)
real candidates(100,4) real candidates(200,5)
real bitmetrics(320,4) real bitmetrics(320,4)
real s4(0:3,NN) real s4(0:3,NN)
real minsync real minsync
@ -57,7 +57,6 @@ contains
integer itone(NN) integer itone(NN)
integer hmod integer hmod
integer*1 apmask(240),cw(240) integer*1 apmask(240),cw(240)
integer*1 hbits(320)
integer*1 message101(101),message74(74),message77(77) integer*1 message101(101),message74(74),message77(77)
integer*1 rvec(77) integer*1 rvec(77)
integer apbits(240) integer apbits(240)
@ -149,8 +148,7 @@ contains
if(i3.ne.1 .or. (msg.ne.msgsent) .or. .not.unpk77_success) go to 10 if(i3.ne.1 .or. (msg.ne.msgsent) .or. .not.unpk77_success) go to 10
read(c77,'(77i1)') message77 read(c77,'(77i1)') message77
message77=mod(message77+rvec,2) message77=mod(message77+rvec,2)
call encode174_91(message77,cw) apbits(1:77)=2*message77-1
apbits=2*cw-1
if(nohiscall) apbits(30)=99 if(nohiscall) apbits(30)=99
10 continue 10 continue
@ -253,38 +251,21 @@ contains
call four2a(c_bigfft,nfft1,1,-1,0) !r2c call four2a(c_bigfft,nfft1,1,-1,0) !r2c
! call blank2(nfa,nfb,nfft1,c_bigfft,iwave) ! call blank2(nfa,nfb,nfft1,c_bigfft,iwave)
if(hmod.eq.1) then nhicoh=1
if(fMHz.lt.2.0) then nsyncoh=8
nsyncoh=8 ! Use N=8 for sync if(iwspr.eq.1) then
nhicoh=1 ! Use N=1,2,4,8 for symbol estimation fa=1400.0
fb=1600.0
else else
nsyncoh=4 ! Use N=4 for sync
nhicoh=0 ! Use N=1,2,3,4 for symbol estimation
endif
else
if(hmod.eq.2) nsyncoh=1
if(hmod.eq.4) nsyncoh=-2
if(hmod.eq.8) nsyncoh=-4
endif
if( single_decode ) then
fa=max(100,nint(nfqso+1.5*hmod*baud-ntol)) fa=max(100,nint(nfqso+1.5*hmod*baud-ntol))
fb=min(4800,nint(nfqso+1.5*hmod*baud+ntol)) fb=min(4800,nint(nfqso+1.5*hmod*baud+ntol))
else
fa=max(100,nfa)
fb=min(4800,nfb)
endif endif
minsync=1.20
if(hmod.eq.1) then
if(ntrperiod.eq.15) minsync=1.15 if(ntrperiod.eq.15) minsync=1.15
if(ntrperiod.gt.15) minsync=1.20
elseif(hmod.gt.1) then
minsync=1.2
endif
! Get first approximation of candidate frequencies ! Get first approximation of candidate frequencies
call get_candidates_fst4(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & call get_candidates_fst4(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, &
minsync,ncand,candidates,base) minsync,ncand,candidates)
ndecodes=0 ndecodes=0
decodes=' ' decodes=' '
@ -300,54 +281,15 @@ contains
! Output array c2 is complex baseband sampled at 12000/ndown Sa/sec. ! Output array c2 is complex baseband sampled at 12000/ndown Sa/sec.
! The size of the downsampled c2 array is nfft2=nfft1/ndown ! The size of the downsampled c2 array is nfft2=nfft1/ndown
call timer('dwnsmpl ',0)
call fst4_downsample(c_bigfft,nfft1,ndown,fc0,sigbw,c2) call fst4_downsample(c_bigfft,nfft1,ndown,fc0,sigbw,c2)
call timer('dwnsmpl ',1)
call timer('sync240 ',0) call timer('sync240 ',0)
fc1=0.0 call fst4_sync_search(c2,nfft2,hmod,fs2,nss,ntrperiod,nsyncoh,emedelay,sbest,fcbest,isbest)
if(emedelay.lt.0.1) then ! search offsets from 0 s to 2 s
is0=1.5*nspsec
ishw=1.5*nspsec
else ! search plus or minus 1.5 s centered on emedelay
is0=nint((emedelay+1.0)*nspsec)
ishw=1.5*nspsec
endif
smax=-1.e30
do if=-12,12
fc=fc1 + 0.1*baud*if
do istart=max(1,is0-ishw),is0+ishw,4*hmod
call sync_fst4(c2,istart,fc,hmod,nsyncoh,nfft2,nss, &
ntrperiod,fs2,sync)
if(sync.gt.smax) then
fc2=fc
isbest=istart
smax=sync
endif
enddo
enddo
fc1=fc2
is0=isbest
ishw=4*hmod
isst=1*hmod
smax=0.0
do if=-7,7
fc=fc1 + 0.02*baud*if
do istart=max(1,is0-ishw),is0+ishw,isst
call sync_fst4(c2,istart,fc,hmod,nsyncoh,nfft2,nss, &
ntrperiod,fs2,sync)
if(sync.gt.smax) then
fc2=fc
isbest=istart
smax=sync
endif
enddo
enddo
call timer('sync240 ',1) call timer('sync240 ',1)
fc_synced = fc0 + fc2 fc_synced = fc0 + fcbest
dt_synced = (isbest-fs2)*dt2 !nominal dt is 1 second so frame starts at sample fs2 dt_synced = (isbest-fs2)*dt2 !nominal dt is 1 second so frame starts at sample fs2
candidates(icand,3)=fc_synced candidates(icand,3)=fc_synced
candidates(icand,4)=isbest candidates(icand,4)=isbest
@ -379,14 +321,18 @@ contains
enddo enddo
ncand=ic ncand=ic
xsnr=0. xsnr=0.
!write(*,*) 'ncand ',ncand
do icand=1,ncand do icand=1,ncand
sync=candidates(icand,2) sync=candidates(icand,2)
fc_synced=candidates(icand,3) fc_synced=candidates(icand,3)
isbest=nint(candidates(icand,4)) isbest=nint(candidates(icand,4))
xdt=(isbest-nspsec)/fs2 xdt=(isbest-nspsec)/fs2
if(ntrperiod.eq.15) xdt=(isbest-real(nspsec)/2.0)/fs2 if(ntrperiod.eq.15) xdt=(isbest-real(nspsec)/2.0)/fs2
call timer('dwnsmpl ',0)
call fst4_downsample(c_bigfft,nfft1,ndown,fc_synced,sigbw,c2) call fst4_downsample(c_bigfft,nfft1,ndown,fc_synced,sigbw,c2)
call timer('dwnsmpl ',1)
do ijitter=0,jittermax do ijitter=0,jittermax
if(ijitter.eq.0) ioffset=0 if(ijitter.eq.0) ioffset=0
if(ijitter.eq.1) ioffset=1 if(ijitter.eq.1) ioffset=1
@ -395,45 +341,20 @@ contains
if(is0.lt.0) cycle if(is0.lt.0) cycle
cframe=c2(is0:is0+160*nss-1) cframe=c2(is0:is0+160*nss-1)
bitmetrics=0 bitmetrics=0
if(hmod.eq.1) then call timer('bitmetrc',0)
call get_fst4_bitmetrics(cframe,nss,hmod,nblock,nhicoh,bitmetrics,s4,badsync) call get_fst4_bitmetrics(cframe,nss,hmod,nblock,nhicoh,bitmetrics, &
else s4,nsync_qual,badsync)
call get_fst4_bitmetrics2(cframe,nss,hmod,nblock,bitmetrics,s4,badsync) call timer('bitmetrc',1)
endif
if(badsync) cycle if(badsync) cycle
hbits=0 do il=1,4
where(bitmetrics(:,1).ge.0) hbits=1 llrs( 1: 60,il)=bitmetrics( 17: 76, il)
ns1=count(hbits( 1: 16).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) llrs( 61:120,il)=bitmetrics( 93:152, il)
ns2=count(hbits( 77: 92).eq.(/1,1,1,0,0,1,0,0,1,0,1,1,0,0,0,1/)) llrs(121:180,il)=bitmetrics(169:228, il)
ns3=count(hbits(153:168).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) llrs(181:240,il)=bitmetrics(245:304, il)
ns4=count(hbits(229:244).eq.(/1,1,1,0,0,1,0,0,1,0,1,1,0,0,0,1/)) enddo
ns5=count(hbits(305:320).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/))
nsync_qual=ns1+ns2+ns3+ns4+ns5
! if(nsync_qual.lt. 46) cycle !### Value ?? ###
scalefac=2.83
llra( 1: 60)=bitmetrics( 17: 76, 1)
llra( 61:120)=bitmetrics( 93:152, 1)
llra(121:180)=bitmetrics(169:228, 1)
llra(181:240)=bitmetrics(245:304, 1)
llra=scalefac*llra
llrb( 1: 60)=bitmetrics( 17: 76, 2)
llrb( 61:120)=bitmetrics( 93:152, 2)
llrb(121:180)=bitmetrics(169:228, 2)
llrb(181:240)=bitmetrics(245:304, 2)
llrb=scalefac*llrb
llrc( 1: 60)=bitmetrics( 17: 76, 3)
llrc( 61:120)=bitmetrics( 93:152, 3)
llrc(121:180)=bitmetrics(169:228, 3)
llrc(181:240)=bitmetrics(245:304, 3)
llrc=scalefac*llrc
llrd( 1: 60)=bitmetrics( 17: 76, 4)
llrd( 61:120)=bitmetrics( 93:152, 4)
llrd(121:180)=bitmetrics(169:228, 4)
llrd(181:240)=bitmetrics(245:304, 4)
llrd=scalefac*llrd
apmag=maxval(abs(llra))*1.1 apmag=maxval(abs(llrs(:,1)))*1.1
ntmax=nblock+nappasses(nQSOProgress) ntmax=nblock+nappasses(nQSOProgress)
if(lapcqonly) ntmax=nblock+1 if(lapcqonly) ntmax=nblock+1
if(ndepth.eq.1) ntmax=nblock if(ndepth.eq.1) ntmax=nblock
@ -445,23 +366,17 @@ contains
endif endif
do itry=1,ntmax do itry=1,ntmax
if(itry.eq.1) llr=llra if(itry.eq.1) llr=llrs(:,1)
if(itry.eq.2.and.itry.le.nblock) llr=llrb if(itry.eq.2.and.itry.le.nblock) llr=llrs(:,2)
if(itry.eq.3.and.itry.le.nblock) llr=llrc if(itry.eq.3.and.itry.le.nblock) llr=llrs(:,3)
if(itry.eq.4.and.itry.le.nblock) llr=llrd if(itry.eq.4.and.itry.le.nblock) llr=llrs(:,4)
if(itry.le.nblock) then if(itry.le.nblock) then
apmask=0 apmask=0
iaptype=0 iaptype=0
endif endif
if(itry.gt.nblock) then if(itry.gt.nblock) then ! do ap passes
llr=llra llr=llrs(:,nblock) ! Use largest blocksize as the basis for AP passes
if(nblock.gt.1) then
if(hmod.eq.1) llr=llrd
if(hmod.eq.2) llr=llrb
if(hmod.eq.4) llr=llrc
if(hmod.eq.8) llr=llrd
endif
iaptype=naptypes(nQSOProgress,itry-nblock) iaptype=naptypes(nQSOProgress,itry-nblock)
if(lapcqonly) iaptype=1 if(lapcqonly) iaptype=1
if(iaptype.ge.2 .and. apbits(1).gt.1) cycle ! No, or nonstandard, mycall if(iaptype.ge.2 .and. apbits(1).gt.1) cycle ! No, or nonstandard, mycall
@ -500,7 +415,7 @@ contains
if(iwspr.eq.0) then if(iwspr.eq.0) then
maxosd=2 maxosd=2
Keff=91 Keff=91
norder=3 norder=4
call timer('d240_101',0) call timer('d240_101',0)
call decode240_101(llr,Keff,maxosd,norder,apmask,message101, & call decode240_101(llr,Keff,maxosd,norder,apmask,message101, &
cw,ntype,nharderrors,dmin) cw,ntype,nharderrors,dmin)
@ -544,14 +459,17 @@ contains
endif endif
inquire(file='plotspec',exist=ex) inquire(file='plotspec',exist=ex)
fmid=-999.0 fmid=-999.0
call timer('dopsprd ',0)
if(ex) then if(ex) then
call dopspread(itone,iwave,nsps,nmax,ndown,hmod, & call dopspread(itone,iwave,nsps,nmax,ndown,hmod, &
isbest,fc_synced,fmid,w50) isbest,fc_synced,fmid,w50)
endif endif
call timer('dopsprd ',1)
xsig=0 xsig=0
do i=1,NN do i=1,NN
xsig=xsig+s4(itone(i),i)**2 xsig=xsig+s4(itone(i),i)
enddo enddo
base=candidates(icand,5)
arg=600.0*(xsig/base)-1.0 arg=600.0*(xsig/base)-1.0
if(arg.gt.0.0) then if(arg.gt.0.0) then
xsnr=10*log10(arg)-35.5-12.5*log10(nsps/8200.0) xsnr=10*log10(arg)-35.5-12.5*log10(nsps/8200.0)
@ -732,14 +650,15 @@ contains
end subroutine fst4_downsample end subroutine fst4_downsample
subroutine get_candidates_fst4(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & subroutine get_candidates_fst4(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, &
minsync,ncand,candidates,base) minsync,ncand,candidates)
complex c_bigfft(0:nfft1/2) !Full length FFT of raw data complex c_bigfft(0:nfft1/2) !Full length FFT of raw data
integer hmod !Modulation index (submode) integer hmod !Modulation index (submode)
integer im(1) !For maxloc integer im(1) !For maxloc
real candidates(100,4) !Candidate list real candidates(200,5) !Candidate list
real, allocatable :: s(:) !Low resolution power spectrum real, allocatable :: s(:) !Low resolution power spectrum
real, allocatable :: s2(:) !CCF of s() with 4 tones real, allocatable :: s2(:) !CCF of s() with 4 tones
real, allocatable :: sbase(:) !noise baseline estimate
real xdb(-3:3) !Model 4-tone CCF peaks real xdb(-3:3) !Model 4-tone CCF peaks
real minsync real minsync
data xdb/0.25,0.50,0.75,1.0,0.75,0.50,0.25/ data xdb/0.25,0.50,0.75,1.0,0.75,0.50,0.25/
@ -755,20 +674,20 @@ contains
signal_bw=4*(12000.0/nsps)*hmod signal_bw=4*(12000.0/nsps)*hmod
analysis_bw=min(4800.0,fb)-max(100.0,fa) analysis_bw=min(4800.0,fb)-max(100.0,fa)
xnoise_bw=10.0*signal_bw !Is this a good compromise? xnoise_bw=10.0*signal_bw !Is this a good compromise?
if(analysis_bw.gt.xnoise_bw) then if(xnoise_bw .lt. 400.0) xnoise_bw=400.0
ina=ia if(analysis_bw.gt.xnoise_bw) then !Estimate noise baseline over analysis bw
inb=ib ina=0.9*ia
else inb=min(int(1.1*ib),nfft1/2)
fcenter=(fa+fb)/2.0 !If noise_bw > analysis_bw, else !Estimate noise baseline over noise bw
fl = max(100.0,fcenter-xnoise_bw/2.)/df2 !we'll search over noise_bw fcenter=(fa+fb)/2.0
fl = max(100.0,fcenter-xnoise_bw/2.)/df2
fh = min(4800.0,fcenter+xnoise_bw/2.)/df2 fh = min(4800.0,fcenter+xnoise_bw/2.)/df2
ina=nint(fl) ina=nint(fl)
inb=nint(fh) inb=nint(fh)
endif endif
nnw=nint(48000.*nsps*2./fs) nnw=nint(48000.*nsps*2./fs)
allocate (s(nnw)) allocate (s(nnw))
s=0. !Compute low-resloution power spectrum s=0. !Compute low-resolution power spectrum
do i=ina,inb ! noise analysis window includes signal analysis window do i=ina,inb ! noise analysis window includes signal analysis window
j0=nint(i*df2/df1) j0=nint(i*df2/df1)
do j=j0-ndh,j0+ndh do j=j0-ndh,j0+ndh
@ -779,12 +698,15 @@ contains
ina=max(ina,1+3*hmod) !Don't run off the ends ina=max(ina,1+3*hmod) !Don't run off the ends
inb=min(inb,nnw-3*hmod) inb=min(inb,nnw-3*hmod)
allocate (s2(nnw)) allocate (s2(nnw))
allocate (sbase(nnw))
s2=0. s2=0.
do i=ina,inb !Compute CCF of s() and 4 tones do i=ina,inb !Compute CCF of s() and 4 tones
s2(i)=s(i-hmod*3) + s(i-hmod) +s(i+hmod) +s(i+hmod*3) s2(i)=s(i-hmod*3) + s(i-hmod) +s(i+hmod) +s(i+hmod*3)
enddo enddo
call pctile(s2(ina+hmod*3:inb-hmod*3),inb-ina+1-hmod*6,30,base) npct=30
s2=s2/base !Normalize wrt noise level call fst4_baseline(s2,nnw,ina+hmod*3,inb-hmod*3,npct,sbase)
if(any(sbase(ina:inb).le.0.0)) return
s2(ina:inb)=s2(ina:inb)/sbase(ina:inb) !Normalize wrt noise level
ncand=0 ncand=0
candidates=0 candidates=0
@ -794,7 +716,7 @@ contains
! Find candidates, using the CLEAN algorithm to remove a model of each one ! Find candidates, using the CLEAN algorithm to remove a model of each one
! from s2() after it has been found. ! from s2() after it has been found.
pval=99.99 pval=99.99
do while(ncand.lt.100) do while(ncand.lt.200)
im=maxloc(s2(ia:ib)) im=maxloc(s2(ia:ib))
iploc=ia+im(1)-1 !Index of CCF peak iploc=ia+im(1)-1 !Index of CCF peak
pval=s2(iploc) !Peak value pval=s2(iploc) !Peak value
@ -808,11 +730,59 @@ contains
ncand=ncand+1 ncand=ncand+1
candidates(ncand,1)=df2*iploc !Candidate frequency candidates(ncand,1)=df2*iploc !Candidate frequency
candidates(ncand,2)=pval !Rough estimate of SNR candidates(ncand,2)=pval !Rough estimate of SNR
candidates(ncand,5)=sbase(iploc)
enddo enddo
return return
end subroutine get_candidates_fst4 end subroutine get_candidates_fst4
subroutine fst4_sync_search(c2,nfft2,hmod,fs2,nss,ntrperiod,nsyncoh,emedelay,sbest,fcbest,isbest)
complex c2(0:nfft2-1)
integer hmod
nspsec=int(fs2)
baud=fs2/real(nss)
fc1=0.0
if(emedelay.lt.0.1) then ! search offsets from 0 s to 2 s
is0=1.5*nspsec
ishw=1.5*nspsec
else ! search plus or minus 1.5 s centered on emedelay
is0=nint((emedelay+1.0)*nspsec)
ishw=1.5*nspsec
endif
sbest=-1.e30
do if=-12,12
fc=fc1 + 0.1*baud*if
do istart=max(1,is0-ishw),is0+ishw,4*hmod
call sync_fst4(c2,istart,fc,hmod,nsyncoh,nfft2,nss, &
ntrperiod,fs2,sync)
if(sync.gt.sbest) then
fcbest=fc
isbest=istart
sbest=sync
endif
enddo
enddo
fc1=fcbest
is0=isbest
ishw=4*hmod
isst=1*hmod
sbest=0.0
do if=-7,7
fc=fc1 + 0.02*baud*if
do istart=max(1,is0-ishw),is0+ishw,isst
call sync_fst4(c2,istart,fc,hmod,nsyncoh,nfft2,nss, &
ntrperiod,fs2,sync)
if(sync.gt.sbest) then
fcbest=fc
isbest=istart
sbest=sync
endif
enddo
enddo
end subroutine fst4_sync_search
subroutine dopspread(itone,iwave,nsps,nmax,ndown,hmod,i0,fc,fmid,w50) subroutine dopspread(itone,iwave,nsps,nmax,ndown,hmod,i0,fc,fmid,w50)
! On "plotspec" special request, compute Doppler spread for a decoded signal ! On "plotspec" special request, compute Doppler spread for a decoded signal

View File

@ -54,7 +54,7 @@ void LiveFrequencyValidator::fixup (QString& input) const
input = input.toLower (); input = input.toLower ();
QVector<QVariant> frequencies; QVector<QVariant> frequencies;
for (auto const& item : frequencies_->frequency_list ()) for (auto const& item : *frequencies_)
{ {
if (bands_->find (item.frequency_) == input) if (bands_->find (item.frequency_) == input)
{ {