Merged from trunk (r8085 thru r8170 inc.):
------------------------------------------------------------------------ r8085 | k9an | 2017-09-13 01:46:16 +0100 (Wed, 13 Sep 2017) | 1 line Open up DT range to +/- 2.5 s for testing. ------------------------------------------------------------------------ r8086 | bsomervi | 2017-09-16 11:12:38 +0100 (Sat, 16 Sep 2017) | 1 line Do not allow window manager events to close the astronomical data window ------------------------------------------------------------------------ r8087 | bsomervi | 2017-09-16 21:27:05 +0100 (Sat, 16 Sep 2017) | 4 lines Fix regression in ADIF parser that caused failure with missing header Improved robustness of the ADIF parser and re-factored to more idiomatic C++. ------------------------------------------------------------------------ r8088 | bsomervi | 2017-09-16 21:27:13 +0100 (Sat, 16 Sep 2017) | 1 line Update band limits as per ADIF 3.0.6 specification ------------------------------------------------------------------------ r8089 | bsomervi | 2017-09-16 21:27:20 +0100 (Sat, 16 Sep 2017) | 1 line Use a single definition of band limits (Bands class) ------------------------------------------------------------------------ r8090 | bsomervi | 2017-09-16 21:27:33 +0100 (Sat, 16 Sep 2017) | 5 lines Add button to the decoded text window context menu to erase the contents Right-click either decoded text window to erase its contents. The "Erase" button on the main UI still operates as before although it is implemented differently now. ------------------------------------------------------------------------ r8091 | bsomervi | 2017-09-16 23:20:51 +0100 (Sat, 16 Sep 2017) | 1 line Correct the actions taken when clearing decodes windows ------------------------------------------------------------------------ r8092 | bsomervi | 2017-09-16 23:20:59 +0100 (Sat, 16 Sep 2017) | 8 lines Restore functionality of sending .WAV playback decodes to UDP Extended the Decode and WSPRDecode UDP messages with an "off air" boolean field indicating the decode was derived from a .WAV fle playback rather than an on air reception. Extended reference applications to use the new off air decode message field. ------------------------------------------------------------------------ r8093 | k9an | 2017-09-17 16:34:32 +0100 (Sun, 17 Sep 2017) | 1 line Experimental tweak to FT8 decoder. Try a second symbol metric if the first one fails - currently configured to use max-amplitude and max-log. ------------------------------------------------------------------------ r8094 | k9an | 2017-09-17 21:43:30 +0100 (Sun, 17 Sep 2017) | 1 line Restore the use of max-amplitude for ap passes. ------------------------------------------------------------------------ r8095 | k1jt | 2017-09-18 16:42:14 +0100 (Mon, 18 Sep 2017) | 2 lines Allow specialized use of "x2 Tone Spacing" in FT8 mode. ------------------------------------------------------------------------ r8096 | k1jt | 2017-09-18 16:47:29 +0100 (Mon, 18 Sep 2017) | 2 lines Allow X2 tone spacing also in JT9 (slow) modes. ------------------------------------------------------------------------ r8097 | k1jt | 2017-09-18 21:42:18 +0100 (Mon, 18 Sep 2017) | 2 lines Change CRLF line endings to *nix style. ------------------------------------------------------------------------ r8098 | k1jt | 2017-09-19 17:04:10 +0100 (Tue, 19 Sep 2017) | 2 lines Add a missing step to description of the Frequency Calibration procedure. ------------------------------------------------------------------------ r8099 | k1jt | 2017-09-20 17:31:04 +0100 (Wed, 20 Sep 2017) | 1 line Insert a link to FT8_Operating_Tips.pdf. ------------------------------------------------------------------------ r8100 | k1jt | 2017-09-20 20:11:04 +0100 (Wed, 20 Sep 2017) | 3 lines As an experiment, move "NA VHF Contest Mode" checkbox to main screen and query operator if d>10000 km. ------------------------------------------------------------------------ r8101 | k1jt | 2017-09-20 20:19:47 +0100 (Wed, 20 Sep 2017) | 2 lines Correct a tool-tip typo. ------------------------------------------------------------------------ r8102 | bsomervi | 2017-09-22 13:31:01 +0100 (Fri, 22 Sep 2017) | 1 line UI tweaks to improve portability between platforms and font size changes ------------------------------------------------------------------------ r8103 | bsomervi | 2017-09-22 16:36:24 +0100 (Fri, 22 Sep 2017) | 5 lines Extend UDP Reply message with keyboard modifiers This allows UDP servers to emulate keyboard modified double-clicks on decoded messages, E.g. ALT+double-click for replying to a CQ or QRZ call without changing ones Tx frequency offset. ------------------------------------------------------------------------ r8104 | bsomervi | 2017-09-22 16:49:42 +0100 (Fri, 22 Sep 2017) | 1 line Updated AD1C cty.dat file (21st Sept 2017) ------------------------------------------------------------------------ r8105 | k1jt | 2017-09-22 18:38:51 +0100 (Fri, 22 Sep 2017) | 2 lines Another attempt at eliminating confusion when NA VHF Contest Mode is in use. ------------------------------------------------------------------------ r8106 | k9an | 2017-09-22 21:36:52 +0100 (Fri, 22 Sep 2017) | 1 line Make sure that fastGrph is properly initialized. ------------------------------------------------------------------------ r8107 | bsomervi | 2017-09-22 23:08:41 +0100 (Fri, 22 Sep 2017) | 1 line Improve performance of the UDP reference application message_aggregator ------------------------------------------------------------------------ r8108 | bsomervi | 2017-09-22 23:08:49 +0100 (Fri, 22 Sep 2017) | 1 line Fix a regression in processing incoming Reply UDP messages ------------------------------------------------------------------------ r8109 | bsomervi | 2017-09-22 23:08:56 +0100 (Fri, 22 Sep 2017) | 4 lines Better handling of worked before and country name display Appended text is added at a fixed column unless the message overlaps in which case the appended information floats to thr right. ------------------------------------------------------------------------ r8110 | bsomervi | 2017-09-22 23:09:04 +0100 (Fri, 22 Sep 2017) | 4 lines Restore printing of MSK144 decode quality information Now that a way of dealing with worked before and country information without losing this information has been found. ------------------------------------------------------------------------ r8111 | bsomervi | 2017-09-22 23:09:11 +0100 (Fri, 22 Sep 2017) | 5 lines Fix an issue with truncated free text messages being generated This is an edge case when working a call like RI9F/GM4WJS where it is not possible to confirm receipt of the full compound callsign in a Tx5 73 message as "RI9F/GM4WJS 73" is 14 characters. ------------------------------------------------------------------------ r8112 | bsomervi | 2017-09-23 19:09:29 +0100 (Sat, 23 Sep 2017) | 1 line Tidy up some ugly code ------------------------------------------------------------------------ r8113 | bsomervi | 2017-09-23 19:09:37 +0100 (Sat, 23 Sep 2017) | 1 line Clean up some main window UI layout ------------------------------------------------------------------------ r8114 | k9an | 2017-09-23 20:39:42 +0100 (Sat, 23 Sep 2017) | 1 line Comment out some diagnostic writes. ------------------------------------------------------------------------ r8115 | k9an | 2017-09-23 20:56:45 +0100 (Sat, 23 Sep 2017) | 1 line Add some text for section 13.3 of the User Guide. ------------------------------------------------------------------------ r8116 | k9an | 2017-09-23 21:01:31 +0100 (Sat, 23 Sep 2017) | 1 line Minor change to new_features.adoc. ------------------------------------------------------------------------ r8117 | bsomervi | 2017-09-23 23:02:24 +0100 (Sat, 23 Sep 2017) | 1 line Minor additions to MSK144 phase eq docs ------------------------------------------------------------------------ r8118 | k9an | 2017-09-23 23:32:06 +0100 (Sat, 23 Sep 2017) | 1 line Fix up Table 2 caption. ------------------------------------------------------------------------ r8119 | bsomervi | 2017-09-24 22:14:10 +0100 (Sun, 24 Sep 2017) | 1 line Fix issues processing free text 73 messages ------------------------------------------------------------------------ r8120 | k1jt | 2017-09-25 18:02:52 +0100 (Mon, 25 Sep 2017) | 3 lines First tests of "RR73 NOW ..." and "NIL NOW ..." (i3bit=1, 2) messages in FT8. DO NOT USE THIS FEATURE ON THE AIR! ------------------------------------------------------------------------ r8121 | k1jt | 2017-09-25 20:21:25 +0100 (Mon, 25 Sep 2017) | 2 lines Make bDXped a member variable, default to false. ------------------------------------------------------------------------ r8122 | bsomervi | 2017-09-26 00:38:19 +0100 (Tue, 26 Sep 2017) | 1 line Fix regression in handling double-clicked CQ and QRZ calls ------------------------------------------------------------------------ r8123 | bsomervi | 2017-09-26 00:38:27 +0100 (Tue, 26 Sep 2017) | 1 line Fix a regression handling compound calls in 73 messages ------------------------------------------------------------------------ r8124 | k1jt | 2017-09-27 13:26:33 +0100 (Wed, 27 Sep 2017) | 2 lines Additions to Section 13.3 of WSJT-X User Guide: "Phase Equalkization". ------------------------------------------------------------------------ r8125 | k1jt | 2017-09-27 13:39:50 +0100 (Wed, 27 Sep 2017) | 31 lines Experimental new behavior for "Lock Tx=Rx" and for clicking on waterfall and decoded text. 1. Checkbox "Lock Tx=Rx" is now labeled "Lock Tx Freq", and its meaning is quite different. If checked, the audio Tx frequency cannot be changed. It's like the "Lock" function on some transceivers. 2. Clicking on the Wide Graph waterfall and on lines of decoded text now behave as follows: Click on Action --------------------------------------------------------------------- Waterfall: Click to set Rx frequency Shift-click to set Tx frequency Ctrl-click to set Rx and Tx frequencies If Lock Tx Freq is checked, Tx freq does not move Double-click to set Rx frequency and decode there Decoded Text: Double-click to copy transmitting callsign to DX Call and locator to DX Grid; change Rx frequency to decoded signal's frequency; generate standard messages. Tx frequency is not changed unless Ctrl is held down and Lock Tx Freq not checked. If this experimental behavior is adopted, some descriptions in the User Guide and Special Mouse Commands will need to be updated. 3. Starting to implement a new function on the Tools menu, "Solve for calibration parameters". This is not yet finished; DO NOT USE in its present form. ------------------------------------------------------------------------ r8126 | k1jt | 2017-09-27 13:50:21 +0100 (Wed, 27 Sep 2017) | 2 lines Add missing routine. ------------------------------------------------------------------------ r8127 | k1jt | 2017-09-28 02:35:09 +0100 (Thu, 28 Sep 2017) | 1 line Functional 'Solve for calibration parameters' on Tools menu. ------------------------------------------------------------------------ r8128 | k1jt | 2017-09-28 13:30:52 +0100 (Thu, 28 Sep 2017) | 1 line dummy ------------------------------------------------------------------------ r8129 | k9an | 2017-09-28 16:00:57 +0100 (Thu, 28 Sep 2017) | 1 line Correct a typo in the docs. ------------------------------------------------------------------------ r8130 | k1jt | 2017-09-28 16:05:41 +0100 (Thu, 28 Sep 2017) | 1 line Minor edits in User Guide. ------------------------------------------------------------------------ r8131 | k1jt | 2017-09-28 16:09:46 +0100 (Thu, 28 Sep 2017) | 3 lines Fix two ways that Loxk Tx Freq could be circumvented; display Echo Graph automatically when Echo mode is started; clean up display of FreqCal parameters. ------------------------------------------------------------------------ r8132 | k1jt | 2017-09-28 16:46:36 +0100 (Thu, 28 Sep 2017) | 2 lines Clean up the display of "Controls" checkbox on Wide Graph. ------------------------------------------------------------------------ r8133 | k1jt | 2017-09-28 16:55:24 +0100 (Thu, 28 Sep 2017) | 2 lines Display "NIL NOW ", etc., only for test cases. ------------------------------------------------------------------------ r8134 | k1jt | 2017-09-28 20:51:04 +0100 (Thu, 28 Sep 2017) | 2 lines Add some FreqCal info to User Guide. ------------------------------------------------------------------------ r8135 | k1jt | 2017-09-29 00:34:13 +0100 (Fri, 29 Sep 2017) | 1 line Move 'Controls' checkbox a few pixels to the right. ------------------------------------------------------------------------ r8136 | bsomervi | 2017-09-29 11:46:43 +0100 (Fri, 29 Sep 2017) | 1 line Fix accidental regression in UDP Reply message handling ------------------------------------------------------------------------ r8137 | bsomervi | 2017-09-29 11:57:22 +0100 (Fri, 29 Sep 2017) | 1 line Minor clarification for the User Guide waterfall controls description ------------------------------------------------------------------------ r8138 | k1jt | 2017-09-29 14:27:55 +0100 (Fri, 29 Sep 2017) | 2 lines Minor change to make shift/ctrl double-click logic more consistent. ------------------------------------------------------------------------ r8139 | k1jt | 2017-09-29 14:47:26 +0100 (Fri, 29 Sep 2017) | 1 line Remove a diagnostic qDebug(). ------------------------------------------------------------------------ r8140 | k1jt | 2017-09-29 14:59:16 +0100 (Fri, 29 Sep 2017) | 2 lines Additional instructions for using the FreqCal procedure. ------------------------------------------------------------------------ r8141 | k1jt | 2017-09-29 17:53:28 +0100 (Fri, 29 Sep 2017) | 2 lines Many updates to User Guide, mostly to reflect changes in "click behavior". ------------------------------------------------------------------------ r8142 | k1jt | 2017-09-29 17:53:57 +0100 (Fri, 29 Sep 2017) | 1 line Update mouse_sommands.txt. ------------------------------------------------------------------------ r8143 | k1jt | 2017-09-29 17:58:05 +0100 (Fri, 29 Sep 2017) | 3 lines Previous commit message should have mentioned a fix to "stdmsg.f90" that was preventing double-click on a JT65 "OOO" message from populating message fields. ------------------------------------------------------------------------ r8144 | k1jt | 2017-09-29 18:40:30 +0100 (Fri, 29 Sep 2017) | 2 lines Add an option to enforce simplex operation (moving both Tx and Rx frequency) when double-clicking on a decoded text line. ------------------------------------------------------------------------ r8145 | k1jt | 2017-09-30 14:56:33 +0100 (Sat, 30 Sep 2017) | 1 line Fix a regression that prevented double-click on call from working as in r8123. ------------------------------------------------------------------------ r8146 | k1jt | 2017-09-30 18:48:46 +0100 (Sat, 30 Sep 2017) | 21 lines Another try at optimizing the GUI for simplex and split behavior. Details below: 1. Checkbox "Double-click on call sets Tx and Rx freqs" has been removed from the Settings -> General tab. 2. Checkbox "Lock Tx Freq" on main window is relabled "Hold Tx Freq". 3. Behavior now defaults to the "simplex" behavior in use up to code revision r8123. In particular, double-clicking on decoded mesages that do not contain your own call moves both Rx and Tx frequencies. If the first callsign is your own call, only Rx freq moves. 4. If "Hold Tx Freq" is checked, double-clicking on decoded messages moves the Rx frequency; Tx frequency is moved only if CTRL was held down. 5. Clicking on the waterfall moves Rx and Tx frequencies as before: Rx only on a simple click, Tx only on SHIFT-click, and both on CTRL-click. This happens even if "Hold Tx Freq" is checked (which is why this box is no longer labeled "Lock Tx Freq"). ------------------------------------------------------------------------ r8147 | k1jt | 2017-09-30 20:25:01 +0100 (Sat, 30 Sep 2017) | 1 line Fix behavior with double-click on 'CQ <AA-ZZ> <call> <grid>.' ------------------------------------------------------------------------ r8148 | k1jt | 2017-10-01 13:35:43 +0100 (Sun, 01 Oct 2017) | 1 line Correct an improper disabling of TxFreqSpinBox. ------------------------------------------------------------------------ r8149 | k1jt | 2017-10-01 15:03:16 +0100 (Sun, 01 Oct 2017) | 1 line Update mouse_commands.txt and tool tips. ------------------------------------------------------------------------ r8150 | k1jt | 2017-10-01 15:58:10 +0100 (Sun, 01 Oct 2017) | 1 line Update 'blank line' band ID at 4*TRperiod/5. ------------------------------------------------------------------------ r8151 | bsomervi | 2017-10-01 22:43:59 +0100 (Sun, 01 Oct 2017) | 1 line Fix an invalid iterator increment when there are no FreqCal frequencies ------------------------------------------------------------------------ r8152 | bsomervi | 2017-10-01 22:44:07 +0100 (Sun, 01 Oct 2017) | 1 line Fix cty.dat lookups that were not honouring exact match flags ------------------------------------------------------------------------ r8153 | bsomervi | 2017-10-01 22:44:15 +0100 (Sun, 01 Oct 2017) | 6 lines Add "Apply" button to calibration solution message box Make calibration solution application iterative so that calibrations can be applied sequentially if desired. Tidy up calibration solution messages boxes and make i18n friendly. ------------------------------------------------------------------------ r8154 | k1jt | 2017-10-02 14:49:37 +0100 (Mon, 02 Oct 2017) | 2 lines Update User Guide and "mouse_commands". ------------------------------------------------------------------------ r8155 | k1jt | 2017-10-02 15:15:15 +0100 (Mon, 02 Oct 2017) | 2 lines Special DXpedition messages must not have the FreeText bit set. ------------------------------------------------------------------------ r8156 | k1jt | 2017-10-02 19:27:08 +0100 (Mon, 02 Oct 2017) | 2 lines Add more on Copyright protections. ------------------------------------------------------------------------ r8157 | k1jt | 2017-10-02 19:33:17 +0100 (Mon, 02 Oct 2017) | 2 lines Update the list of keyboard shortcuts. ------------------------------------------------------------------------ r8158 | k1jt | 2017-10-02 19:35:06 +0100 (Mon, 02 Oct 2017) | 2 lines Minor edits. ------------------------------------------------------------------------ r8159 | k1jt | 2017-10-03 02:23:24 +0100 (Tue, 03 Oct 2017) | 1 line Correct a misspelling; add quote marks; push 'About' to bottom of Tools menu. ------------------------------------------------------------------------ r8160 | k1jt | 2017-10-03 16:59:47 +0100 (Tue, 03 Oct 2017) | 2 lines Add KA9Q to the copyright notice. ------------------------------------------------------------------------ r8161 | k1jt | 2017-10-04 14:14:51 +0100 (Wed, 04 Oct 2017) | 2 lines Update an image; fix a typo. ------------------------------------------------------------------------ r8162 | k1jt | 2017-10-05 19:27:34 +0100 (Thu, 05 Oct 2017) | 2 lines Fix a bug involving "firstcall contains mycall" but not equal to mycall. ------------------------------------------------------------------------ r8163 | bsomervi | 2017-10-06 17:18:17 +0100 (Fri, 06 Oct 2017) | 1 line Add an accessor method to Configuration to get the current calibration parameters ------------------------------------------------------------------------ r8164 | bsomervi | 2017-10-06 17:18:25 +0100 (Fri, 06 Oct 2017) | 5 lines Rename the fmt.all calibration measurements file after accepting a solution This allows those who want to keep their calibration measurements after finding a solution to calibrate their station. The fmt.all file used to find and accept a solution is renamed to fmt.bak. ------------------------------------------------------------------------ r8165 | k1jt | 2017-10-13 15:36:10 +0100 (Fri, 13 Oct 2017) | 2 lines Update the Tool Tip displayed for Frequency Calibration parameters. ------------------------------------------------------------------------ r8166 | bsomervi | 2017-10-13 23:34:10 +0100 (Fri, 13 Oct 2017) | 1 line Fix an issue with editing IARU regions in the working frequencies table ------------------------------------------------------------------------ r8167 | bsomervi | 2017-10-13 23:34:21 +0100 (Fri, 13 Oct 2017) | 32 lines Improved frequency calibration Measure check box added to FreqCal mode, check to record to fmt.all with current calibration correction disabled, uncheck to see the impact of the current calibration parameters. The fmt.all file is now optionally renamed to fmt.bak when a calibration solution is accepted. This allows users to preserve an fmt.all file that they might have edited for best fit. A calibration procedure might proceed thus:- 1) select FreqCal mode, 2) step through suggested calibration test frequencies deleting those that have no usable signal, 3) enable "Menu->Tools->Execute frequency calibration cycle" and check that suitable signals are present, 4) select a suitable FTol and T/R period, 5) check "Measure" and let the cycle complete a few times to gather data, 6) uncheck "Measure" to complete the data capture, optionally tidy the fmt.all file with your favourite editor, 7) push "Menu->Tools->Solve for calibration parameters" and accept if you like what you see, 8) sit back and admire your accurately frequency calibrated station. ------------------------------------------------------------------------ r8168 | bsomervi | 2017-10-13 23:34:36 +0100 (Fri, 13 Oct 2017) | 4 lines Generic handling of keyboard modifiers via UDP and double-clicks This change opens up all keyboard modifier options to UDP Reply messages as well as double-clicks of decoded messages. ------------------------------------------------------------------------ r8169 | bsomervi | 2017-10-13 23:34:48 +0100 (Fri, 13 Oct 2017) | 3 lines User guide updates for frequency calibration mode Also some instances of non-italicized WSJT-X fixed. ------------------------------------------------------------------------ r8170 | k9an | 2017-10-14 02:02:38 +0100 (Sat, 14 Oct 2017) | 1 line Don't open the false_decodes.txt file. ------------------------------------------------------------------------ git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx-1.8@8171 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
|
@ -8,7 +8,7 @@
|
|||
namespace
|
||||
{
|
||||
// Table of ADIF band definitions as defined in the ADIF
|
||||
// specification.
|
||||
// specification as at ADIF v3.0.6
|
||||
struct ADIFBand
|
||||
{
|
||||
char const * const name_;
|
||||
|
@ -20,7 +20,7 @@ namespace
|
|||
{"560m", 501000u, 504000u},
|
||||
{"160m", 1800000u, 2000000u},
|
||||
{"80m", 3500000u, 4000000u},
|
||||
{"60m", 5102000u, 5406500u},
|
||||
{"60m", 5060000u, 5450000u},
|
||||
{"40m", 7000000u, 7300000u},
|
||||
{"30m", 10000000u, 10150000u},
|
||||
{"20m", 14000000u, 14350000u},
|
||||
|
|
|
@ -374,6 +374,7 @@ set (wsjt_FSRCS
|
|||
lib/fsk4hf/bpdecode174.f90
|
||||
lib/fsk4hf/bpdecode300.f90
|
||||
lib/baddata.f90
|
||||
lib/calibrate.f90
|
||||
lib/ccf2.f90
|
||||
lib/ccf65.f90
|
||||
lib/fsk4hf/chkcrc10.f90
|
||||
|
@ -424,6 +425,7 @@ set (wsjt_FSRCS
|
|||
lib/fil4.f90
|
||||
lib/fil6521.f90
|
||||
lib/filbig.f90
|
||||
lib/fitcal.f90
|
||||
lib/fix_contest_msg.f90
|
||||
lib/flat1.f90
|
||||
lib/flat1a.f90
|
||||
|
|
|
@ -237,7 +237,7 @@ public:
|
|||
{
|
||||
return {frequency_line_edit_.frequency ()
|
||||
, Modes::value (mode_combo_box_.currentText ())
|
||||
, IARURegions::value (region_combo_box_.currentIndex ())};
|
||||
, IARURegions::value (region_combo_box_.currentText ())};
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -517,8 +517,8 @@ private:
|
|||
bool rig_changed_;
|
||||
TransceiverState cached_rig_state_;
|
||||
int rig_resolution_; // see Transceiver::resolution signal
|
||||
double frequency_calibration_intercept_;
|
||||
double frequency_calibration_slope_ppm_;
|
||||
CalibrationParams calibration_;
|
||||
bool frequency_calibration_disabled_; // not persistent
|
||||
unsigned transceiver_command_number_;
|
||||
|
||||
// configuration fields that we publish
|
||||
|
@ -561,7 +561,6 @@ private:
|
|||
bool single_decode_;
|
||||
bool twoPass_;
|
||||
bool x2ToneSpacing_;
|
||||
bool contestMode_;
|
||||
bool realTimeDecode_;
|
||||
QString udp_server_name_;
|
||||
port_type udp_server_port_;
|
||||
|
@ -652,7 +651,6 @@ bool Configuration::decode_at_52s () const {return m_->decode_at_52s_;}
|
|||
bool Configuration::single_decode () const {return m_->single_decode_;}
|
||||
bool Configuration::twoPass() const {return m_->twoPass_;}
|
||||
bool Configuration::x2ToneSpacing() const {return m_->x2ToneSpacing_;}
|
||||
bool Configuration::contestMode() const {return m_->contestMode_;}
|
||||
bool Configuration::realTimeDecode() const {return m_->realTimeDecode_;}
|
||||
bool Configuration::split_mode () const {return m_->split_mode ();}
|
||||
QString Configuration::udp_server_name () const {return m_->udp_server_name_;}
|
||||
|
@ -675,6 +673,18 @@ QString Configuration::rig_name () const {return m_->rig_params_.rig_name;}
|
|||
bool Configuration::pwrBandTxMemory () const {return m_->pwrBandTxMemory_;}
|
||||
bool Configuration::pwrBandTuneMemory () const {return m_->pwrBandTuneMemory_;}
|
||||
|
||||
void Configuration::set_calibration (CalibrationParams params)
|
||||
{
|
||||
m_->calibration_ = params;
|
||||
}
|
||||
|
||||
void Configuration::enable_calibration (bool on)
|
||||
{
|
||||
auto target_frequency = m_->remove_calibration (m_->cached_rig_state_.frequency ()) - m_->current_offset_;
|
||||
m_->frequency_calibration_disabled_ = !on;
|
||||
transceiver_frequency (target_frequency);
|
||||
}
|
||||
|
||||
bool Configuration::is_transceiver_online () const
|
||||
{
|
||||
return m_->rig_active_;
|
||||
|
@ -794,12 +804,15 @@ Configuration::impl::impl (Configuration * self, QDir const& temp_directory,
|
|||
QSettings * settings, QWidget * parent)
|
||||
: QDialog {parent}
|
||||
, self_ {self}
|
||||
, transceiver_thread_ {nullptr}
|
||||
, ui_ {new Ui::configuration_dialog}
|
||||
, settings_ {settings}
|
||||
, doc_dir_ {doc_path ()}
|
||||
, data_dir_ {data_path ()}
|
||||
, temp_dir_ {temp_directory}
|
||||
, writeable_data_dir_ {QStandardPaths::writableLocation (QStandardPaths::DataLocation)}
|
||||
, restart_sound_input_device_ {false}
|
||||
, restart_sound_output_device_ {false}
|
||||
, frequencies_ {&bands_}
|
||||
, next_frequencies_ {&bands_}
|
||||
, stations_ {&bands_}
|
||||
|
@ -814,6 +827,7 @@ Configuration::impl::impl (Configuration * self, QDir const& temp_directory,
|
|||
, have_rig_ {false}
|
||||
, rig_changed_ {false}
|
||||
, rig_resolution_ {0}
|
||||
, frequency_calibration_disabled_ {false}
|
||||
, transceiver_command_number_ {0}
|
||||
, degrade_ {0.} // initialize to zero each run, not
|
||||
// saved in settings
|
||||
|
@ -1025,9 +1039,6 @@ Configuration::impl::impl (Configuration * self, QDir const& temp_directory,
|
|||
ui_->sound_input_channel_combo_box->setCurrentIndex (audio_input_channel_);
|
||||
ui_->sound_output_channel_combo_box->setCurrentIndex (audio_output_channel_);
|
||||
|
||||
restart_sound_input_device_ = false;
|
||||
restart_sound_output_device_ = false;
|
||||
|
||||
enumerate_rigs ();
|
||||
initialize_models ();
|
||||
|
||||
|
@ -1092,7 +1103,6 @@ void Configuration::impl::initialize_models ()
|
|||
ui_->single_decode_check_box->setChecked(single_decode_);
|
||||
ui_->cbTwoPass->setChecked(twoPass_);
|
||||
ui_->cbx2ToneSpacing->setChecked(x2ToneSpacing_);
|
||||
ui_->cbContestMode->setChecked(contestMode_);
|
||||
ui_->cbRealTime->setChecked(realTimeDecode_);
|
||||
ui_->cbRealTime->setVisible(false); //Tempoary -- probably will remove this control
|
||||
ui_->type_2_msg_gen_combo_box->setCurrentIndex (type_2_msg_gen_);
|
||||
|
@ -1128,8 +1138,8 @@ void Configuration::impl::initialize_models ()
|
|||
ui_->accept_udp_requests_check_box->setChecked (accept_udp_requests_);
|
||||
ui_->udpWindowToFront->setChecked(udpWindowToFront_);
|
||||
ui_->udpWindowRestore->setChecked(udpWindowRestore_);
|
||||
ui_->calibration_intercept_spin_box->setValue (frequency_calibration_intercept_);
|
||||
ui_->calibration_slope_ppm_spin_box->setValue (frequency_calibration_slope_ppm_);
|
||||
ui_->calibration_intercept_spin_box->setValue (calibration_.intercept);
|
||||
ui_->calibration_slope_ppm_spin_box->setValue (calibration_.slope_ppm);
|
||||
|
||||
if (rig_params_.ptt_port.isEmpty ())
|
||||
{
|
||||
|
@ -1323,7 +1333,6 @@ void Configuration::impl::read_settings ()
|
|||
single_decode_ = settings_->value("SingleDecode",false).toBool ();
|
||||
twoPass_ = settings_->value("TwoPass",true).toBool ();
|
||||
x2ToneSpacing_ = settings_->value("x2ToneSpacing",false).toBool ();
|
||||
contestMode_ = settings_->value("ContestMode",false).toBool ();
|
||||
realTimeDecode_ = settings_->value("RealTimeDecode",false).toBool ();
|
||||
rig_params_.poll_interval = settings_->value ("Polling", 0).toInt ();
|
||||
rig_params_.split_mode = settings_->value ("SplitMode", QVariant::fromValue (TransceiverFactory::split_mode_none)).value<TransceiverFactory::SplitMode> ();
|
||||
|
@ -1332,8 +1341,8 @@ void Configuration::impl::read_settings ()
|
|||
accept_udp_requests_ = settings_->value ("AcceptUDPRequests", false).toBool ();
|
||||
udpWindowToFront_ = settings_->value ("udpWindowToFront",false).toBool ();
|
||||
udpWindowRestore_ = settings_->value ("udpWindowRestore",false).toBool ();
|
||||
frequency_calibration_intercept_ = settings_->value ("CalibrationIntercept", 0.).toDouble ();
|
||||
frequency_calibration_slope_ppm_ = settings_->value ("CalibrationSlopePPM", 0.).toDouble ();
|
||||
calibration_.intercept = settings_->value ("CalibrationIntercept", 0.).toDouble ();
|
||||
calibration_.slope_ppm = settings_->value ("CalibrationSlopePPM", 0.).toDouble ();
|
||||
pwrBandTxMemory_ = settings_->value("pwrBandTxMemory",false).toBool ();
|
||||
pwrBandTuneMemory_ = settings_->value("pwrBandTuneMemory",false).toBool ();
|
||||
}
|
||||
|
@ -1422,15 +1431,14 @@ void Configuration::impl::write_settings ()
|
|||
settings_->setValue ("SingleDecode", single_decode_);
|
||||
settings_->setValue ("TwoPass", twoPass_);
|
||||
settings_->setValue ("x2ToneSpacing", x2ToneSpacing_);
|
||||
settings_->setValue ("ContestMode", contestMode_);
|
||||
settings_->setValue ("RealTimeDecode", realTimeDecode_);
|
||||
settings_->setValue ("UDPServer", udp_server_name_);
|
||||
settings_->setValue ("UDPServerPort", udp_server_port_);
|
||||
settings_->setValue ("AcceptUDPRequests", accept_udp_requests_);
|
||||
settings_->setValue ("udpWindowToFront", udpWindowToFront_);
|
||||
settings_->setValue ("udpWindowRestore", udpWindowRestore_);
|
||||
settings_->setValue ("CalibrationIntercept", frequency_calibration_intercept_);
|
||||
settings_->setValue ("CalibrationSlopePPM", frequency_calibration_slope_ppm_);
|
||||
settings_->setValue ("CalibrationIntercept", calibration_.intercept);
|
||||
settings_->setValue ("CalibrationSlopePPM", calibration_.slope_ppm);
|
||||
settings_->setValue ("pwrBandTxMemory", pwrBandTxMemory_);
|
||||
settings_->setValue ("pwrBandTuneMemory", pwrBandTuneMemory_);
|
||||
settings_->setValue ("Region", QVariant::fromValue (region_));
|
||||
|
@ -1818,10 +1826,9 @@ void Configuration::impl::accept ()
|
|||
single_decode_ = ui_->single_decode_check_box->isChecked ();
|
||||
twoPass_ = ui_->cbTwoPass->isChecked ();
|
||||
x2ToneSpacing_ = ui_->cbx2ToneSpacing->isChecked ();
|
||||
contestMode_ = ui_->cbContestMode->isChecked ();
|
||||
realTimeDecode_ = ui_->cbRealTime->isChecked ();
|
||||
frequency_calibration_intercept_ = ui_->calibration_intercept_spin_box->value ();
|
||||
frequency_calibration_slope_ppm_ = ui_->calibration_slope_ppm_spin_box->value ();
|
||||
calibration_.intercept = ui_->calibration_intercept_spin_box->value ();
|
||||
calibration_.slope_ppm = ui_->calibration_slope_ppm_spin_box->value ();
|
||||
pwrBandTxMemory_ = ui_->checkBoxPwrBandTxMemory->isChecked ();
|
||||
pwrBandTuneMemory_ = ui_->checkBoxPwrBandTuneMemory->isChecked ();
|
||||
auto new_server = ui_->udp_server_line_edit->text ();
|
||||
|
@ -1847,7 +1854,7 @@ void Configuration::impl::accept ()
|
|||
macros_.setStringList (next_macros_.stringList ());
|
||||
}
|
||||
|
||||
region_ = IARURegions::value (ui_->region_combo_box->currentIndex ());
|
||||
region_ = IARURegions::value (ui_->region_combo_box->currentText ());
|
||||
|
||||
if (frequencies_.frequency_list () != next_frequencies_.frequency_list ())
|
||||
{
|
||||
|
@ -2673,14 +2680,16 @@ void Configuration::impl::fill_port_combo_box (QComboBox * cb)
|
|||
|
||||
auto Configuration::impl::apply_calibration (Frequency f) const -> Frequency
|
||||
{
|
||||
return std::llround (frequency_calibration_intercept_
|
||||
+ (1. + frequency_calibration_slope_ppm_ / 1.e6) * f);
|
||||
if (frequency_calibration_disabled_) return f;
|
||||
return std::llround (calibration_.intercept
|
||||
+ (1. + calibration_.slope_ppm / 1.e6) * f);
|
||||
}
|
||||
|
||||
auto Configuration::impl::remove_calibration (Frequency f) const -> Frequency
|
||||
{
|
||||
return std::llround ((f - frequency_calibration_intercept_)
|
||||
/ (1. + frequency_calibration_slope_ppm_ / 1.e6));
|
||||
if (frequency_calibration_disabled_) return f;
|
||||
return std::llround ((f - calibration_.intercept)
|
||||
/ (1. + calibration_.slope_ppm / 1.e6));
|
||||
}
|
||||
|
||||
#if !defined (QT_NO_DEBUG_STREAM)
|
||||
|
|
|
@ -159,6 +159,31 @@ public:
|
|||
QColor color_NewCall () const;
|
||||
bool pwrBandTxMemory () const;
|
||||
bool pwrBandTuneMemory () const;
|
||||
|
||||
struct CalibrationParams
|
||||
{
|
||||
CalibrationParams ()
|
||||
: intercept {0.}
|
||||
, slope_ppm {0.}
|
||||
{
|
||||
}
|
||||
|
||||
CalibrationParams (double the_intercept, double the_slope_ppm)
|
||||
: intercept {the_intercept}
|
||||
, slope_ppm {the_slope_ppm}
|
||||
{
|
||||
}
|
||||
|
||||
double intercept; // Hertz
|
||||
double slope_ppm; // Hertz
|
||||
};
|
||||
|
||||
// Temporarily enable or disable calibration adjustments.
|
||||
void enable_calibration (bool = true);
|
||||
|
||||
// Set the calibration parameters and enable calibration corrections.
|
||||
void set_calibration (CalibrationParams);
|
||||
|
||||
// This method queries if a CAT and PTT connection is operational.
|
||||
bool is_transceiver_online () const;
|
||||
|
||||
|
|
166
Configuration.ui
|
@ -6,7 +6,7 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>536</width>
|
||||
<width>521</width>
|
||||
<height>507</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
@ -120,7 +120,7 @@
|
|||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Type 2 compound callsigns are those with prefixes or suffixes not included in the allowed shortlist (See Help-&gt;Add-on prefixes and suffixes).</p><p>This option determines which generated messages should contain your full type 2 compound call sign rather than your base callsign. It only applies if you have a type 2 compound callsign.</p><p>This option controls the way the messages that are used to answer CQ calls are generated. Generated messages 6 (CQ) and 5 (73) will always contain your full callsign. The JT65 and JT9 protocols allow for some standard messages with your full call at the expense of another piece of information such as the DX call or your locator.</p><p>Choosing message 1 omits the DX callsign which may be an issue when replying to CQ calls. Choosing message 3 also omits the DX callsign and many versions of this and other software will not extract the report. Choosing neither means that your full callsign only goes in your message 5 (73) so your QSO partner my log the wrong callsign.</p><p>None of these options are perfect, message 3 is best but be aware your QSO partner may not log the report you send them.</p></body></html></string>
|
||||
<string><html><head/><body><p>Type 2 compound callsigns are those with prefixes or suffixes not included in the allowed shortlist (See Help-&gt;Add-on prefixes and suffixes).</p><p>This option determines which generated messages should contain your full type 2 compound call sign rather than your base callsign. It only applies if you have a type 2 compound callsign.</p><p>This option controls the way the messages that are used to answer CQ calls are generated. Generated messages 6 (CQ) and 5 (73) will always contain your full callsign. The JT65 and JT9 protocols allow for some standard messages with your full call at the expense of another piece of information such as the DX call or your locator.</p><p>Choosing message 1 omits the DX callsign which may be an issue when replying to CQ calls. Choosing message 3 also omits the DX callsign and many versions of this and other software will not extract the report. Choosing neither means that your full callsign only goes in your message 5 (73) so your QSO partner may log the wrong callsign.</p><p>None of these options are perfect, message 3 is usually best but be aware your QSO partner may not log the report you send them.</p></body></html></string>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
|
@ -269,12 +269,51 @@
|
|||
<string>Behavior</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_8">
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="enable_VHF_features_check_box">
|
||||
<property name="text">
|
||||
<string>Enable VHF/UHF/Microwave features</string>
|
||||
</property>
|
||||
</widget>
|
||||
<item row="4" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Tx watchdog:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>tx_watchdog_spin_box</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="tx_watchdog_spin_box">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Number of minutes before unattended transmissions are aborted</p></body></html></string>
|
||||
</property>
|
||||
<property name="specialValueText">
|
||||
<string>Disabled</string>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> minutes</string>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>6</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="monitor_off_check_box">
|
||||
|
@ -289,6 +328,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="enable_VHF_features_check_box">
|
||||
<property name="text">
|
||||
<string>Enable VHF/UHF/Microwave features</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QCheckBox" name="decode_at_52s_check_box">
|
||||
<property name="text">
|
||||
|
@ -296,6 +342,23 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="single_decode_check_box">
|
||||
<property name="text">
|
||||
<string>Single decode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="tx_QSY_check_box">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Some rigs are not able to process CAT commands while transmitting. This means that if you are operating in split mode you may have to uncheck this option.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Allow Tx frequency changes while transmitting</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||
<item>
|
||||
|
@ -355,69 +418,6 @@ quiet period when decoding is done.</string>
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="single_decode_check_box">
|
||||
<property name="text">
|
||||
<string>Single decode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="tx_QSY_check_box">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Some rigs are not able to process CAT commands while transmitting. This means that if you are operating in split mode you may have to uncheck this option.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Allow Tx frequency changes while transmitting</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Tx watchdog:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>tx_watchdog_spin_box</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="tx_watchdog_spin_box">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Number of minutes before unattended transmissions are aborted</p></body></html></string>
|
||||
</property>
|
||||
<property name="specialValueText">
|
||||
<string>Disabled</string>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> minutes</string>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>6</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="monitor_last_used_check_box">
|
||||
<property name="toolTip">
|
||||
|
@ -1820,7 +1820,7 @@ for assessing propagation and system performance.</string>
|
|||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="toolTip">
|
||||
<string>See WSPR documentation Appendix C for details of how to determine these factors for your radio.</string>
|
||||
<string><html><head/><body><p>See &quot;Frequency Calibration&quot; in the WSJT-X User Guide for details of how to determine these parameters for your radio.</p></body></html></string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Frequency Calibration</string>
|
||||
|
@ -2337,16 +2337,6 @@ Right click for insert and delete options.</string>
|
|||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QCheckBox" name="cbContestMode">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Exchange 4-character grid locators instead of reports. See User Guide for details.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>FT8 and MSK144: NA VHF Contest Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QCheckBox" name="cbx2ToneSpacing">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Generate Tx audio with twice the normal tone spacing. Intended for special LF/MF transmitters that use a divide-by-2 before generating RF.</p></body></html></string>
|
||||
|
@ -2356,7 +2346,7 @@ Right click for insert and delete options.</string>
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<item row="8" column="0">
|
||||
<widget class="QCheckBox" name="cbRealTime">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
|
@ -2489,7 +2479,6 @@ soundcard changes</string>
|
|||
<tabstop>monitor_off_check_box</tabstop>
|
||||
<tabstop>monitor_last_used_check_box</tabstop>
|
||||
<tabstop>quick_call_check_box</tabstop>
|
||||
<tabstop>disable_TX_on_73_check_box</tabstop>
|
||||
<tabstop>tx_watchdog_spin_box</tabstop>
|
||||
<tabstop>CW_id_after_73_check_box</tabstop>
|
||||
<tabstop>enable_VHF_features_check_box</tabstop>
|
||||
|
@ -2562,7 +2551,6 @@ soundcard changes</string>
|
|||
<tabstop>sbDegrade</tabstop>
|
||||
<tabstop>sbBandwidth</tabstop>
|
||||
<tabstop>sbTxDelay</tabstop>
|
||||
<tabstop>cbContestMode</tabstop>
|
||||
<tabstop>cbx2ToneSpacing</tabstop>
|
||||
<tabstop>cbRealTime</tabstop>
|
||||
</tabstops>
|
||||
|
@ -2634,12 +2622,12 @@ soundcard changes</string>
|
|||
</connection>
|
||||
</connections>
|
||||
<buttongroups>
|
||||
<buttongroup name="split_mode_button_group"/>
|
||||
<buttongroup name="TX_audio_source_button_group"/>
|
||||
<buttongroup name="CAT_handshake_button_group"/>
|
||||
<buttongroup name="CAT_stop_bits_button_group"/>
|
||||
<buttongroup name="TX_audio_source_button_group"/>
|
||||
<buttongroup name="split_mode_button_group"/>
|
||||
<buttongroup name="PTT_method_button_group"/>
|
||||
<buttongroup name="TX_mode_button_group"/>
|
||||
<buttongroup name="CAT_data_bits_button_group"/>
|
||||
<buttongroup name="CAT_handshake_button_group"/>
|
||||
<buttongroup name="PTT_method_button_group"/>
|
||||
</buttongroups>
|
||||
</ui>
|
||||
|
|
|
@ -610,29 +610,27 @@ bool FrequencyList_v2::impl::setData (QModelIndex const& model_index, QVariant c
|
|||
switch (model_index.column ())
|
||||
{
|
||||
case region_column:
|
||||
if (value.canConvert<Region> ())
|
||||
{
|
||||
auto region = static_cast<Region> (value.toUInt ());
|
||||
if (region != item.region_)
|
||||
{
|
||||
item.region_ = region;
|
||||
Q_EMIT dataChanged (model_index, model_index, roles);
|
||||
changed = true;
|
||||
}
|
||||
{
|
||||
auto region = IARURegions::value (value.toString ());
|
||||
if (region != item.region_)
|
||||
{
|
||||
item.region_ = region;
|
||||
Q_EMIT dataChanged (model_index, model_index, roles);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case mode_column:
|
||||
if (value.canConvert<Mode> ())
|
||||
{
|
||||
auto mode = Modes::value (value.toString ());
|
||||
if (mode != item.mode_)
|
||||
{
|
||||
item.mode_ = mode;
|
||||
Q_EMIT dataChanged (model_index, model_index, roles);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
{
|
||||
auto mode = Modes::value (value.toString ());
|
||||
if (mode != item.mode_)
|
||||
{
|
||||
item.mode_ = mode;
|
||||
Q_EMIT dataChanged (model_index, model_index, roles);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case frequency_column:
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
JT4 JT9 9+65 JT65 QRA SCAT M144 WSPR Echo
|
||||
---------------------------------------------------------------------
|
||||
0. txFirstCheckBox 11 111 1 11 11 11 1
|
||||
1. TxFreqSpinBox 11 111 1 11 11
|
||||
2. RxFreqSpinBox 11 111 1 11 11 1
|
||||
3. sbFtol 1 11 1 11 11 1
|
||||
4. rptSpinBox 11 111 1 11 11 11 1
|
||||
5. sbTR 11 1
|
||||
6. sbCQRxFreq 1
|
||||
7. cbShMsgs 1 1
|
||||
8. cbFast9 11
|
||||
9. cbAutoSeq 1
|
||||
10. cbTx6 1
|
||||
11. pbTxMode 1
|
||||
12. pbR2T 11 11 1 11 11
|
||||
13. pbT2R 11 11 1 11 11
|
||||
14. cbTxLock 1 11 1 11 11
|
||||
15. sbSubMode 1 1 1 11 11
|
||||
16. syncSpinBox 1 1 1 11 11
|
||||
17. WSPR_Controls_Widget 1
|
||||
18. ClrAvgButton 11 1
|
||||
---------------------------------------------------------------------
|
||||
19. FastNormalDeep 11 11 1 11 1 1
|
||||
20. IncludeAveraging 1 1
|
||||
21. IncludeCorrelation 1 1
|
||||
22. EchoGraph 1
|
||||
---------------------------------------------------------------------
|
||||
|
||||
For each mode:
|
||||
Column 1 applies when VHF features is OFF (or col 2 absent)
|
||||
Column 2 (if present) applies when VHF features is ON
|
||||
Column 3 (JT9 only) applies for submodes E-H with Fast checked
|
||||
JT4 JT9 9+65 JT65 QRA SCAT M144 WSPR Echo
|
||||
---------------------------------------------------------------------
|
||||
0. txFirstCheckBox 11 111 1 11 11 11 1
|
||||
1. TxFreqSpinBox 11 111 1 11 11
|
||||
2. RxFreqSpinBox 11 111 1 11 11 1
|
||||
3. sbFtol 1 11 1 11 11 1
|
||||
4. rptSpinBox 11 111 1 11 11 11 1
|
||||
5. sbTR 11 1
|
||||
6. sbCQRxFreq 1
|
||||
7. cbShMsgs 1 1
|
||||
8. cbFast9 11
|
||||
9. cbAutoSeq 1
|
||||
10. cbTx6 1
|
||||
11. pbTxMode 1
|
||||
12. pbR2T 11 11 1 11 11
|
||||
13. pbT2R 11 11 1 11 11
|
||||
14. cbTxLock 1 11 1 11 11
|
||||
15. sbSubMode 1 1 1 11 11
|
||||
16. syncSpinBox 1 1 1 11 11
|
||||
17. WSPR_Controls_Widget 1
|
||||
18. ClrAvgButton 11 1
|
||||
---------------------------------------------------------------------
|
||||
19. FastNormalDeep 11 11 1 11 1 1
|
||||
20. IncludeAveraging 1 1
|
||||
21. IncludeCorrelation 1 1
|
||||
22. EchoGraph 1
|
||||
---------------------------------------------------------------------
|
||||
|
||||
For each mode:
|
||||
Column 1 applies when VHF features is OFF (or col 2 absent)
|
||||
Column 2 (if present) applies when VHF features is ON
|
||||
Column 3 (JT9 only) applies for submodes E-H with Fast checked
|
||||
|
|
|
@ -34,10 +34,14 @@ char const * IARURegions::name (Region r)
|
|||
return region_names[static_cast<int> (r)];
|
||||
}
|
||||
|
||||
auto IARURegions::value (int r) -> Region
|
||||
auto IARURegions::value (QString const& s) -> Region
|
||||
{
|
||||
if (r < 0 || r + 1 >= SENTINAL) return ALL;
|
||||
return static_cast<Region> (r);
|
||||
auto end = region_names + region_names_size;
|
||||
auto p = std::find_if (region_names, end
|
||||
, [&s] (char const * const name) {
|
||||
return name == s;
|
||||
});
|
||||
return p != end ? static_cast<Region> (p - region_names) : ALL;
|
||||
}
|
||||
|
||||
QVariant IARURegions::data (QModelIndex const& index, int role) const
|
||||
|
|
|
@ -51,7 +51,7 @@ public:
|
|||
|
||||
// translate between enumeration and human readable strings
|
||||
static char const * name (Region);
|
||||
static Region value (int);
|
||||
static Region value (QString const&);
|
||||
|
||||
// Implement the QAbstractListModel interface
|
||||
int rowCount (QModelIndex const& parent = QModelIndex {}) const override
|
||||
|
|
|
@ -152,12 +152,14 @@ void MessageClient::impl::parse_message (QByteArray const& msg)
|
|||
QByteArray mode;
|
||||
QByteArray message;
|
||||
bool low_confidence {false};
|
||||
in >> time >> snr >> delta_time >> delta_frequency >> mode >> message >> low_confidence;
|
||||
quint8 modifiers {0};
|
||||
in >> time >> snr >> delta_time >> delta_frequency >> mode >> message
|
||||
>> low_confidence >> modifiers;
|
||||
if (check_status (in) != Fail)
|
||||
{
|
||||
Q_EMIT self_->reply (time, snr, delta_time, delta_frequency
|
||||
, QString::fromUtf8 (mode), QString::fromUtf8 (message)
|
||||
, low_confidence);
|
||||
, low_confidence, modifiers);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -368,27 +370,29 @@ void MessageClient::status_update (Frequency f, QString const& mode, QString con
|
|||
}
|
||||
|
||||
void MessageClient::decode (bool is_new, QTime time, qint32 snr, float delta_time, quint32 delta_frequency
|
||||
, QString const& mode, QString const& message_text, bool low_confidence)
|
||||
, QString const& mode, QString const& message_text, bool low_confidence
|
||||
, bool off_air)
|
||||
{
|
||||
if (m_->server_port_ && !m_->server_string_.isEmpty ())
|
||||
{
|
||||
QByteArray message;
|
||||
NetworkMessage::Builder out {&message, NetworkMessage::Decode, m_->id_, m_->schema_};
|
||||
out << is_new << time << snr << delta_time << delta_frequency << mode.toUtf8 ()
|
||||
<< message_text.toUtf8 () << low_confidence;
|
||||
<< message_text.toUtf8 () << low_confidence << off_air;
|
||||
m_->send_message (out, message);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageClient::WSPR_decode (bool is_new, QTime time, qint32 snr, float delta_time, Frequency frequency
|
||||
, qint32 drift, QString const& callsign, QString const& grid, qint32 power)
|
||||
, qint32 drift, QString const& callsign, QString const& grid, qint32 power
|
||||
, bool off_air)
|
||||
{
|
||||
if (m_->server_port_ && !m_->server_string_.isEmpty ())
|
||||
{
|
||||
QByteArray message;
|
||||
NetworkMessage::Builder out {&message, NetworkMessage::WSPRDecode, m_->id_, m_->schema_};
|
||||
out << is_new << time << snr << delta_time << frequency << drift << callsign.toUtf8 ()
|
||||
<< grid.toUtf8 () << power;
|
||||
<< grid.toUtf8 () << power << off_air;
|
||||
m_->send_message (out, message);
|
||||
}
|
||||
}
|
||||
|
@ -403,17 +407,18 @@ void MessageClient::clear_decodes ()
|
|||
}
|
||||
}
|
||||
|
||||
void MessageClient::qso_logged (QDateTime timeOff, QString const& dx_call, QString const& dx_grid
|
||||
void MessageClient::qso_logged (QDateTime time_off, QString const& dx_call, QString const& dx_grid
|
||||
, Frequency dial_frequency, QString const& mode, QString const& report_sent
|
||||
, QString const& report_received, QString const& tx_power
|
||||
, QString const& comments, QString const& name, QDateTime timeOn)
|
||||
, QString const& comments, QString const& name, QDateTime time_on)
|
||||
{
|
||||
if (m_->server_port_ && !m_->server_string_.isEmpty ())
|
||||
{
|
||||
QByteArray message;
|
||||
NetworkMessage::Builder out {&message, NetworkMessage::QSOLogged, m_->id_, m_->schema_};
|
||||
out << timeOff << dx_call.toUtf8 () << dx_grid.toUtf8 () << dial_frequency << mode.toUtf8 ()
|
||||
<< report_sent.toUtf8 () << report_received.toUtf8 () << tx_power.toUtf8 () << comments.toUtf8 () << name.toUtf8 () << timeOn;
|
||||
out << time_off << dx_call.toUtf8 () << dx_grid.toUtf8 () << dial_frequency << mode.toUtf8 ()
|
||||
<< report_sent.toUtf8 () << report_received.toUtf8 () << tx_power.toUtf8 () << comments.toUtf8 ()
|
||||
<< name.toUtf8 () << time_on;
|
||||
m_->send_message (out, message);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,14 +53,16 @@ public:
|
|||
, QString const& dx_grid, bool watchdog_timeout, QString const& sub_mode
|
||||
, bool fast_mode);
|
||||
Q_SLOT void decode (bool is_new, QTime time, qint32 snr, float delta_time, quint32 delta_frequency
|
||||
, QString const& mode, QString const& message, bool low_confidence);
|
||||
, QString const& mode, QString const& message, bool low_confidence
|
||||
, bool off_air);
|
||||
Q_SLOT void WSPR_decode (bool is_new, QTime time, qint32 snr, float delta_time, Frequency
|
||||
, qint32 drift, QString const& callsign, QString const& grid, qint32 power);
|
||||
, qint32 drift, QString const& callsign, QString const& grid, qint32 power
|
||||
, bool off_air);
|
||||
Q_SLOT void clear_decodes ();
|
||||
Q_SLOT void qso_logged (QDateTime timeOff, QString const& dx_call, QString const& dx_grid
|
||||
Q_SLOT void qso_logged (QDateTime time_off, QString const& dx_call, QString const& dx_grid
|
||||
, Frequency dial_frequency, QString const& mode, QString const& report_sent
|
||||
, QString const& report_received, QString const& tx_power, QString const& comments
|
||||
, QString const& name, QDateTime timeOn);
|
||||
, QString const& name, QDateTime time_on);
|
||||
|
||||
// this slot may be used to send arbitrary UDP datagrams to and
|
||||
// destination allowing the underlying socket to be used for general
|
||||
|
@ -70,7 +72,7 @@ public:
|
|||
// this signal is emitted if the server sends us a reply, the only
|
||||
// reply supported is reply to a prior CQ or QRZ message
|
||||
Q_SIGNAL void reply (QTime, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode
|
||||
, QString const& message_text, bool low_confidence);
|
||||
, QString const& message_text, bool low_confidence, quint8 modifiers);
|
||||
|
||||
// this signal is emitted if the server has requested a replay of
|
||||
// all decodes
|
||||
|
|
|
@ -241,14 +241,15 @@ void MessageServer::impl::parse_message (QHostAddress const& sender, port_type s
|
|||
quint32 delta_frequency;
|
||||
QByteArray mode;
|
||||
QByteArray message;
|
||||
bool low_confidence;
|
||||
bool low_confidence {false};
|
||||
bool off_air {false};
|
||||
in >> is_new >> time >> snr >> delta_time >> delta_frequency >> mode
|
||||
>> message >> low_confidence;
|
||||
>> message >> low_confidence >> off_air;
|
||||
if (check_status (in) != Fail)
|
||||
{
|
||||
Q_EMIT self_->decode (is_new, id, time, snr, delta_time, delta_frequency
|
||||
, QString::fromUtf8 (mode), QString::fromUtf8 (message)
|
||||
, low_confidence);
|
||||
, low_confidence, off_air);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -265,18 +266,21 @@ void MessageServer::impl::parse_message (QHostAddress const& sender, port_type s
|
|||
QByteArray callsign;
|
||||
QByteArray grid;
|
||||
qint32 power;
|
||||
in >> is_new >> time >> snr >> delta_time >> frequency >> drift >> callsign >> grid >> power;
|
||||
bool off_air {false};
|
||||
in >> is_new >> time >> snr >> delta_time >> frequency >> drift >> callsign >> grid >> power
|
||||
>> off_air;
|
||||
if (check_status (in) != Fail)
|
||||
{
|
||||
Q_EMIT self_->WSPR_decode (is_new, id, time, snr, delta_time, frequency, drift
|
||||
, QString::fromUtf8 (callsign), QString::fromUtf8 (grid), power);
|
||||
, QString::fromUtf8 (callsign), QString::fromUtf8 (grid)
|
||||
, power, off_air);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NetworkMessage::QSOLogged:
|
||||
{
|
||||
QDateTime timeOff;
|
||||
QDateTime time_off;
|
||||
QByteArray dx_call;
|
||||
QByteArray dx_grid;
|
||||
Frequency dial_frequency;
|
||||
|
@ -286,15 +290,15 @@ void MessageServer::impl::parse_message (QHostAddress const& sender, port_type s
|
|||
QByteArray tx_power;
|
||||
QByteArray comments;
|
||||
QByteArray name;
|
||||
QDateTime timeOn; // Note: LOTW uses TIME_ON for their +/- 30-minute time window
|
||||
in >> timeOff >> dx_call >> dx_grid >> dial_frequency >> mode >> report_sent >> report_received
|
||||
>> tx_power >> comments >> name >> timeOn;
|
||||
QDateTime time_on; // Note: LOTW uses TIME_ON for their +/- 30-minute time window
|
||||
in >> time_off >> dx_call >> dx_grid >> dial_frequency >> mode >> report_sent >> report_received
|
||||
>> tx_power >> comments >> name >> time_on;
|
||||
if (check_status (in) != Fail)
|
||||
{
|
||||
Q_EMIT self_->qso_logged (id, timeOff, QString::fromUtf8 (dx_call), QString::fromUtf8 (dx_grid)
|
||||
Q_EMIT self_->qso_logged (id, time_off, QString::fromUtf8 (dx_call), QString::fromUtf8 (dx_grid)
|
||||
, dial_frequency, QString::fromUtf8 (mode), QString::fromUtf8 (report_sent)
|
||||
, QString::fromUtf8 (report_received), QString::fromUtf8 (tx_power)
|
||||
, QString::fromUtf8 (comments), QString::fromUtf8 (name), timeOn);
|
||||
, QString::fromUtf8 (comments), QString::fromUtf8 (name), time_on);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -399,7 +403,9 @@ void MessageServer::start (port_type port, QHostAddress const& multicast_group_a
|
|||
}
|
||||
}
|
||||
|
||||
void MessageServer::reply (QString const& id, QTime time, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode, QString const& message_text, bool low_confidence)
|
||||
void MessageServer::reply (QString const& id, QTime time, qint32 snr, float delta_time
|
||||
, quint32 delta_frequency, QString const& mode
|
||||
, QString const& message_text, bool low_confidence, quint8 modifiers)
|
||||
{
|
||||
auto iter = m_->clients_.find (id);
|
||||
if (iter != std::end (m_->clients_))
|
||||
|
@ -407,7 +413,7 @@ void MessageServer::reply (QString const& id, QTime time, qint32 snr, float delt
|
|||
QByteArray message;
|
||||
NetworkMessage::Builder out {&message, NetworkMessage::Reply, id, (*iter).negotiated_schema_number_};
|
||||
out << time << snr << delta_time << delta_frequency << mode.toUtf8 ()
|
||||
<< message_text.toUtf8 () << low_confidence;
|
||||
<< message_text.toUtf8 () << low_confidence << modifiers;
|
||||
m_->send_message (out, message, iter.value ().sender_address_, (*iter).sender_port_);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
// note that the client is not obliged to take any action and only
|
||||
// takes any action if the decode is present and is a CQ or QRZ message
|
||||
Q_SLOT void reply (QString const& id, QTime time, qint32 snr, float delta_time, quint32 delta_frequency
|
||||
, QString const& mode, QString const& message, bool low_confidence);
|
||||
, QString const& mode, QString const& message, bool low_confidence, quint8 modifiers);
|
||||
|
||||
// ask the client with identification 'id' to replay all decodes
|
||||
Q_SLOT void replay (QString const& id);
|
||||
|
@ -70,13 +70,14 @@ public:
|
|||
Q_SIGNAL void client_closed (QString const& id);
|
||||
Q_SIGNAL void decode (bool is_new, QString const& id, QTime time, qint32 snr, float delta_time
|
||||
, quint32 delta_frequency, QString const& mode, QString const& message
|
||||
, bool low_confidence);
|
||||
, bool low_confidence, bool off_air);
|
||||
Q_SIGNAL void WSPR_decode (bool is_new, QString const& id, QTime time, qint32 snr, float delta_time, Frequency
|
||||
, qint32 drift, QString const& callsign, QString const& grid, qint32 power);
|
||||
Q_SIGNAL void qso_logged (QString const& id, QDateTime timeOff, QString const& dx_call, QString const& dx_grid
|
||||
, qint32 drift, QString const& callsign, QString const& grid, qint32 power
|
||||
, bool off_air);
|
||||
Q_SIGNAL void qso_logged (QString const& id, QDateTime time_off, QString const& dx_call, QString const& dx_grid
|
||||
, Frequency dial_frequency, QString const& mode, QString const& report_sent
|
||||
, QString const& report_received, QString const& tx_power, QString const& comments
|
||||
, QString const& name, QDateTime timeOn);
|
||||
, QString const& name, QDateTime time_on);
|
||||
Q_SIGNAL void clear_decodes (QString const& id);
|
||||
|
||||
// this signal is emitted when a network error occurs
|
||||
|
|
|
@ -157,6 +157,7 @@
|
|||
* Mode utf8
|
||||
* Message utf8
|
||||
* Low confidence bool
|
||||
* Off air bool
|
||||
*
|
||||
* The decode message is sent when a new decode is completed, in
|
||||
* this case the 'New' field is true. It is also used in response
|
||||
|
@ -168,7 +169,8 @@
|
|||
* has knows that a decode has a higher than normal probability
|
||||
* of being false, they should not be reported on publicly
|
||||
* accessible services without some attached warning or further
|
||||
* validation.
|
||||
* validation. Off air decodes are those that result from playing
|
||||
* back a .WAV file.
|
||||
*
|
||||
*
|
||||
* Clear Out 3 quint32
|
||||
|
@ -191,6 +193,7 @@
|
|||
* Mode utf8
|
||||
* Message utf8
|
||||
* Low confidence bool
|
||||
* Modifiers quint8
|
||||
*
|
||||
* In order for a server to provide a useful cooperative service
|
||||
* to WSJT-X it is possible for it to initiate a QSO by sending
|
||||
|
@ -207,6 +210,19 @@
|
|||
* initiation the rest of the QSO is carried out manually using
|
||||
* the normal WSJT-X user interface.
|
||||
*
|
||||
* The Modifiers field allows the equivalent of keyboard
|
||||
* modifiers to be sent "as if" those modifier keys where pressed
|
||||
* while double-clicking the specified decoded message. The
|
||||
* modifier values (hexadecimal) are as follows:
|
||||
*
|
||||
* no modifier 0x00
|
||||
* SHIFT 0x02
|
||||
* CTRL 0x04 CMD on Mac
|
||||
* ALT 0x08
|
||||
* META 0x10 Windows key on MS Windows
|
||||
* KEYPAD 0x20 Keypad or arrows
|
||||
* Group switch 0x40 X11 only
|
||||
*
|
||||
*
|
||||
* QSO Logged Out 5 quint32
|
||||
* Id (unique key) utf8
|
||||
|
@ -299,13 +315,16 @@
|
|||
* Callsign utf8
|
||||
* Grid utf8
|
||||
* Power (dBm) qint32
|
||||
* Off air bool
|
||||
*
|
||||
* The decode message is sent when a new decode is completed, in
|
||||
* this case the 'New' field is true. It is also used in response
|
||||
* to a "Replay" message where each old decode in the "Band
|
||||
* activity" window, that has not been erased, is sent in order
|
||||
* as a one of these messages with the 'New' field set to
|
||||
* false. See the "Replay" message below for details of usage.
|
||||
* false. See the "Replay" message below for details of
|
||||
* usage. The off air field indicates that the decode was decoded
|
||||
* from a played back recording.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -12,16 +12,22 @@ namespace
|
|||
QT_TRANSLATE_NOOP ("BeaconsModel", "DT"),
|
||||
QT_TRANSLATE_NOOP ("BeaconsModel", "Frequency"),
|
||||
QT_TRANSLATE_NOOP ("BeaconsModel", "Drift"),
|
||||
QT_TRANSLATE_NOOP ("BeaconsModel", "Callsign"),
|
||||
QT_TRANSLATE_NOOP ("BeaconsModel", "Grid"),
|
||||
QT_TRANSLATE_NOOP ("BeaconsModel", "Power"),
|
||||
QT_TRANSLATE_NOOP ("BeaconsModel", "Live"),
|
||||
QT_TRANSLATE_NOOP ("BeaconsModel", "Callsign"),
|
||||
};
|
||||
|
||||
QString live_string (bool off_air)
|
||||
{
|
||||
return off_air ? QT_TRANSLATE_NOOP ("BeaconsModel", "no") : QT_TRANSLATE_NOOP ("BeaconsModel", "yes");
|
||||
}
|
||||
|
||||
QFont text_font {"Courier", 10};
|
||||
|
||||
QList<QStandardItem *> make_row (QString const& client_id, QTime time, qint32 snr, float delta_time
|
||||
, Frequency frequency, qint32 drift, QString const& callsign
|
||||
, QString const& grid, qint32 power)
|
||||
, QString const& grid, qint32 power, bool off_air)
|
||||
{
|
||||
auto time_item = new QStandardItem {time.toString ("hh:mm")};
|
||||
time_item->setData (time);
|
||||
|
@ -50,8 +56,11 @@ namespace
|
|||
pwr->setData (power);
|
||||
pwr->setTextAlignment (Qt::AlignRight);
|
||||
|
||||
auto live = new QStandardItem {live_string (off_air)};
|
||||
live->setTextAlignment (Qt::AlignHCenter);
|
||||
|
||||
QList<QStandardItem *> row {
|
||||
new QStandardItem {client_id}, time_item, snr_item, dt, freq, dri, new QStandardItem {callsign}, gd, pwr};
|
||||
new QStandardItem {client_id}, time_item, snr_item, dt, freq, dri, gd, pwr, live, new QStandardItem {callsign}};
|
||||
Q_FOREACH (auto& item, row)
|
||||
{
|
||||
item->setEditable (false);
|
||||
|
@ -63,7 +72,7 @@ namespace
|
|||
}
|
||||
|
||||
BeaconsModel::BeaconsModel (QObject * parent)
|
||||
: QStandardItemModel {0, 9, parent}
|
||||
: QStandardItemModel {0, sizeof (headings) / sizeof (headings[0]), parent}
|
||||
{
|
||||
int column {0};
|
||||
for (auto const& heading : headings)
|
||||
|
@ -74,7 +83,7 @@ BeaconsModel::BeaconsModel (QObject * parent)
|
|||
|
||||
void BeaconsModel::add_beacon_spot (bool is_new, QString const& client_id, QTime time, qint32 snr, float delta_time
|
||||
, Frequency frequency, qint32 drift, QString const& callsign
|
||||
, QString const& grid, qint32 power)
|
||||
, QString const& grid, qint32 power, bool off_air)
|
||||
{
|
||||
if (!is_new)
|
||||
{
|
||||
|
@ -89,9 +98,10 @@ void BeaconsModel::add_beacon_spot (bool is_new, QString const& client_id, QTime
|
|||
&& item (row, 3)->data ().toFloat () == delta_time
|
||||
&& item (row, 4)->data ().value<Frequency> () == frequency
|
||||
&& data (index (row, 5)).toInt () == drift
|
||||
&& data (index (row, 6)).toString () == callsign
|
||||
&& data (index (row, 7)).toString () == grid
|
||||
&& data (index (row, 8)).toInt () == power)
|
||||
&& data (index (row, 8)).toInt () == power
|
||||
&& data (index (row, 6)).toString () == live_string (off_air)
|
||||
&& data (index (row, 9)).toString () == callsign)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -103,12 +113,12 @@ void BeaconsModel::add_beacon_spot (bool is_new, QString const& client_id, QTime
|
|||
}
|
||||
if (target_row >= 0)
|
||||
{
|
||||
insertRow (target_row + 1, make_row (client_id, time, snr, delta_time, frequency, drift, callsign, grid, power));
|
||||
insertRow (target_row + 1, make_row (client_id, time, snr, delta_time, frequency, drift, callsign, grid, power, off_air));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
appendRow (make_row (client_id, time, snr, delta_time, frequency, drift, callsign, grid, power));
|
||||
appendRow (make_row (client_id, time, snr, delta_time, frequency, drift, callsign, grid, power, off_air));
|
||||
}
|
||||
|
||||
void BeaconsModel::clear_decodes (QString const& client_id)
|
||||
|
|
|
@ -31,7 +31,7 @@ public:
|
|||
|
||||
Q_SLOT void add_beacon_spot (bool is_new, QString const& client_id, QTime time, qint32 snr, float delta_time
|
||||
, Frequency frequency, qint32 drift, QString const& callsign, QString const& grid
|
||||
, qint32 power);
|
||||
, qint32 power, bool off_air);
|
||||
Q_SLOT void clear_decodes (QString const& client_id);
|
||||
};
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ QVariant ClientWidget::IdFilterModel::data (QModelIndex const& proxy_index, int
|
|||
{
|
||||
switch (proxy_index.column ())
|
||||
{
|
||||
case 6: // message
|
||||
case 8: // message
|
||||
{
|
||||
auto message = QSortFilterProxyModel::data (proxy_index).toString ();
|
||||
if (base_call_re_.pattern ().size ()
|
||||
|
@ -130,6 +130,7 @@ ClientWidget::ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemMod
|
|||
, rx_df_label_ {new QLabel}
|
||||
, tx_df_label_ {new QLabel}
|
||||
, report_label_ {new QLabel}
|
||||
, columns_resized_ {false}
|
||||
{
|
||||
// set up widgets
|
||||
decodes_proxy_model_.setSourceModel (decodes_model);
|
||||
|
@ -208,7 +209,7 @@ ClientWidget::ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemMod
|
|||
|
||||
// connect up table view signals
|
||||
connect (decodes_table_view_, &QTableView::doubleClicked, this, [this] (QModelIndex const& index) {
|
||||
Q_EMIT do_reply (decodes_proxy_model_.mapToSource (index));
|
||||
Q_EMIT do_reply (decodes_proxy_model_.mapToSource (index), QApplication::keyboardModifiers () >> 24);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -244,25 +245,36 @@ void ClientWidget::update_status (QString const& id, Frequency f, QString const&
|
|||
|
||||
void ClientWidget::decode_added (bool /*is_new*/, QString const& client_id, QTime /*time*/, qint32 /*snr*/
|
||||
, float /*delta_time*/, quint32 /*delta_frequency*/, QString const& /*mode*/
|
||||
, QString const& /*message*/, bool /*low_confidence*/)
|
||||
, QString const& /*message*/, bool /*low_confidence*/, bool /*off_air*/)
|
||||
{
|
||||
if (client_id == id_)
|
||||
if (client_id == id_ && !columns_resized_)
|
||||
{
|
||||
decodes_stack_->setCurrentIndex (0);
|
||||
decodes_table_view_->resizeColumnsToContents ();
|
||||
decodes_table_view_->scrollToBottom ();
|
||||
columns_resized_ = true;
|
||||
}
|
||||
decodes_table_view_->scrollToBottom ();
|
||||
}
|
||||
|
||||
void ClientWidget::beacon_spot_added (bool /*is_new*/, QString const& client_id, QTime /*time*/, qint32 /*snr*/
|
||||
, float /*delta_time*/, Frequency /*delta_frequency*/, qint32 /*drift*/
|
||||
, QString const& /*callsign*/, QString const& /*grid*/, qint32 /*power*/)
|
||||
, QString const& /*callsign*/, QString const& /*grid*/, qint32 /*power*/
|
||||
, bool /*off_air*/)
|
||||
{
|
||||
if (client_id == id_)
|
||||
if (client_id == id_ && !columns_resized_)
|
||||
{
|
||||
decodes_stack_->setCurrentIndex (1);
|
||||
beacons_table_view_->resizeColumnsToContents ();
|
||||
beacons_table_view_->scrollToBottom ();
|
||||
columns_resized_ = true;
|
||||
}
|
||||
beacons_table_view_->scrollToBottom ();
|
||||
}
|
||||
|
||||
void ClientWidget::clear_decodes (QString const& client_id)
|
||||
{
|
||||
if (client_id == id_)
|
||||
{
|
||||
columns_resized_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,12 +33,14 @@ public:
|
|||
, bool watchdog_timeout, QString const& sub_mode, bool fast_mode);
|
||||
Q_SLOT void decode_added (bool is_new, QString const& client_id, QTime, qint32 snr
|
||||
, float delta_time, quint32 delta_frequency, QString const& mode
|
||||
, QString const& message, bool low_confidence);
|
||||
, QString const& message, bool low_confidence, bool off_air);
|
||||
Q_SLOT void beacon_spot_added (bool is_new, QString const& client_id, QTime, qint32 snr
|
||||
, float delta_time, Frequency delta_frequency, qint32 drift
|
||||
, QString const& callsign, QString const& grid, qint32 power);
|
||||
, QString const& callsign, QString const& grid, qint32 power
|
||||
, bool off_air);
|
||||
Q_SLOT void clear_decodes (QString const& client_id);
|
||||
|
||||
Q_SIGNAL void do_reply (QModelIndex const&);
|
||||
Q_SIGNAL void do_reply (QModelIndex const&, quint8 modifier);
|
||||
Q_SIGNAL void do_halt_tx (QString const& id, bool auto_only);
|
||||
Q_SIGNAL void do_free_text (QString const& id, QString const& text, bool);
|
||||
|
||||
|
@ -77,6 +79,7 @@ private:
|
|||
QLabel * rx_df_label_;
|
||||
QLabel * tx_df_label_;
|
||||
QLabel * report_label_;
|
||||
bool columns_resized_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -16,8 +16,9 @@ namespace
|
|||
QT_TRANSLATE_NOOP ("DecodesModel", "DT"),
|
||||
QT_TRANSLATE_NOOP ("DecodesModel", "DF"),
|
||||
QT_TRANSLATE_NOOP ("DecodesModel", "Md"),
|
||||
QT_TRANSLATE_NOOP ("DecodesModel", "Message"),
|
||||
QT_TRANSLATE_NOOP ("DecodesModel", "Confidence"),
|
||||
QT_TRANSLATE_NOOP ("DecodesModel", "Live"),
|
||||
QT_TRANSLATE_NOOP ("DecodesModel", "Message"),
|
||||
};
|
||||
|
||||
QString confidence_string (bool low_confidence)
|
||||
|
@ -25,11 +26,16 @@ namespace
|
|||
return low_confidence ? QT_TRANSLATE_NOOP ("DecodesModel", "low") : QT_TRANSLATE_NOOP ("DecodesModel", "high");
|
||||
}
|
||||
|
||||
QString live_string (bool off_air)
|
||||
{
|
||||
return off_air ? QT_TRANSLATE_NOOP ("DecodesModel", "no") : QT_TRANSLATE_NOOP ("DecodesModel", "yes");
|
||||
}
|
||||
|
||||
QFont text_font {"Courier", 10};
|
||||
|
||||
QList<QStandardItem *> make_row (QString const& client_id, QTime time, qint32 snr, float delta_time
|
||||
, quint32 delta_frequency, QString const& mode, QString const& message
|
||||
, bool low_confidence, bool is_fast)
|
||||
, bool low_confidence, bool off_air, bool is_fast)
|
||||
{
|
||||
auto time_item = new QStandardItem {time.toString (is_fast || "~" == mode ? "hh:mm:ss" : "hh:mm")};
|
||||
time_item->setData (time);
|
||||
|
@ -53,8 +59,11 @@ namespace
|
|||
auto confidence = new QStandardItem {confidence_string (low_confidence)};
|
||||
confidence->setTextAlignment (Qt::AlignHCenter);
|
||||
|
||||
auto live = new QStandardItem {live_string (off_air)};
|
||||
live->setTextAlignment (Qt::AlignHCenter);
|
||||
|
||||
QList<QStandardItem *> row {
|
||||
new QStandardItem {client_id}, time_item, snr_item, dt, df, md, new QStandardItem {message}, confidence};
|
||||
new QStandardItem {client_id}, time_item, snr_item, dt, df, md, confidence, live, new QStandardItem {message}};
|
||||
Q_FOREACH (auto& item, row)
|
||||
{
|
||||
item->setEditable (false);
|
||||
|
@ -77,7 +86,7 @@ DecodesModel::DecodesModel (QObject * parent)
|
|||
|
||||
void DecodesModel::add_decode (bool is_new, QString const& client_id, QTime time, qint32 snr, float delta_time
|
||||
, quint32 delta_frequency, QString const& mode, QString const& message
|
||||
, bool low_confidence, bool is_fast)
|
||||
, bool low_confidence, bool off_air, bool is_fast)
|
||||
{
|
||||
if (!is_new)
|
||||
{
|
||||
|
@ -92,8 +101,9 @@ void DecodesModel::add_decode (bool is_new, QString const& client_id, QTime time
|
|||
&& item (row, 3)->data ().toFloat () == delta_time
|
||||
&& item (row, 4)->data ().toUInt () == delta_frequency
|
||||
&& data (index (row, 5)).toString () == mode
|
||||
&& data (index (row, 6)).toString () == message
|
||||
&& data (index (row, 7)).toString () == confidence_string (low_confidence))
|
||||
&& data (index (row, 7)).toString () == confidence_string (low_confidence)
|
||||
&& data (index (row, 6)).toString () == live_string (off_air)
|
||||
&& data (index (row, 8)).toString () == message)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -106,12 +116,13 @@ void DecodesModel::add_decode (bool is_new, QString const& client_id, QTime time
|
|||
if (target_row >= 0)
|
||||
{
|
||||
insertRow (target_row + 1, make_row (client_id, time, snr, delta_time, delta_frequency, mode
|
||||
, message, low_confidence, is_fast));
|
||||
, message, low_confidence, off_air, is_fast));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
appendRow (make_row (client_id, time, snr, delta_time, delta_frequency, mode, message, low_confidence, is_fast));
|
||||
appendRow (make_row (client_id, time, snr, delta_time, delta_frequency, mode, message, low_confidence
|
||||
, off_air, is_fast));
|
||||
}
|
||||
|
||||
void DecodesModel::clear_decodes (QString const& client_id)
|
||||
|
@ -125,7 +136,7 @@ void DecodesModel::clear_decodes (QString const& client_id)
|
|||
}
|
||||
}
|
||||
|
||||
void DecodesModel::do_reply (QModelIndex const& source)
|
||||
void DecodesModel::do_reply (QModelIndex const& source, quint8 modifiers)
|
||||
{
|
||||
auto row = source.row ();
|
||||
Q_EMIT reply (data (index (row, 0)).toString ()
|
||||
|
@ -134,8 +145,9 @@ void DecodesModel::do_reply (QModelIndex const& source)
|
|||
, item (row, 3)->data ().toFloat ()
|
||||
, item (row, 4)->data ().toInt ()
|
||||
, data (index (row, 5)).toString ()
|
||||
, data (index (row, 6)).toString ()
|
||||
, confidence_string (true) == data (index (row, 7)).toString ());
|
||||
, data (index (row, 8)).toString ()
|
||||
, confidence_string (true) == data (index (row, 7)).toString ()
|
||||
, modifiers);
|
||||
}
|
||||
|
||||
#include "moc_DecodesModel.cpp"
|
||||
|
|
|
@ -33,12 +33,12 @@ public:
|
|||
|
||||
Q_SLOT void add_decode (bool is_new, QString const& client_id, QTime time, qint32 snr, float delta_time
|
||||
, quint32 delta_frequency, QString const& mode, QString const& message
|
||||
, bool low_confidence, bool is_fast);
|
||||
, bool low_confidence, bool off_air, bool is_fast);
|
||||
Q_SLOT void clear_decodes (QString const& client_id);
|
||||
Q_SLOT void do_reply (QModelIndex const& source);
|
||||
Q_SLOT void do_reply (QModelIndex const& source, quint8 modifiers);
|
||||
|
||||
Q_SIGNAL void reply (QString const& id, QTime time, qint32 snr, float delta_time, quint32 delta_frequency
|
||||
, QString const& mode, QString const& message, bool low_confidence);
|
||||
, QString const& mode, QString const& message, bool low_confidence, quint8 modifiers);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -91,9 +91,10 @@ MessageAggregatorMainWindow::MessageAggregatorMainWindow ()
|
|||
connect (server_, &MessageServer::decode, [this] (bool is_new, QString const& id, QTime time
|
||||
, qint32 snr, float delta_time
|
||||
, quint32 delta_frequency, QString const& mode
|
||||
, QString const& message, bool low_confidence) {
|
||||
, QString const& message, bool low_confidence
|
||||
, bool off_air) {
|
||||
decodes_model_->add_decode (is_new, id, time, snr, delta_time, delta_frequency, mode, message
|
||||
, low_confidence, dock_widgets_[id]->fast_mode ());});
|
||||
, low_confidence, off_air, dock_widgets_[id]->fast_mode ());});
|
||||
connect (server_, &MessageServer::WSPR_decode, beacons_model_, &BeaconsModel::add_beacon_spot);
|
||||
connect (server_, &MessageServer::clear_decodes, decodes_model_, &DecodesModel::clear_decodes);
|
||||
connect (server_, &MessageServer::clear_decodes, beacons_model_, &BeaconsModel::clear_decodes);
|
||||
|
@ -110,14 +111,14 @@ MessageAggregatorMainWindow::MessageAggregatorMainWindow ()
|
|||
show ();
|
||||
}
|
||||
|
||||
void MessageAggregatorMainWindow::log_qso (QString const& /*id*/, QDateTime timeOff, QString const& dx_call, QString const& dx_grid
|
||||
void MessageAggregatorMainWindow::log_qso (QString const& /*id*/, QDateTime time_off, QString const& dx_call, QString const& dx_grid
|
||||
, Frequency dial_frequency, QString const& mode, QString const& report_sent
|
||||
, QString const& report_received, QString const& tx_power, QString const& comments
|
||||
, QString const& name, QDateTime timeOn)
|
||||
, QString const& name, QDateTime time_on)
|
||||
{
|
||||
QList<QStandardItem *> row;
|
||||
row << new QStandardItem {timeOn.toString ("dd-MMM-yyyy hh:mm:ss")}
|
||||
<< new QStandardItem {timeOff.toString ("dd-MMM-yyyy hh:mm:ss")}
|
||||
row << new QStandardItem {time_on.toString ("dd-MMM-yyyy hh:mm:ss")}
|
||||
<< new QStandardItem {time_off.toString ("dd-MMM-yyyy hh:mm:ss")}
|
||||
<< new QStandardItem {dx_call}
|
||||
<< new QStandardItem {dx_grid}
|
||||
<< new QStandardItem {name}
|
||||
|
@ -144,6 +145,7 @@ void MessageAggregatorMainWindow::add_client (QString const& id, QString const&
|
|||
connect (server_, &MessageServer::status_update, dock, &ClientWidget::update_status);
|
||||
connect (server_, &MessageServer::decode, dock, &ClientWidget::decode_added);
|
||||
connect (server_, &MessageServer::WSPR_decode, dock, &ClientWidget::beacon_spot_added);
|
||||
connect (server_, &MessageServer::clear_decodes, dock, &ClientWidget::clear_decodes);
|
||||
connect (dock, &ClientWidget::do_reply, decodes_model_, &DecodesModel::do_reply);
|
||||
connect (dock, &ClientWidget::do_halt_tx, server_, &MessageServer::halt_tx);
|
||||
connect (dock, &ClientWidget::do_free_text, server_, &MessageServer::free_text);
|
||||
|
|
|
@ -26,10 +26,10 @@ class MessageAggregatorMainWindow
|
|||
public:
|
||||
MessageAggregatorMainWindow ();
|
||||
|
||||
Q_SLOT void log_qso (QString const& /*id*/, QDateTime timeOff, QString const& dx_call, QString const& dx_grid
|
||||
Q_SLOT void log_qso (QString const& /*id*/, QDateTime time_off, QString const& dx_call, QString const& dx_grid
|
||||
, Frequency dial_frequency, QString const& mode, QString const& report_sent
|
||||
, QString const& report_received, QString const& tx_power, QString const& comments
|
||||
, QString const& name, QDateTime timeOn);
|
||||
, QString const& name, QDateTime time_on);
|
||||
|
||||
private:
|
||||
void add_client (QString const& id, QString const& version, QString const& revision);
|
||||
|
|
|
@ -68,28 +68,30 @@ public:
|
|||
}
|
||||
|
||||
Q_SLOT void decode_added (bool is_new, QString const& client_id, QTime time, qint32 snr
|
||||
, float delta_time, quint32 delta_frequency, QString const& mode
|
||||
, QString const& message, bool low_confidence)
|
||||
, float delta_time, quint32 delta_frequency, QString const& mode
|
||||
, QString const& message, bool low_confidence, bool off_air)
|
||||
{
|
||||
if (client_id == id_)
|
||||
{
|
||||
qDebug () << "new:" << is_new << "t:" << time << "snr:" << snr
|
||||
<< "Dt:" << delta_time << "Df:" << delta_frequency
|
||||
<< "mode:" << mode << "Confidence:" << (low_confidence ? "low" : "high");
|
||||
<< "mode:" << mode << "Confidence:" << (low_confidence ? "low" : "high")
|
||||
<< "On air:" << !off_air;
|
||||
std::cout << tr ("%1: Decoded %2").arg (id_).arg (message).toStdString () << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
Q_SLOT void beacon_spot_added (bool is_new, QString const& client_id, QTime time, qint32 snr
|
||||
, float delta_time, Frequency delta_frequency, qint32 drift, QString const& callsign
|
||||
, QString const& grid, qint32 power)
|
||||
, QString const& grid, qint32 power, bool off_air)
|
||||
{
|
||||
if (client_id == id_)
|
||||
{
|
||||
qDebug () << "new:" << is_new << "t:" << time << "snr:" << snr
|
||||
<< "Dt:" << delta_time << "Df:" << delta_frequency
|
||||
<< "drift:" << drift;
|
||||
std::cout << tr ("%1: WSPR decode %2 grid %3 power: %4").arg (id_).arg (callsign).arg (grid).arg (power).toStdString () << std::endl;
|
||||
std::cout << tr ("%1: WSPR decode %2 grid %3 power: %4").arg (id_).arg (callsign).arg (grid).arg (power).toStdString ()
|
||||
<< "On air:" << !off_air << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <QSettings>
|
||||
#include <QDateTime>
|
||||
#include <QDir>
|
||||
#include <QCloseEvent>
|
||||
#include <QDebug>
|
||||
|
||||
#include "commons.h"
|
||||
|
@ -56,7 +57,7 @@ Astro::~Astro ()
|
|||
void Astro::closeEvent (QCloseEvent * e)
|
||||
{
|
||||
write_settings ();
|
||||
QWidget::closeEvent (e);
|
||||
e->ignore (); // do not allow closure by the window system
|
||||
}
|
||||
|
||||
void Astro::read_settings ()
|
||||
|
|
|
@ -14,14 +14,13 @@ namespace
|
|||
}
|
||||
|
||||
DecodedText::DecodedText (QString const& the_string, bool contest_mode, QString const& my_grid)
|
||||
: string_ {the_string}
|
||||
, padding_ {the_string.indexOf (" ") > 4 ? 2 : 0} // allow for
|
||||
: string_ {the_string.left (the_string.indexOf (QChar::Nbsp))} // discard appended info
|
||||
, padding_ {string_.indexOf (" ") > 4 ? 2 : 0} // allow for
|
||||
// seconds
|
||||
, contest_mode_ {contest_mode}
|
||||
, message_ {string_.mid (column_qsoText + padding_).trimmed ()}
|
||||
, is_standard_ {false}
|
||||
{
|
||||
string_ = string_.left (column_qsoText + padding_ + 25);
|
||||
if (message_.length() >= 1)
|
||||
{
|
||||
message_ = message_.left (21).remove (QRegularExpression {"[<>]"});
|
||||
|
|
178
displaytext.cpp
|
@ -5,18 +5,39 @@
|
|||
#include <QTextCharFormat>
|
||||
#include <QTextCursor>
|
||||
#include <QTextBlock>
|
||||
#include <QMenu>
|
||||
#include <QAction>
|
||||
|
||||
#include "qt_helpers.hpp"
|
||||
|
||||
#include "moc_displaytext.cpp"
|
||||
|
||||
DisplayText::DisplayText(QWidget *parent) :
|
||||
QTextEdit(parent)
|
||||
DisplayText::DisplayText(QWidget *parent)
|
||||
: QTextEdit(parent)
|
||||
, erase_action_ {new QAction {tr ("&Erase"), this}}
|
||||
{
|
||||
setReadOnly (true);
|
||||
viewport ()->setCursor (Qt::ArrowCursor);
|
||||
setWordWrapMode (QTextOption::NoWrap);
|
||||
document ()->setMaximumBlockCount (5000); // max lines to limit heap usage
|
||||
|
||||
// max lines to limit heap usage
|
||||
document ()->setMaximumBlockCount (5000);
|
||||
|
||||
// context menu erase action
|
||||
setContextMenuPolicy (Qt::CustomContextMenu);
|
||||
connect (this, &DisplayText::customContextMenuRequested, [this] (QPoint const& position) {
|
||||
auto * menu = createStandardContextMenu (position);
|
||||
menu->addAction (erase_action_);
|
||||
menu->exec (mapToGlobal (position));
|
||||
delete menu;
|
||||
});
|
||||
connect (erase_action_, &QAction::triggered, this, &DisplayText::erase);
|
||||
}
|
||||
|
||||
void DisplayText::erase ()
|
||||
{
|
||||
clear ();
|
||||
Q_EMIT erased ();
|
||||
}
|
||||
|
||||
void DisplayText::setContentFont(QFont const& font)
|
||||
|
@ -42,9 +63,7 @@ void DisplayText::setContentFont(QFont const& font)
|
|||
|
||||
void DisplayText::mouseDoubleClickEvent(QMouseEvent *e)
|
||||
{
|
||||
bool ctrl = (e->modifiers() & Qt::ControlModifier);
|
||||
bool alt = (e->modifiers() & Qt::AltModifier);
|
||||
emit(selectCallsign(alt,ctrl));
|
||||
Q_EMIT selectCallsign(e->modifiers ());
|
||||
QTextEdit::mouseDoubleClickEvent(e);
|
||||
}
|
||||
|
||||
|
@ -81,12 +100,12 @@ void DisplayText::appendText(QString const& text, QColor bg)
|
|||
|
||||
|
||||
QString DisplayText::appendDXCCWorkedB4(QString message, QString const& callsign, QColor * bg,
|
||||
LogBook const& logBook, QColor color_CQ,
|
||||
QColor color_DXCC,
|
||||
QColor color_NewCall)
|
||||
LogBook const& logBook, QColor color_CQ,
|
||||
QColor color_DXCC,
|
||||
QColor color_NewCall)
|
||||
{
|
||||
// allow for seconds
|
||||
unsigned padding {message.indexOf (" ") > 4 ? 2U : 0U};
|
||||
int padding {message.indexOf (" ") > 4 ? 2 : 0};
|
||||
QString call = callsign;
|
||||
QString countryName;
|
||||
bool callWorkedBefore;
|
||||
|
@ -102,64 +121,60 @@ QString DisplayText::appendDXCCWorkedB4(QString message, QString const& callsign
|
|||
if(!call.contains(QRegExp("[0-9]|[A-Z]"))) return message;
|
||||
|
||||
logBook.match(/*in*/call,/*out*/countryName,callWorkedBefore,countryWorkedBefore);
|
||||
int charsAvail = 52 + padding;
|
||||
|
||||
// the decoder (seems) to always generate 41 chars. For a normal CQ
|
||||
// call, the last five are spaces
|
||||
//
|
||||
// A maximum length call is "QRZ VP2X/GM4WJS IO91" "CQ AA ..." or CQ
|
||||
// nnn ..." don't allow grid squares so are not longer. Here we align
|
||||
// the added info at least after the longest CQ/QRZ message plus one
|
||||
// space so that it can be stripped off algorithmically later.
|
||||
//
|
||||
int nmin = 46 + padding;
|
||||
int s3 = message.indexOf (" ", nmin);
|
||||
if (s3 < nmin) s3 = nmin; // always want at least the characters to position 45
|
||||
s3 += 1; // convert the index into a character count
|
||||
message = message.left(s3); // reduce trailing white space
|
||||
charsAvail -= s3;
|
||||
if (charsAvail > 4)
|
||||
message = message.trimmed ();
|
||||
QString appendage;
|
||||
if (!countryWorkedBefore) // therefore not worked call either
|
||||
{
|
||||
if (!countryWorkedBefore) // therefore not worked call either
|
||||
appendage += "!";
|
||||
*bg = color_DXCC;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!callWorkedBefore) // but have worked the country
|
||||
{
|
||||
message += "!";
|
||||
*bg = color_DXCC;
|
||||
appendage += "~";
|
||||
*bg = color_NewCall;
|
||||
}
|
||||
else
|
||||
if (!callWorkedBefore) // but have worked the country
|
||||
{
|
||||
message += "~";
|
||||
*bg = color_NewCall;
|
||||
}
|
||||
else
|
||||
{
|
||||
message += " "; // have worked this call before
|
||||
*bg = color_CQ;
|
||||
}
|
||||
charsAvail -= 1;
|
||||
|
||||
// do some obvious abbreviations
|
||||
countryName.replace ("Islands", "Is.");
|
||||
countryName.replace ("Island", "Is.");
|
||||
countryName.replace ("North ", "N. ");
|
||||
countryName.replace ("Northern ", "N. ");
|
||||
countryName.replace ("South ", "S. ");
|
||||
countryName.replace ("East ", "E. ");
|
||||
countryName.replace ("Eastern ", "E. ");
|
||||
countryName.replace ("West ", "W. ");
|
||||
countryName.replace ("Western ", "W. ");
|
||||
countryName.replace ("Central ", "C. ");
|
||||
countryName.replace (" and ", " & ");
|
||||
countryName.replace ("Republic", "Rep.");
|
||||
countryName.replace ("United States", "U.S.A.");
|
||||
countryName.replace ("Fed. Rep. of ", "");
|
||||
countryName.replace ("French ", "Fr.");
|
||||
countryName.replace ("Asiatic", "AS");
|
||||
countryName.replace ("European", "EU");
|
||||
countryName.replace ("African", "AF");
|
||||
|
||||
message += countryName;
|
||||
{
|
||||
appendage += " "; // have worked this call before
|
||||
*bg = color_CQ;
|
||||
}
|
||||
}
|
||||
|
||||
// do some obvious abbreviations
|
||||
countryName.replace ("Islands", "Is.");
|
||||
countryName.replace ("Island", "Is.");
|
||||
countryName.replace ("North ", "N. ");
|
||||
countryName.replace ("Northern ", "N. ");
|
||||
countryName.replace ("South ", "S. ");
|
||||
countryName.replace ("East ", "E. ");
|
||||
countryName.replace ("Eastern ", "E. ");
|
||||
countryName.replace ("West ", "W. ");
|
||||
countryName.replace ("Western ", "W. ");
|
||||
countryName.replace ("Central ", "C. ");
|
||||
countryName.replace (" and ", " & ");
|
||||
countryName.replace ("Republic", "Rep.");
|
||||
countryName.replace ("United States", "U.S.A.");
|
||||
countryName.replace ("Fed. Rep. of ", "");
|
||||
countryName.replace ("French ", "Fr.");
|
||||
countryName.replace ("Asiatic", "AS");
|
||||
countryName.replace ("European", "EU");
|
||||
countryName.replace ("African", "AF");
|
||||
|
||||
appendage += countryName;
|
||||
|
||||
// use a nbsp to save the start of appended text so we can find
|
||||
// it again later, align appended data at a fixed column if
|
||||
// there is space otherwise let it float to the right
|
||||
int space_count {40 + padding - message.size ()};
|
||||
if (space_count > 0)
|
||||
{
|
||||
message += QString {space_count, QChar {' '}};
|
||||
}
|
||||
message += QChar::Nbsp + appendage;
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
|
@ -169,29 +184,30 @@ void DisplayText::displayDecodedText(DecodedText const& decodedText, QString con
|
|||
QColor color_DXCC, QColor color_NewCall)
|
||||
{
|
||||
QColor bg {Qt::white};
|
||||
bool CQcall = false;
|
||||
if (decodedText.string ().contains (" CQ ")
|
||||
|| decodedText.string ().contains (" CQDX ")
|
||||
|| decodedText.string ().contains (" QRZ "))
|
||||
bool CQcall = false;
|
||||
if (decodedText.string ().contains (" CQ ")
|
||||
|| decodedText.string ().contains (" CQDX ")
|
||||
|| decodedText.string ().contains (" QRZ "))
|
||||
{
|
||||
CQcall = true;
|
||||
bg = color_CQ;
|
||||
}
|
||||
if (myCall != "" and (
|
||||
decodedText.indexOf (" " + myCall + " ") >= 0
|
||||
or decodedText.indexOf (" " + myCall + "/") >= 0
|
||||
or decodedText.indexOf ("/" + myCall + " ") >= 0
|
||||
or decodedText.indexOf ("<" + myCall + " ") >= 0
|
||||
or decodedText.indexOf (" " + myCall + ">") >= 0)) {
|
||||
bg = color_MyCall;
|
||||
CQcall = true;
|
||||
bg = color_CQ;
|
||||
}
|
||||
if (myCall != "" and (
|
||||
decodedText.indexOf (" " + myCall + " ") >= 0
|
||||
or decodedText.indexOf (" " + myCall + "/") >= 0
|
||||
or decodedText.indexOf ("/" + myCall + " ") >= 0
|
||||
or decodedText.indexOf ("<" + myCall + " ") >= 0
|
||||
or decodedText.indexOf (" " + myCall + ">") >= 0)) {
|
||||
bg = color_MyCall;
|
||||
}
|
||||
auto message = decodedText.string ();
|
||||
message = message.left (message.indexOf (QChar::Nbsp)); // strip appended info
|
||||
if (displayDXCCEntity && CQcall)
|
||||
// if enabled add the DXCC entity and B4 status to the end of the
|
||||
// preformated text line t1
|
||||
auto message = decodedText.string ();
|
||||
if (displayDXCCEntity && CQcall)
|
||||
message = appendDXCCWorkedB4 (message, decodedText.CQersCall (), &bg, logBook, color_CQ,
|
||||
color_DXCC, color_NewCall);
|
||||
appendText (message, bg);
|
||||
message = appendDXCCWorkedB4 (message, decodedText.CQersCall (), &bg, logBook, color_CQ,
|
||||
color_DXCC, color_NewCall);
|
||||
appendText (message.trimmed (), bg);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include "logbook/logbook.h"
|
||||
#include "decodedtext.h"
|
||||
|
||||
class QAction;
|
||||
|
||||
class DisplayText
|
||||
: public QTextEdit
|
||||
{
|
||||
|
@ -24,9 +26,11 @@ public:
|
|||
QColor color_TxMsg, bool bFastMode);
|
||||
void displayQSY(QString text);
|
||||
|
||||
Q_SIGNAL void selectCallsign (bool alt, bool ctrl);
|
||||
Q_SIGNAL void selectCallsign (Qt::KeyboardModifiers);
|
||||
Q_SIGNAL void erased ();
|
||||
|
||||
Q_SLOT void appendText (QString const& text, QColor bg = Qt::white);
|
||||
Q_SLOT void erase ();
|
||||
|
||||
protected:
|
||||
void mouseDoubleClickEvent(QMouseEvent *e);
|
||||
|
@ -36,6 +40,7 @@ private:
|
|||
QColor color_CQ, QColor color_DXCC, QColor color_NewCall);
|
||||
|
||||
QFont char_font_;
|
||||
QAction * erase_action_;
|
||||
};
|
||||
|
||||
#endif // DISPLAYTEXT_H
|
||||
|
|
|
@ -34,6 +34,7 @@ set (UG_SRCS
|
|||
protocols.adoc
|
||||
logging.adoc
|
||||
make-qso.adoc
|
||||
measurement_tools.adoc
|
||||
new_features.adoc
|
||||
platform-dependencies.adoc
|
||||
protocols.adoc
|
||||
|
@ -72,11 +73,15 @@ set (UG_IMGS
|
|||
images/decodes.png
|
||||
images/download_samples.png
|
||||
images/file-menu.png
|
||||
images/FreqCal.png
|
||||
images/FreqCal_Graph.png
|
||||
images/FreqCal_Results.png
|
||||
images/freemsg.png
|
||||
images/ft8_decodes.png
|
||||
images/help-menu.png
|
||||
images/JT4F.png
|
||||
images/JT65B.png
|
||||
images/keyboard-shortcuts.png
|
||||
images/MSK144.png
|
||||
images/QRA64.png
|
||||
images/WSPR_WideGraphControls.png
|
||||
|
@ -109,6 +114,7 @@ set (UG_IMGS
|
|||
images/tools-menu.png
|
||||
images/traditional-msg-box.png
|
||||
images/tx-macros.png
|
||||
images/VHF_controls.png
|
||||
images/view-menu.png
|
||||
images/wide-graph-controls.png
|
||||
|
||||
|
|
|
@ -12,4 +12,18 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this documentation. If not, see {gnu_gpl}.
|
||||
|
||||
Copyright (C) 2001-2017 Joseph H Taylor, Jr., K1JT.
|
||||
Except where otherwise noted, all algorithms, protocol designs, source
|
||||
code, and supporting files contained in the _{prog}_ package are the
|
||||
intellectual property of the program's authors. The authors assert
|
||||
*Copyright ownership* of this material, whether or not such copyright
|
||||
notice appears in each individual file. Others who make fair use of
|
||||
our work under terms of the GNU General Public License must display
|
||||
the following copyright notice prominently:
|
||||
|
||||
*The algorithms, source code, look-and-feel of _{prog}_ and related
|
||||
programs, and protocol specifications for the modes FSK441, FT8, JT4,
|
||||
JT6M, JT9, JT65, JTMS, QRA64, ISCAT, and MSK144 are Copyright (C)
|
||||
2001-2017 by one or more of the following authors: Joseph Taylor,
|
||||
K1JT; Bill Somerville, G4WJS; Steven Franke, K9AN; Nico Palermo,
|
||||
IV3NWV; Greg Beam, KI7MT; Michael Black, W9MDB; Edson Pereira, PY2SDR;
|
||||
Philip Karn, KA9Q; and other members of the WSJT Development Group.*
|
||||
|
|
|
@ -67,6 +67,7 @@ d). Edit lines as needed. Keeping them in alphabetic order help see dupes.
|
|||
:fmt_group: https://groups.yahoo.com/neo/groups/FMT-nuts/info[FMT Group]
|
||||
:fmt_k5cm: http://www.k5cm.com/[FMT Event Info]
|
||||
:fmt_wspr: http://www.physics.princeton.edu/pulsar/K1JT/FMT_User.pdf[Accurate Frequency Measurements with your WSPR Setup]
|
||||
:ft8_tips: http://www.physics.princeton.edu/pulsar/K1JT/FT8_Operating_Tips.pdf[here]
|
||||
:gnu_gpl: http://www.gnu.org/licenses/gpl-3.0.txt[GNU General Public License]
|
||||
:homepage: http://physics.princeton.edu/pulsar/K1JT/[WSJT Home Page]
|
||||
:hrd: http://www.hrdsoftwarellc.com/[Ham Radio Deluxe]
|
||||
|
@ -76,6 +77,7 @@ d). Edit lines as needed. Keeping them in alphabetic order help see dupes.
|
|||
:launchpadki7mt: https://launchpad.net/~ki7mt[KI7MT PPA's]
|
||||
:log4om: http://www.log4om.com[Log4OM]
|
||||
:lunarEchoes: http://physics.princeton.edu/pulsar/K1JT/LunarEchoes_QEX.pdf[QEX]
|
||||
:msk144: http://physics.princeton.edu/pulsar/k1jt/MSK144_Protocol_QEX.pdf[QEX]
|
||||
:msys_url: http://sourceforge.net/projects/mingwbuilds/files/external-binary-packages/[MSYS Download]
|
||||
:ntpsetup: http://www.satsignal.eu/ntp/setup.html[Network Time Protocol Setup]
|
||||
:osx_instructions: http://physics.princeton.edu/pulsar/K1JT/OSX_Readme[Mac OS X Install Instructions]
|
||||
|
@ -107,6 +109,7 @@ d). Edit lines as needed. Keeping them in alphabetic order help see dupes.
|
|||
:QRA64_EME: http://physics.princeton.edu/pulsar/K1JT/QRA64_EME.pdf[QRA64 for microwave EME]
|
||||
:svn: http://subversion.apache.org/packages.html#windows[Subversion]
|
||||
:win32: http://physics.princeton.edu/pulsar/K1JT/wsjtx-{VERSION}-win32.exe[wsjtx-{VERSION}-win32.exe]
|
||||
:wsjt-devel: https://lists.sourceforge.net/lists/listinfo/wsjt-devel[here]
|
||||
:wsjt_svn: http://sourceforge.net/p/wsjt/wsjt/HEAD/tree/[WSJT Source Repository]
|
||||
:wspr_code: http://physics.princeton.edu/pulsar/K1JT/WSPRcode.exe[WSPRcode.exe]
|
||||
:wspr_svn: http://sourceforge.net/p/wsjt/wsjt/HEAD/tree/branches/wspr/[WSPR Source Repository]
|
||||
|
|
|
@ -5,7 +5,7 @@ and operation. Most of the items are self-explanatory; a few
|
|||
additional details are provided below. Keyboard shortcuts for some
|
||||
frequently used menu items are listed at the right edge of the menu.
|
||||
|
||||
==== WSJT-X menu
|
||||
==== _WSJT-X_ menu
|
||||
image::MacAppMenu.png[align="left",alt="Mac App Menu"]
|
||||
|
||||
This menu appears on the Macintosh only. *Settings* appears here,
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
// Status=review
|
||||
|
||||
The following controls appear at the bottom of the Wide Graph window.
|
||||
With the exception of *JT65 nnnn JT9* (when operating in JT9+JT65
|
||||
mode), they affect only the graphical displays. They have no effect
|
||||
on the decoding process.
|
||||
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.
|
||||
|
||||
image::wide-graph-controls.png[align="center",alt="Wide Graph Controls"]
|
||||
|
||||
|
|
|
@ -44,10 +44,11 @@ successful decode used MyCall as hypothetically known information.
|
|||
|===============================================
|
||||
|
||||
Table 2 lists the six possible QSO states that are tracked by the
|
||||
WSJT-X auto-sequencer, along with the type of AP decoding that would
|
||||
_WSJT-X_ auto-sequencer, along with the type of AP decoding that would
|
||||
be attempted in each state.
|
||||
|
||||
[[AP decoding types for each QSO state]]
|
||||
[[AP_DECODING_TYPES_TABLE]]
|
||||
.AP decoding types for each QSO state
|
||||
[width="35%",cols="h10,<m20",frame=topbot,options="header"]
|
||||
|===========================================
|
||||
|State |AP type
|
||||
|
|
|
@ -69,6 +69,9 @@ command-prompt window:
|
|||
sudo apt remove appmenu-qt5
|
||||
|
||||
+
|
||||
Alternatively, you can disable the common menu bar for just WSJT-X by starting the application with the environment variable QT_QPA_PLATFORMTHEME set to empty (the space after the '=' character is necessary):
|
||||
Alternatively, you can disable the common menu bar for just _WSJT-X_
|
||||
by starting the application with the environment variable
|
||||
QT_QPA_PLATFORMTHEME set to empty (the space after the '=' character
|
||||
is necessary):
|
||||
|
||||
QT_QPA_PLATFORMTHEME= wsjtx
|
||||
|
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 8.0 KiB |
Before Width: | Height: | Size: 162 KiB After Width: | Height: | Size: 170 KiB |
Before Width: | Height: | Size: 151 KiB After Width: | Height: | Size: 153 KiB |
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 88 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 82 KiB |
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.8 KiB |
|
@ -76,11 +76,11 @@ fully automated QSOs.
|
|||
|
||||
=== VHF Contest Mode
|
||||
|
||||
A special *VHF Contest Mode* can be activated for FT8 and MSK144 modes
|
||||
by checking a box on the *Settings | Advanced* tab. This mode is
|
||||
configured especially for VHF contests in which four-character grid
|
||||
locators are the required exchange. When *Contest Mode* is active,
|
||||
the standard QSO sequence looks like this:
|
||||
A special *NA VHF Contest* mode can be activated for FT8 and MSK144
|
||||
modes by checking a box on the main window. This mode is configured
|
||||
especially for contests in which four-character grid locators are the
|
||||
required exchange. When *NA VHF Contest* mode is active, the standard
|
||||
QSO sequence looks like this:
|
||||
|
||||
CQ K1ABC FN42
|
||||
K1ABC W9XYZ EN37
|
||||
|
|
|
@ -1,74 +1,226 @@
|
|||
=== Frequency Calibration
|
||||
|
||||
Many _WSJT-X_ capabilities depend on signal-detection bandwidths no
|
||||
more than a few Hz. Frequency accuracy and stability are therefore
|
||||
unusually important. We provide tools to enable accurate frequency
|
||||
calibration of your radio, as well as precise frequency measurement of
|
||||
on-the-air signals. The calibration procedure works by automatically
|
||||
cycling your CAT-controlled radio through a series of preset
|
||||
frequencies of carrier-based signals at reliably known frequencies,
|
||||
measuring the error in dial frequency for each signal.
|
||||
|
||||
You will probably find it convenient to define and use a special
|
||||
<<CONFIG-MENU,Configuration>> dedicated to frequency calibration.
|
||||
Then complete the following steps, as appropriate for your system.
|
||||
|
||||
- Switch to FreqCal mode
|
||||
|
||||
- In the _Working Frequencies_ box on the *Settings -> Frequencies*
|
||||
tab, delete any default frequencies for *FreqCal* mode that are not
|
||||
relevant for your location. You may want to replace some of them with
|
||||
reliably known frequencies receivable at your location.
|
||||
|
||||
TIP: We find major-city AM broadcast stations generally serve well as
|
||||
frequency calibrators at the low frequency end of the spectrum. In
|
||||
North America we also use the standard time-and-frequency broadcasts
|
||||
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
|
||||
in other parts of the world.
|
||||
|
||||
- During the calibration procedure, the radio's USB dial frequency is
|
||||
offset 1500 Hz below each *FreqCal* entry in the default frequencies
|
||||
list. As shown in the screen shot below, detected signal carriers
|
||||
therefore appear at about 1500 Hz in the WSJT-X waterfall.
|
||||
|
||||
image::FreqCal.png[align="left",alt="FreqCal"]
|
||||
|
||||
With modern synthesized radios, small measured offsets from 1500 Hz
|
||||
will exhibit a straight-line dependence on frequency. You can
|
||||
approximate the calibration of your radio by simply dividing the
|
||||
measured frequency offset (in Hz) at the highest reliable frequency by
|
||||
the nominal frequency itself (in MHz). For example, the 20 MHz
|
||||
measurement for WWV shown above produced a measured tone offset of
|
||||
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
|
||||
may be entered as *Slope* on the *settings -> Frequencies* tab.
|
||||
|
||||
A more precise calibration can be effected by fitting the intercept
|
||||
and slope of a straight line to the whole sequence of calibration
|
||||
measurements, as shown for these measurements in the graph plotted
|
||||
below. Software tools for completing this task are included with the
|
||||
_WSJT-X_ installation, and detailed instructions for their use are
|
||||
available at https://physics.princeton.edu/pulsar/k1jt/FMT_User.pdf.
|
||||
Using these tools and no specialized hardware beyond your
|
||||
CAT-interfaced radio, you can calibrate the radio to better than 1 Hz
|
||||
and compete very effectively in the ARRL's periodic Frequency
|
||||
Measuring Tests.
|
||||
|
||||
image::FreqCal_Graph.png[align="left",alt="FreqCal_Graph"]
|
||||
|
||||
=== Reference Spectrum
|
||||
|
||||
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
|
||||
a quiet frequency with no signals. With WSJT-X running in one of the
|
||||
slow modes, select *Measure reference spectrum* from the *Tools* menu.
|
||||
Wait for about a minute and then hit the *Stop* button. A file named
|
||||
`refspec.dat` will appear in your log directory.
|
||||
|
||||
[ ... TBD ... ]
|
||||
|
||||
=== Equalization
|
||||
|
||||
[ ... TBD ... ]
|
||||
|
||||
=== Frequency Calibration
|
||||
|
||||
Many _WSJT-X_ capabilities depend on signal-detection bandwidths no
|
||||
more than a few Hz. Frequency accuracy and stability are therefore
|
||||
unusually important. We provide tools to enable accurate frequency
|
||||
calibration of your radio, as well as precise frequency measurement of
|
||||
on-the-air signals. The calibration procedure works by automatically
|
||||
cycling your CAT-controlled radio through a series of preset
|
||||
frequencies of carrier-based signals at reliably known frequencies,
|
||||
measuring the error in dial frequency for each signal.
|
||||
|
||||
You will probably find it convenient to define and use a special
|
||||
<<CONFIG-MENU,Configuration>> dedicated to frequency calibration.
|
||||
Then complete the following steps, as appropriate for your system.
|
||||
|
||||
- Switch to FreqCal mode
|
||||
|
||||
- In the _Working Frequencies_ box on the *Settings -> Frequencies*
|
||||
tab, delete any default frequencies for *FreqCal* mode that are not
|
||||
relevant for your location. You may want to replace some of them with
|
||||
reliably known frequencies receivable at your location.
|
||||
|
||||
TIP: We find major-city AM broadcast stations generally serve well as
|
||||
frequency calibrators at the low frequency end of the spectrum. In
|
||||
North America we also use the standard time-and-frequency broadcasts
|
||||
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
|
||||
in other parts of the world.
|
||||
|
||||
- In most cases you will want to start by deleting any existing file
|
||||
`fmt.all` in the directory where your log files are kept.
|
||||
|
||||
- To cycle automatically through your chosen list of calibration
|
||||
frequencies, check *Execute frequency calibration cycle* on the
|
||||
*Tools* menu. _WSJT-X_ will spend 30 seconds at each
|
||||
frequency. Initially no measurement data is saved to the `fmt.all`
|
||||
file although it is displayed on screen, this allows you to check you
|
||||
current calibration parameters.
|
||||
|
||||
- During the calibration procedure, the radio's USB dial frequency is
|
||||
offset 1500 Hz below each *FreqCal* entry in the default frequencies
|
||||
list. As shown in the screen shot below, detected signal carriers
|
||||
therefore appear at about 1500 Hz in the _WSJT-X_ waterfall.
|
||||
|
||||
- To start a measurement session check the *Measure* option and let
|
||||
the calibration cycle run for at least one complete sequence. Note
|
||||
that, while measuring, any existing calibration parameters are
|
||||
automatically disabled so you may have to increase the *FTol* range if
|
||||
your rig is off freqeuncy by more than a few Hertz in order to capture
|
||||
valid measurements.
|
||||
|
||||
image::FreqCal.png[align="left",alt="FreqCal"]
|
||||
|
||||
With modern synthesized radios, small measured offsets from 1500 Hz
|
||||
will exhibit a straight-line dependence on frequency. You can
|
||||
approximate the calibration of your radio by simply dividing the
|
||||
measured frequency offset (in Hz) at the highest reliable frequency by
|
||||
the nominal frequency itself (in MHz). For example, the 20 MHz
|
||||
measurement for WWV shown above produced a measured tone offset of
|
||||
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
|
||||
may be entered as *Slope* on the *settings -> Frequencies* tab.
|
||||
|
||||
A more precise calibration can be effected by fitting the intercept
|
||||
and slope of a straight line to the whole sequence of calibration
|
||||
measurements, as shown for these measurements in the graph plotted
|
||||
below. Software tools for completing this task are included with the
|
||||
_WSJT-X_ installation, and detailed instructions for their use are
|
||||
available at https://physics.princeton.edu/pulsar/k1jt/FMT_User.pdf.
|
||||
|
||||
Using these tools and no specialized hardware beyond your
|
||||
CAT-interfaced radio, you can calibrate the radio to better than 1 Hz
|
||||
and compete very effectively in the ARRL's periodic Frequency
|
||||
Measuring Tests.
|
||||
|
||||
image::FreqCal_Graph.png[align="left",alt="FreqCal_Graph"]
|
||||
|
||||
After running *Execute frequency calibration cycle* at least once with
|
||||
good results, check and edit the file `fmt.all` in the log directory
|
||||
and delete any spurious or outlier measurements. The line-fitting
|
||||
procedure can then be carried out automatically by clicking *Solve for
|
||||
calibration parameters* on the *Tools* menu. The results will be
|
||||
displayed as in the following screen shot. Estimated uncertainties
|
||||
are included for slope and intercept; `N` is the number of averaged
|
||||
frequency measurements included in the fit, and `StdDev` is the root
|
||||
mean square deviation of averaged measurements from the fitted
|
||||
straight line. If the solution seems valid you will be offered an
|
||||
*Apply* button to push that will automatically set the calibration
|
||||
parameters in *Settings -> Frequencies -> Frequency Calibration*.
|
||||
|
||||
image::FreqCal_Results.png[align="center",alt="FreqCal_Results"]
|
||||
|
||||
For a quick visual check of the resulting calibration, stay in
|
||||
*FreqCal* mode with the *Measure* option cleared. _WSJT-X_ will show
|
||||
the adjusted results directly on the waterfall and the displayed
|
||||
records.
|
||||
|
||||
=== Reference Spectrum
|
||||
|
||||
_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
|
||||
a quiet frequency with no signals. With _WSJT-X_ running in one of
|
||||
the slow modes, select *Measure reference spectrum* from the *Tools*
|
||||
menu. Wait for about a minute and then hit the *Stop* button. A file
|
||||
named `refspec.dat` will appear in your log directory.
|
||||
|
||||
[ ... more to come ... ]
|
||||
|
||||
=== Phase Equalization
|
||||
|
||||
*Measure phase response* under the *Tools* menu is for advanced MSK144
|
||||
users. Phase equalization is used to compensate for group-delay
|
||||
variation across your receiver passband. Careful application of this
|
||||
facility can reduce intersymbol interference, resulting in improved
|
||||
decoding sensitivity. If you use a software-defined receiver with
|
||||
linear-phase filters there is no need to apply phase equalization.
|
||||
|
||||
After a frame of received data has been decoded, *Measure phase
|
||||
response* generates an undistorted audio waveform equal to the one
|
||||
generated by the transmitting station. Its Fourier transform is then
|
||||
used as a frequency-dependent phase reference to compare with the
|
||||
phase of the received frame's Fourier coefficients. Phase differences
|
||||
between the reference spectrum and received spectrum will include
|
||||
contributions from the originating station's transmit filter, the
|
||||
propagation channel, and filters in the receiver. If the received
|
||||
frame originates from a station known to transmit signals having
|
||||
little phase distortion (say, a station known to use a properly
|
||||
adjusted software-defined-transceiver) and if the received signal is
|
||||
relatively free from multipath distortion so that the channel phase is
|
||||
close to linear, the measured phase differences will be representative
|
||||
of the local receiver's phase response.
|
||||
|
||||
Complete the following steps to generate a phase equalization curve:
|
||||
|
||||
- Record a number of wav files that contain decodable signals from
|
||||
your chosen reference station. Best results will be obtained when the
|
||||
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.
|
||||
|
||||
- Select *Measure phase response* from the *Tools* menu, and open each
|
||||
of the wav files in turn. The mode character on decoded text lines
|
||||
will change from `&` to `^` while _WSJT-X_ is measuring the phase
|
||||
response, and it will change back to `&` after the measurement is
|
||||
completed. The program needs to average a number of high-SNR frames to
|
||||
accurately estimate the phase, so it may be necessary to process
|
||||
several wav files. The measurement can be aborted at any time by
|
||||
selecting *Measure phase response* again to toggle the phase
|
||||
measurement off.
|
||||
|
||||
+
|
||||
|
||||
When the measurement is complete _WSJT-X_ will save the measured
|
||||
phase response in the *Log directory*, in a file with suffix
|
||||
".pcoeff". The filename will contain the callsign of the reference
|
||||
station and a timestamp, for example `K0TPP_170923_112027.pcoeff`.
|
||||
|
||||
- Select *Equalization tools ...* under the *Tools* menu and click the
|
||||
*Phase ...* button to view the contents of the *Log directory*. Select
|
||||
the desired pcoeff file. The measured phase values will be plotted as
|
||||
filled circles along with a fitted red curve labeled "Proposed". This is
|
||||
the proposed phase equalization curve. It's a good idea to repeat the
|
||||
phase measurement several times, using different wav files for each
|
||||
measurement, to ensure that your measurements are repeatable.
|
||||
|
||||
- Once you are satisfied with a fitted curve, push the *Apply* button
|
||||
to save the proposed response. The red curve will be replaced with a
|
||||
light green curve labeled "Current" to indicate that the phase
|
||||
equalization curve is now being applied to the received data. Another
|
||||
curve labeled "Group Delay" will appear. The "Group Delay" curve shows
|
||||
the group delay variation across the passband, in ms. Click the
|
||||
*Discard* button to remove the captured data, leaving only the applied
|
||||
phase equalization curve and corresponding group delay curve.
|
||||
|
||||
- To revert to no phase equalization, push the *Restore Defaults*
|
||||
button followed by the *Apply* button.
|
||||
|
||||
The three numbers printed at the end of each MSK144 decode line can be
|
||||
used to assess the improvement provided by equalization. These numbers
|
||||
are: `N` = Number of frames averaged, `H` = Number of hard bit errors
|
||||
corrected, `E` = Size of MSK eye diagram opening.
|
||||
|
||||
Here is a decode of K0TPP obtained while *Measure phase response* was measuring
|
||||
the phase response:
|
||||
|
||||
103900 17 6.5 1493 ^ WA8CLT K0TPP +07 1 0 1.2
|
||||
|
||||
The "^" symbol indicates that a phase measurement is being accumulated
|
||||
but is not yet finished. The three numbers at the end of the line
|
||||
indicate that one frame was used to obtain the decode, there were no
|
||||
hard bit errors, and the eye-opening was 1.2 on a -2 to +2
|
||||
scale. Here's how the same decode looks after phase equalization:
|
||||
|
||||
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
|
||||
1.6. Larger positive eye openings are associated with reduced
|
||||
likelihood of bit errors and higher likelihood that a frame will be
|
||||
successfully decoded. In this case, the larger eye-opening tells us
|
||||
that phase equalization was successful, but it is important to note
|
||||
that this test does not by itself tell us whether the applied phase
|
||||
equalization curve is going to improve decoding of signals other than
|
||||
those from the reference station, K0TPP.
|
||||
|
||||
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
|
||||
stations, to help decide whether your equalization curve improves
|
||||
decoding for most signals. When doing such comparisons, keep in mind
|
||||
that equalization may cause _WSJT-X_ to successfully decode a frame
|
||||
that was not decoded before equalization was applied. For this
|
||||
reason, be sure that the time "T" of the two decodes are the same
|
||||
before comparing their end-of-line quality numbers.
|
||||
|
||||
When comparing before and after decodes having the same "T", keep in
|
||||
mind that a smaller first number means that decoding has improved,
|
||||
even if the second and third numbers appear to be "worse". For
|
||||
example, suppose that the end-of-line quality numbers before
|
||||
equalization are `2 0 0.2` and after equalization `1 5 -0.5`. These
|
||||
numbers show improved decoding because the decode was obtained using
|
||||
only a single frame after equalization whereas a 2-frame average was
|
||||
needed before equalization. This implies that shorter and/or weaker
|
||||
pings could be decodable.
|
||||
|
||||
NOTE: Further details on phase equalization and examples of fitted
|
||||
phase curves and eye diagrams can be found in the article on MSK144 by
|
||||
K9AN and K1JT published in {msk144}.
|
||||
|
|
|
@ -11,7 +11,7 @@ added to _WSJT-X_ since Version 1.7.0:
|
|||
|
||||
- *SWL* option for third-party decoding short-format MSK144 messages
|
||||
|
||||
- Experimental amplitude and phase equalization for MSK144
|
||||
- Experimental phase equalization for MSK144
|
||||
|
||||
- Options to minimize screen space used by *Main* and *Wide Graph*
|
||||
windows
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Status=review
|
||||
|
||||
image::settings-audio.png[align="center",alt="WSJT-X Audio Configuration Screen"]
|
||||
image::settings-audio.png[align="center",alt="_WSJT-X_ Audio Configuration Screen"]
|
||||
|
||||
Select the *Audio* tab to configure your sound system.
|
||||
|
||||
|
|
|
@ -14,8 +14,10 @@ volunteer programmers to make the program better. Bugs may be
|
|||
reported to {wsjt_yahoo_group} (email address
|
||||
wsjtgroup@yahoogroups.com) or the WSJT Developers list
|
||||
(wsjt-devel@lists.sourceforge.net). Again, you will need to join the
|
||||
group or subscribe to the list. To be useful, bug reports should
|
||||
include at least the following information:
|
||||
group or subscribe to the list. You can register for the list {wsjt-devel}.
|
||||
|
||||
To be useful, bug reports should include at least the following
|
||||
information:
|
||||
|
||||
- Program version
|
||||
- Operating system
|
||||
|
|
|
@ -16,10 +16,10 @@ image::main-ui.png[align="center",alt="Main UI and Wide Graph"]
|
|||
|
||||
Decoding takes place at the end of a receive sequence and proceeds in
|
||||
two steps. The first decode is done at the selected Rx frequency,
|
||||
indicated by the U-shaped green marker on the waterfall scale.
|
||||
Results appear in both the left (*Band Activity*) and right (*Rx
|
||||
Frequency*) text windows on the main screen. The program then finds
|
||||
and decodes all signals in the selected mode over the displayed
|
||||
indicated by the U-shaped green marker on the waterfall frequency
|
||||
scale. Results appear in both the left (*Band Activity*) and right
|
||||
(*Rx Frequency*) text windows on the main screen. The program then
|
||||
finds and decodes all signals in the selected mode over the displayed
|
||||
frequency range. The red marker on the waterfall scale indicates your
|
||||
Tx frequency.
|
||||
|
||||
|
@ -51,8 +51,8 @@ Call* and *DX Grid* entry fields.
|
|||
** The *Tx even* box is checked or cleared appropriately, so that you
|
||||
will transmit in the proper (odd or even) minutes.
|
||||
|
||||
** The Rx and Tx frequency markers are moved to the frequency of the
|
||||
CQing station.
|
||||
** The Rx frequency marker is moved to the frequency of the CQing
|
||||
station.
|
||||
|
||||
** The *Gen Msg* ("`generated message`") radio button at bottom right
|
||||
of the main window is selected.
|
||||
|
@ -61,23 +61,23 @@ of the main window is selected.
|
|||
*Setup* menu, *Enable Tx* would be activated and a transmission would
|
||||
start automatically at the proper time.
|
||||
|
||||
- Double-click on the decoded message `K1JT N5KDV EM41`,
|
||||
highlighted in red. Results will be similar to those in the
|
||||
previous step, except the Tx frequency (red marker) is not
|
||||
moved. Such messages 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.
|
||||
** 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.
|
||||
|
||||
- By holding down the *Ctrl* key when double-clicking on a decoded
|
||||
line you can cause both Tx and Rx frequencies to be moved. This
|
||||
behavior can also be forced by checking *Lock Tx=Rx*.
|
||||
- Double-click on the decoded message `K1JT N5KDV EM41`, 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.
|
||||
|
||||
- Double-click on the message from KF4RWA in either window. He is
|
||||
sending `73` to K1JT, signifying that the QSO is over. Most likely
|
||||
you want to send 73 to him, so the message `KF4RWA K1JT 73` is
|
||||
automatically generated and selected for your next transmission.
|
||||
(Alternatively, you might choose to send a free-text message or to
|
||||
call CQ again.)
|
||||
NOTE: Double-clicking on decoded messages can be defaulted to simplex
|
||||
operation by checking *Double click on call sets Tx and Rx freqs* on
|
||||
the *Settings -> General* tab.
|
||||
|
||||
NOTE: You can prevent your Tx frequency from being changed by checking the
|
||||
box *Lock Tx Freq*.
|
||||
|
||||
- Click somewhere on the waterfall to set Rx frequency (green marker
|
||||
on waterfall scale).
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// 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
|
||||
- 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.
|
||||
|
||||
|
@ -75,18 +75,21 @@ JT9 message from IZ0MIT:
|
|||
[width="80%",align="center",cols="^10,2*^8,2*^10,54",options="header"]
|
||||
|===
|
||||
|UTC|dB|DT|Freq|Mode|Message
|
||||
|+2343+|+-7+|+0.3+|+3196+|+@+|+WB8QPG IZ0MIT -11+
|
||||
|+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 Tx
|
||||
and Rx frequencies to that of DL7ACA, 975 Hz. If you had checked
|
||||
*Double-click on call sets Tx Enable* on the *Setup* menu, the program
|
||||
would configure itself to start a QSO with DL7ACA.
|
||||
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.
|
||||
|
||||
- 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.
|
||||
- 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`.
|
||||
|
|
|
@ -25,34 +25,36 @@ image::ft8_decodes.png[align="left"]
|
|||
frequency marker will jump to your selected frequency, and the Rx
|
||||
frequency control on the main window will be updated accordingly.
|
||||
|
||||
- Do the same thing with the Shift key held down. Now the red Tx
|
||||
- Do the same thing with the *Shift* key held down. Now the red Tx
|
||||
frequency marker and its associated control on the main window will
|
||||
follow your frequency selections.
|
||||
|
||||
- Do the same thing with the Ctrl key held down. Now the both colored
|
||||
- Do the same thing with the *Ctrl* key held down. Now the both colored
|
||||
markers and both spinner controls will follow your selections.
|
||||
|
||||
- Double-clicking at any frequency on the waterfall does all the
|
||||
things just described and also invokes the decoder in a small range
|
||||
around that frequency. To decode a particular signal, double-click
|
||||
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 the lines of decoded text in the main
|
||||
window. Unless you have *My Call* set to K1JT or KY7M on the
|
||||
*Settings -> General* tab, all three lines will show the same
|
||||
behavior, setting both RxFreq and TxFreq to the frequency of the
|
||||
selected message. However, if MyCall is set to K1JT then clicking on
|
||||
a message directed to K1JT will move only the Rx frequency setting.
|
||||
This behavior is desirable so that you will not inadvertently change
|
||||
your Tx frequency to that of a tail-ender who called you somewhere
|
||||
else in the FT8 subband.
|
||||
window. All three lines 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.
|
||||
|
||||
NOTE: To avoid QRM from competing callers, it is frequently desirable
|
||||
to answer a CQ on a different frequency from that of the CQing
|
||||
station. Choose a Tx frequency that appears to be not in use. The
|
||||
same is true when you tail-end another QSO.
|
||||
|
||||
NOTE: The FT8 decoder can often copy several overlapping signals at
|
||||
nearly the same frequency. However, in crowded band conditions you
|
||||
will often find it advantageous to move off the frequency of the
|
||||
station you are calling. Keyboard shortcuts *Shift+F11* and
|
||||
*Shift+F12* provide an easy way to move your Tx frequency in 60 Hz
|
||||
steps.
|
||||
nearly the same frequency. Keyboard shortcuts *Shift+F11* and
|
||||
*Shift+F12* provide an easy way to move your Tx frequency down or up
|
||||
in 60 Hz steps.
|
||||
|
||||
NOTE: Further helpful tips on FT8 operating procedures are available
|
||||
{ft8_tips}. Thanks to ZL2IFB!
|
||||
|
||||
IMPORTANT: When finished with this Tutorial, don't forget to re-enter
|
||||
your own callsign as *My Call* on the *Settings | General* tab.
|
||||
|
|
|
@ -9,5 +9,5 @@
|
|||
- *Gain* and *Zero* sliders for waterfall and spectrum set near midscale
|
||||
- *Spec* = 25%
|
||||
|
||||
- Use the mouse to adjust the width of the *Wide Graph* so that its
|
||||
upper frequency limit is about 2400 Hz.
|
||||
- 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.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// This is a comment line, anything with // is ignored at process time.
|
||||
= WSJT-X User Guide
|
||||
= _WSJT-X_ User Guide
|
||||
Joseph H Taylor, Jr, K1JT
|
||||
:revnumber: {VERSION}
|
||||
// For web-pages, adding :badges: is ok, but is a security issue for
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
Auto-Sequencing algorithm for DXpedition station:
|
||||
|
||||
Start:
|
||||
CQMsg = "CQ VK9MA" (or "CQ UP VK9MA", "CQ 116 VK9MA", etc.)
|
||||
CQMsg = "CQ KH1DX" (or "CQ UP KH1DX", "CQ 116 KH1DX", etc.)
|
||||
TxMsg = CQMsg
|
||||
Ntry = 0
|
||||
QCALL = "" # Callsign of current QSO partner
|
||||
|
@ -16,7 +16,7 @@ Receive:
|
|||
N = number of decodes # RxMsg[i], i=1,N
|
||||
if(N == 0)
|
||||
go to Transmit
|
||||
J = index of a reply from current QCALL # RxMsg[J] = "VK9MA QCALL R<rpt>"
|
||||
J = index of a reply from current QCALL # RxMsg[J] = "KH1DX QCALL R<rpt>"
|
||||
|
||||
if(QCALL == "") # No QSO in progress
|
||||
Select new QCALL # Op chooses a caller
|
||||
|
@ -48,7 +48,7 @@ Receive:
|
|||
Auto-Sequencing algorithm for those calling the DXpedition:
|
||||
|
||||
Start:
|
||||
TxMsg = "VK9MA MyCall"
|
||||
TxMsg = "KH1DX MyCall"
|
||||
InQSO = false
|
||||
|
||||
Transmit:
|
||||
|
@ -59,13 +59,13 @@ Receive:
|
|||
RX # (... takes ~14 s)
|
||||
if(RxMsg[i] contains "MyCall <rpt>")
|
||||
InQSO = true
|
||||
TxMsg = "VK9MA MyCall R<rpt>"
|
||||
TxMsg = "KH1DX MyCall R<rpt>"
|
||||
go to Transmit
|
||||
|
||||
if(RxMsg[i] contains "<rpt>")
|
||||
TxEnable = false
|
||||
go to Receive
|
||||
|
||||
if(RxMsg[i] contains "CQ VK9MA")
|
||||
if(RxMsg[i] contains "CQ KH1DX")
|
||||
TxEnable = true
|
||||
go to Transmit
|
||||
|
|
|
@ -60,7 +60,8 @@ program allsim
|
|||
call gen4(message,0,msgsent,itone,itype)
|
||||
call addit(itone,11025,206,2520,1200,sig,dat) !JT4
|
||||
|
||||
call genft8(message,mygrid,bcontest,msgsent,msgbits,itone)
|
||||
i3bit=0 ! ### TEMPORARY ??? ###
|
||||
call genft8(message,mygrid,bcontest,i3bit,msgsent,msgbits,itone)
|
||||
call addit(itone,12000,79,1920,1400,sig,dat) !FT8
|
||||
|
||||
call genqra64(message,0,msgsent,itone,itype)
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
subroutine calibrate(data_dir,iz,a,b,rms,sigmaa,sigmab,irc)
|
||||
|
||||
! Average groups of frequency-calibration measurements, then fit a
|
||||
! straight line for slope and intercept.
|
||||
|
||||
parameter (NZ=1000)
|
||||
implicit real*8 (a-h,o-z)
|
||||
character*(*) data_dir
|
||||
character*256 infile,outfile
|
||||
character*8 cutc,cutc1
|
||||
character*1 c1
|
||||
real*8 fd(NZ),deltaf(NZ),r(NZ),rmsd(NZ)
|
||||
integer nn(NZ)
|
||||
|
||||
infile=trim(data_dir)//'fmt.all'
|
||||
outfile=trim(data_dir)//'fcal2.out'
|
||||
|
||||
open(10,file=trim(infile),status='old',err=996)
|
||||
open(12,file=trim(outfile),status='unknown',err=997)
|
||||
|
||||
nkhz0=0
|
||||
sum=0.d0
|
||||
sumsq=0.d0
|
||||
n=0
|
||||
j=0
|
||||
do i=1,99999
|
||||
read(10,*,end=10,err=995) cutc,nkHz,ncal,noffset,faudio,df,dblevel,snr
|
||||
if((nkHz.ne.nkHz0) .and. i.ne.1) then
|
||||
ave=sum/n
|
||||
rms=0.d0
|
||||
if(n.gt.1) then
|
||||
rms=sqrt(abs(sumsq - sum*sum/n)/(n-1.d0))
|
||||
endif
|
||||
fMHz=0.001d0*nkHz0
|
||||
j=j+1
|
||||
fd(j)=fMHz
|
||||
deltaf(j)=ave
|
||||
r(j)=0.d0
|
||||
rmsd(j)=rms
|
||||
nn(j)=n
|
||||
sum=0.d0
|
||||
sumsq=0.d0
|
||||
n=0
|
||||
endif
|
||||
dial_error=faudio-noffset
|
||||
sum=sum + dial_error
|
||||
sumsq=sumsq + dial_error**2
|
||||
n=n+1
|
||||
if(n.eq.1) then
|
||||
cutc1=cutc
|
||||
ncal0=ncal
|
||||
endif
|
||||
nkHz0=nkHz
|
||||
enddo
|
||||
|
||||
10 ave=sum/n
|
||||
rms=0.d0
|
||||
if(n.gt.0) then
|
||||
rms=sqrt((sumsq - sum*sum/n)/(n-1.d0))
|
||||
endif
|
||||
fMHz=0.001d0*nkHz
|
||||
j=j+1
|
||||
fd(j)=fMHz
|
||||
deltaf(j)=ave
|
||||
r(j)=0.d0
|
||||
rmsd(j)=rms
|
||||
nn(j)=n
|
||||
iz=j
|
||||
if(iz.lt.2) go to 998
|
||||
|
||||
call fitcal(fd,deltaf,r,iz,a,b,sigmaa,sigmab,rms)
|
||||
|
||||
write(12,1002)
|
||||
1002 format(' Freq DF Meas Freq N rms Resid'/ &
|
||||
' (MHz) (Hz) (MHz) (Hz) (Hz)'/ &
|
||||
'----------------------------------------------------')
|
||||
irc=0
|
||||
do i=1,iz
|
||||
fm=fd(i) + 1.d-6*deltaf(i)
|
||||
c1=' '
|
||||
if(rmsd(i).gt.1.0d0) c1='*'
|
||||
write(12,1012) fd(i),deltaf(i),fm,nn(i),rmsd(i),r(i),c1
|
||||
1012 format(f8.3,f9.3,f14.9,i4,f7.2,f9.3,1x,a1)
|
||||
enddo
|
||||
go to 999
|
||||
|
||||
995 irc=-4; iz=i; go to 999
|
||||
996 irc=-1; go to 999
|
||||
997 irc=-2; go to 999
|
||||
998 irc=-3
|
||||
999 continue
|
||||
close(10)
|
||||
close(12)
|
||||
|
||||
return
|
||||
end subroutine calibrate
|
|
@ -0,0 +1,34 @@
|
|||
subroutine fitcal(x,y,r,iz,a,b,sigmaa,sigmab,rms)
|
||||
implicit real*8 (a-h,o-z)
|
||||
real*8 x(iz),y(iz),r(iz)
|
||||
|
||||
sx=0.d0
|
||||
sy=0.d0
|
||||
sxy=0.d0
|
||||
sx2=0.d0
|
||||
do i=1,iz
|
||||
sx=sx + x(i)
|
||||
sy=sy + y(i)
|
||||
sxy=sxy + x(i)*y(i)
|
||||
sx2=sx2 + x(i)*x(i)
|
||||
enddo
|
||||
delta=iz*sx2 - sx*sx
|
||||
a=(sx2*sy - sx*sxy)/delta
|
||||
b=(iz*sxy - sx*sy)/delta
|
||||
|
||||
sq=0.d0
|
||||
do i=1,iz
|
||||
r(i)=y(i) - (a + b*x(i))
|
||||
sq=sq + r(i)**2
|
||||
enddo
|
||||
rms=0.
|
||||
sigmaa=0.
|
||||
sigmab=0.
|
||||
if(iz.ge.3) then
|
||||
rms=sqrt(sq/(iz-2))
|
||||
sigmaa=sqrt(rms*rms*sx2/delta)
|
||||
sigmab=sqrt(iz*rms*rms/delta)
|
||||
endif
|
||||
|
||||
return
|
||||
end subroutine fitcal
|
|
@ -27,7 +27,6 @@ program fmeasure
|
|||
|
||||
parameter(NZ=1000)
|
||||
implicit real*8 (a-h,o-z)
|
||||
real*8 fd(NZ),deltaf(NZ),r(NZ)
|
||||
character infile*50
|
||||
character line*80
|
||||
|
||||
|
|
|
@ -23,7 +23,8 @@ subroutine ft8apset(mycall12,mygrid6,hiscall12,hisgrid6,bcontest,apsym,iaptype)
|
|||
! if(len_trim(hisgrid).eq.0) hisgrid="EN50"
|
||||
if(index(hisgrid," ").eq.0) hisgrid="EN50"
|
||||
msg=mycall//' '//hiscall//' '//hisgrid
|
||||
call genft8(msg,mygrid6,bcontest,msgsent,msgbits,itone)
|
||||
i3bit=0 ! ### TEMPORARY ??? ###
|
||||
call genft8(msg,mygrid6,bcontest,i3bit,msgsent,msgbits,itone)
|
||||
apsym=2*msgbits-1
|
||||
|
||||
return
|
||||
|
|
|
@ -10,16 +10,17 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,napwid, &
|
|||
character*6 mygrid6
|
||||
logical bcontest
|
||||
real a(5)
|
||||
real s1(0:7,ND),s2(0:7,NN)
|
||||
real ps(0:7)
|
||||
real bmeta(3*ND),bmetap(3*ND)
|
||||
real llr(3*ND),llra(3*ND),llr0(3*ND),llrap(3*ND) !Soft symbols
|
||||
real s1(0:7,ND),s2(0:7,NN),s1sort(8*ND)
|
||||
real ps(0:7),psl(0:7)
|
||||
real bmeta(3*ND),bmetb(3*ND),bmetap(3*ND)
|
||||
real llr(3*ND),llra(3*ND),llr0(3*ND),llr1(3*ND),llrap(3*ND) !Soft symbols
|
||||
real dd0(15*12000)
|
||||
integer*1 decoded(KK),apmask(3*ND),cw(3*ND)
|
||||
integer*1 msgbits(KK)
|
||||
integer apsym(KK)
|
||||
integer mcq(28),mde(28),mrrr(16),m73(16),mrr73(16)
|
||||
integer itone(NN)
|
||||
integer indxs1(8*ND)
|
||||
integer icos7(0:6),ip(1)
|
||||
integer nappasses(0:5) ! the number of decoding passes to use for each QSO state
|
||||
integer naptypes(0:5,4) ! (nQSOProgress, decoding pass) maximum of 4 passes for now
|
||||
|
@ -27,6 +28,7 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,napwid, &
|
|||
complex ctwk(32)
|
||||
complex csymb(32)
|
||||
logical first,newdat,lsubtract,lapon,nagain
|
||||
equivalence (s1,s1sort)
|
||||
data icos7/2,5,6,0,4,1,3/
|
||||
data mcq/1,1,1,1,1,0,1,0,0,0,0,0,1,0,0,0,0,0,1,1,0,0,0,1,1,0,0,1/
|
||||
data mrrr/0,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1/
|
||||
|
@ -153,10 +155,15 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,napwid, &
|
|||
s1(0:7,j)=s2(0:7,k)
|
||||
enddo
|
||||
|
||||
call indexx(s1sort,8*ND,indxs1)
|
||||
xmeds1=s1sort(indxs1(nint(0.5*8*ND)))
|
||||
s1=s1/xmeds1
|
||||
|
||||
do j=1,ND
|
||||
i4=3*j-2
|
||||
i2=3*j-1
|
||||
i1=3*j
|
||||
! Max amplitude
|
||||
ps=s1(0:7,j)
|
||||
r1=max(ps(1),ps(3),ps(5),ps(7))-max(ps(0),ps(2),ps(4),ps(6))
|
||||
r2=max(ps(2),ps(3),ps(6),ps(7))-max(ps(0),ps(1),ps(4),ps(5))
|
||||
|
@ -167,6 +174,35 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,napwid, &
|
|||
bmetap(i4)=r4
|
||||
bmetap(i2)=r2
|
||||
bmetap(i1)=r1
|
||||
! Max log metric
|
||||
psl=log(ps)
|
||||
r1=max(psl(1),psl(3),psl(5),psl(7))-max(psl(0),psl(2),psl(4),psl(6))
|
||||
r2=max(psl(2),psl(3),psl(6),psl(7))-max(psl(0),psl(1),psl(4),psl(5))
|
||||
r4=max(psl(4),psl(5),psl(6),psl(7))-max(psl(0),psl(1),psl(2),psl(3))
|
||||
bmetb(i4)=r4
|
||||
bmetb(i2)=r2
|
||||
bmetb(i1)=r1
|
||||
|
||||
! Metric for Cauchy noise
|
||||
! r1=log(ps(1)**3+ps(3)**3+ps(5)**3+ps(7)**3)- &
|
||||
! log(ps(0)**3+ps(2)**3+ps(4)**3+ps(6)**3)
|
||||
! r2=log(ps(2)**3+ps(3)**3+ps(6)**3+ps(7)**3)- &
|
||||
! log(ps(0)**3+ps(1)**3+ps(4)**3+ps(5)**3)
|
||||
! r4=log(ps(4)**3+ps(5)**3+ps(6)**3+ps(7)**3)- &
|
||||
! log(ps(0)**3+ps(1)**3+ps(2)**3+ps(3)**3)
|
||||
! Metric for AWGN, no fading
|
||||
! bscale=2.5
|
||||
! b0=bessi0(bscale*ps(0))
|
||||
! b1=bessi0(bscale*ps(1))
|
||||
! b2=bessi0(bscale*ps(2))
|
||||
! b3=bessi0(bscale*ps(3))
|
||||
! b4=bessi0(bscale*ps(4))
|
||||
! b5=bessi0(bscale*ps(5))
|
||||
! b6=bessi0(bscale*ps(6))
|
||||
! b7=bessi0(bscale*ps(7))
|
||||
! r1=log(b1+b3+b5+b7)-log(b0+b2+b4+b6)
|
||||
! r2=log(b2+b3+b6+b7)-log(b0+b1+b4+b5)
|
||||
! r4=log(b4+b5+b6+b7)-log(b0+b1+b2+b3)
|
||||
|
||||
if(nQSOProgress .eq. 0 .or. nQSOProgress .eq. 5) then
|
||||
! When bits 88:115 are set as ap bits, bit 115 lives in symbol 39 along
|
||||
|
@ -209,12 +245,14 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,napwid, &
|
|||
enddo
|
||||
|
||||
call normalizebmet(bmeta,3*ND)
|
||||
call normalizebmet(bmetb,3*ND)
|
||||
call normalizebmet(bmetap,3*ND)
|
||||
|
||||
ss=0.84
|
||||
llr0=2.0*bmeta/(ss*ss)
|
||||
llra=2.0*bmetap/(ss*ss) ! llr's for use with ap
|
||||
apmag=4.0
|
||||
scalefac=2.83
|
||||
llr0=scalefac*bmeta
|
||||
llr1=scalefac*bmetb
|
||||
llra=scalefac*bmetap ! llr's for use with ap
|
||||
apmag=scalefac*(maxval(abs(bmetap))*1.01)
|
||||
|
||||
! pass #
|
||||
!------------------------------
|
||||
|
@ -227,35 +265,36 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,napwid, &
|
|||
! 7 ap pass 4, etc.
|
||||
|
||||
if(lapon) then
|
||||
npasses=3+nappasses(nQSOProgress)
|
||||
npasses=4+nappasses(nQSOProgress)
|
||||
else
|
||||
npasses=3
|
||||
npasses=4
|
||||
endif
|
||||
|
||||
do ipass=1,npasses
|
||||
|
||||
llr=llr0
|
||||
if(ipass.eq.2) llr(1:24)=0.
|
||||
if(ipass.eq.3) llr(1:48)=0.
|
||||
if(ipass.le.3) then
|
||||
if(ipass.eq.2) llr=llr1
|
||||
if(ipass.eq.3) llr(1:24)=0.
|
||||
if(ipass.eq.4) llr(1:48)=0.
|
||||
if(ipass.le.4) then
|
||||
apmask=0
|
||||
llrap=llr
|
||||
iaptype=0
|
||||
endif
|
||||
|
||||
if(ipass .gt. 3) then
|
||||
iaptype=naptypes(nQSOProgress,ipass-3)
|
||||
if(ipass .gt. 4) then
|
||||
iaptype=naptypes(nQSOProgress,ipass-4)
|
||||
if(iaptype.ge.3 .and. (abs(f1-nfqso).gt.napwid .and. abs(f1-nftx).gt.napwid) ) cycle
|
||||
if(iaptype.eq.1 .or. iaptype.eq.2 ) then ! AP,???,???
|
||||
apmask=0
|
||||
apmask(88:115)=1 ! first 28 bits are AP
|
||||
apmask(144)=1 ! not free text
|
||||
llrap=llr
|
||||
if(iaptype.eq.1) llrap(88:115)=apmag*mcq/ss
|
||||
if(iaptype.eq.2) llrap(88:115)=apmag*apsym(1:28)/ss
|
||||
if(iaptype.eq.1) llrap(88:115)=apmag*mcq
|
||||
if(iaptype.eq.2) llrap(88:115)=apmag*apsym(1:28)
|
||||
llrap(116:117)=llra(116:117)
|
||||
llrap(142:143)=llra(142:143)
|
||||
llrap(144)=-apmag/ss
|
||||
llrap(144)=-apmag
|
||||
endif
|
||||
if(iaptype.eq.3) then ! mycall, dxcall, ???
|
||||
apmask=0
|
||||
|
@ -263,8 +302,8 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,napwid, &
|
|||
apmask(116:143)=1 ! hiscall
|
||||
apmask(144)=1 ! not free text
|
||||
llrap=llr
|
||||
llrap(88:143)=apmag*apsym(1:56)/ss
|
||||
llrap(144)=-apmag/ss
|
||||
llrap(88:143)=apmag*apsym(1:56)
|
||||
llrap(144)=-apmag
|
||||
endif
|
||||
if(iaptype.eq.4 .or. iaptype.eq.5 .or. iaptype.eq.6) then
|
||||
apmask=0
|
||||
|
@ -272,10 +311,10 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,napwid, &
|
|||
apmask(116:143)=1 ! hiscall
|
||||
apmask(144:159)=1 ! RRR or 73 or RR73
|
||||
llrap=llr
|
||||
llrap(88:143)=apmag*apsym(1:56)/ss
|
||||
if(iaptype.eq.4) llrap(144:159)=apmag*mrrr/ss
|
||||
if(iaptype.eq.5) llrap(144:159)=apmag*m73/ss
|
||||
if(iaptype.eq.6) llrap(144:159)=apmag*mrr73/ss
|
||||
llrap(88:143)=apmag*apsym(1:56)
|
||||
if(iaptype.eq.4) llrap(144:159)=apmag*mrrr
|
||||
if(iaptype.eq.5) llrap(144:159)=apmag*m73
|
||||
if(iaptype.eq.6) llrap(144:159)=apmag*mrr73
|
||||
endif
|
||||
if(iaptype.eq.7) then ! ???, dxcall, ???
|
||||
apmask=0
|
||||
|
@ -283,8 +322,8 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,napwid, &
|
|||
apmask(144)=1 ! not free text
|
||||
llrap=llr
|
||||
llrap(115)=llra(115)
|
||||
llrap(116:143)=apmag*apsym(29:56)/ss
|
||||
llrap(144)=-apmag/ss
|
||||
llrap(116:143)=apmag*apsym(29:56)
|
||||
llrap(144)=-apmag
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -297,7 +336,7 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,napwid, &
|
|||
if(ndepth.eq.3 .and. nharderrors.lt.0) then
|
||||
ndeep=3
|
||||
if(abs(nfqso-f1).le.napwid .or. abs(nftx-f1).le.napwid) then
|
||||
if((ipass.eq.2 .or. ipass.eq.3) .and. .not.nagain) then
|
||||
if((ipass.eq.3 .or. ipass.eq.4) .and. .not.nagain) then
|
||||
ndeep=3
|
||||
else
|
||||
ndeep=4
|
||||
|
@ -312,20 +351,28 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,napwid, &
|
|||
message=' '
|
||||
xsnr=-99.0
|
||||
if(count(cw.eq.0).eq.174) cycle !Reject the all-zero codeword
|
||||
if(any(decoded(73:75).ne.0)) cycle !Reject if any of the 3 extra bits are nonzero
|
||||
!### if(any(decoded(73:75).ne.0)) cycle !Reject if any of the 3 extra bits is nonzero
|
||||
if(nharderrors.ge.0 .and. nharderrors+dmin.lt.60.0 .and. &
|
||||
.not.(sync.lt.2.0 .and. nharderrors.gt.35) .and. &
|
||||
.not.(ipass.gt.1 .and. nharderrors.gt.39) .and. &
|
||||
.not.(ipass.eq.3 .and. nharderrors.gt.30) &
|
||||
.not.(ipass.gt.2 .and. nharderrors.gt.39) .and. &
|
||||
.not.(ipass.eq.4 .and. nharderrors.gt.30) &
|
||||
) then
|
||||
call chkcrc12a(decoded,nbadcrc)
|
||||
else
|
||||
nharderrors=-1
|
||||
cycle
|
||||
endif
|
||||
!###
|
||||
i3bit=4*decoded(73) + 2*decoded(74) + decoded(75)
|
||||
iFreeText=decoded(57)
|
||||
! if(nbadcrc.eq.0) write(*,3001) nharderrors,nbadcrc,i3bit
|
||||
!3001 format('A',3i5)
|
||||
!###
|
||||
if(nbadcrc.eq.0) then
|
||||
call extractmessage174(decoded,message,ncrcflag,recent_calls,nrecent)
|
||||
call genft8(message,mygrid6,bcontest,msgsent,msgbits,itone)
|
||||
call genft8(message,mygrid6,bcontest,i3bit,msgsent,msgbits,itone)
|
||||
if(i3bit.eq.1 .and. iFreeText.eq.0) message(21:21)='1'
|
||||
if(i3bit.eq.2 .and. iFreeText.eq.0) message(21:21)='2'
|
||||
if(lsubtract) call subtractft8(dd0,itone,f1,xdt2)
|
||||
xsig=0.0
|
||||
xnoi=0.0
|
||||
|
@ -363,3 +410,28 @@ subroutine normalizebmet(bmet,n)
|
|||
bmet=bmet/bmetsig
|
||||
return
|
||||
end subroutine normalizebmet
|
||||
|
||||
|
||||
function bessi0(x)
|
||||
! From Numerical Recipes
|
||||
real bessi0,x
|
||||
double precision p1,p2,p3,p4,p5,p6,p7,q1,q2,q3,q4,q5,q6,q7,q8,q9,y
|
||||
save p1,p2,p3,p4,p5,p6,p7,q1,q2,q3,q4,q5,q6,q7,q8,q9
|
||||
data p1,p2,p3,p4,p5,p6,p7/1.0d0,3.5156229d0,3.0899424d0,1.2067492d0, &
|
||||
0.2659732d0,0.360768d-1,0.45813d-2/
|
||||
data q1,q2,q3,q4,q5,q6,q7,q8,q9/0.39894228d0,0.1328592d-1, &
|
||||
0.225319d-2,-0.157565d-2,0.916281d-2,-0.2057706d-1, &
|
||||
0.2635537d-1,-0.1647633d-1,0.392377d-2/
|
||||
|
||||
if (abs(x).lt.3.75) then
|
||||
y=(x/3.75)**2
|
||||
bessi0=p1+y*(p2+y*(p3+y*(p4+y*(p5+y*(p6+y*p7)))))
|
||||
else
|
||||
ax=abs(x)
|
||||
y=3.75/ax
|
||||
bessi0=(exp(ax)/sqrt(ax))*(q1+y*(q2+y*(q3+y*(q4 &
|
||||
+y*(q5+y*(q6+y*(q7+y*(q8+y*q9))))))))
|
||||
endif
|
||||
return
|
||||
end function bessi0
|
||||
|
||||
|
|
|
@ -65,9 +65,10 @@ program ft8sim
|
|||
sig=sqrt(2*bandwidth_ratio) * 10.0**(0.05*snrdb)
|
||||
if(snrdb.gt.90.0) sig=1.0
|
||||
txt=NN*NSPS/12000.0
|
||||
i3bit=0 ! ### TEMPORARY ??? ###
|
||||
|
||||
! Source-encode, then get itone()
|
||||
call genft8(msg,mygrid6,bcontest,msgsent,msgbits,itone)
|
||||
call genft8(msg,mygrid6,bcontest,i3bit,msgsent,msgbits,itone)
|
||||
write(*,1000) f0,xdt,txt,snrdb,bw,msgsent
|
||||
1000 format('f0:',f9.3,' DT:',f6.2,' TxT:',f6.1,' SNR:',f6.1, &
|
||||
' BW:',f4.1,2x,a22)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
subroutine genft8(msg,mygrid,bcontest,msgsent,msgbits,itone)
|
||||
subroutine genft8(msg,mygrid,bcontest,i3bit,msgsent,msgbits,itone)
|
||||
|
||||
! Encode an FT8 message, producing array itone().
|
||||
|
||||
|
@ -19,7 +19,6 @@ subroutine genft8(msg,mygrid,bcontest,msgsent,msgbits,itone)
|
|||
call packmsg(msg,i4Msg6BitWords,itype,bcontest) !Pack into 12 6-bit bytes
|
||||
call unpackmsg(i4Msg6BitWords,msgsent,bcontest,mygrid) !Unpack to get msgsent
|
||||
|
||||
i3bit=0 !### temporary ###
|
||||
write(cbits,1000) i4Msg6BitWords,32*i3bit
|
||||
1000 format(12b6.6,b8.8)
|
||||
read(cbits,1001) i1Msg8BitBytes(1:10)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
subroutine sync8(dd,nfa,nfb,syncmin,nfqso,s,candidate,ncand,sbase)
|
||||
|
||||
include 'ft8_params.f90'
|
||||
! Search over +/- 1.5s relative to 0.5s TX start time.
|
||||
parameter (JZ=38)
|
||||
! Search over +/- 2.5s relative to 0.5s TX start time.
|
||||
parameter (JZ=62)
|
||||
complex cx(0:NH1)
|
||||
real s(NH1,NHSYM)
|
||||
real savg(NH1)
|
||||
|
@ -138,7 +138,8 @@ subroutine sync8(dd,nfa,nfb,syncmin,nfqso,s,candidate,ncand,sbase)
|
|||
! do i=ncand,1,-1
|
||||
do i=1,ncand
|
||||
j=indx(i)
|
||||
if( candidate0(3,j) .ge. syncmin .and. candidate0(2,j).ge.-1.5 ) then
|
||||
! if( candidate0(3,j) .ge. syncmin .and. candidate0(2,j).ge.-1.5 ) then
|
||||
if( candidate0(3,j) .ge. syncmin ) then
|
||||
candidate(1,k)=abs(candidate0(1,j))
|
||||
candidate(2,k)=candidate0(2,j)
|
||||
candidate(3,k)=candidate0(3,j)
|
||||
|
|
|
@ -161,8 +161,6 @@ program jt9
|
|||
! Import FFTW wisdom, if available
|
||||
wisfile=trim(data_dir)//'/jt9_wisdom.dat'// C_NULL_CHAR
|
||||
iret=fftwf_import_wisdom_from_filename(wisfile)
|
||||
open(19,file=trim(data_dir)//'/false_decodes.txt',status='unknown', &
|
||||
position='append')
|
||||
|
||||
ntry65a=0
|
||||
ntry65b=0
|
||||
|
|
|
@ -66,7 +66,7 @@ subroutine msk144signalquality(cframe,snr,freq,t0,softbits,msg,dxcall, &
|
|||
currently_training=.false.
|
||||
training_dxcall(1:12)=' '
|
||||
trained_dxcall(1:12)=' '
|
||||
write(*,*) 'reset to untrained state '
|
||||
!write(*,*) 'reset to untrained state '
|
||||
endif
|
||||
|
||||
indx_dxcall=index(msg,trim(dxcall))
|
||||
|
@ -76,7 +76,7 @@ write(*,*) 'reset to untrained state '
|
|||
currently_training=.true.
|
||||
training_dxcall=trim(dxcall)
|
||||
trained_dxcall(1:12)=' '
|
||||
write(*,*) 'start training on call ',training_dxcall
|
||||
!write(*,*) 'start training on call ',training_dxcall
|
||||
endif
|
||||
|
||||
if( msg_has_dxcall .and. currently_training ) then
|
||||
|
@ -188,7 +188,7 @@ write(*,*) 'start training on call ',training_dxcall
|
|||
call polyfit(x,y,sigmay,npts,nterms,mode,a,chisqr)
|
||||
pp=a(1)+x*(a(2)+x*(a(3)+x*(a(4)+x*a(5))))
|
||||
rmsdiff=sum( (pp-phase((864/2-nm/2):(864/2+nm/2)))**2 )/145.0
|
||||
write(*,*) 'training ',navg,sqrt(chisqr),rmsdiff
|
||||
!write(*,*) 'training ',navg,sqrt(chisqr),rmsdiff
|
||||
if( (sqrt(chisqr).lt.1.8) .and. (rmsdiff.lt.0.5) .and. (navg.ge.5) ) then
|
||||
trained_dxcall=dxcall
|
||||
call date_and_time(date,time,zone,values)
|
||||
|
@ -198,7 +198,7 @@ write(*,*) 'training ',navg,sqrt(chisqr),rmsdiff
|
|||
l1=index(datadir,char(0))-1
|
||||
datadir(l1+1:l1+1)="/"
|
||||
pcoeff_filename=datadir(1:l1+1)//trim(pcoeff_filename)
|
||||
write(*,*) 'trained - writing coefficients to: ',pcoeff_filename
|
||||
!write(*,*) 'trained - writing coefficients to: ',pcoeff_filename
|
||||
open(17,file=pcoeff_filename,status='new')
|
||||
write(17,'(i4,2f10.2,3i5,5e25.16)') navg,sqrt(chisqr),rmsdiff,NFREQLOW,NFREQHIGH,nterms,a
|
||||
do i=1, 145
|
||||
|
|
|
@ -506,8 +506,8 @@ subroutine packbits(dbits,nsymd,m0,sym)
|
|||
20 continue
|
||||
if(itype.ne.6) itype=max(nv2a,nv2b)
|
||||
jt_itype=itype
|
||||
jt_c1=c1
|
||||
jt_c2=c2
|
||||
jt_c1=c1(1:6)
|
||||
jt_c2=c2(1:6)
|
||||
jt_c3=c3
|
||||
jt_k1=k1
|
||||
jt_k2=k2
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
function stdmsg(msg0,bcontest,mygrid)
|
||||
|
||||
! Is msg0 a standard "JT-style" message?
|
||||
|
||||
use iso_c_binding, only: c_bool
|
||||
use packjt
|
||||
character*22 msg0,msg
|
||||
character*22 msg0,msg1,msg
|
||||
character*6 mygrid
|
||||
integer dat(12)
|
||||
logical(c_bool), value :: bcontest
|
||||
logical(c_bool) :: stdmsg
|
||||
|
||||
msg1=msg0
|
||||
i0=index(msg1,' OOO ')
|
||||
if(i0.gt.10) msg1=msg0(1:i0)
|
||||
call packmsg(msg0,dat,itype,logical(bcontest))
|
||||
call unpackmsg(dat,msg,logical(bcontest),mygrid)
|
||||
stdmsg=(msg.eq.msg0) .and. (itype.ge.0) .and. itype.ne.6
|
||||
stdmsg=(msg.eq.msg1) .and. (itype.ge.0) .and. itype.ne.6
|
||||
|
||||
return
|
||||
end function stdmsg
|
||||
|
|
110
logbook/adif.cpp
|
@ -18,17 +18,17 @@ void ADIF::init(QString const& filename)
|
|||
}
|
||||
|
||||
|
||||
QString ADIF::_extractField(QString const& line, QString const& fieldName) const
|
||||
QString ADIF::extractField(QString const& record, QString const& fieldName) const
|
||||
{
|
||||
int fieldNameIndex = line.indexOf(fieldName,0,Qt::CaseInsensitive);
|
||||
int fieldNameIndex = record.indexOf (fieldName + ':', 0, Qt::CaseInsensitive);
|
||||
if (fieldNameIndex >=0)
|
||||
{
|
||||
int closingBracketIndex = line.indexOf('>',fieldNameIndex);
|
||||
int fieldLengthIndex = line.indexOf(':',fieldNameIndex); // find the size delimiter
|
||||
int closingBracketIndex = record.indexOf('>',fieldNameIndex);
|
||||
int fieldLengthIndex = record.indexOf(':',fieldNameIndex); // find the size delimiter
|
||||
int dataTypeIndex = -1;
|
||||
if (fieldLengthIndex >= 0)
|
||||
{
|
||||
dataTypeIndex = line.indexOf(':',fieldLengthIndex+1); // check for a second : indicating there is a data type
|
||||
dataTypeIndex = record.indexOf(':',fieldLengthIndex+1); // check for a second : indicating there is a data type
|
||||
if (dataTypeIndex > closingBracketIndex)
|
||||
dataTypeIndex = -1; // second : was found but it was beyond the closing >
|
||||
}
|
||||
|
@ -38,11 +38,11 @@ QString ADIF::_extractField(QString const& line, QString const& fieldName) const
|
|||
int fieldLengthCharCount = closingBracketIndex - fieldLengthIndex -1;
|
||||
if (dataTypeIndex >= 0)
|
||||
fieldLengthCharCount -= 2; // data type indicator is always a colon followed by a single character
|
||||
QString fieldLengthString = line.mid(fieldLengthIndex+1,fieldLengthCharCount);
|
||||
QString fieldLengthString = record.mid(fieldLengthIndex+1,fieldLengthCharCount);
|
||||
int fieldLength = fieldLengthString.toInt();
|
||||
if (fieldLength > 0)
|
||||
{
|
||||
QString field = line.mid(closingBracketIndex+1,fieldLength);
|
||||
QString field = record.mid(closingBracketIndex+1,fieldLength);
|
||||
return field;
|
||||
}
|
||||
}
|
||||
|
@ -59,29 +59,50 @@ void ADIF::load()
|
|||
if (inputFile.open(QIODevice::ReadOnly))
|
||||
{
|
||||
QTextStream in(&inputFile);
|
||||
QString record;
|
||||
QString buffer;
|
||||
bool pre_read {false};
|
||||
int end_position {-1};
|
||||
|
||||
// skip header record
|
||||
while (!in.atEnd () && !record.contains ("<EOH>", Qt::CaseInsensitive))
|
||||
// skip optional header record
|
||||
do
|
||||
{
|
||||
record += in.readLine ();
|
||||
}
|
||||
while ( !in.atEnd() )
|
||||
{
|
||||
record.clear ();
|
||||
while (!in.atEnd () && !record.contains ("<EOR>", Qt::CaseInsensitive))
|
||||
buffer += in.readLine () + '\n';
|
||||
if (buffer.startsWith (QChar {'<'})) // denotes no header
|
||||
{
|
||||
record += in.readLine ();
|
||||
pre_read = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
end_position = buffer.indexOf ("<EOH>", 0, Qt::CaseInsensitive);
|
||||
}
|
||||
QSO q;
|
||||
q.call = _extractField(record,"CALL:");
|
||||
q.band = _extractField(record,"BAND:");
|
||||
q.mode = _extractField(record,"MODE:");
|
||||
q.date = _extractField(record,"QSO_DATE:");
|
||||
if (q.call != "")
|
||||
_data.insert(q.call,q);
|
||||
}
|
||||
inputFile.close();
|
||||
while (!in.atEnd () && !pre_read && end_position < 0);
|
||||
if (!pre_read) // found header
|
||||
{
|
||||
buffer.remove (0, end_position + 5);
|
||||
}
|
||||
while (buffer.size () || !in.atEnd ())
|
||||
{
|
||||
do
|
||||
{
|
||||
end_position = buffer.indexOf ("<EOR>", 0, Qt::CaseInsensitive);
|
||||
if (!in.atEnd () && end_position < 0)
|
||||
{
|
||||
buffer += in.readLine () + '\n';
|
||||
}
|
||||
}
|
||||
while (!in.atEnd () && end_position < 0);
|
||||
int record_length {end_position >= 0 ? end_position + 5 : -1};
|
||||
auto record = buffer.left (record_length).trimmed ();
|
||||
auto next_record = buffer.indexOf (QChar {'<'}, record_length);
|
||||
buffer.remove (0, next_record >=0 ? next_record : buffer.size ());
|
||||
record = record.mid (record.indexOf (QChar {'<'}));
|
||||
add (extractField (record, "CALL")
|
||||
, extractField (record, "BAND")
|
||||
, extractField (record, "MODE")
|
||||
, extractField (record, "QSO_DATE"));
|
||||
}
|
||||
inputFile.close ();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,8 +114,11 @@ void ADIF::add(QString const& call, QString const& band, QString const& mode, QS
|
|||
q.band = band;
|
||||
q.mode = mode;
|
||||
q.date = date;
|
||||
_data.insert(q.call,q);
|
||||
//qDebug() << "Added as worked:" << call << band << mode << date;
|
||||
if (q.call.size ())
|
||||
{
|
||||
_data.insert(q.call,q);
|
||||
// qDebug() << "Added as worked:" << call << band << mode << date;
|
||||
}
|
||||
}
|
||||
|
||||
// return true if in the log same band and mode (where JT65 == JT9)
|
||||
|
@ -190,35 +214,3 @@ bool ADIF::addQSOToFile(QString const& hisCall, QString const& hisGrid, QString
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QString ADIF::bandFromFrequency(double dialFreq)
|
||||
{
|
||||
QString band="";
|
||||
if(dialFreq>0.135 and dialFreq<0.139) band="2200m";
|
||||
else if(dialFreq>0.45 and dialFreq<0.55) band="630m";
|
||||
else if(dialFreq>1.8 and dialFreq<2.0) band="160m";
|
||||
else if(dialFreq>3.5 and dialFreq<4.0) band="80m";
|
||||
else if(dialFreq>5.1 and dialFreq<5.45) band="60m";
|
||||
else if(dialFreq>7.0 and dialFreq<7.3) band="40m";
|
||||
else if(dialFreq>10.0 and dialFreq<10.15) band="30m";
|
||||
else if(dialFreq>14.0 and dialFreq<14.35) band="20m";
|
||||
else if(dialFreq>18.068 and dialFreq<18.168) band="17m";
|
||||
else if(dialFreq>21.0 and dialFreq<21.45) band="15m";
|
||||
else if(dialFreq>24.890 and dialFreq<24.990) band="12m";
|
||||
else if(dialFreq>28.0 and dialFreq<29.7) band="10m";
|
||||
else if(dialFreq>50.0 and dialFreq<54.0) band="6m";
|
||||
else if(dialFreq>70.0 and dialFreq<71.0) band="4m";
|
||||
else if(dialFreq>144.0 and dialFreq<148.0) band="2m";
|
||||
else if(dialFreq>222.0 and dialFreq<225.0) band="1.25m";
|
||||
else if(dialFreq>420.0 and dialFreq<450.0) band="70cm";
|
||||
else if(dialFreq>902.0 and dialFreq<928.0) band="33cm";
|
||||
else if(dialFreq>1240.0 and dialFreq<1300.0) band="23cm";
|
||||
else if(dialFreq>2300.0 and dialFreq<2450.0) band="13cm";
|
||||
else if(dialFreq>3300.0 and dialFreq<3500.0) band="9cm";
|
||||
else if(dialFreq>5650.0 and dialFreq<5925.0) band="6cm";
|
||||
else if(dialFreq>10000.0 and dialFreq<10500.0) band="3cm";
|
||||
else if(dialFreq>24000.0 and dialFreq<24250.0) band="1.25cm";
|
||||
else if(dialFreq>47000.0 and dialFreq<47200.0) band="6mm";
|
||||
else if(dialFreq>75500.0 and dialFreq<81000.0) band="4mm";
|
||||
return band;
|
||||
}
|
||||
|
|
|
@ -32,8 +32,6 @@ class ADIF
|
|||
bool addQSOToFile(QString const& hisCall, QString const& hisGrid, QString const& mode, QString const& rptSent, QString const& rptRcvd, QDateTime const& dateTimeOn, QDateTime const& dateTimeOff, QString const& band,
|
||||
QString const& comments, QString const& name, QString const& strDialFreq, QString const& m_myCall, QString const& m_myGrid, QString const& m_txPower);
|
||||
|
||||
static QString bandFromFrequency(double dialFreq);
|
||||
|
||||
private:
|
||||
struct QSO
|
||||
{
|
||||
|
@ -43,7 +41,7 @@ class ADIF
|
|||
QMultiHash<QString, QSO> _data;
|
||||
QString _filename;
|
||||
|
||||
QString _extractField(QString const& line, QString const& fieldName) const;
|
||||
QString extractField(QString const& line, QString const& fieldName) const;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -51,7 +51,6 @@ void CountryDat::_removeBrackets(QString &line, const QString a, const QString b
|
|||
QStringList CountryDat::_extractPrefix(QString &line, bool &more) const
|
||||
{
|
||||
line = line.remove(" \n");
|
||||
line = line.replace("=","");
|
||||
line = line.replace(" ","");
|
||||
|
||||
_removeBrackets(line,"(",")");
|
||||
|
@ -117,29 +116,38 @@ void CountryDat::load()
|
|||
}
|
||||
|
||||
// return country name else ""
|
||||
QString CountryDat::find(QString prefix) const
|
||||
QString CountryDat::find(QString call) const
|
||||
{
|
||||
prefix = prefix.toUpper ();
|
||||
auto pf = prefix;
|
||||
while (pf.size () >= 1)
|
||||
{
|
||||
if (_data.contains (pf))
|
||||
call = call.toUpper ();
|
||||
|
||||
// check for exact match first
|
||||
if (_data.contains ("=" + call))
|
||||
{
|
||||
return fixup (_data.value ("=" + call), call);
|
||||
}
|
||||
|
||||
auto prefix = call;
|
||||
while (prefix.size () >= 1)
|
||||
{
|
||||
if (_data.contains (prefix))
|
||||
{
|
||||
QString country {_data.value (pf)};
|
||||
|
||||
//
|
||||
// deal with special rules that cty.dat does not cope with
|
||||
//
|
||||
|
||||
// KG4 2x1 and 2x3 calls that map to Gitmo are mainland US not Gitmo
|
||||
if (prefix.startsWith ("KG4") && prefix.size () != 5)
|
||||
{
|
||||
country.replace ("Guantanamo Bay", "United States");
|
||||
}
|
||||
|
||||
return country;
|
||||
return fixup (_data.value (prefix), call);
|
||||
}
|
||||
pf = pf.left (pf.size () - 1);
|
||||
prefix = prefix.left (prefix.size () - 1);
|
||||
}
|
||||
return QString {};
|
||||
}
|
||||
}
|
||||
|
||||
QString CountryDat::fixup (QString country, QString const& call) const
|
||||
{
|
||||
//
|
||||
// deal with special rules that cty.dat does not cope with
|
||||
//
|
||||
|
||||
// KG4 2x1 and 2x3 calls that map to Gitmo are mainland US not Gitmo
|
||||
if (call.startsWith ("KG4") && call.size () != 5)
|
||||
{
|
||||
country.replace ("Guantanamo Bay", "United States");
|
||||
}
|
||||
return country;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ private:
|
|||
QString _extractName(const QString line) const;
|
||||
void _removeBrackets(QString &line, const QString a, const QString b) const;
|
||||
QStringList _extractPrefix(QString &line, bool &more) const;
|
||||
QString fixup (QString country, QString const& call) const;
|
||||
|
||||
QString _filename;
|
||||
QStringList _countryNames;
|
||||
|
|
|
@ -8,14 +8,18 @@
|
|||
|
||||
#include "logbook/adif.h"
|
||||
#include "MessageBox.hpp"
|
||||
#include "Configuration.hpp"
|
||||
#include "Bands.hpp"
|
||||
|
||||
#include "ui_logqso.h"
|
||||
#include "moc_logqso.cpp"
|
||||
|
||||
LogQSO::LogQSO(QString const& programTitle, QSettings * settings, QWidget *parent)
|
||||
LogQSO::LogQSO(QString const& programTitle, QSettings * settings
|
||||
, Configuration const * config, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui::LogQSO)
|
||||
, m_settings (settings)
|
||||
, m_config {config}
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowTitle(programTitle + " - Log QSO");
|
||||
|
@ -78,8 +82,7 @@ void LogQSO::initLogQSO(QString const& hisCall, QString const& hisGrid, QString
|
|||
m_dialFreq=dialFreq;
|
||||
m_myCall=myCall;
|
||||
m_myGrid=myGrid;
|
||||
QString band= ADIF::bandFromFrequency(dialFreq / 1.e6);
|
||||
ui->band->setText(band);
|
||||
ui->band->setText (m_config->bands ()->find (dialFreq));
|
||||
|
||||
show ();
|
||||
}
|
||||
|
|
4
logqso.h
|
@ -17,13 +17,14 @@ namespace Ui {
|
|||
}
|
||||
|
||||
class QSettings;
|
||||
class Configuration;
|
||||
|
||||
class LogQSO : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit LogQSO(QString const& programTitle, QSettings *, QWidget *parent = 0);
|
||||
explicit LogQSO(QString const& programTitle, QSettings *, Configuration const *, QWidget *parent = 0);
|
||||
~LogQSO();
|
||||
void initLogQSO(QString const& hisCall, QString const& hisGrid, QString mode,
|
||||
QString const& rptSent, QString const& rptRcvd, QDateTime const& dateTimeOn,
|
||||
|
@ -50,6 +51,7 @@ private:
|
|||
|
||||
QScopedPointer<Ui::LogQSO> ui;
|
||||
QSettings * m_settings;
|
||||
Configuration const * m_config;
|
||||
QString m_txPower;
|
||||
QString m_comments;
|
||||
Radio::Frequency m_dialFreq;
|
||||
|
|
509
mainwindow.cpp
21
mainwindow.h
|
@ -107,8 +107,8 @@ public slots:
|
|||
void diskDat();
|
||||
void freezeDecode(int n);
|
||||
void guiUpdate();
|
||||
void doubleClickOnCall(bool shift, bool ctrl);
|
||||
void doubleClickOnCall2(bool shift, bool ctrl);
|
||||
void doubleClickOnCall (Qt::KeyboardModifiers);
|
||||
void doubleClickOnCall2(Qt::KeyboardModifiers);
|
||||
void readFromStdout();
|
||||
void p1ReadFromStdout();
|
||||
void setXIT(int n, Frequency base = 0u);
|
||||
|
@ -149,10 +149,14 @@ private slots:
|
|||
void on_actionSave_all_triggered();
|
||||
void on_actionKeyboard_shortcuts_triggered();
|
||||
void on_actionSpecial_mouse_commands_triggered();
|
||||
void on_actionSolve_FreqCal_triggered();
|
||||
void on_actionCopyright_Notice_triggered();
|
||||
void on_DecodeButton_clicked (bool);
|
||||
void decode();
|
||||
void decodeBusy(bool b);
|
||||
void on_EraseButton_clicked();
|
||||
void band_activity_cleared ();
|
||||
void rx_frequency_activity_cleared ();
|
||||
void on_txFirstCheckBox_stateChanged(int arg1);
|
||||
void set_dateTimeQSO(int m_ntx);
|
||||
void set_ntx(int n);
|
||||
|
@ -222,7 +226,7 @@ private slots:
|
|||
void on_readFreq_clicked();
|
||||
void on_pbTxMode_clicked();
|
||||
void on_RxFreqSpinBox_valueChanged(int n);
|
||||
void on_cbTxLock_clicked(bool checked);
|
||||
void on_cbHoldTxFreq_clicked(bool checked);
|
||||
void on_outAttenuation_valueChanged (int);
|
||||
void rigOpen ();
|
||||
void handle_transceiver_update (Transceiver::TransceiverState const&);
|
||||
|
@ -277,6 +281,7 @@ private slots:
|
|||
void on_actionQRA64_triggered();
|
||||
void on_actionFreqCal_triggered();
|
||||
void splash_done ();
|
||||
void on_measure_check_box_stateChanged (int);
|
||||
|
||||
private:
|
||||
Q_SIGNAL void initializeAudioOutputStream (QAudioDeviceInfo,
|
||||
|
@ -401,6 +406,7 @@ private:
|
|||
qint32 m_nTx73;
|
||||
qint32 m_UTCdisk;
|
||||
qint32 m_wait;
|
||||
qint32 m_i3bit;
|
||||
|
||||
bool m_btxok; //True if OK to transmit
|
||||
bool m_diskData;
|
||||
|
@ -425,7 +431,7 @@ private:
|
|||
QString m_currentMessage;
|
||||
int m_lastMessageType;
|
||||
QString m_lastMessageSent;
|
||||
bool m_lockTxFreq;
|
||||
bool m_holdTxFreq;
|
||||
bool m_bShMsgs;
|
||||
bool m_bSWL;
|
||||
bool m_uploadSpots;
|
||||
|
@ -454,6 +460,9 @@ private:
|
|||
bool m_bDoubleClicked;
|
||||
bool m_bCallingCQ;
|
||||
bool m_bAutoReply;
|
||||
bool m_bCheckedContest;
|
||||
bool m_bDXped;
|
||||
|
||||
enum
|
||||
{
|
||||
CALLING,
|
||||
|
@ -593,8 +602,8 @@ private:
|
|||
void pskPost(DecodedText const& decodedtext);
|
||||
void displayDialFrequency ();
|
||||
void transmitDisplay (bool);
|
||||
void processMessage(DecodedText const&, bool ctrl = false, bool alt = false);
|
||||
void replyToCQ (QTime, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode, QString const& message_text);
|
||||
void processMessage(DecodedText const&, Qt::KeyboardModifiers = 0);
|
||||
void replyToCQ (QTime, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode, QString const& message_text, bool low_confidence, quint8 modifiers);
|
||||
void replayDecodes ();
|
||||
void postDecode (bool is_new, QString const& message);
|
||||
void postWSPRDecode (bool is_new, QStringList message_parts);
|
||||
|
|
959
mainwindow.ui
|
@ -8,20 +8,18 @@
|
|||
<td><b>Click</b> to set the Rx frequency.<br/>
|
||||
<b>Shift-click</b> to set Tx frequency.<br/>
|
||||
<b>Ctrl-click</b> to set Rx and Tx frequencies.<br/>
|
||||
<b>Double-click</b> to decode at resulting Rx frequency.<br/>
|
||||
If <b>Lock Tx=Rx</b> is checked all actions set Tx/Rx.
|
||||
<b>Double-click</b> to also decode at Rx frequency.<br/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">Decoded text:</td>
|
||||
<td><b>Double-click</b> to copy second callsign to Dx Call,<br/>
|
||||
locator to Dx Grid; change Rx and Tx frequencies to<br/>
|
||||
decoded signal's frequency; generate standard messages.<br/>
|
||||
If first callsign is your own, Tx frequency is not<br/>
|
||||
changed unless <b>Ctrl</b> is held down when double-clicking.<br/>
|
||||
<br/>
|
||||
<b>Alt-Double-click</b> to move only Rx frequency when<br/>
|
||||
replying to a CQ or QRZ caller.
|
||||
locator to Dx Grid, change Rx and Tx frequency to<br/>
|
||||
decoded signal's frequency, and generate standard<br/>
|
||||
messages.<br/>
|
||||
If <b>Hold Tx Freq</b> is checked or first callsign in message<br/>
|
||||
is your own call, Tx frequency is not changed unless <br/>
|
||||
<b>Ctrl</b> is held down.<br/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
15
plotter.cpp
|
@ -355,8 +355,10 @@ void CPlotter::DrawOverlay() //DrawOverlay()
|
|||
//draw frequency values
|
||||
for( int i=0; i<=m_hdivs; i++) {
|
||||
x = (int)((m_xOffset+i)*pixperdiv - pixperdiv/2);
|
||||
rect0.setRect(x,0, (int)pixperdiv, 20);
|
||||
painter0.drawText(rect0, Qt::AlignHCenter|Qt::AlignVCenter,m_HDivText[i]);
|
||||
if(int(x+pixperdiv/2) > 70) {
|
||||
rect0.setRect(x,0, (int)pixperdiv, 20);
|
||||
painter0.drawText(rect0, Qt::AlignHCenter|Qt::AlignVCenter,m_HDivText[i]);
|
||||
}
|
||||
}
|
||||
|
||||
float bw=9.0*12000.0/m_nsps; //JT9
|
||||
|
@ -637,14 +639,11 @@ void CPlotter::mousePressEvent(QMouseEvent *event) //mousePressEvent
|
|||
int newFreq = int(FreqfromX(x)+0.5);
|
||||
int oldTxFreq = m_txFreq;
|
||||
int oldRxFreq = m_rxFreq;
|
||||
|
||||
if (ctrl or m_lockTxFreq) {
|
||||
if (ctrl) {
|
||||
emit setFreq1 (newFreq, newFreq);
|
||||
}
|
||||
else if (shift) {
|
||||
} else if (shift) {
|
||||
emit setFreq1 (oldRxFreq, newFreq);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
emit setFreq1(newFreq,oldTxFreq);
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,6 @@ public:
|
|||
void setBreadth(qint32 w) {m_w = w;}
|
||||
qint32 breadth() const {return m_w;}
|
||||
float fSpan() const {return m_fSpan;}
|
||||
void setLockTxFreq(bool b) {m_lockTxFreq = b;}
|
||||
void setColours(QVector<QColor> const& cl);
|
||||
void setFlatten(bool b1, bool b2);
|
||||
void setTol(int n);
|
||||
|
@ -106,7 +105,6 @@ private:
|
|||
bool m_bLinearAvg;
|
||||
bool m_bReference;
|
||||
bool m_bReference0;
|
||||
bool m_lockTxFreq;
|
||||
bool m_bVHF;
|
||||
|
||||
float m_fSpan;
|
||||
|
|
54
prefixes.txt
|
@ -1,27 +1,27 @@
|
|||
Type 1 Prefixes and Suffixes:
|
||||
|
||||
1A 1S 3A 3B6 3B8 3B9 3C 3C0 3D2 3D2C 3D2R 3DA 3V 3W 3X
|
||||
3Y 3YB 3YP 4J 4L 4S 4U1I 4U1U 4W 4X 5A 5B 5H 5N 5R
|
||||
5T 5U 5V 5W 5X 5Z 6W 6Y 7O 7P 7Q 7X 8P 8Q 8R
|
||||
9A 9G 9H 9J 9K 9L 9M2 9M6 9N 9Q 9U 9V 9X 9Y A2
|
||||
A3 A4 A5 A6 A7 A9 AP BS7 BV BV9 BY C2 C3 C5 C6
|
||||
C9 CE CE0X CE0Y CE0Z CE9 CM CN CP CT CT3 CU CX CY0 CY9
|
||||
D2 D4 D6 DL DU E3 E4 EA EA6 EA8 EA9 EI EK EL EP
|
||||
ER ES ET EU EX EY EZ F FG FH FJ FK FKC FM FO
|
||||
FOA FOC FOM FP FR FRG FRJ FRT FT5W FT5X FT5Z FW FY M MD
|
||||
MI MJ MM MU MW H4 H40 HA HB HB0 HC HC8 HH HI HK
|
||||
HK0A HK0M HL HM HP HR HS HV HZ I IS IS0 J2 J3 J5
|
||||
J6 J7 J8 JA JDM JDO JT JW JX JY K KG4 KH0 KH1 KH2
|
||||
KH3 KH4 KH5 KH5K KH6 KH7 KH8 KH9 KL KP1 KP2 KP4 KP5 LA LU
|
||||
LX LY LZ OA OD OE OH OH0 OJ0 OK OM ON OX OY OZ
|
||||
P2 P4 PA PJ2 PJ7 PY PY0F PT0S PY0T PZ R1F R1M S0 S2 S5
|
||||
S7 S9 SM SP ST SU SV SVA SV5 SV9 T2 T30 T31 T32 T33
|
||||
T5 T7 T8 T9 TA TF TG TI TI9 TJ TK TL TN TR TT
|
||||
TU TY TZ UA UA2 UA9 UK UN UR V2 V3 V4 V5 V6 V7
|
||||
V8 VE VK VK0H VK0M VK9C VK9L VK9M VK9N VK9W VK9X VP2E VP2M VP2V VP5
|
||||
VP6 VP6D VP8 VP8G VP8H VP8O VP8S VP9 VQ9 VR VU VU4 VU7 XE XF4
|
||||
XT XU XW XX9 XZ YA YB YI YJ YK YL YN YO YS YU
|
||||
YV YV0 Z2 Z3 ZA ZB ZC4 ZD7 ZD8 ZD9 ZF ZK1N ZK1S ZK2 ZK3
|
||||
ZL ZL7 ZL8 ZL9 ZP ZS ZS8 KC4 E5
|
||||
|
||||
Short-list of Add-on Suffixes: /0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /A /P
|
||||
Type 1 Prefixes and Suffixes:
|
||||
|
||||
1A 1S 3A 3B6 3B8 3B9 3C 3C0 3D2 3D2C 3D2R 3DA 3V 3W 3X
|
||||
3Y 3YB 3YP 4J 4L 4S 4U1I 4U1U 4W 4X 5A 5B 5H 5N 5R
|
||||
5T 5U 5V 5W 5X 5Z 6W 6Y 7O 7P 7Q 7X 8P 8Q 8R
|
||||
9A 9G 9H 9J 9K 9L 9M2 9M6 9N 9Q 9U 9V 9X 9Y A2
|
||||
A3 A4 A5 A6 A7 A9 AP BS7 BV BV9 BY C2 C3 C5 C6
|
||||
C9 CE CE0X CE0Y CE0Z CE9 CM CN CP CT CT3 CU CX CY0 CY9
|
||||
D2 D4 D6 DL DU E3 E4 EA EA6 EA8 EA9 EI EK EL EP
|
||||
ER ES ET EU EX EY EZ F FG FH FJ FK FKC FM FO
|
||||
FOA FOC FOM FP FR FRG FRJ FRT FT5W FT5X FT5Z FW FY M MD
|
||||
MI MJ MM MU MW H4 H40 HA HB HB0 HC HC8 HH HI HK
|
||||
HK0A HK0M HL HM HP HR HS HV HZ I IS IS0 J2 J3 J5
|
||||
J6 J7 J8 JA JDM JDO JT JW JX JY K KG4 KH0 KH1 KH2
|
||||
KH3 KH4 KH5 KH5K KH6 KH7 KH8 KH9 KL KP1 KP2 KP4 KP5 LA LU
|
||||
LX LY LZ OA OD OE OH OH0 OJ0 OK OM ON OX OY OZ
|
||||
P2 P4 PA PJ2 PJ7 PY PY0F PT0S PY0T PZ R1F R1M S0 S2 S5
|
||||
S7 S9 SM SP ST SU SV SVA SV5 SV9 T2 T30 T31 T32 T33
|
||||
T5 T7 T8 T9 TA TF TG TI TI9 TJ TK TL TN TR TT
|
||||
TU TY TZ UA UA2 UA9 UK UN UR V2 V3 V4 V5 V6 V7
|
||||
V8 VE VK VK0H VK0M VK9C VK9L VK9M VK9N VK9W VK9X VP2E VP2M VP2V VP5
|
||||
VP6 VP6D VP8 VP8G VP8H VP8O VP8S VP9 VQ9 VR VU VU4 VU7 XE XF4
|
||||
XT XU XW XX9 XZ YA YB YI YJ YK YL YN YO YS YU
|
||||
YV YV0 Z2 Z3 ZA ZB ZC4 ZD7 ZD8 ZD9 ZF ZK1N ZK1S ZK2 ZK3
|
||||
ZL ZL7 ZL8 ZL9 ZP ZS ZS8 KC4 E5
|
||||
|
||||
Short-list of Add-on Suffixes: /0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /A /P
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<table cellspacing=1>
|
||||
<tr><td><b>F1 </b></td><td>Online User's Guide</td></tr>
|
||||
<tr><td><b>Shift+F1 </b></td><td>Copyright Notice</td></tr>
|
||||
<tr><td><b>Ctrl+F1 </b></td><td>About WSJT-X</td></tr>
|
||||
<tr><td><b>F2 </b></td><td>Open settings window</td></tr>
|
||||
<tr><td><b>F3 </b></td><td>Display keyboard shortcuts</td></tr>
|
||||
|
|
|
@ -22,7 +22,6 @@ WideGraph::WideGraph(QSettings * settings, QWidget *parent) :
|
|||
m_settings (settings),
|
||||
m_palettes_path {":/Palettes"},
|
||||
m_ntr0 {0},
|
||||
m_lockTxFreq {false},
|
||||
m_bHaveTransmitted {false},
|
||||
m_n {0}
|
||||
{
|
||||
|
@ -230,7 +229,6 @@ void WideGraph::setRxFreq(int n) //set
|
|||
{
|
||||
ui->widePlot->setRxFreq(n);
|
||||
ui->widePlot->draw(swide,false,false);
|
||||
if(m_lockTxFreq) setTxFreq(n);
|
||||
}
|
||||
|
||||
int WideGraph::rxFreq() //rxFreq
|
||||
|
@ -333,12 +331,6 @@ void WideGraph::on_fSplitSpinBox_valueChanged(int n) //fSplit
|
|||
setRxRange ();
|
||||
}
|
||||
|
||||
void WideGraph::setLockTxFreq(bool b) //LockTxFreq
|
||||
{
|
||||
m_lockTxFreq=b;
|
||||
ui->widePlot->setLockTxFreq(b);
|
||||
}
|
||||
|
||||
void WideGraph::setFreq2(int rxFreq, int txFreq) //setFreq2
|
||||
{
|
||||
emit setFreq3(rxFreq,txFreq);
|
||||
|
|
|
@ -40,7 +40,6 @@ public:
|
|||
void setMode(QString mode);
|
||||
void setSubMode(int n);
|
||||
void setModeTx(QString modeTx);
|
||||
void setLockTxFreq(bool b);
|
||||
bool flatten();
|
||||
bool useRef();
|
||||
void setTol(int n);
|
||||
|
@ -104,7 +103,6 @@ private:
|
|||
qint32 m_nSubMode;
|
||||
qint32 m_nsmo;
|
||||
qint32 m_Percent2DScreen;
|
||||
bool m_lockTxFreq;
|
||||
bool m_bFlatten;
|
||||
bool m_bRef;
|
||||
bool m_bHaveTransmitted; //Set true at end of a WSPR transmission
|
||||
|
|
22
widegraph.ui
|
@ -7,7 +7,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>799</width>
|
||||
<height>395</height>
|
||||
<height>337</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -34,6 +34,12 @@
|
|||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
|
@ -52,18 +58,12 @@
|
|||
<widget class="QCheckBox" name="cbControls">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>9</x>
|
||||
<y>10</y>
|
||||
<width>60</width>
|
||||
<x>5</x>
|
||||
<y>0</y>
|
||||
<width>63</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>65</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Controls</string>
|
||||
</property>
|
||||
|
@ -76,7 +76,7 @@
|
|||
<item>
|
||||
<widget class="QWidget" name="controls_widget" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
|
|
|
@ -66,7 +66,8 @@ SOURCES += \
|
|||
main.cpp decodedtext.cpp wsprnet.cpp messageaveraging.cpp \
|
||||
echoplot.cpp echograph.cpp fastgraph.cpp fastplot.cpp Modes.cpp \
|
||||
WSPRBandHopping.cpp MessageAggregator.cpp SampleDownloader.cpp qt_helpers.cpp\
|
||||
MultiSettings.cpp PhaseEqualizationDialog.cpp IARURegions.cpp
|
||||
MultiSettings.cpp PhaseEqualizationDialog.cpp IARURegions.cpp MessageBox.cpp \
|
||||
EqualizationToolsDialog.cpp
|
||||
|
||||
HEADERS += qt_helpers.hpp \
|
||||
pimpl_h.hpp pimpl_impl.hpp \
|
||||
|
@ -82,7 +83,8 @@ HEADERS += qt_helpers.hpp \
|
|||
logbook/logbook.h logbook/countrydat.h logbook/countriesworked.h logbook/adif.h \
|
||||
messageaveraging.h echoplot.h echograph.h fastgraph.h fastplot.h Modes.hpp WSPRBandHopping.hpp \
|
||||
WsprTxScheduler.h SampleDownloader.hpp MultiSettings.hpp PhaseEqualizationDialog.hpp \
|
||||
IARURegions.hpp
|
||||
IARURegions.hpp MessageBox.hpp EqualizationToolsDialog.hpp
|
||||
|
||||
|
||||
INCLUDEPATH += qmake_only
|
||||
|
||||
|
|