Compare commits

...

487 Commits

Author SHA1 Message Date
Joe Taylor
bf4aa5f4e9 Merge branch 'develop' of bitbucket.org:k1jt/wsjtx into develop 2024-09-27 10:02:18 -04:00
Joe Taylor
25ae16af1a A few more updates to Release Notes and NEWS. 2024-09-27 10:01:42 -04:00
Uwe Risse
ac406a1559 Update window "Special mouse commands". 2024-09-27 14:49:06 +02:00
Uwe Risse
656793f2d7 Right-clicking on the H button now activates/deactivates SuperFox mode. 2024-09-27 13:41:34 +02:00
Joe Taylor
043b721ad7 Fix a typo in User Guide. 2024-09-26 21:09:04 -04:00
Joe Taylor
7cfafa7846 Write the $VERIFY$ messages to ALL.TXT, after all. 2024-09-26 14:18:42 -04:00
Joe Taylor
999caa9e99 Merge branch 'develop' of bitbucket.org:k1jt/wsjtx into develop 2024-09-26 09:16:41 -04:00
Uwe Risse
eaa47122d8 Allow a compound prefix or suffix to be added to the DX call in SuperHound mode. 2024-09-26 14:44:17 +02:00
Uwe Risse
c75574339b Minor correction of the notes. 2024-09-26 09:09:32 +02:00
Uwe Risse
7b27757c2a Don't send SuperFox OTP messages to messageClient. 2024-09-26 08:54:29 +02:00
Brian Moran
761bf83069 handle slashes in a callsign that needs verification 2024-09-25 14:37:55 -07:00
Uwe Risse
5172c1da52 Fix Enable Tx is locked when switching from SH to SF, and make sure m_XIT is zero. 2024-09-25 20:57:45 +02:00
Joe Taylor
6d0b47f129 Update the SuperFox bit-packing documentation. 2024-09-25 14:49:18 -04:00
Uwe Risse
c2cf7d3353 Activate CW QRM subtraction. 2024-09-25 18:56:37 +02:00
Joe Taylor
9f7a6a4988 Do the NQU1RKS patch for SF message type i3=3, the CQ message. 2024-09-25 11:20:45 -04:00
Joe Taylor
f01239c000 Apply the QU1RKS patch to SF i3=0 messages, and some code cleanup. 2024-09-25 10:49:00 -04:00
Joe Taylor
3fc573f4e1 Allow sfoxsim to generate "CQ <FoxCall> FN20" messages. 2024-09-25 10:20:26 -04:00
Uwe Risse
9ea6d8d3b9 Preparations for release. 2024-09-24 20:06:58 +02:00
Uwe Risse
197d7cb7a9 Update file NEWS. 2024-09-24 18:55:10 +02:00
Steven Franke
4eceffa9a2 Tweaks to sfox_remove_tone. 2024-09-24 10:07:40 -05:00
Joe Taylor
4b37a41dc6 Minor editing of Release_Notes.txt. 2024-09-24 11:02:06 -04:00
Joe Taylor
33637034af Merge branch 'develop' of bitbucket.org:k1jt/wsjtx into develop 2024-09-24 10:07:30 -04:00
Joe Taylor
b571f63d98 Add the file describing bit packing for SuperFox message types. 2024-09-24 09:59:14 -04:00
Uwe Risse
37d71f4af7 Minor corrections. 2024-09-24 14:23:27 +02:00
Uwe Risse
b1c7b732e6 Update links to the OpenSSL v1.1.1 installation packages to my server for now, as v1.1.1 files are no longer available on https://slsproweb.com. 2024-09-24 14:17:05 +02:00
Uwe Risse
aa9e625c23 Update cty.dat file. 2024-09-24 13:51:54 +02:00
Uwe Risse
2ab23d18ab Some text modules for the Release Notes. 2024-09-24 13:39:06 +02:00
Steven Franke
69629c3748 More work on tone removal. 2024-09-23 17:27:01 -05:00
Uwe Risse
fbe0fe216b Fix an inconsistency with the WideGraph goal posts. 2024-09-23 22:06:22 +02:00
Uwe Risse
86dfd480af We better leave this condition here. For SF, this is initialized later anyway.
(cherry picked from commit 1aa77bd4dd760626c77a7461dca265d6a4b87059)
2024-09-23 18:02:39 +02:00
Uwe Risse
1c37576885 Revert "Let's try it again with NSlots=4 (but with m_NSlots correctly set)."
This reverts commit 0b5cfb26ebf9b5814bb18dc36437968d8882e979.
2024-09-23 14:11:58 +02:00
Uwe Risse
0b5cfb26eb Let's try it again with NSlots=4 (but with m_NSlots correctly set). 2024-09-23 13:07:22 +02:00
Uwe Risse
24ea7d0e6a Make sure that m_Nslots is really changed. 2024-09-23 12:58:20 +02:00
Uwe Risse
be021f0d01 Change expiry date to October 10, 2024. 2024-09-23 12:52:18 +02:00
Uwe Risse
8304c9f3cd Display sbNslots in SuperFox mode too, but then don't allow to change its value manually. 2024-09-23 12:50:59 +02:00
Uwe Risse
a87fd4b6a1 This code is perhaps a little more robust. 2024-09-23 12:24:14 +02:00
Uwe Risse
3a9c1256bd Limit NSlots to 2 if an SF free text message is to be sent. 2024-09-23 12:22:24 +02:00
Uwe Risse
131aca18dc Revert "More (final?) corrections to logic for handling SF free text messages."
This reverts commit f8079fbcbebcc1e2c9f9a951405e29582ea94483.
2024-09-23 12:18:42 +02:00
Uwe Risse
24db8a23eb Delete this line as it causes the program to crash on macOS Sequoia. 2024-09-23 10:56:32 +02:00
Joe Taylor
2c5aaca6ab Change Tx message display from 'TE0ST RR73 DG2YCB' to 'TE0ST DG2YCB RR73'. 2024-09-22 16:17:16 -04:00
Steven Franke
16d85d0867 Minor tweaks to sfrx.f90. 2024-09-22 10:00:20 -05:00
Steven Franke
6a154b4e6f Reconfigure sfrx to call sfrx_sub. 2024-09-22 09:57:36 -05:00
Uwe Risse
bf242d03e5 Limit free text message to 13 characters for old-style Fox mode. 2024-09-22 13:58:28 +02:00
Steven Franke
37f5abc35c Fix argument handling in sfoxsim.f90. 2024-09-21 18:28:49 -05:00
Joe Taylor
77e93a81e1 Merge branch 'sfox5b' of bitbucket.org:k1jt/wsjtx into sfox5b 2024-09-21 15:33:02 -04:00
Joe Taylor
f8079fbcbe More (final?) corrections to logic for handling SF free text messages. 2024-09-21 15:31:48 -04:00
Steven Franke
e1f455d821 Bring sfoxsim over from superfoxtx repository. 2024-09-21 12:51:48 -05:00
Uwe Risse
9b65b6c4e5 Change it here too. 2024-09-21 18:10:37 +02:00
Joe Taylor
2c54019a4b Merge branch 'sfox5b' of bitbucket.org:k1jt/wsjtx into sfox5b 2024-09-21 10:30:52 -04:00
Joe Taylor
2e5ef07a72 Correct the logic for nMaxRemainingSlots. 2024-09-21 10:30:04 -04:00
Uwe Risse
0f3b451c87 Prevent SuperHounds from being able to edit Tx3 manually. 2024-09-21 14:43:17 +02:00
Uwe Risse
6723004254 Tab 1 must be the default Tab (currentIndex=0). 2024-09-20 23:37:02 +02:00
Joe Taylor
0b32418727 Display yellow-background SF free text message only once. 2024-09-20 16:02:48 -04:00
Uwe Risse
a958874d3b Fix SuperFox free text messages not working anymore. 2024-09-20 18:09:29 +02:00
Uwe Risse
4dfc1cc98f Restore the previous NSlots value when switching from SuperFox to Fox mode. 2024-09-20 17:18:58 +02:00
Uwe Risse
cbd79b24e6 Correct GUI stretching for tab 2. 2024-09-20 16:59:47 +02:00
Uwe Risse
5e370438c3 Revert "Set a max horiz size for the "Queue" panel on Fox tab 2."
This reverts commit 57b524db513e8f9ba9c29b5fa2e5f0d561c525b9.
2024-09-20 16:58:15 +02:00
Joe Taylor
959b93bf61 Merge branch 'sfox5b' of bitbucket.org:k1jt/wsjtx into sfox5b 2024-09-20 10:11:39 -04:00
Joe Taylor
57b524db51 Set a max horiz size for the "Queue" panel on Fox tab 2. 2024-09-20 10:08:04 -04:00
Uwe Risse
ed19a92e2a Revert "Explicitly allow the Fox to transmit after the Tx frequency has been set at least 3 kHz from the main FT8 sub-bands."
This reverts commit 8e0df8c0eacca481922aae88ee841913cf3d375a.
2024-09-20 15:33:42 +02:00
Uwe Risse
8e0df8c0ea Explicitly allow the Fox to transmit after the Tx frequency has been set at least 3 kHz from the main FT8 sub-bands. 2024-09-20 14:50:03 +02:00
Uwe Risse
4f9d0da8c6 Don't reset to band/mode default frequency unless really needed when in FT8 mode. Very useful for (Super) Fox or Hound operation. 2024-09-20 14:30:24 +02:00
Uwe Risse
2458468411 Make sure Rx frequency is really set to 750 +- 50 Hz when switching to SuperHound mode. 2024-09-20 10:43:18 +02:00
Joe Taylor
10aead3962 Better to just delete the whole block. 2024-09-19 13:25:11 -04:00
Joe Taylor
f60db58372 Fix the Superfox "please confirm Rx Freq" warning. Don't set FTol=20 in SuperFox mode. 2024-09-19 13:19:59 -04:00
Uwe Risse
2b2d790da2 Correct some inconsistencies. 2024-09-19 13:08:12 +02:00
Uwe Risse
5053ddf063 Prevent tuning from being started at even periods when in SuperHound mode. 2024-09-19 11:36:43 +02:00
Uwe Risse
2ab36d0a13 Ignore stations calling in the wrong time slot when in Hound mode. 2024-09-19 11:13:45 +02:00
Brian Moran
885691e170 leadings zeroes should be included 2024-09-18 19:31:25 -07:00
Uwe Risse
ab8917d66a Update Darwin ReadME.txt file. Thanks to John G4KLA. 2024-09-18 20:52:53 +02:00
Steven Franke
acbc3095e9 Updates to remove_tone() routine. Currently disabled pending more tests. 2024-09-18 13:18:07 -05:00
Uwe Risse
6b98c85473 Remove the Fox MaxDB function. Keep m_max_dB for now, just set it to 70 dB. 2024-09-18 18:25:28 +02:00
Uwe Risse
463f655236 Use ShowOTP instead of HideOTP, and reverse the logic of this checkbox. 2024-09-18 16:52:11 +02:00
Uwe Risse
8eb0f8a50c Better initialization of the height of tab 1. 2024-09-18 12:04:01 +02:00
Uwe Risse
bc480ede6d Save some height when not in Fox or SuperFox mode. 2024-09-18 02:26:36 +02:00
Steven Franke
e027c9ea3c fortran_charlen_t should be size_t, not int, with Clang on MacOS. 2024-09-17 16:00:13 -05:00
Joe Taylor
5c2d01d8b4 Merge branch 'sfox5b' of bitbucket.org:k1jt/wsjtx into sfox5b 2024-09-17 15:28:55 -04:00
Joe Taylor
c826220c01 Remove another unused argument, this time for sfox_wave_gfsk(). 2024-09-17 15:27:59 -04:00
Brian Moran
d15f992864 freetext message dialog for regular FH
(cherry picked from commit 8b09f479fef76f3c862f6d05f47c17938fcd3625)
2024-09-17 20:54:30 +02:00
Joe Taylor
75c66390ea Merge branch 'sfox5b' of bitbucket.org:k1jt/wsjtx into sfox5b 2024-09-17 14:46:15 -04:00
Joe Taylor
e7c0cde160 Remove unused arguments to sftx_sub(). Fix a bug transmitting with empty OTP key. 2024-09-17 14:44:54 -04:00
Steven Franke
3446b45b2b This fixes the all-zeroes SNR issue on MacOS. 2024-09-17 13:44:10 -05:00
Joe Taylor
7895172d3f Code cleanup to satisfy warning messages. 2024-09-17 13:21:01 -04:00
Joe Taylor
3c4450cdc2 Do not use sfox_1.dat and sfox_2.dat; pass some args in common/foxcom3/. 2024-09-17 12:50:30 -04:00
Joe Taylor
11749ebef9 Add subroutine sftx_sub.f90. 2024-09-17 11:35:30 -04:00
Joe Taylor
f0a329c4d2 Call sftx_sub() rather than invoking external process sftx[.exe]. 2024-09-17 11:29:16 -04:00
Joe Taylor
dcb8c6ce6b SuperFox Tx now works with sftx[.exe] built as part of the wsjtx package. 2024-09-17 10:24:02 -04:00
Joe Taylor
4400f7464c Minor code cleanup. 2024-09-17 09:34:06 -04:00
Joe Taylor
1621ec61e5 Add sfrx_sub.f90. 2024-09-17 09:15:23 -04:00
Joe Taylor
eb500cbe87 Call sfrx_sub as a subroutine rather than sfrx as a separate process. 2024-09-17 09:13:27 -04:00
Uwe Risse
a18f1a5f66 Minor corrections. 2024-09-17 13:49:02 +02:00
Uwe Risse
eca508faf9 Remove links to the old SF binaries. 2024-09-17 12:24:12 +02:00
Uwe Risse
ecde7e8cc9 A slightly more intuitive arrangement of the OTP control elements. 2024-09-17 12:23:21 +02:00
Joe Taylor
0aee7e747b Update wsjtx.pro by adding Network.pri, etc. 2024-09-16 16:43:33 -04:00
Joe Taylor
d845bd0466 Building sfrx[.exe] in the wsjtx repository is now basically operational. 2024-09-16 14:49:07 -04:00
Joe Taylor
073e644f12 Reconcile sync8.f90 between superfoxtx branch and sfox5b. 2024-09-16 10:36:03 -04:00
Joe Taylor
9a8e43c1d5 Remove pre-built binaries of sfrx, sftx, and foxchk. 2024-09-16 09:29:50 -04:00
Joe Taylor
398a2dc671 Merge branch 'sfox5a' into sfox5 2024-09-16 09:15:16 -04:00
Joe Taylor
5f06e6d535 Remove another reference to RC6 FoxKey; warn if SuperHound sets rxFreq far away from 750 Hz. 2024-09-12 14:15:51 -04:00
Joe Taylor
712cf59fbb Remove the code for input of the RC6-style FoxKey. 2024-09-12 14:14:22 -04:00
Uwe Risse
19ccf338af Allow waterfall clicks to set the Rx frequency in Super Hound mode only between 700 and 800 Hz. 2024-09-12 11:08:28 +02:00
Uwe Risse
d8f42ec965 Allow the SuperFox to be called only by double-clicking so that it must be received first. 2024-09-09 15:38:48 +02:00
Uwe Risse
49eac1dbd3 Remove an obsolete file. 2024-09-09 15:32:44 +02:00
Uwe Risse
46595d45e8 Don't reset bg color of the Hound label to red for every non-verified message. 2024-09-09 15:30:36 +02:00
Uwe Risse
b4d8f47bab Add 64-bit SF binaries for Windows, Linux and macOS x86_64 (e4430e3). 2024-09-09 15:20:31 +02:00
Uwe Risse
827e8e37b5 Ad an option to Hide OTP messages, and switch bg color of the Hound label to green when verified is received. 2024-09-09 12:29:13 +02:00
Uwe Risse
a52559758a Switch FOX_OTP option ON, and prevent a compilation error when it is switched of. 2024-09-08 17:01:18 +02:00
Uwe Risse
223d9f5d63 Workaround for a compilation error with Qt 5.12. 2024-09-08 14:02:57 +02:00
Brian Moran
521a0e1a0d remove qcalendar header inclusion 2024-09-07 09:02:17 -07:00
Brian Moran
4c0eaece7e use more QT-specific library for TOTP 2024-09-07 08:23:02 -07:00
Brian Moran
f8c31aea3e add key only if OTPEnabled 2024-09-06 10:26:40 -07:00
Brian Moran
4298a000a0 lower case for verified and invalid messages 2024-09-06 06:43:58 -07:00
Brian Moran
ec72810451 up to 6 chars in callsign. Use setting for OTP URL 2024-09-06 06:19:50 -07:00
Brian Moran
ea11259c27 fix issue with show already worked not working 2024-09-03 17:07:27 -07:00
Brian Moran
869cff683f fix issue with braces; change type 2024-09-03 13:18:00 -07:00
Brian Moran
bd00c25ca2 clean up some definitions 2 2024-09-03 13:11:44 -07:00
Brian Moran
f9906120d3 clean up some definitions 2024-09-03 13:11:12 -07:00
Brian Moran
91661c1d95 show freq of regular fox verification msg 2024-09-03 13:09:36 -07:00
Brian Moran
fe833b26ce add otp code 2024-09-03 10:51:12 -07:00
Brian Moran
6997682425 OTP for regular f/h mode 2024-09-03 09:35:50 -07:00
Brian Moran
b0979968f3 Merge remote-tracking branch 'origin/sfox4' into sfox4_b2_otp 2024-09-01 14:03:38 -07:00
Uwe Risse
991cdd1912 Update 64-bit SF binaries for Windows and Linux to commit 81cd19b. 2024-09-01 22:15:01 +02:00
Uwe Risse
ab5f75192b Set RxFreqSpinBox to 750 Hz when switching to Super Hound mode and > 50 Hz away from 750 Hz. 2024-09-01 21:54:09 +02:00
Uwe Risse
3f4f88e712 Limit the processing of some lines to ARRL_DIGI mode. This prevents a program crash when compiled with Qt6 and in Fox mode. 2024-09-01 10:44:37 +02:00
Uwe Risse
7040d69a46 Limit the number of Tx3 hound replies to 6. 2024-08-31 11:54:24 +02:00
Brian Moran
6a52bb1f69 per Uwe 2024-08-30 10:34:33 -07:00
Brian Moran
2886979717 Merge branch 'sfox4' into sfox4_b2_otp 2024-08-30 08:05:00 -07:00
Brian Moran
ffd5dd1db2 remove hound callsign from left hand side if clicked on in active station window 2024-08-29 10:11:23 -07:00
Brian Moran
30c87ea019 disregard clicks in active stations window for those already in progress 2024-08-27 13:10:42 -07:00
Uwe Risse
85437c4e9d Show all combo box entries without scrolling. 2024-08-27 14:39:45 +02:00
Uwe Risse
467451e37d Fix a compatibility issue with Qt 5.12. 2024-08-26 20:46:26 +02:00
Brian Moran
764c64a829 merge 2024-08-18 19:56:45 -07:00
Brian Moran
157642d7cb merge 2024-08-18 18:21:29 -07:00
Uwe Risse
39dd848b66 Add SF f78fcfe executables for Windows 64-bit. 2024-08-18 16:32:08 +02:00
Uwe Risse
4cbc957593 Save and restore the SF Ftol value independently of the other modes.
(cherry picked from commit 9ef5cbb990df60b141be9ce0d808ff4452238984)
2024-08-18 11:38:47 +02:00
Brian Moran
9c7316226a SF-type 0 msgs send only 4 call+rpt but up to 5 RR73 2024-08-16 14:48:16 -07:00
Brian Moran
4916c77d10 Merge remote-tracking branch 'origin/sfox4_b2' into sfox4_b2 2024-08-15 15:31:37 -07:00
Brian Moran
cc4d56691f sort hound Age ascending 2024-08-15 15:30:54 -07:00
Uwe Risse
3e76477a61 Reset m_wideGraph->setSuperHound() parameter when leaving SuperHound mode.
(cherry picked from commit 30d86bfa923cb4e87a08939f02851e4d56576eef)
2024-08-15 21:21:10 +02:00
Joe Taylor
69cdb486cf Reset red/greep goal posts in Wide Graph for SuperFox and SuperHound. 2024-08-15 11:33:46 -04:00
Joe Taylor
4a549b9a3b Correct the logic for setting green tick mark for highest SuperFox freq. 2024-08-15 09:13:09 -04:00
Brian Moran
9c3a0d5e1c widen key field 2024-08-14 20:49:12 -07:00
Brian Moran
e26d2cb02c merge 2024-08-14 20:26:51 -07:00
Joe Taylor
56f862287a Bump RC number to 7. 2024-08-14 19:20:58 -04:00
Brian Moran
a8eaa66f2a default colors in Hound controls 2024-08-14 09:51:26 -07:00
Joe Taylor
3efa42cb65 Finisg commiting the removal of [-c grid] from ft4code.f90 and ft8code.f90. 2024-08-14 12:47:43 -04:00
Joe Taylor
d1d0d8a0d0 Remove unused part of the ft8code "Usage" message. Thanks to Pengo, VK3PGO. 2024-08-14 12:23:44 -04:00
Joe Taylor
fb1a75e81f Use forward slash in path, even on Windows. 2024-08-14 12:10:15 -04:00
Joe Taylor
1186b0bb8b Send RxFreq and FTol from wsjtx to sfrx, and display them on WideGraph. 2024-08-14 10:03:46 -04:00
Brian Moran
8066947c53 default colors in Hound controls 2024-08-13 19:29:54 -07:00
Brian Moran
d7981738fe use age calculation consistently 2024-08-13 18:19:55 -07:00
Brian Moran
0d7612218f show SFox tx messages in ALL.TXT 2024-08-13 18:19:43 -07:00
Brian Moran
2e6a4f597b additional array sizes needing adjustment 2024-08-13 18:19:24 -07:00
Brian Moran
3fdd69d021 increase # of early decodes; check bounds before increasing iterator 2024-08-13 18:18:56 -07:00
Brian Moran
a304177491 Merge remote-tracking branch 'origin/sfox4' into sfox4_b2 2024-08-13 18:17:45 -07:00
Brian Moran
f40b2c255c add foxverifier files 2024-08-11 14:28:39 -07:00
Uwe Risse
08866b0d75 Ignore stations calling in the wrong time slot when in Hound mode. 2024-08-11 11:54:09 +02:00
Uwe Risse
914c6f3e7b Prevent tuning on top of a SuperFox message. 2024-08-10 20:42:24 +02:00
Brian Moran
6ddc7cf7f9 prototype automated checking of OTPs 2024-08-08 15:25:57 -07:00
Brian Moran
c2531f675e FOX_OTP option; embiggen the FoxKey field 2024-08-08 15:18:10 -07:00
Brian Moran
8e6ca93259 highlighting callsigns, annotating callsigns, sort hounds on more criteria 2024-08-02 16:46:22 -07:00
Steven Franke
9a7ae401e7 An attempt to fix the msk144 crash on macos. 2024-07-22 13:28:21 -05:00
Uwe Risse
875602975b Update SF executables to commit 6e3f191. 2024-07-18 16:58:51 +02:00
Joe Taylor
458641f827 Merge branch 'sfox4' of bitbucket.org:k1jt/wsjtx into sfox4 2024-07-18 10:42:20 -04:00
Joe Taylor
e94d243d61 Update Release_Notes.txt and NEWS for RC6. 2024-07-18 10:41:26 -04:00
Steven Franke
c9f90dcb06 Update mac executables to commit 9a3db75. 2024-07-18 09:17:43 -05:00
Joe Taylor
a6f8237dac Updates to cwsim. 2024-07-18 08:33:41 -04:00
Uwe Risse
13b66c111f Remove support for directory paths with embedded blanks, as the previous code can lead to problems on macOS and Linux. 2024-07-18 12:02:48 +02:00
Steven Franke
3935c4997e Update mac executables to sf commit 6e3f191. 2024-07-17 16:29:19 -05:00
Joe Taylor
c79d24ca61 Tell Windows users not to install into a directory path with an embedded blank. 2024-07-17 16:57:50 -04:00
Joe Taylor
867d2fe1d9 Correct for UTC wrap-around in setting Hound 'Age'. Max Age = 99. 2024-07-17 16:36:47 -04:00
Uwe Risse
b0bd2b6310 Add SF executables for Windows 32-bit (f582329). 2024-07-17 12:59:45 +02:00
Uwe Risse
743e187729 Remove some old SF executables. 2024-07-17 12:58:05 +02:00
Uwe Risse
1e7c92fe76 Update Windows executables to f582329. 2024-07-17 12:02:29 +02:00
Uwe Risse
52022e507e First steps towards RC6. 2024-07-17 12:00:28 +02:00
Steven Franke
9cb2eae76e Update mac x86 executables. 2024-07-16 17:25:57 -05:00
Uwe Risse
12c1b4d976 Fixed background color of the Super Hound label not always being reset correctly. 2024-07-13 14:28:06 +02:00
Uwe Risse
ab1669b6f2 Allow spotting of received SuperFox massages to PSK Reporter. 2024-07-13 12:19:05 +02:00
Brian Moran
66d1b6640e FT8_SH should be indicated for Tx too 2024-07-12 13:47:42 -07:00
Brian Moran
d8b17cff83 ALL.txt displays verified message, FT8_SH mode indicator 2024-07-12 13:17:33 -07:00
Uwe Risse
be0923b68d Fix Super Hound label not turning green for 3-digit or compound callsigns. 2024-07-11 11:11:12 +02:00
Brian Moran
a8e7c08c93 update for 2024 2024-07-09 17:52:18 -07:00
Uwe Risse
9cec90e44e Make the HamlibTransceiver ready for a future Hamlib function (patch by Mike). 2024-07-06 15:59:19 +02:00
Uwe Risse
716027de6e Update the SuperFox executables to version a87aacf. 2024-07-06 15:38:56 +02:00
Uwe Risse
67639f2294 Update Chinese translation. 2024-07-03 15:54:57 +02:00
Joe Taylor
4c84aab38e Correct the calculation of sig in cwsim. 2024-06-28 15:18:59 -04:00
Joe Taylor
354d3bcb1a Rescale the output from cwsim. 2024-06-28 12:58:28 -04:00
Joe Taylor
1dbc8ac18f Add new program "cwsim". 2024-06-28 12:12:50 -04:00
Joe Taylor
86891c0b00 Merge branch 'sfox4' of bitbucket.org:k1jt/wsjtx into sfox4 2024-06-24 11:08:41 -04:00
Joe Taylor
194d9999a3 Update Release_Notes.txt, NEWS, and WSJT-X User Guide for release of v2.7.0-RC5. 2024-06-24 11:07:49 -04:00
Joe Taylor
a3b5b6b2ab Must age the houndcallers by one Rx sequence even if no decodes. Fix the UTC wraparound for computing ages of houndcallers. 2024-06-23 19:52:54 -04:00
Uwe Risse
ec712007d9 A better way to address the SuperFox executables for the Raspberry Pi. 2024-06-23 19:21:35 +02:00
Uwe Risse
4063fe2285 Allow Dupes: Prevent that the last worked station is displayed again when no other hound station is received anymore. 2024-06-23 16:27:54 +02:00
Uwe Risse
2768e87618 Allow Dupes should be deactivated by default. 2024-06-23 15:47:52 +02:00
Uwe Risse
66880b29c0 Save status of Allow Dupes checkbox. 2024-06-23 15:04:59 +02:00
Uwe Risse
024b799ebb Don't display old messages again of stations already logged when "Allow Dupes" is checked. 2024-06-23 15:02:08 +02:00
Uwe Risse
98ee149be6 Don't let RETURN initiate TXing when in Hound mode. 2024-06-22 14:20:22 +02:00
Joe Taylor
149c177d5f Zero the wave() array at start of subroutine sfox_wave_gfsk.f90. 2024-06-20 13:45:51 -04:00
Steven Franke
25097b6baa Update MacOS executables. 2024-06-18 06:40:56 -05:00
Uwe Risse
322efdd681 Add one more executable, and add code to CMakeLists.txt to find ARM processors. 2024-06-18 12:21:27 +02:00
Uwe Risse
59aa8c1632 Add updated executables for Windows, Linux and the Raspberry Pi (2a85ab4). 2024-06-18 12:18:41 +02:00
Uwe Risse
532994d48d Add executables for the Raspberry Pi (515d5f8). 2024-06-14 10:18:20 +02:00
Joe Taylor
897abe611a Merge branch 'sfox4' of bitbucket.org:k1jt/wsjtx into sfox4 2024-06-12 08:43:47 -04:00
Joe Taylor
bccfda16e7 Save only 26 characters of an entered SuperFox free text message. 2024-06-12 08:40:18 -04:00
Uwe Risse
4c5efb0961 Optimize some line breaks in NEWS. 2024-06-12 14:39:38 +02:00
Joe Taylor
c24f0402ef Revert "Change from a LineEdit to a ComboBox for SuperFox Free Text messages."
This reverts commit 6518f52a80a811b65f0c98b78dc44f18d8fa2573.
2024-06-12 08:19:01 -04:00
Joe Taylor
e93c6b5955 Revert "Trim SuperFox free text messages to 26 characters."
This reverts commit 44432d7b1c41c8585a9256e1c60e15b1cc5dd33c.
2024-06-12 08:18:24 -04:00
Joe Taylor
44432d7b1c Trim SuperFox free text messages to 26 characters. 2024-06-11 16:18:28 -04:00
Joe Taylor
6518f52a80 Change from a LineEdit to a ComboBox for SuperFox Free Text messages. 2024-06-11 11:48:14 -04:00
Uwe Risse
d57d22556a Copy text from Release_Notes.txt to NEWS. Optimize some line breaks. 2024-06-11 13:11:39 +02:00
Joe Taylor
e3fe59a7b4 Merge branch 'sfox4' of bitbucket.org:k1jt/wsjtx into sfox4 2024-06-10 12:08:43 -04:00
Uwe Risse
fde7df8c1c Add updated executables for Windows and Linux (515d5f8). 2024-06-10 16:51:57 +02:00
Joe Taylor
46976e7fcd Minor edits to Release_Notes.txt. 2024-06-10 10:51:45 -04:00
Joe Taylor
7f3fa166a6 This time I actually add the new Tool Tips. 2024-06-10 10:10:23 -04:00
Joe Taylor
036b3eb24e Change the "SuperFox" label to "SuperFox mode". Add several Tool Tips. 2024-06-10 09:59:45 -04:00
Joe Taylor
e439a005f1 Merge branch 'sfox4' of bitbucket.org:k1jt/wsjtx into sfox4 2024-06-10 08:36:18 -04:00
Uwe Risse
4c07429ddb Some more text for the Release Notes. 2024-06-10 10:48:29 +02:00
Uwe Risse
365b3b09c4 A few initial text modules for the Release Notes. 2024-06-09 21:08:15 +02:00
Steven Franke
6fad818965 Update MacOS executables. 2024-06-09 13:08:54 -05:00
Uwe Risse
0b1b50db2e Add updated executables for Windows and Linux (e117138). 2024-06-09 16:55:54 +02:00
Uwe Risse
20056f0c4a Add updated executables for Linux. 2024-06-08 21:44:09 +02:00
Uwe Risse
f8d11f6894 Add updated executables for Windows. 2024-06-08 14:42:25 +02:00
Uwe Risse
b11514c54b Reset color of the "Super Hound" label only when an unverified fox is transmitting (not when other hound messages are received). 2024-06-08 10:20:27 +02:00
Steven Franke
d68ef69e9e Change lower case nsps to upper case NSPS in sfox_wave_gfsk.f90. 2024-06-07 16:19:57 -05:00
Steven Franke
e83290b1c9 Use GFSK for SuperFox fox transmissions. 2024-06-07 14:48:13 -05:00
Joe Taylor
647b6e231f For Hound, only 'for_us' received messages should be displayed in right panel. 2024-06-07 12:28:38 -04:00
Steven Franke
bb95fbf405 Only change Tx duration when mode==Fox and when SuperFox is checked. 2024-06-06 16:06:59 -05:00
Steven Franke
e1118390be Set the correct transmit duration for SuperFox fox transmissions. 2024-06-06 16:02:08 -05:00
Brian Moran
1b68336edb enable auto-logging for arrl_digi contest
(cherry picked from commit 4bc472ac5f85fe1c9a37206d99b2f7146666c7db)
2024-06-06 14:44:25 +02:00
Uwe Risse
ec880ffe4c Save and restore the Fox Tx frequency separately. 2024-06-04 21:14:52 +02:00
Steven Franke
3b36cb99e2 Update macos executables. 2024-06-03 16:50:17 -05:00
Uwe Risse
21bacaced2 Add updated Windows and Linux executables for 64-bit and 32-bit. 2024-06-03 19:21:21 +02:00
Joe Taylor
405c5c164c Merge branch 'sfox4' of bitbucket.org:k1jt/wsjtx into sfox4 2024-06-03 08:15:50 -04:00
Joe Taylor
fb44b4fbd9 Send SF callsign to sftx, in case it is compound. 2024-06-03 08:14:48 -04:00
Uwe Risse
c8e03b7505 Update 32-bit SuperFox binaries for Windows and Linux. 2024-06-01 22:32:21 +02:00
Uwe Risse
67c4c34ea2 Update SuperFox binaries for Linux 64-bit. 2024-06-01 20:18:43 +02:00
Steven Franke
6eb07a94a7 Add updated macos executables. 2024-06-01 12:38:55 -05:00
Uwe Risse
e7f2d56cd2 Update SuperFox binaries for Windows 64-bit. 2024-06-01 18:46:39 +02:00
Joe Taylor
4506b76671 Don't allow SuperFox to transmit without a valid key. 2024-06-01 10:06:01 -04:00
Joe Taylor
3372fac76b Merge branch 'sfox4' of bitbucket.org:k1jt/wsjtx into sfox4 2024-05-31 15:52:54 -04:00
Uwe Risse
574f6988e3 Perhaps this arrangement of the Fox controls is a little more intuitive. 2024-05-31 17:08:56 +02:00
Uwe Risse
9779c16446 Disable the 'Rx All Freqs' checkbox when in Hound mode and SuperFox is enabled. 2024-05-31 17:06:42 +02:00
Joe Taylor
6f02013694 Make cbRxAll invisible in SuperHound mode, and treat it as checked. 2024-05-31 09:03:15 -04:00
Joe Taylor
82afc82dd1 Split SuperFox ";" messages into two lines in the right text window. 2024-05-30 13:43:12 -04:00
Joe Taylor
77b779b7b7 Merge branch 'sfox4' of bitbucket.org:k1jt/wsjtx into sfox4 2024-05-30 12:35:36 -04:00
Joe Taylor
e56e617707 Add a checkbox that allows Fox to see and select dupes to be worked again. 2024-05-30 12:33:50 -04:00
Uwe Risse
e65d797159 Fix some inconsistencies regarding the visibility of checkboxes and fields when special operating activity are switched on or off. 2024-05-30 16:31:42 +02:00
Joe Taylor
41b5b1f6b7 Merge branch 'sfox4' of bitbucket.org:k1jt/wsjtx into sfox4 2024-05-30 09:39:58 -04:00
Uwe Risse
11a1fbf027 Allow SuperFox to receive Tx1 messages below 1000 Hz. 2024-05-29 20:22:44 +02:00
Joe Taylor
7e133b43e9 Remove some special test code. 2024-05-29 11:30:57 -04:00
Joe Taylor
9f97d94a05 Merge branch 'sfox4' of bitbucket.org:k1jt/wsjtx into sfox4 2024-05-29 10:09:31 -04:00
Joe Taylor
517980ac3c Revert "Hounds in SuperFox mode are allowed to transmit below 1000 Hz."
This reverts commit da5e072d731661251c719b3c1bd3de261c4829b5.
2024-05-29 10:09:20 -04:00
Joe Taylor
da5e072d73 Hounds in SuperFox mode are allowed to transmit below 1000 Hz. 2024-05-29 10:02:25 -04:00
Uwe Risse
9b2efd1649 Don't randomize Hound Tx frequency when in SuperFox mode. 2024-05-29 16:00:25 +02:00
Uwe Risse
b4e7e6fcb0 Disable two further checkboxes if the respective function is not applicable. 2024-05-27 20:56:23 +02:00
Brian Moran
3a09a4c452 fix typo in ui and associated translations
(cherry picked from commit 52a08a3c13a6abb1842b18687679396344aceb67)
2024-05-27 11:58:40 +02:00
Uwe Risse
9d857e4768 Also disable the other controls under Settings/Advanced if they cannot be used. 2024-05-25 11:35:18 +02:00
Uwe Risse
b991bdfd13 Disable SuperFox key control elements unless applicable. 2024-05-25 10:21:16 +02:00
Uwe Risse
4535997837 Add updated 64-bit binaries for Windows and Linux. 2024-05-24 19:48:34 +02:00
Uwe Risse
cb7efff3fc Update Notes on WSJT-X Installation for Mac OS X. 2024-05-24 19:47:25 +02:00
Steven Franke
2bad1fbf5d Update mac binaries. 2024-05-24 12:09:38 -05:00
Steven Franke
cdd4b9c4c3 Update sfrx binary. 2024-05-24 09:26:02 -05:00
Steven Franke
f9bdef41e2 Add updated binaries for macos. 2024-05-24 08:35:53 -05:00
Steven Franke
e4f89e3cf6 Revert "Update lib/superfox/mac/sfrx"
This reverts commit 253505ff5d19ef25f832b85f82bd2e8bc5bdecd4.
2024-05-23 17:20:08 -05:00
Steven Franke
253505ff5d Update lib/superfox/mac/sfrx 2024-05-23 16:52:54 -05:00
Uwe Risse
e269130cff Another attempt to set the correct file permissions for sftx, sfrx and foxchk. 2024-05-23 20:18:17 +02:00
Uwe Risse
24254175be Further improvements to the arrangement of SuperFox-related controls on Settings -> Advanced. 2024-05-23 15:12:19 +02:00
Steven Franke
92fe13154a Add updated mac sf binaries. 2024-05-22 07:44:13 -05:00
Uwe Risse
560a22393d Add 32-bit executables for Windows and Linux. 2024-05-21 17:24:10 +02:00
Joe Taylor
f28d6f277b Merge branch 'sfox4' of bitbucket.org:k1jt/wsjtx into sfox4 2024-05-21 11:16:43 -04:00
Joe Taylor
e83258b812 Possibly a better arrangement of SuperFox-related controls on Settings -> Advanced. 2024-05-21 11:14:52 -04:00
Joe Taylor
d180d65ced Fix the cause of a CMake warning message. 2024-05-21 10:59:51 -04:00
Steven Franke
491d450968 Change permissions for installed sfrx, sftx, foxchk to 755. 2024-05-21 09:52:49 -05:00
Steven Franke
cc82b1e4b7 Add macos executables for sfrx, sftx, foxchk. 2024-05-21 09:45:03 -05:00
Joe Taylor
d4552213ce Remove the unneeded files, but keep sfox_wave.f90. 2024-05-21 10:21:57 -04:00
Joe Taylor
c8d109b0a0 Replace the use of environment variable SFOX_DIR in CMakeLists.txt. 2024-05-21 10:05:57 -04:00
Joe Taylor
b9c364fbca Revert "Remove obsolete files. Modify CMakeLists.txt to use env variable SFOX_DIR."
This reverts commit d9e042d13b9e3b440c12b268082bf7d236f87df1.
2024-05-21 10:04:57 -04:00
Joe Taylor
d9e042d13b Remove obsolete files. Modify CMakeLists.txt to use env variable SFOX_DIR. 2024-05-21 09:48:26 -04:00
Uwe Risse
4509b12937 This code ensures that the height of the control panel is initialized correctly when SuperFox controls are hidden. 2024-05-18 14:09:20 +02:00
Joe Taylor
5dcc224252 Oops! Missing statement added. 2024-05-17 10:49:08 -04:00
Joe Taylor
ef09479168 Merge branch 'sfox4' of bitbucket.org:k1jt/wsjtx into sfox4 2024-05-17 10:29:42 -04:00
Joe Taylor
0788cc50cb Add ToolTips for SuperFox controls and link to a SuperFox User Guide. 2024-05-17 10:27:57 -04:00
Uwe Risse
f591043030 Another attempt to save and restore FoxNSlots independently of SuperFox settings. 2024-05-17 13:30:08 +02:00
Uwe Risse
255aa671af Fixed a few inconsistencies. 2024-05-17 12:29:02 +02:00
Uwe Risse
6bac88d491 Add convenience feature: Right-click to toggle SuperFox mode On/Off. It works both for Fox mode and Hound mode. 2024-05-16 21:08:24 +02:00
Uwe Risse
895067929d Automatic setting of the N Slot spin box in SuperFox mode. 2024-05-16 20:26:01 +02:00
Uwe Risse
8b6744ec7f Replace executables for Windows and Linux by stripped versions. 2024-05-16 16:58:08 +02:00
Joe Taylor
e1446e3ac5 Merge branch 'sfox4' of bitbucket.org:k1jt/wsjtx into sfox4 2024-05-16 08:33:26 -04:00
Joe Taylor
fa5a5b8b64 Set max Nslots to 2 if Send Msg is checked. 2024-05-16 08:31:57 -04:00
Uwe Risse
96955a5351 Display transmitted SuperFox free text messages in the Rx Frequency window. 2024-05-16 13:53:36 +02:00
Uwe Risse
69dfc83417 Don't do split when in Super Fox mode. 2024-05-15 21:46:28 +02:00
Joe Taylor
65cb809241 Don't shift transceiver dial frequency for SuperFox transmissions. 2024-05-15 14:55:56 -04:00
Joe Taylor
13cd962a64 If we're in SuperFox mode, do not warn that Split is normally required. 2024-05-15 14:47:33 -04:00
Uwe Risse
eefacf34f1 Update executables for Windows and Linux (free text messages functional). 2024-05-15 16:27:47 +02:00
Uwe Risse
38eb22469b Update executables for Linux (free text support). 2024-05-15 14:13:45 +02:00
Uwe Risse
98e0ed133b Update executables for Windows which support free text messages. 2024-05-15 11:13:19 +02:00
Joe Taylor
43845a7f21 Only SuperFox should use FT8_SF as the Tx mode. 2024-05-14 13:29:09 -04:00
Joe Taylor
5d65264e9a SuperFox transmits at 750 Hz; write FT8_SF in ALL.TXT for SuperFox transmissions. 2024-05-14 13:17:59 -04:00
Joe Taylor
651006748d SuperFox message types i3=0, 2, and 3 and now functional. 2024-05-14 12:45:48 -04:00
Uwe Risse
026569e653 Switch "Super Hound" label to green when verified SuperFox messages are received. 2024-05-13 18:51:40 +02:00
Uwe Risse
2817a66d55 Update sfrx executable for Linux. It now shows the “K1ABC verified” message. 2024-05-13 17:02:59 +02:00
Uwe Risse
47fdcb9c28 No blank line before messages that do not contain a timestamp (e.g. " verified"). 2024-05-13 09:51:56 +02:00
Uwe Risse
c8f72e5eec Make decoder.f90 functional on Windows if exe_dir contains a space. (Temporary commit until we have a better solution). 2024-05-12 08:35:21 +02:00
Uwe Risse
db51d7f61b Set the correct permissions for sfrx, sftx, and foxchk on Linux and macOS. 2024-05-11 22:24:41 +02:00
Uwe Risse
8978b81308 Install executables for sfrx, sftx, and foxchk in the WSJT-X installation package. 2024-05-11 16:44:31 +02:00
Joe Taylor
0b709251ed Another try at fixing embedded blanks in a path name. 2024-05-08 16:32:22 -04:00
Joe Taylor
4c188eb604 Better this way? 2024-05-08 12:32:42 -04:00
Joe Taylor
d388ee85dd Protect against path names with embedded blanks. 2024-05-08 12:27:19 -04:00
Joe Taylor
a003ac530b Move "fort.47" into temp_dir for platform independence. 2024-05-08 10:43:32 -04:00
Joe Taylor
3812f2f9bc Add code to support use of SuperFox digital signatures. 2024-05-07 09:10:57 -04:00
Joe Taylor
e1be3ad4e8 Add input widget for SuperFox KEY, and send it to sftx[.exe] for use there. 2024-05-05 16:15:24 -04:00
Uwe Risse
c0f71136b4 Set version number to 2.7.0-RC5. 2024-05-04 16:04:57 +02:00
Uwe Risse
622ce228f2 Fix missing parameter breaking GCC>=14 on Fedora 40 (patch by Morgan, K4WUT).
(cherry picked from commit 89f4ba363faaef4d9f6d28d536a3fe09b021bab8)
2024-05-04 15:57:46 +02:00
Uwe Risse
830cd87489 Make right-click mouse press events less error-prone.
(cherry picked from commit a5aa00c27f0a405f2d6c0ee2522057b9e59e9ecf)
2024-05-04 15:57:39 +02:00
Uwe Risse
a916045d40 Some minor code optimizations.
(cherry picked from commit 1f6fe675163c981eeb3a00e59bb2a177e8bf52dd)
2024-05-04 15:57:31 +02:00
Uwe Risse
673084f225 Allow lookup again, but log only 4-digit grids in certain contest modes.
(cherry picked from commit b0e8717b2946201efa8b172d2e8b2a717e2f530d)
2024-05-04 15:57:20 +02:00
Uwe Risse
aab90a94e4 Fix the root cause of a long-standing error that caused "Start new period decodes at top" to stop working properly after some time, as a replacement for the previous workaround.
(cherry picked from commit d9af0541487c3bf982fe895ca511265ddee6f865)
2024-05-04 15:56:58 +02:00
Uwe Risse
343c339de0 Improve readability of the first line when "Start new period decodes at top" is checked.
(cherry picked from commit a00229c8854121e63db6633e5cf47b99b88cdba1)
2024-05-04 15:56:36 +02:00
Uwe Risse
3097b20bc7 Some updates and corrections to the translations of the UI. Removed the Hong Kong version. Thanks to VR2UPU.
(cherry picked from commit 90c9d26e3edf8ef4e78132e55a8e02d92eee3e9b)
2024-05-04 15:56:02 +02:00
Uwe Risse
a1955ed1fe Update Chinese translation of the UI, Thanks to VR2UPU.
(cherry picked from commit 2bef0fcd8b40108e5f189ca3a5a1a0dea23be745)
2024-05-04 15:55:01 +02:00
Uwe Risse
b918915614 Update Catalan translation of the UI. Thanks to Xavi, EA3W.
(cherry picked from commit 4eb20bec32dd982b20ea321c6a0e14b45418b3b8)
2024-05-04 15:54:18 +02:00
Uwe Risse
076e715221 Minor changes to the Release Notes.
(cherry picked from commit 90008e9e179e1de815951efd9abebddf583a47c6)
2024-05-04 15:54:05 +02:00
Uwe Risse
7f58e205a9 Further updates to the Spanish translation of the UI. Thanks to Cedrik, EA4AC.
(cherry picked from commit 3f29f91b3ad68164823d48b4ed0c8683fd0a5ffd)
2024-05-04 15:53:54 +02:00
Uwe Risse
1312d238d9 Update Spanish translation of the UI.
(cherry picked from commit 90ca6ee4602fa4d86e087b865ec6bcc98d5a283f)
2024-05-04 15:53:44 +02:00
Uwe Risse
269cb0fbf7 Update NEWS and Release Note for RC4.
(cherry picked from commit 08785eff569e8d7818ea8d887b20849711c60764)
2024-05-04 15:52:09 +02:00
Uwe Risse
5235600d2b Preparations for RC4.
(cherry picked from commit d4a5ea60e6355325e520d590e99d8754bf30b9a8)
2024-05-04 15:51:17 +02:00
Uwe Risse
4e66d1eb9f Don't change Tx frequency in SuperHound mode. 2024-04-05 16:45:07 +02:00
Joe Taylor
da477107cc SuperFox transmits at 750 Hz. 2024-03-28 15:28:16 -04:00
Joe Taylor
cf4167ea2d Complete the handling of SuperFox text messages. 2024-03-27 11:03:59 -04:00
Joe Taylor
c652763932 Merge branch 'sfox3' of bitbucket.org:k1jt/wsjtx into sfox3 2024-03-25 15:47:10 -04:00
Joe Taylor
76db12cff0 Working toward free-text message capability for SuperFox. 2024-03-25 15:46:20 -04:00
Uwe Risse
96a3eebb8a Fix a minor GUI issue caused by Qt Creator. 2024-03-23 11:39:06 +01:00
Joe Taylor
e7bfdbc656 Merge branch 'sfox3' of bitbucket.org:k1jt/wsjtx into sfox3 2024-03-22 15:55:37 -04:00
Joe Taylor
b12d5488ff Add GUI widgets for free text messages from SuperFox. 2024-03-22 15:02:40 -04:00
Joe Taylor
2ec0a54d2a Pass state of "More CQs" checkbox to sftx in cmsg(1)(40:40). 2024-03-22 14:00:03 -04:00
Steven Franke
d040026672 Tweak erasure probability in ftrsd3.f90 2024-03-21 11:20:28 -05:00
Joe Taylor
0c38d3b83f Update some text in the license/ 2024-03-17 10:23:34 -04:00
Joe Taylor
1cadab6e04 Use native separators to start sftx[.exe]. 2024-03-16 16:00:16 -04:00
Joe Taylor
afcf0abb40 A few tweaks in the WSJT-X interface to sftx and sfrx. 2024-03-14 14:28:57 -04:00
Joe Taylor
276657866d Merge branch 'sfox3' of bitbucket.org:k1jt/wsjtx into sfox3 2024-03-14 09:01:04 -04:00
Joe Taylor
a58fa2d67d Tweak the logic for when sf[.exe] is invoked. 2024-03-13 12:14:20 -04:00
Joe Taylor
0148cf596f Merge branch 'sfox3' of bitbucket.org:k1jt/wsjtx into sfox3 2024-03-13 08:43:40 -04:00
Joe Taylor
cd5cf5a110 Bug fix: correct the misuse of variable 'ncand' in both q65 module and a common block. 2024-03-12 12:21:08 -04:00
Joe Taylor
b220643237 Add routines that will be needed to decode SuperFox. (Presently, that's done in sf.exe.) 2024-03-11 19:02:38 -04:00
Joe Taylor
835e4936c1 Preparing to allow calling a SuperFox decoder. 2024-03-06 15:49:54 -05:00
Joe Taylor
b299700d97 Tentative: change the red labels to "SuperFox" and "SuperHound". 2024-03-06 11:04:49 -05:00
Joe Taylor
ca18e58c77 Remove the .../lib/superfox directory and its contents. 2024-03-05 11:03:43 -05:00
Joe Taylor
ce08913e3a Correct the use separate files sfox_1.dat and sfox_2.dat. 2024-03-05 10:05:13 -05:00
Joe Taylor
a5f68966ab More WIP toward implementing sfox_tx. 2024-03-04 13:15:56 -05:00
Joe Taylor
56ce1b7441 Complete the sfox wavefile generation. 2024-03-03 15:35:57 -05:00
Joe Taylor
05dd89c552 WIP on SuperFox transmit capability. 2024-03-03 15:08:19 -05:00
Joe Taylor
ed248eb702 WIP toward moving the conversion from old Fox messages to new command string in the new external program sfox_tx. 2024-03-03 08:50:42 -05:00
Joe Taylor
2f600ae198 Functional with bare-bones sfox_tx executable. 2024-03-02 16:01:55 -05:00
Joe Taylor
5948c0d024 More WIP on SuperFox. 2024-03-02 14:38:40 -05:00
Joe Taylor
027b84f047 WIP on SuperFox integration into WSJT-X. 2024-03-02 14:24:45 -05:00
Joe Taylor
b495531f78 Separate sfox_assemble.f90 from foxgen2.f90. 2024-03-02 09:36:19 -05:00
Joe Taylor
16346c0c1b Merge branch 'develop' into sfox3 2024-03-01 16:30:27 -05:00
Joe Taylor
f53d864269 Display NS to sfoxtest user instead of Tsync. 2024-02-29 08:26:43 -05:00
Joe Taylor
51757d474b Merge branch 'develop' into sfox3 2024-02-28 13:59:55 -05:00
Joe Taylor
69c4e4acb6 Restrict the search range for SuperFox sync. 2024-02-28 13:34:50 -05:00
Joe Taylor
06d648f1d7 Protect against bounds error. 2024-02-27 12:12:14 -05:00
Joe Taylor
6a59223b70 Add quick-and-dirty measurement of sync width (Doppler spread). 2024-02-27 11:39:48 -05:00
Joe Taylor
b59ed5dd93 Do a final sync peakup in frequency using longer FFTs. 2024-02-27 10:56:24 -05:00
Joe Taylor
993705d581 Don't call peakup if we're too close to the edge. 2024-02-26 17:15:37 -05:00
Joe Taylor
376f0d1e53 Running now with Q65-type sync and full decoding. 2024-02-26 17:04:04 -05:00
Joe Taylor
f263a70dd3 Several optional sync vectors. 2024-02-26 15:08:48 -05:00
Joe Taylor
cbb42e9cdd Q65-style sync basically working. Have not yet proceeded to decode step. 2024-02-26 13:14:33 -05:00
Joe Taylor
271c2eec6c More WIP on superfox sync. 2024-02-26 12:54:31 -05:00
Joe Taylor
391536f35a WIP in q65 sync scheme for superfox. 2024-02-26 12:32:25 -05:00
Joe Taylor
6d4372cafe More work toward testing Q65-style sync. 2024-02-25 20:31:21 -05:00
Joe Taylor
4491da67f7 Work in progress toward trying a Q65-style sync. 2024-02-25 10:10:51 -05:00
Joe Taylor
b25e7fce8c Code cleanup in sfox_sync. 2024-02-24 17:06:11 -05:00
Joe Taylor
665e18f656 Omit display of 'worst', it's no longer very useful. 2024-02-24 17:04:14 -05:00
Joe Taylor
25b6df82fe Some format adjustments. 2024-02-24 10:42:27 -05:00
Joe Taylor
7c7a985bfe One more try, on the ccf index limits. 2024-02-23 15:12:19 -05:00
Joe Taylor
12bda0f84e Better protection of edge values of ccf array indexes. 2024-02-23 14:52:02 -05:00
Joe Taylor
161f456101 Tweaks to sfox_sync routine. 2024-02-23 14:42:09 -05:00
Joe Taylor
577f6f3097 Clean up sync routine; add 'peakup' in f and t directions. 2024-02-23 14:33:11 -05:00
Joe Taylor
6d72b295c8 Put the sync values into a data statement. 2024-02-23 13:49:22 -05:00
Joe Taylor
1b9071fd8c Good working model with random sync symbols rather than sweeping sync. 2024-02-23 10:44:49 -05:00
Joe Taylor
12bcddf366 Revert "Compile the random sync pattern into sfox_mod."
This reverts commit baec5dcfd25e964d6d61962ad18a429560b44eae.
2024-02-22 14:57:17 -05:00
Joe Taylor
532c808316 Revert "Revert "Input ts (approx tsync) from command line.""
This reverts commit 863ac4fd3d07ed9ac2f198984e9e8d78eaf74586.
2024-02-22 14:56:52 -05:00
Joe Taylor
863ac4fd3d Revert "Input ts (approx tsync) from command line."
This reverts commit fada229d83df9c9cd5498e4607e41626ef459c76.
2024-02-22 14:55:10 -05:00
Joe Taylor
baec5dcfd2 Compile the random sync pattern into sfox_mod. 2024-02-22 14:45:36 -05:00
Joe Taylor
fada229d83 Input ts (approx tsync) from command line. 2024-02-22 14:35:41 -05:00
Joe Taylor
8948daabb0 Remove diagnostic print. 2024-02-22 14:26:38 -05:00
Joe Taylor
523023fe65 Code cleanup after changing sync scheme. 2024-02-22 14:25:17 -05:00
Joe Taylor
0c03b9fc00 Revert to old-style sync scheme, using symbol length same as for data. 2024-02-22 13:41:09 -05:00
Joe Taylor
b1e2a54f91 Break the sweeping sync tone into pieces with different frequency offsets and slopes. Needs testing! 2024-02-21 15:28:36 -05:00
Joe Taylor
f1e4f998ce Merge branch 'superfox' of bitbucket.org:k1jt/wsjtx into superfox 2024-02-21 14:59:17 -05:00
Joe Taylor
0393d7bd7c More code cleanup; possible scheme for more frequency diversity in sync. 2024-02-21 14:57:44 -05:00
Steven Franke
f99e906a59 Add noise to the output of watterson.f90 instead of the input. 2024-02-21 13:21:05 -06:00
Joe Taylor
f896df064d Complete the process of separating calculation of the sync waveform. 2024-02-21 13:49:25 -05:00
Joe Taylor
254a15b4f6 Move the sweep generator into a separate routine. 2024-02-21 13:44:20 -05:00
Joe Taylor
d44d00453f Replace many instances of 12000.0 with fsample. 2024-02-21 13:33:37 -05:00
Joe Taylor
2effe7e4c7 Reset ftrsd ntrials to 1000. 2024-02-21 09:23:45 -05:00
Joe Taylor
d12e16c7d1 Add an option in sfoxtest for simulations with hard-wired sync. 2024-02-20 09:07:02 -05:00
Steven Franke
61711e905d Add Eb/No to sfoxtest output. 2024-02-20 07:46:48 -06:00
Joe Taylor
cc6e7b1c16 Merge branch 'superfox' of bitbucket.org:k1jt/wsjtx into superfox 2024-02-19 14:33:04 -05:00
Joe Taylor
2a95463c80 Correct the computed duration of a SuperFox transmission, in sfoxtest. 2024-02-19 14:32:15 -05:00
Steven Franke
2346145fba Merge remote-tracking branch 'refs/remotes/origin/superfox' into superfox 2024-02-19 13:30:47 -06:00
Steven Franke
7ce6e29a7e Make watterson.f90 spreading function the same as that used in ITU report ITU-R F.1487. 2024-02-19 13:21:03 -06:00
Joe Taylor
d234986165 Add optional code to q65sim to confirm calkibration of SNR_2500. 2024-02-19 13:52:37 -05:00
Joe Taylor
fb19d27602 Compute signal power, noise power, and SNR_2500 explicitly in ft8sim.f90. 2024-02-19 13:23:42 -05:00
Steven Franke
ec0c31d849 Make ftrsd3 work better for a (127,48) Reed Solomon code. 2024-02-18 12:45:29 -06:00
Steven Franke
d438f91845 Make ftrsd3 work with (127,48) 128-ary code. 2024-02-18 11:18:47 -06:00
Steven Franke
5c53a43171 Reconcile the SNR of simulated complex and real noisy signals. 2024-02-17 10:00:33 -06:00
Joe Taylor
cdcdedfe40 Temporary code (### commented out ###) for calibrating SNR. 2024-02-16 16:11:01 -05:00
Joe Taylor
40331f3c1f Add timer calls to sfoxtest. 2024-02-16 10:51:27 -05:00
Joe Taylor
faf0554cbf Soft-decision RS decoding now basically working. Needs better tuning, no doubt. 2024-02-15 15:46:09 -05:00
Joe Taylor
8a2e3e50d9 Commit ftrsd3.c. (Not used at present, and not fully updated from ftrsd2.c.) 2024-02-15 14:14:51 -05:00
Joe Taylor
93fd8246fb Ann new file getpp3.f90. 2024-02-15 14:12:45 -05:00
Joe Taylor
17d9c6bf81 Print column headings on first isnr pass. 2024-02-15 13:36:48 -05:00
Joe Taylor
50f9c73ad3 Merge branch 'superfox' of bitbucket.org:k1jt/wsjtx into superfox 2024-02-15 13:27:00 -05:00
Joe Taylor
33aa347e24 Correct the argument list in second call to sfox_gen(). 2024-02-15 13:24:06 -05:00
Joe Taylor
09f456d6a3 Add new file ftrsd3.f90. 2024-02-15 08:53:44 -05:00
Joe Taylor
d7d8a70322 Add untested Fortran routuine ftrsd3.f90. 2024-02-14 17:51:55 -05:00
Joe Taylor
f21f37ad05 Correct the definition of fspread in watterson.f90. 2024-02-14 16:30:37 -05:00
Joe Taylor
ce7d5b8d02 Simplify a few parts of code used for SuperFox simulations. 2024-02-14 11:49:59 -05:00
Joe Taylor
939eaa11ef Add new file sym_prob.f90. 2024-02-14 11:43:58 -05:00
Joe Taylor
a516184a3c Work in progress, starting toward implementing soft-decision ftrsd decoder. 2024-02-13 14:56:20 -05:00
Joe Taylor
8dd19ee80c Change subroutine name sfox_hard to sfox_demod; introduce array s3(NQ,ND) to be used for soft-decision decoding. 2024-02-13 12:02:04 -05:00
Joe Taylor
7bf4aaef2e Allow different lag step sizes in sfox_sync routine. 2024-02-11 16:05:31 -05:00
Joe Taylor
5349ba7dc5 Extend the looping snr range down to -25 dB. 2024-02-10 20:00:19 -05:00
Joe Taylor
d4414e3ce3 Better usage instructions. 2024-02-10 19:54:25 -05:00
Joe Taylor
cc4bcfa462 Tidy up the SuperFox subroutine names. 2024-02-10 19:51:36 -05:00
Joe Taylor
ddbe0eb078 Better usage hints. 2024-02-10 15:09:37 -05:00
Joe Taylor
060fdf6763 Input syncwidth on command line; more options for verbose output. 2024-02-10 13:56:45 -05:00
Joe Taylor
c24a0d3c72 Separate generation of SuperFox sync LO, and rationalize frequencies used in gen_sfox.f90 and hard_symbols.f90. 2024-02-10 13:35:06 -05:00
Joe Taylor
6310419a4d Pretty up the Threshold output line. 2024-02-10 10:50:42 -05:00
Joe Taylor
129ee5439a Correct a typo. Always output summary decoding results. 2024-02-10 09:47:11 -05:00
Joe Taylor
05d720201a Test smoothing of symbol spectra ... 2024-02-10 09:29:57 -05:00
Joe Taylor
b6ad4d701d Better criteria for having established good sync. 2024-02-10 09:09:45 -05:00
Joe Taylor
dc6f78d50b Code cleanup. 2024-02-09 13:36:01 -05:00
Joe Taylor
05cae7b911 Add needed file. 2024-02-09 07:15:15 -05:00
Joe Taylor
62c2e5c645 Display fspread, delay, MaxErr. 2024-02-08 13:58:00 -05:00
Joe Taylor
5e6a9d59ed Add standard ITU channel parameters. 2024-02-08 13:46:11 -05:00
Joe Taylor
ec535541db Interpolate threshold sensitivity for 50% decoding probability. 2024-02-08 13:06:54 -05:00
Joe Taylor
4a1e6a19fc Add a flag for verbose output. 2024-02-08 12:36:48 -05:00
Joe Taylor
56d0aac243 Input M, N, K from sfoxtext command line. Correct freq after sync. 2024-02-08 12:21:36 -05:00
Joe Taylor
c051168a6b WIP: sfoxtest now running with parameters set in sfox_mod. 2024-02-08 10:45:43 -05:00
Joe Taylor
464838aa78 Tweaks. 2024-02-08 04:11:12 -05:00
Joe Taylor
ca5bc0e86b WIP on sfoxtest. 2024-02-07 14:24:05 -05:00
Joe Taylor
8c61d303bf WIP on superfox test progs. 2024-02-07 11:40:25 -05:00
Joe Taylor
84e5fbe6d5 Add librs.a. (This should be TEMPORARY.) 2024-02-05 16:27:59 -05:00
Joe Taylor
c1033e1cff Add rst8.f90. 2024-02-05 16:26:55 -05:00
Joe Taylor
290b34c99c WIP on rst8. 2024-02-05 16:25:51 -05:00
Joe Taylor
3e27ce83e6 Tweaks to sfox test programs. 2024-02-04 22:01:53 -05:00
Joe Taylor
9642d41c6d Cleanup. 2024-02-02 21:08:45 -05:00
Joe Taylor
7804716991 Build sfoxtext from CMakefiles.txt, with RS(125,49) encode and decode. 2024-02-02 15:44:03 -05:00
Joe Taylor
5d07f86334 Add erasure capability to rs_125_49. 2024-02-02 14:15:36 -05:00
Joe Taylor
c8f8356c28 More cleanup. 2024-02-02 14:15:20 -05:00
Joe Taylor
ae462a9cb8 More code cleanup. 2024-02-02 13:22:42 -05:00
Joe Taylor
5cc29df68f Code cleanup. 2024-02-02 12:30:32 -05:00
Joe Taylor
347e32548c Errors and erasures is now working for RS. 2024-02-02 12:07:40 -05:00
Joe Taylor
3bfbe4deb4 WIP on RS utilities. 2024-02-02 11:29:21 -05:00
Joe Taylor
2535a24481 Add the crc14 routine. 2024-02-01 20:59:27 -05:00
Joe Taylor
6b8b0e1b10 Add program rs_125_49. 2024-02-01 19:26:09 -05:00
Joe Taylor
d805820446 WIP on rs_125_49. Erasures not yet being used. 2024-02-01 19:19:17 -05:00
Joe Taylor
959026aad5 Makefile for rstest. 2024-02-01 16:07:55 -05:00
Joe Taylor
db71f7d480 Use integer rather than i*1 for idat and jdat so they can work with int RS version. 2024-02-01 13:25:41 -05:00
Joe Taylor
a382fbfe7b WIP: sfoxtest and rstest both working at this point. 2024-02-01 10:51:48 -05:00
Joe Taylor
ca44347507 Change name synctest to sfoxtest. 2024-02-01 10:24:56 -05:00
Joe Taylor
0cf544e3aa Add modified versions of Karn RS routines. 2024-02-01 08:52:46 -05:00
Joe Taylor
c228340519 Tighter sync criteria. 2024-01-31 21:07:58 -05:00
Joe Taylor
d6d4ad3c23 Minor tweaks. 2024-01-31 19:39:45 -05:00
Joe Taylor
1296134820 Allow f0 and xdt to be randomized. 2024-01-31 19:35:08 -05:00
Joe Taylor
d9b6691dbf Rearrange a few lines of code. 2024-01-31 19:21:02 -05:00
Joe Taylor
0c3174f9e3 WIP on SuperFox synctest. 2024-01-31 18:59:41 -05:00
Joe Taylor
e43e81f73f Update the synctest usage example. 2024-01-31 16:51:26 -05:00
Joe Taylor
7201e5baab Add a missing file. 2024-01-31 16:38:22 -05:00
Joe Taylor
5ac2f4f4eb Improve the synctest code for large nfiles. 2024-01-31 15:40:33 -05:00
Joe Taylor
b0bc73e3f3 Build synctest from top-level CMakeLists.txt. Add 'nfiles' capability. 2024-01-31 15:13:42 -05:00
Joe Taylor
0531f339e8 Use ran1 instead of random_number(). 2024-01-31 14:16:40 -05:00
Joe Taylor
3434faf84a Check for hard symbol errors. 2024-01-31 14:02:33 -05:00
Joe Taylor
42439c2b6d Count hard errors in simulated SuperFox signal. 2024-01-31 13:45:53 -05:00
Joe Taylor
9d882e01e5 Remove an incorrect cdat=0. 2024-01-31 13:03:21 -05:00
Joe Taylor
cc005bf69b Add gen_sfox.f90. We're now generating data as well as sync symbols. 2024-01-31 12:58:27 -05:00
Joe Taylor
181b22be67 Separate generation of clo and cdat. 2024-01-31 12:46:24 -05:00
Joe Taylor
245d63d980 Code cleanup. 2024-01-31 12:18:31 -05:00
Joe Taylor
a7ea051cb0 Better way to apply xdt to received signal. 2024-01-31 12:08:50 -05:00
Joe Taylor
efedc50fe1 Add Watterson channel model to the SuperFox synctest. 2024-01-31 11:37:19 -05:00
Joe Taylor
88838fca62 Put superfox parameters in sfox_params.f90. 2024-01-31 11:18:42 -05:00
Joe Taylor
0d664e4ed1 WIP on superfox synctest. 2024-01-31 10:47:16 -05:00
Joe Taylor
d100c4e9e0 Merge branch 'develop' into superfox 2024-01-31 10:15:25 -05:00
Joe Taylor
aedc9ec3c1 MOve the sync patterm 60 symbols (5.12 s) into the transmission. 2024-01-30 18:34:43 -05:00
Joe Taylor
27824dc45d First commits in the superfox branch: synctest, sfocsim, and rstest. 2024-01-30 18:10:44 -05:00
114 changed files with 16965 additions and 12370 deletions

1
.gitignore vendored
View File

@ -7,7 +7,6 @@ GTAGS
*~
junk*
jnq*
*.exe
*.o
*.mod
*.pro.user

View File

@ -148,7 +148,6 @@ void SoundOutput::stop ()
m_stream->reset ();
m_stream->stop ();
}
m_stream.reset ();
}
qreal SoundOutput::attenuation () const

View File

@ -50,6 +50,7 @@ project (wsjtx
)
set (PROJECT_DESCRIPTION "WSJT-X: Digital Modes for Weak Signal Communications in Amateur Radio")
set (CMAKE_PROJECT_DESCRIPTION ${PROJECT_DESCRIPTION})
set (CMAKE_AUTOUIC ON)
#
# Local CMake modules and support files
@ -71,7 +72,7 @@ message (STATUS "******************************************************")
include (set_build_type)
# RC 0 or omitted is a development build, GA is a General Availability release build
set_build_type (RC 4)
set_build_type (RC 7)
set (wsjtx_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}${BUILD_TYPE_REVISION}")
#
@ -80,7 +81,7 @@ set (wsjtx_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_
set (PROJECT_BUNDLE_NAME "WSJT-X")
set (PROJECT_VENDOR "Joe Taylor, K1JT")
set (PROJECT_CONTACT "Joe Taylor <k1jt@arrl.net>")
set (PROJECT_COPYRIGHT "Copyright (C) 2001-2023 by Joe Taylor, K1JT")
set (PROJECT_COPYRIGHT "Copyright (C) 2001-2024 by Joe Taylor, K1JT")
set (PROJECT_HOMEPAGE https://wsjt.sourceforge.io/wsjtx.html)
set (PROJECT_MANUAL wsjtx-main)
set (PROJECT_MANUAL_DIRECTORY_URL https://wsjt.sourceforge.io/wsjtx-doc/)
@ -126,6 +127,7 @@ option (WSJT_GENERATE_DOCS "Generate documentation files." ON)
option (WSJT_RIG_NONE_CAN_SPLIT "Allow split operation with \"None\" as rig.")
option (WSJT_TRACE_UDP "Debugging option that turns on UDP message protocol diagnostics.")
option (WSJT_BUILD_UTILS "Build simulators and code demonstrators." ON)
option (WSJT_FOX_OTP "Enable Fox OTP Verification Messages." ON)
CMAKE_DEPENDENT_OPTION (WSJT_QDEBUG_IN_RELEASE "Leave Qt debugging statements in Release configuration." OFF
"NOT is_debug_build" OFF)
CMAKE_DEPENDENT_OPTION (WSJT_ENABLE_EXPERIMENTAL_FEATURES "Enable features not fully ready for public releases." ON
@ -161,6 +163,12 @@ endif ()
set (WSJT_PLUGIN_DESTINATION ${PLUGIN_DESTINATION} CACHE PATH "Path for plugins")
set (WSJT_QT_CONF_DESTINATION ${QT_CONF_DESTINATION} CACHE PATH "Path for the qt.conf file")
if (WSJT_FOX_OTP)
set (wsjt_fox_CXXSRCS
)
message (STATUS "Including Fox verification code feature")
endif ()
#
# Project sources
@ -223,6 +231,7 @@ set (wsjt_qt_CXXSRCS
widgets/DoubleClickableRadioButton.cpp
Network/LotWUsers.cpp
Network/FileDownload.cpp
Network/FoxVerifier.cpp
models/DecodeHighlightingModel.cpp
widgets/DecodeHighlightingListView.cpp
models/FoxLog.cpp
@ -242,6 +251,7 @@ set (wsjt_qt_CXXSRCS
widgets/LazyFillComboBox.cpp
widgets/CheckableItemComboBox.cpp
widgets/BandComboBox.cpp
otpgenerator.cpp
)
set (wsjt_qtmm_CXXSRCS
@ -292,6 +302,7 @@ set (wsjt_CXXSRCS
lib/crc10.cpp
lib/crc13.cpp
lib/crc14.cpp
${wsjt_fox_CXXSRCS}
)
# deal with a GCC v6 UB error message
set_source_files_properties (
@ -342,6 +353,10 @@ set (wsjt_FSRCS
lib/wavhdr.f90
lib/qra/q65/q65_encoding_modules.f90
lib/ft8/ft8_a7.f90
lib/superfox/sfox_mod.f90
lib/superfox/julian.f90
lib/superfox/popen_module.f90
lib/superfox/qpc/qpc_mod.f90
# remaining non-module sources
lib/addit.f90
@ -427,8 +442,7 @@ set (wsjt_FSRCS
lib/fspread_lorentz.f90
lib/ft8/foxfilt.f90
lib/ft8/foxgen.f90
lib/superfox/foxgen2.f90
lib/ft8/foxgen_wrap.f90
# lib/ft8/foxgen_wrap.f90
lib/freqcal.f90
lib/ft8/ft8apset.f90
lib/ft8/ft8b.f90
@ -587,6 +601,27 @@ set (wsjt_FSRCS
lib/fst4/get_crc24.f90
lib/fst4/fst4_baseline.f90
lib/77bit/hash22calc.f90
lib/superfox/foxgen2.f90
lib/superfox/qpc_decode2.f90
lib/superfox/qpc_likelihoods2.f90
lib/superfox/qpc_snr.f90
lib/superfox/qpc_sync.f90
lib/superfox/sfox_ana.f90
lib/superfox/sfox_assemble.f90
lib/superfox/sfox_demod.f90
lib/superfox/sfox_pack.f90
lib/superfox/sfox_remove_ft8.f90
lib/superfox/sfox_remove_tone.f90
lib/superfox/sfox_unpack.f90
lib/superfox/sfox_wave.f90
lib/superfox/sfox_wave_gfsk.f90
lib/superfox/sfrx_sub.f90
lib/superfox/sftx_sub.f90
lib/superfox/twkfreq2.f90
lib/superfox/sfox_gen_gfsk.f90
lib/superfox/ran1.f90
lib/superfox/sfoxsim.f90
)
# temporary workaround for a gfortran v7.3 ICE on Fedora 27 64-bit
@ -629,6 +664,15 @@ set (wsjt_CSRCS
lib/wrapkarn.c
${ldpc_CSRCS}
${qra_CSRCS}
lib/superfox/qpc/dbgprintf.c
lib/superfox/qpc/nhash2.c
lib/superfox/qpc/np_qpc.c
lib/superfox/qpc/np_rnd.c
lib/superfox/qpc/qpc_fwht.c
lib/superfox/qpc/qpc_n127k50q128.c
lib/superfox/qpc/qpc_subs.c
)
set (wsjt_qt_UISRCS
@ -902,7 +946,9 @@ check_type_size (CACHE_ALL HAMLIB_OLD_CACHING)
check_symbol_exists (rig_set_cache_timeout_ms "hamlib/rig.h" HAVE_HAMLIB_CACHING)
find_package (Usb REQUIRED)
if (WSJT_FOX_OTP)
add_definitions (-DFOX_OTP)
endif ()
#
# Qt5 setup
#
@ -1155,6 +1201,9 @@ target_link_libraries (test_snr wsjt_fort)
add_executable (q65sim lib/qra/q65/q65sim.f90)
target_link_libraries (q65sim wsjt_fort wsjt_cxx)
add_executable (cwsim lib/cwsim.f90)
target_link_libraries (cwsim wsjt_fort wsjt_cxx)
add_executable (q65code lib/qra/q65/q65code.f90)
target_link_libraries (q65code wsjt_fort wsjt_cxx)
@ -1209,6 +1258,15 @@ target_link_libraries (echosim wsjt_fort wsjt_cxx)
add_executable (ft8sim lib/ft8/ft8sim.f90)
target_link_libraries (ft8sim wsjt_fort wsjt_cxx)
add_executable (sfoxsim lib/superfox/sfoxsim.f90)
target_link_libraries (sfoxsim wsjt_fort wsjt_cxx)
add_executable (sfrx lib/superfox/sfrx.f90)
target_link_libraries (sfrx wsjt_fort wsjt_cxx)
#add_executable (sftx lib/superfox/sftx.f90)
#target_link_libraries (sftx wsjt_fort wsjt_cxx)
add_executable (msk144sim lib/msk144sim.f90)
target_link_libraries (msk144sim wsjt_fort wsjt_cxx)
@ -1293,9 +1351,7 @@ set (LANGUAGES
ru # Russian
#sv # Swedish
zh # Chinese
zh_HK # Chinese per Hong Kong
zh_TW # Chinese traditional
it # Italian
)
foreach (lang_ ${LANGUAGES})
file (TO_NATIVE_PATH ${CMAKE_SOURCE_DIR}/translations/wsjtx_${lang_}.ts ts_)
@ -1598,7 +1654,7 @@ install (TARGETS udp_daemon message_aggregator wsjtx_app_version
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
)
install (TARGETS jt9 wsprd fmtave fcal fmeasure
install (TARGETS jt9 wsprd fmtave fcal fmeasure
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
)

View File

@ -193,6 +193,7 @@
#include "models/FrequencyList.hpp"
#include "models/StationList.hpp"
#include "Network/NetworkServerLookup.hpp"
#include "Network/FoxVerifier.hpp"
#include "widgets/MessageBox.hpp"
#include "validators/MaidenheadLocatorValidator.hpp"
#include "validators/CallsignValidator.hpp"
@ -584,9 +585,25 @@ private:
Q_SLOT void on_LotW_CSV_fetch_push_button_clicked (bool);
Q_SLOT void on_hamlib_download_button_clicked (bool);
Q_SLOT void on_revert_update_button_clicked (bool);
Q_SLOT void on_gbSpecialOpActivity_clicked (bool);
Q_SLOT void on_rbFox_clicked (bool);
Q_SLOT void on_rbHound_clicked (bool);
Q_SLOT void on_rbNA_VHF_Contest_clicked (bool);
Q_SLOT void on_rbEU_VHF_Contest_clicked (bool);
Q_SLOT void on_rbWW_DIGI_clicked (bool);
Q_SLOT void on_rbQ65pileup_clicked (bool);
Q_SLOT void on_rbField_Day_clicked (bool);
Q_SLOT void on_rbRTTY_Roundup_clicked (bool);
Q_SLOT void on_rbARRL_Digi_clicked (bool);
Q_SLOT void on_cbSuperFox_clicked (bool);
Q_SLOT void on_cbContestName_clicked (bool);
Q_SLOT void on_cbOTP_clicked (bool);
Q_SLOT void on_cbShowOTP_clicked (bool);
void error_during_hamlib_download (QString const& reason);
void after_hamlib_downloaded();
void display_file_information();
void check_visibility();
Q_SLOT void on_cbx2ToneSpacing_clicked(bool);
Q_SLOT void on_cbx4ToneSpacing_clicked(bool);
@ -594,6 +611,8 @@ private:
Q_SLOT void on_cbAutoLog_clicked(bool);
Q_SLOT void on_Field_Day_Exchange_textEdited (QString const&);
Q_SLOT void on_RTTY_Exchange_textEdited (QString const&);
Q_SLOT void on_OTPUrl_textEdited (QString const&);
Q_SLOT void on_OTPSeed_textEdited (QString const&);
Q_SLOT void on_Contest_Name_textEdited (QString const&);
// typenames used as arguments must match registered type names :(
@ -693,6 +712,12 @@ private:
QString Contest_Name_;
QString hamlib_backed_up_;
QString OTPUrl_;
QString OTPSeed_;
bool OTPEnabled_;
bool ShowOTP_;
qint32 OTPinterval_;
qint32 id_interval_;
qint32 ntrials_;
qint32 aggressive_;
@ -963,6 +988,26 @@ void Configuration::invalidate_audio_output_device (QString /* error */)
m_->audio_output_device_ = QAudioDeviceInfo {};
}
// OTP seed can be empty, in which case it is not used, or a valid 16 character base32 string.
bool Configuration::validate_otp_seed(QString seed)
{
if (seed.isEmpty())
{
return true;
}
if (seed.size() != 16)
{
return false;
}
for (QChar c: seed)
{
if (!QString(BASE32_CHARSET).contains(c))
{
return false;
}
}
return true;
}
bool Configuration::valid_n1mm_info () const
{
// do very rudimentary checking on the n1mm server name and port number.
@ -1052,6 +1097,43 @@ void Configuration::setSpecial_None()
m_->SelectedActivity_ = static_cast<int> (SpecialOperatingActivity::HOUND); // brings backward compatibility to versions without Q65_PILEUP
m_->write_settings();
}
void Configuration::toggle_SF()
{
if (m_->bSuperFox_) {
m_->ui_->cbSuperFox->setChecked(false);
} else {
m_->ui_->cbSuperFox->setChecked(true);
}
m_->bSuperFox_ = m_->ui_->cbSuperFox->isChecked ();
m_->write_settings();
}
QString Configuration::OTPSeed() const
{
return m_->OTPSeed_;
}
QString Configuration::OTPUrl() const
{
return m_->OTPUrl_;
}
unsigned int Configuration::OTPinterval() const
{
return m_->OTPinterval_;
}
bool Configuration::OTPEnabled() const
{
return m_->OTPSeed_.size() == 16 && m_->OTPEnabled_;
}
bool Configuration::ShowOTP () const
{
return m_->ShowOTP_;
}
namespace
{
#if defined (Q_OS_MAC)
@ -1222,6 +1304,8 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network
ui_->add_macro_line_edit->setValidator (new QRegularExpressionValidator {message_alphabet, this});
ui_->Field_Day_Exchange->setValidator (new QRegularExpressionValidator {field_day_exchange_re, this});
ui_->RTTY_Exchange->setValidator (new QRegularExpressionValidator {RTTY_roundup_exchange_re, this});
QRegularExpression b32(QString("(^[") + QString(BASE32_CHARSET)+QString(BASE32_CHARSET).toLower() + QString("]{16}$)|(^$)"));
ui_->OTPSeed->setValidator(new QRegularExpressionValidator(b32, this));
//
// assign ids to radio buttons
@ -1549,6 +1633,8 @@ void Configuration::impl::initialize_models ()
ui_->cbHighlightDXcall->setChecked(highlight_DXcall_);
ui_->cbHighlightDXgrid->setChecked(highlight_DXgrid_);
check_visibility ();
set_rig_invariants ();
}
@ -1583,6 +1669,19 @@ void Configuration::impl::read_settings ()
ui_->Contest_Name->setText(Contest_Name_);
hamlib_backed_up_ = settings_->value ("HamlibBackedUp",QString {}).toString ();
OTPinterval_ = settings_->value ("OTPinterval", 1).toUInt ();
OTPUrl_ = settings_->value ("OTPUrl", FoxVerifier::default_url()).toString ();
OTPSeed_ = settings_->value ("OTPSeed", QString {}).toString ();
OTPEnabled_ = settings_->value ("OTPEnabled", false).toBool ();
ShowOTP_ = settings_->value ("ShowOTP", false).toBool ();
ui_->sbOTPinterval->setValue(OTPinterval_);
ui_->OTPUrl->setText(OTPUrl_);
ui_->OTPSeed->setText(OTPSeed_);
ui_->cbOTP->setChecked(OTPEnabled_);
ui_->cbShowOTP->setChecked(ShowOTP_);
if (next_font_.fromString (settings_->value ("Font", QGuiApplication::font ().toString ()).toString ())
&& next_font_ != font_)
{
@ -1908,6 +2007,11 @@ void Configuration::impl::write_settings ()
settings_->setValue ("AutoGrid", use_dynamic_grid_);
settings_->setValue ("highlight_DXcall", highlight_DXcall_);
settings_->setValue ("highlight_DXgrid", highlight_DXgrid_);
settings_->setValue ("OTPinterval", OTPinterval_);
settings_->setValue ("OTPUrl", OTPUrl_);
settings_->setValue ("OTPSeed", OTPSeed_);
settings_->setValue ("OTPEnabled", OTPEnabled_);
settings_->setValue ("ShowOTP", ShowOTP_);
settings_->sync ();
}
@ -2324,6 +2428,11 @@ void Configuration::impl::accept ()
pwrBandTxMemory_ = ui_->checkBoxPwrBandTxMemory->isChecked ();
pwrBandTuneMemory_ = ui_->checkBoxPwrBandTuneMemory->isChecked ();
opCall_=ui_->opCallEntry->text();
OTPinterval_=ui_->sbOTPinterval->value();
OTPSeed_=ui_->OTPSeed->text();
OTPUrl_=ui_->OTPUrl->text();
OTPEnabled_=ui_->cbOTP->isChecked();
ShowOTP_=ui_->cbShowOTP->isChecked();
auto new_server = ui_->udp_server_line_edit->text ().trimmed ();
auto new_interfaces = get_selected_network_interfaces (ui_->udp_interfaces_combo_box);
@ -3113,6 +3222,160 @@ void Configuration::impl::on_cbx4ToneSpacing_clicked(bool b)
if(b) ui_->cbx2ToneSpacing->setChecked(false);
}
void Configuration::impl::on_gbSpecialOpActivity_clicked (bool)
{
check_visibility ();
}
void Configuration::impl::on_rbFox_clicked (bool)
{
check_visibility ();
}
void Configuration::impl::on_rbHound_clicked (bool)
{
check_visibility ();
}
void Configuration::impl::on_rbNA_VHF_Contest_clicked (bool)
{
check_visibility ();
}
void Configuration::impl::on_rbEU_VHF_Contest_clicked (bool)
{
check_visibility ();
}
void Configuration::impl::on_rbWW_DIGI_clicked (bool)
{
check_visibility ();
}
void Configuration::impl::on_rbQ65pileup_clicked (bool)
{
check_visibility ();
}
void Configuration::impl::on_rbField_Day_clicked (bool)
{
check_visibility ();
}
void Configuration::impl::on_rbRTTY_Roundup_clicked (bool)
{
check_visibility ();
}
void Configuration::impl::on_rbARRL_Digi_clicked (bool)
{
check_visibility ();
}
void Configuration::impl::on_cbSuperFox_clicked (bool)
{
check_visibility ();
}
void Configuration::impl::on_cbContestName_clicked (bool)
{
check_visibility ();
}
void Configuration::impl::on_cbOTP_clicked(bool)
{
check_visibility();
}
void Configuration::impl::on_cbShowOTP_clicked(bool)
{
check_visibility();
}
void Configuration::impl::check_visibility ()
{
if (ui_->rbField_Day->isChecked() and ui_->gbSpecialOpActivity->isChecked()) {
ui_->labFD->setEnabled (true);
ui_->Field_Day_Exchange->setEnabled (true);
} else {
ui_->labFD->setEnabled (false);
ui_->Field_Day_Exchange->setEnabled (false);
}
if (ui_->rbRTTY_Roundup->isChecked() and ui_->gbSpecialOpActivity->isChecked()) {
ui_->labRTTY->setEnabled (true);
ui_->RTTY_Exchange->setEnabled (true);
} else {
ui_->labRTTY->setEnabled (false);
ui_->RTTY_Exchange->setEnabled (false);
}
if (ui_->cbContestName->isChecked() and !ui_->rbFox->isChecked() and !ui_->rbHound->isChecked()
and !ui_->rbQ65pileup->isChecked() and ui_->gbSpecialOpActivity->isChecked()) {
ui_->labCN->setEnabled (true);
ui_->Contest_Name->setEnabled (true);
} else {
ui_->labCN->setEnabled (false);
ui_->Contest_Name->setEnabled (false);
}
if ((ui_->rbFox->isChecked() or ui_->rbHound->isChecked()) and ui_->gbSpecialOpActivity->isChecked()) {
ui_->cbSuperFox->setEnabled (true);
ui_->cbOTP->setEnabled (true);
} else {
ui_->cbSuperFox->setEnabled (false);
ui_->cbOTP->setEnabled (false);
ui_->cbShowOTP->setEnabled(false);
}
if (!ui_->rbFox->isChecked() and !ui_->rbHound->isChecked() and !ui_->rbQ65pileup->isChecked()
and ui_->gbSpecialOpActivity->isChecked()) {
ui_->cbContestName->setEnabled (true);
} else {
ui_->cbContestName->setEnabled (false);
}
if (!ui_->cbOTP->isChecked() or !ui_->gbSpecialOpActivity->isChecked()) {
ui_->OTPSeed->setEnabled(false);
ui_->OTPUrl->setEnabled(false);
ui_->sbOTPinterval->setEnabled(false);
ui_->lblOTPSeed->setEnabled(false);
ui_->lblOTPUrl->setEnabled(false);
ui_->lblOTPEvery->setEnabled(false);
ui_->cbShowOTP->setEnabled(false);
} else {
if (ui_->rbHound->isChecked()) {
if (ui_->OTPUrl->text().isEmpty())
{
ui_->OTPUrl->setText(FoxVerifier::default_url());
}
ui_->OTPUrl->setEnabled(true);
ui_->lblOTPUrl->setEnabled(true);
ui_->cbShowOTP->setEnabled(true);
} else {
ui_->OTPUrl->setEnabled(false);
ui_->lblOTPUrl->setEnabled(false);
}
if (ui_->rbFox->isChecked()) {
ui_->sbOTPinterval->setEnabled(true);
ui_->OTPSeed->setEnabled(true);
ui_->lblOTPSeed->setEnabled(true);
ui_->lblOTPEvery->setEnabled(true);
ui_->cbShowOTP->setEnabled(false);
} else {
ui_->OTPSeed->setEnabled(false);
ui_->lblOTPSeed->setEnabled(false);
ui_->lblOTPEvery->setEnabled(false);
ui_->sbOTPinterval->setEnabled(false);
}
}
}
void Configuration::impl::on_OTPUrl_textEdited (QString const& url){
auto text = url;
if (text.size() == 0)
{
ui_->OTPUrl->setText(FoxVerifier::default_url());
}
}
void Configuration::impl::on_OTPSeed_textEdited (QString const& url){
ui_->OTPSeed->setText(url.toUpper());
}
void Configuration::impl::on_Field_Day_Exchange_textEdited (QString const& exchange)
{
auto text = exchange.simplified ().toUpper ();

View File

@ -9,6 +9,7 @@
#include "models/IARURegions.hpp"
#include "Audio/AudioDevice.hpp"
#include "Transceiver/Transceiver.hpp"
#include "otpgenerator.h"
#include "pimpl_h.hpp"
@ -188,10 +189,16 @@ public:
void setSpecial_Hound();
void setSpecial_Fox();
void setSpecial_None();
void toggle_SF();
bool highlight_DXcall () const;
bool highlight_DXgrid () const;
bool Individual_Contest_Name() const;
bool validate_otp_seed(QString);
QString OTPSeed() const;
QString OTPUrl() const;
bool OTPEnabled() const;
bool ShowOTP() const;
unsigned int OTPinterval() const;
// 0 1 2 3 4 5 6 7 8 9
enum class SpecialOperatingActivity {NONE, NA_VHF, EU_VHF, FIELD_DAY, RTTY, WW_DIGI, FOX, HOUND, ARRL_DIGI, Q65_PILEUP};
SpecialOperatingActivity special_op_id () const;

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
<width>760</width>
<height>648</height>
</rect>
</property>
<property name="windowTitle">
@ -2907,267 +2907,8 @@ Right click for insert and delete options.</string>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout_15" columnstretch="1,0,0,0,0">
<item row="0" column="2" rowspan="3">
<spacer name="horizontalSpacer_11">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="0">
<widget class="QRadioButton" name="rbQ65pileup">
<property name="minimumSize">
<size>
<width>0</width>
<height>18</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Exchange 4-character locator instead of signal report. Provides q3-level sensitivities for the DX operator. Especially useful for 6m EME DXpeditions.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Q65 Pileup</string>
</property>
<attribute name="buttonGroup">
<string notr="true">special_op_activity_button_group</string>
</attribute>
</widget>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="rbNA_VHF_Contest">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;North American VHF/UHF/Microwave contests and others in which a 4-character grid locator is the required exchange.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="accessibleName">
<string>NA VHF Contest</string>
</property>
<property name="text">
<string>NA VHF</string>
</property>
<attribute name="buttonGroup">
<string notr="true">special_op_activity_button_group</string>
</attribute>
</widget>
</item>
<item row="3" column="0">
<widget class="QRadioButton" name="rbWW_DIGI">
<property name="minimumSize">
<size>
<width>0</width>
<height>18</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;World-Wide Digi-mode contest&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="accessibleName">
<string>WW Digital Contest</string>
</property>
<property name="text">
<string>WW Digi Contest</string>
</property>
<attribute name="buttonGroup">
<string notr="true">special_op_activity_button_group</string>
</attribute>
</widget>
</item>
<item row="2" column="4">
<layout class="QHBoxLayout" name="horizontalLayout_18" stretch="2,1,1">
<item>
<widget class="QRadioButton" name="rbRTTY_Roundup">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;FT Roundup and similar contests. Exchange is US state, Canadian province, or &amp;quot;DX&amp;quot;.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="accessibleName">
<string>R T T Y Roundup</string>
</property>
<property name="text">
<string>FT Roundup</string>
</property>
<attribute name="buttonGroup">
<string notr="true">special_op_activity_button_group</string>
</attribute>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_10">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QFormLayout" name="formLayout_17">
<item row="0" column="0">
<widget class="QLabel" name="labRTTY">
<property name="accessibleName">
<string>RTTY Roundup exchange</string>
</property>
<property name="text">
<string>FT RU Exch:</string>
</property>
<property name="buddy">
<cstring>RTTY_Exchange</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="RTTY_Exchange">
<property name="minimumSize">
<size>
<width>70</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;FT Roundup and similar contests. Exchange is US state, Canadian province, or &amp;quot;DX&amp;quot;.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>NJ</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item row="4" column="4">
<layout class="QHBoxLayout" name="horizontalLayout_24">
<item>
<widget class="QCheckBox" name="cbContestName">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Call CQ with an individual contest name instead of TEST, RU, or WW. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>CQ with individual contest name</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_12">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_25">
<item>
<widget class="QLabel" name="labCN">
<property name="text">
<string>Contest name:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="Contest_Name">
<property name="maximumSize">
<size>
<width>70</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="maxLength">
<number>4</number>
</property>
<property name="cursorPosition">
<number>0</number>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item row="3" column="4">
<widget class="QRadioButton" name="rbARRL_Digi">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;ARRL International Digital Contest&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>ARRL Digi Contest</string>
</property>
<attribute name="buttonGroup">
<string notr="true">special_op_activity_button_group</string>
</attribute>
</widget>
</item>
<item row="2" column="0">
<widget class="QRadioButton" name="rbEU_VHF_Contest">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;European VHF+ contests requiring a signal report, serial number, and 6-character locator.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="accessibleName">
<string>EU VHF Contest</string>
</property>
<property name="text">
<string>EU VHF Contest</string>
</property>
<attribute name="buttonGroup">
<string notr="true">special_op_activity_button_group</string>
</attribute>
</widget>
</item>
<item row="0" column="0">
<widget class="QRadioButton" name="rbFox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;FT8 DXpedition mode: Fox (DXpedition) operator.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="accessibleName">
<string>Fox</string>
</property>
<property name="text">
<string>Fox</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">special_op_activity_button_group</string>
</attribute>
</widget>
</item>
<item row="1" column="4">
<layout class="QGridLayout" name="gridLayout_15" columnstretch="1,1,0,2">
<item row="2" column="3">
<layout class="QHBoxLayout" name="horizontalLayout_17" stretch="2,1,1">
<item>
<widget class="QRadioButton" name="rbField_Day">
@ -3236,19 +2977,119 @@ Right click for insert and delete options.</string>
</item>
</layout>
</item>
<item row="0" column="4">
<widget class="QRadioButton" name="rbHound">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;FT8 DXpedition mode: Hound operator calling the DX.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<item row="1" column="3">
<layout class="QHBoxLayout" name="OTP_Layout_2" stretch="0,0,0,1">
<item>
<widget class="QCheckBox" name="cbShowOTP">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Show OTP messages in the Band Activity window.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Show OTP messages</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_17">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="lblOTPUrl">
<property name="text">
<string>OTP URL:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="OTPUrl">
<property name="minimumSize">
<size>
<width>110</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;URL used to verify OTP codes.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>https://www.9dx.cc</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="5" column="0">
<widget class="QRadioButton" name="rbQ65pileup">
<property name="minimumSize">
<size>
<width>0</width>
<height>18</height>
</size>
</property>
<property name="accessibleName">
<string>Hound</string>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Exchange 4-character locator instead of signal report. Provides q3-level sensitivities for the DX operator. Especially useful for 6m EME DXpeditions.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Hound</string>
<string>Q65 Pileup</string>
</property>
<property name="checked">
<bool>true</bool>
<attribute name="buttonGroup">
<string notr="true">special_op_activity_button_group</string>
</attribute>
</widget>
</item>
<item row="2" column="0">
<widget class="QRadioButton" name="rbNA_VHF_Contest">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;North American VHF/UHF/Microwave contests and others in which a 4-character grid locator is the required exchange.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="accessibleName">
<string>NA VHF Contest</string>
</property>
<property name="text">
<string>NA VHF</string>
</property>
<attribute name="buttonGroup">
<string notr="true">special_op_activity_button_group</string>
</attribute>
</widget>
</item>
<item row="3" column="0">
<widget class="QRadioButton" name="rbEU_VHF_Contest">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;European VHF+ contests requiring a signal report, serial number, and 6-character locator.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="accessibleName">
<string>EU VHF Contest</string>
</property>
<property name="text">
<string>EU VHF Contest</string>
</property>
<attribute name="buttonGroup">
<string notr="true">special_op_activity_button_group</string>
@ -3257,11 +3098,338 @@ Right click for insert and delete options.</string>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="cbSuperFox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Check this box to transmit (Fox) or receive (Hound) the SuperFox waveform.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>SuperFox</string>
<string>SuperFox mode</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QRadioButton" name="rbFox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;FT8 DXpedition mode: Fox (DXpedition) operator.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="accessibleName">
<string>Fox</string>
</property>
<property name="text">
<string>Fox</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">special_op_activity_button_group</string>
</attribute>
</widget>
</item>
<item row="4" column="3">
<widget class="QRadioButton" name="rbARRL_Digi">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;ARRL International Digital Contest&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>ARRL Digi Contest</string>
</property>
<attribute name="buttonGroup">
<string notr="true">special_op_activity_button_group</string>
</attribute>
</widget>
</item>
<item row="5" column="3">
<layout class="QHBoxLayout" name="horizontalLayout_24">
<item>
<widget class="QCheckBox" name="cbContestName">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Call CQ with an individual contest name instead of TEST, RU, or WW. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>CQ with individual contest name</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_12">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_25">
<item>
<widget class="QLabel" name="labCN">
<property name="text">
<string>Contest name:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="Contest_Name">
<property name="maximumSize">
<size>
<width>70</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="maxLength">
<number>4</number>
</property>
<property name="cursorPosition">
<number>0</number>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item row="3" column="3">
<layout class="QHBoxLayout" name="horizontalLayout_18" stretch="2,1,1">
<item>
<widget class="QRadioButton" name="rbRTTY_Roundup">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;FT Roundup and similar contests. Exchange is US state, Canadian province, or &amp;quot;DX&amp;quot;.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="accessibleName">
<string>R T T Y Roundup</string>
</property>
<property name="text">
<string>FT Roundup</string>
</property>
<attribute name="buttonGroup">
<string notr="true">special_op_activity_button_group</string>
</attribute>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_10">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QFormLayout" name="formLayout_17">
<item row="0" column="0">
<widget class="QLabel" name="labRTTY">
<property name="accessibleName">
<string>RTTY Roundup exchange</string>
</property>
<property name="text">
<string>FT RU Exch:</string>
</property>
<property name="buddy">
<cstring>RTTY_Exchange</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="RTTY_Exchange">
<property name="minimumSize">
<size>
<width>70</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;FT Roundup and similar contests. Exchange is US state, Canadian province, or &amp;quot;DX&amp;quot;.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>NJ</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item row="4" column="0">
<widget class="QRadioButton" name="rbWW_DIGI">
<property name="minimumSize">
<size>
<width>0</width>
<height>18</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;World-Wide Digi-mode contest&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="accessibleName">
<string>WW Digital Contest</string>
</property>
<property name="text">
<string>WW Digi Contest</string>
</property>
<attribute name="buttonGroup">
<string notr="true">special_op_activity_button_group</string>
</attribute>
</widget>
</item>
<item row="0" column="3">
<layout class="QHBoxLayout" name="horizontalLayout_27" stretch="0,1">
<item>
<widget class="QRadioButton" name="rbHound">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;FT8 DXpedition mode: Hound operator calling the DX.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="accessibleName">
<string>Hound</string>
</property>
<property name="text">
<string>Hound</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">special_op_activity_button_group</string>
</attribute>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_15">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="0" colspan="3">
<layout class="QHBoxLayout" name="OTP_Layout" stretch="0,0,0,1,0,0,0,1">
<item>
<widget class="QCheckBox" name="cbOTP">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Click to enable OTP method of Fox verification. Requires internet.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>OTP</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_11">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>7</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="lblOTPSeed">
<property name="text">
<string>Key:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="OTPSeed">
<property name="minimumSize">
<size>
<width>110</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Fox's key to generate OTP Codes.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>M2ZUU5CW6EVOY2HU</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_14">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="lblOTPEvery">
<property name="text">
<string>Interval</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="sbOTPinterval">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Interval at which the OTP messages are sent. Select 1 to sign every message.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="maximum">
<number>20</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_15">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
@ -3427,13 +3595,8 @@ Right click for insert and delete options.</string>
<tabstop>rbLowSidelobes</tabstop>
<tabstop>rbMaxSensitivity</tabstop>
<tabstop>gbSpecialOpActivity</tabstop>
<tabstop>rbFox</tabstop>
<tabstop>rbHound</tabstop>
<tabstop>rbNA_VHF_Contest</tabstop>
<tabstop>rbField_Day</tabstop>
<tabstop>rbEU_VHF_Contest</tabstop>
<tabstop>rbRTTY_Roundup</tabstop>
<tabstop>rbWW_DIGI</tabstop>
<tabstop>Field_Day_Exchange</tabstop>
<tabstop>RTTY_Exchange</tabstop>
</tabstops>
@ -3505,13 +3668,13 @@ Right click for insert and delete options.</string>
</connection>
</connections>
<buttongroups>
<buttongroup name="split_mode_button_group"/>
<buttongroup name="TX_mode_button_group"/>
<buttongroup name="CAT_data_bits_button_group"/>
<buttongroup name="CAT_stop_bits_button_group"/>
<buttongroup name="TX_audio_source_button_group"/>
<buttongroup name="PTT_method_button_group"/>
<buttongroup name="CAT_handshake_button_group"/>
<buttongroup name="special_op_activity_button_group"/>
<buttongroup name="TX_audio_source_button_group"/>
<buttongroup name="PTT_method_button_group"/>
<buttongroup name="TX_mode_button_group"/>
<buttongroup name="CAT_stop_bits_button_group"/>
<buttongroup name="CAT_data_bits_button_group"/>
<buttongroup name="split_mode_button_group"/>
</buttongroups>
</ui>

View File

@ -1,122 +1,132 @@
Notes on WSJT-X Installation for Mac OS X
-----------------------------------------
If you have already downloaded a previous version of WSJT-X then I suggest
you change the name in the Applications folder from WSJT-X to WSJT-X_previous
before proceeding.
I recommend that you follow the installation instructions especially if you
are moving from v2.5 to v2.6 or later, of WSJT-X or you have upgraded macOS.
Double-click on the wsjtx-...-Darwin.dmg file you have downloaded from K1JT's web-site.
Make sure that you leave this window open for the remaining installation steps.
Now open a Terminal window by going to Applications->Utilities and clicking on Terminal.
Along with this ReadMe file there is a file: com.wsjtx.sysctl.plist which must be copied to a
system area by typing these lines in the Terminal window and then pressing the Return key after
each line.
sudo cp /Volumes/WSJT-X/com.wsjtx.sysctl.plist /Library/LaunchDaemons
sudo chown root:wheel /Library/LaunchDaemons/com.wsjtx.sysctl.plist
you will be asked for your normal password because authorisation is needed to copy this file.
(Your password will not be echoed but press the Return key when completed.)
IMPORTANT: Now re-boot your Mac otherwise these changes will not take effect.
After the reboot you should re-open the Terminal window as before and you can check
that the change has been made by typing:
sysctl -a | grep sysv.shm
If shmmax is not shown as 52428800 then contact me since WSJT-X will fail to load with
an error message: "Unable to create shared memory segment". If the value of shmmax
is shown as 20971520 then it is probable that you have download JTDX. WSJT-X and JTDX
cannot both control the shmmax paramter. Contact me for advice.
You can now close the Terminal window. It will not be necessary to repeat this procedure
again, even when you download an updated version of WSJT-X. It might be necessary if you
upgrade macOS.
Drag the WSJT-X app to your preferred location, such as Applications.
You need to configure your sound card. Visit Applications > Utilities > Audio MIDI
Setup and select your sound card and then set Format to be "48000Hz 2ch-16bit" for
input and output.
Now double-click on the WSJT-X app and two windows will appear. Select Preferences
under the WSJT-X Menu and fill in various station details on the General panel.
I recommend checking the 4 boxes under the Display heading and the first 4 boxes under
the Behaviour heading.
Depending on your macOS you might see a pop-up window suggesting that wsjtx wants to use the
microphone. What this means is that audio input must be allowed. Agree.
Next visit the Audio panel and select the Audio Codec you use to communicate between
WSJT-X and your rig. There are so many audio interfaces available that it is not
possible to give detailed advice on selection. If you have difficulties contact me.
Note the location of the Save Directory. Decoded wave forms are located here.
Look at the Reporting panel. If you check the "Prompt me" box, a logging panel will appear
at the end of the QSO. Visit Section 11 of the User Guide for information about log files
and how to access them.
Finally, visit the Radio panel. WSJT-X is most effective when operated with CAT
control. You will need to install the relevant Mac device driver for your rig,
and then re-launch WSJT-X. Return to the Radio panel in Preferences and in
the "Serial port" panel select your driver from the list that is presented.
You may need a device driver for your Mac. The USB/UART Bridge chip inside the Icom,
Yaesu and Kenwood radios is a Silicon Labs USB to UART Bridge Controller and the Mac
drivers are available here:
https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers
Visit the SiLabs site and download v6 for a Mac. Then in WSJT-X if you use the drop-down menu
for Serial Port you should see something like /dev/tty.SLAB_USBtoUART if the driver has been
installed correctly. Make sure you read the release notes that come with the driver.
WSJT-X needs the Mac clock to be accurate. Visit System Preferences > Date & Time
and make sure that Date and Time are set automatically. The drop-down menu will
normally offer you several time servers to choose from.
On the Help menu, have a look at the new Online User's Guide for operational hints
and tips and possible solutions to any problem you might have.
Please email me if you have problems.
--- John G4KLA (g4kla@rmnjmn.co.uk)
Addendum: Information about com.wsjtx.sysctl.plist and multiple instances of WSJT-X.
WSJT-X makes use of a block of memory which is shared between different parts of
the code. The normal allocation of shared memory on a Mac is insufficient and this
has to be increased. The com.wsjtx.sysctl.plist file is used for this purpose. You can
use a Mac editor to examine the file. (Do not use another editor - the file
would probably be corrupted.)
It is possible to run two instances of WSJT-X simultaneously. See "Section 16.2
Frequently asked Questions" in the User Guide. If you wish to run more than two instances
simultaneously, the shmall parameter in the com.wsjtx.sysctl.plist file needs to be modified as follows.
The shmall parameter determines the amount of shared memory which is allocated in 4096 byte pages
with 50MB (52428800) required for each instance. The shmall parameter is calculated as:
(n * 52428800)/4096 where 'n' is the number of instances required to run simultaneously.
Replace your new version of this file in /Library/LaunchDaemons and remember to reboot your
Mac afterwards.
Note that the shmmax parameter remains unchanged. This is the maximum amount of shared memory that
any one instance is allowed to request from the total shared memory allocation and should not
be changed.
If two instances of WSJT-X are running, it is likely that you might need additional
audio devices, from two rigs for example. Visit Audio MIDI Setup and create an Aggregate Device
which will allow you to specify more than one interface. I recommend you consult Apple's guide
on combining multiple audio interfaces which is at https://support.apple.com/en-us/HT202000.
2. Preventing WSJT-X from being put into 'sleep' mode (App Nap).
In normal circumstances an application which has not been directly accessed for a while can be
subject to App Nap which means it is suspended until such time as its windows are accessed. If
Notes on WSJT-X Installation for Mac OS X
-----------------------------------------
If you have already downloaded a previous version of WSJT-X then I suggest
you change the name in the Applications folder from WSJT-X to WSJT-X_previous
before proceeding.
I recommend that you follow the installation instructions especially if you
are moving from v2.5 to v2.6 or later, of WSJT-X or you have upgraded macOS.
Double-click on the wsjtx-...-Darwin.dmg file you have downloaded from the main web-site.
Make sure that you leave this window open for the remaining installation steps.
Now open a Terminal window by going to Applications->Utilities and clicking on Terminal.
Along with this ReadMe file there is a file: com.wsjtx.sysctl.plist which must be copied to a
system area by typing these lines in the Terminal window and then pressing the Return key after
each line.
sudo cp /Volumes/WSJT-X/com.wsjtx.sysctl.plist /Library/LaunchDaemons
sudo chown root:wheel /Library/LaunchDaemons/com.wsjtx.sysctl.plist
you will be asked for your normal password because authorisation is needed to copy this file.
(Your password will not be echoed but press the Return key when completed.)
If your Mac is using Sonoma 14.6 or later then in addition to these two commands you must visit:
System Settings > General > Login Items > sysctl and select ON for sysctl.
IMPORTANT: Now re-boot your Mac otherwise these changes will not take effect.
After the reboot you should re-open the Terminal window as before and you can check
that the change has been made by typing:
sysctl -a | grep sysv.shm
If shmmax is not shown as 52428800 then contact me since WSJT-X will fail to load with
an error message: "Unable to create shared memory segment". If the value of shmmax
is shown as 20971520 then it is probable that you have download JTDX. WSJT-X and JTDX
cannot both control the shmmax parameter. Contact me for advice.
You can now close the Terminal window. It will not be necessary to repeat this procedure
again, even when you download an updated version of WSJT-X. It might be necessary if you
upgrade macOS.
Drag the WSJT-X app to your preferred location, such as Applications, and close the window.
You need to configure your sound card. Visit Applications > Utilities > Audio MIDI
Setup and select your sound card and then set Format to be "48000Hz 2ch-16bit" for
input and output. On rare occasions problems with audio output to your rig can be
corrected if you select 44100Hz for output format.
Now double-click on the WSJT-X app and two windows will appear. Select Preferences
under the WSJT-X Menu and fill in various station details on the General panel.
I recommend checking the 4 boxes under the Display heading and the first 4 boxes under
the Behaviour heading.
Depending on your macOS you might see a pop-up window suggesting that wsjtx wants to use the
microphone. What this means is that audio input must be allowed. Agree.
Next visit the Audio panel and select the Audio Codec you use to communicate between
WSJT-X and your rig. There are so many audio interfaces available that it is not
possible to give detailed advice on selection. If you have difficulties contact me.
Note the location of the Save Directory. Decoded wave forms are located here.
Look at the Reporting panel. If you check the "Prompt me" box, a logging panel will appear
at the end of the QSO. Visit Section 11 of the User Guide for information about log files
and how to access them.
Finally, visit the Radio panel. WSJT-X is most effective when operated with CAT
control. You will need to install the relevant Mac device driver for your rig,
and then re-launch WSJT-X. Return to the Radio panel in Preferences and in
the "Serial port" panel select your driver from the list that is presented.
You may need a device driver for your Mac. The USB/UART Bridge chip inside the Icom,
Yaesu and Kenwood radios is a Silicon Labs USB to UART Bridge Controller and the Mac
drivers are available here:
https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers
Visit the SiLabs site and download v6 for a Mac. Then in WSJT-X if you use the drop-down menu
for Serial Port you should see something like /dev/tty.SLAB_USBtoUART if the driver has been
installed correctly. Make sure you read the release notes that come with the driver.
WSJT-X needs the Mac clock to be accurate. Visit System Preferences > Date & Time
and make sure that Date and Time are set automatically. The drop-down menu will
normally offer you several time servers to choose from.
On the Help menu, have a look at the new Online User's Guide for operational hints
and tips and possible solutions to any problem you might have.
Please email me if you have problems.
--- John G4KLA (g4kla@rmnjmn.co.uk)
Addendum: Information about com.wsjtx.sysctl.plist and multiple instances of WSJT-X.
WSJT-X makes use of a block of memory which is shared between different parts of
the code. The normal allocation of shared memory on a Mac is insufficient and this
has to be increased. The com.wsjtx.sysctl.plist file is used for this purpose. You can
use a Mac editor to examine the file. (Do not use another editor - the file
would probably be corrupted.)
It is possible to run two instances of WSJT-X simultaneously. See "Section 16.2
Frequently asked Questions" in the User Guide. If you wish to run more than two instances
simultaneously, the shmall parameter in the com.wsjtx.sysctl.plist file needs to be modified as follows.
The shmall parameter determines the amount of shared memory which is allocated in 4096 byte pages
with 50MB (52428800) required for each instance. The shmall parameter is calculated as:
(n * 52428800)/4096 where 'n' is the number of instances required to run simultaneously.
Replace your new version of this file in /Library/LaunchDaemons and remember to reboot your
Mac afterwards.
Note that the shmmax parameter remains unchanged. This is the maximum amount of shared memory that
any one instance is allowed to request from the total shared memory allocation and should not
be changed.
If two instances of WSJT-X are running, it is likely that you might need additional
audio devices, from two rigs for example. Visit Audio MIDI Setup and create an Aggregate Device
which will allow you to specify more than one interface. I recommend you consult Apple's guide
on combining multiple audio interfaces which is at https://support.apple.com/en-us/HT202000.
2. Preventing WSJT-X from being put into 'sleep' mode (App Nap).
In normal circumstances an application which has not been directly accessed for a while can be
subject to App Nap which means it is suspended until such time as its windows are accessed. If
you find that WSJT-X seems disabled check this by opening Applications > Utilities > Activity Monitor and
then select Energy and look at the column marked App Nap. If you see wsjtx marked "Yes" then you need
to disable App Nap by opening a Terminal window and typing:
defaults write NSGlobalDomain NSAppSleepDisabled -bool YES
This will disable App Nap for all applications. If you wish to reverse this type:
defaults delete NSGlobalDomain NSAppSleepDisabled

View File

@ -70,9 +70,10 @@ void Modulator::start (QString mode, unsigned symbolsLength, double framesPerSym
m_bFastMode=fastMode;
m_TRperiod=TRperiod;
unsigned delay_ms=1000;
if(mode=="FT8" or (mode=="FST4" and m_nsps==720)) delay_ms=500; //FT8, FST4-15
if(mode=="Q65" and m_nsps<=3600) delay_ms=500; //Q65-15 and Q65-30
if(mode=="FT4") delay_ms=300; //FT4
if((mode=="FT8" and m_nsps==1920) or (mode=="FST4" and m_nsps==720)) delay_ms=500; //FT8, FST4-15
if((mode=="FT8" and m_nsps==1024)) delay_ms=400; //SuperFox Qary Polar Code transmission
if(mode=="Q65" and m_nsps<=3600) delay_ms=500; //Q65-15 and Q65-30
if(mode=="FT4") delay_ms=300; //FT4
// noise generator parameters
if (m_addNoise) {

244
NEWS
View File

@ -11,6 +11,250 @@
Copyright 2001 - 2024 by Joe Taylor, K1JT, and the WSJT Development Team
Release: WSJT-X 2.7.0-rc7
September 30, 2024
-------------------------
WSJT-X 2.7.0 Release Candidate 7 brings significant improvements for
the new SuperFox mode. It introduces a new verification system which
replaces the previous one, and works for both the SuperFox mode and
for old-style Fox and Hound operation. All code for SuperFox
operation is now open source.
IMPORTANT: OpenSSL v1.1.1 or higher is required for the real-time
verification of Fox and SuperFox messages.
Enhancements to the SuperFox decoder:
- Performance of the SuperFox decoder has been further improved.
- You can now set individual FTol values and tune the decoder to
the exact sync frequency of the SuperFox signal if it is not exactly
750 Hz. Both result in a better decodability in certain situations.
- Important: The Rx frequency must be set close to the sync frequency
+/- FTol, for example 750 +/- 50 Hz.
Introduction of a new Fox verification system:
- The new Fox verification system uses one time passwords (OTPs), and
works for the SuperFox mode as well as for old-style Fox and Hound
operation. It can be enabled by the new OTP checkbox on the Advanced
tab of the Settings dialog.
- Fox or SuperFox stations send individual OTPs via radio. Hounds
automatically check the validity of the received OTPs in real time
from a server when there is an internet connection. Otherwise, the
validity can also be queried manually later. OTP verifications can
only be retrieved once the transmission has already taken place.
- You may optionally display the received OTP values by checking
the box "Show OTP messages".
- If the Fox or SuperFox callsign is verified by receipt of the
correct OTP, the background color of the Hound or Super Hound label
switches to green.
- Theoretically, DXpeditions can set up their own OTP server, however,
we recommend using the server at https://www.9dx.cc.
- Use of the new Fox verification system requires an OTP key. The
system uses open source code and standard encryption
technology. For testing purposes, non-verified SuperFox
transmissions are now possible without a key.
Improvements to SuperFox/Hound operation:
- SuperHounds must now first decode the SuperFox before they can
call, and a QSO must be started by double-clicking on a SuperFox
decode. (Note that calling the Fox blindly not only leads to
unnecessary band utilization, but can also significantly reduce the
QSO rate due to unanswered (Super)Fox replies.)
- Switching to SuperHound mode automatically sets the Rx frequency to
750 Hz. The previously selected frequency is saved and restored
afterwards.
- Right-clicking on the H button now activates/deactivates SuperFox mode.
- A flaw resulting in sub-optimal SuperFox QSO rates has been
corrected.
- SuperFox decoder now does a more thorough job of rejecting QRM from
non-SuperFox signals.
- Fields in the SuperFox payload not otherwise used in a particular
transmission are now set to known nonzero values. Do NOT use RC6 or
earlier versions to decode SuperFox transmissions from RC7 or
later.
- Old-style Fox stations can now transmit free text messages (up to
13 characters) by using an available stream.
- Some enhancements useful for Fox operators: Active Station Window now
shows band activity. Hound callsigns can be highlighted via UDP API, and
assigned a score for sorting via UDP API. Fox Tx frequency is preserved
when switching in/out of Fox mode.
- UDP Status Update messages now include information on how many callsigns
have highlighting applied, and how many callsigns have a score assigned.
Other enhancements and fixes:
- In FT8 mode, the Settings dialog no longer resets the VFO frequency
to band/mode default unless really needed.
- Several code improvements specifically for macOS.
- Updated CTY.DAT and Hamlib.
Release: WSJT-X 2.7.0-rc6
July 19, 2024
-------------------------
WSJT-X 2.7.0 Release Candidate 6 is a bug-fix release primarily
affecting the new SuperFox mode. The following bugs have been fixed:
- Strong signals from Superfox too frequently failed to decode.
- SuperFox sometimes sent incorrect signal reports and an invalid
digital signature.
- A Fortran bounds error could sometimes occur in the SuperFox
decoder.
- For SuperFox operator, the "age" displayed for Hound callers
became garbled after the 0000 UTC date change.
- Decodes of SuperFox transmissions were not posted to PSK Reporter.
- Some SuperFox-related messages were posted incorrectly to ALL.TXT.
- Logic for turning the SuperHound label green was flawed in some
circumstances.
Release Candidate 6 also includes updates to Hamlib and the Chinese
user interface translation.
Release: WSJT-X 2.7.0-rc5
July 1, 2024
-------------------------
WSJT-X 2.7.0 Release Candidate 5 introduces "SuperFox" mode, a
powerful new tool designed to help DXpeditions make digital QSOs at
very high rates. RC5 also brings several other improvements and bug
fixes.
SuperFox mode:
- The SuperFox mode behaves operationally like the present Fox and
Hounds mode but uses a constant envelope waveform for Fox's
transmissions rather than sending concurrent streams of up to five
normal FT8 signals. This approach means that up to 9 messages can
be transmitted simultaneously with no signal-strength penalty,
resulting in a system gain of about +10 dB compared to the
conventional Fox/Hound operation with 5 slots.
- IMPORTANT: Older revisions of WSJT-X and derivative programs will
not be able to decode SuperFox transmissions. Hounds must use
WSJT-X 2.7.0-rc5 (or a later release, when available) to receive
SuperFox messages.
- Hounds chasing the DX station will transmit normal FT8 signals, as
in the old-style Fox and Hound mode. QSOs will be logged as FT8
mode.
- When using SuperFox mode, Hound stations may call at any frequency
in Fox's received passband, including the range 0 - 1000 Hz.
Hounds do not QSY to a lower frequency for their final
transmission.
- SuperFox Operation requires the Fox operator to use a valid digital
key. Keys will be issued in advance to legitimate DXpeditions by
the Northern California DX Foundation, and will be kept secret.
- Every SuperFox transmission includes a unique digital signature.
Hounds receiving a SuperFox message will see a "<callsign> verified"
flag if the transmitted signature is valid, and the on-screen
"Super Hound" label will turn from red to green.
- Hound operation should begin by selecting "Special operating
activity", "Hound", and "SuperFox mode" on the Settings -> Advanced
tab. Alternatively, right-clicking on the FT8 button toggles
SuperFox mode on/off for either Fox or Hound, allowing quick
transitions between SuperFox and old-style Fox and Hound operation.
- SuperFox stations can send free text messages of up to 26 characters
together with messages to as many as 4 Hounds.
Other enhancements:
- Corrected a flaw that caused "Log automatically" to not work for
the ARRL Digi Contest.
- Control elements for special operating activities are now disabled
(grayed out) if the respective function is not applicable.
- Corrected a longstanding flaw that caused "Start new period
decodes at top" to stop working properly after some time.
- Right-click mouse press events are now less error-prone.
- Improved the readability of the first line when "Start new period
decodes at top" is checked.
- 4-digit grids are now logged for certain contest modes to ensure that
the log complies with contest rules.
- The Fox Tx frequency is now saved and restored separately.
Release: WSJT-X 2.7.0-rc4
March 11, 2024
-------------------------
WSJT-X 2.7.0 Release Candidate 4 brings some improvements for Fox-mode
operators, new features for companion program QMAP, and a number of
relatively minor enhancements and bug fixes.
QMAP enhancements -- of particular interest to EME operators:
- QMAP now decodes Q65 submodes with both 60-second and 30-second T/R
sequence lengths. Clicking on a resulting line in the WSJT-X Active
Stations window automatically sets dial frequency and working
submode as needed to call that station.
- QMAP operates in 60-second receive sequences, and its Q65 decoder
starts at t=19.5, 30.0, 49.5, and 58.5 s into the sequence. Most
decoded messages are displayed well before the end of the relevant
time slot.
- A new, more compact file format is now used for wideband data
files. A "Save decoded" option has been added to the Save menu.
- An option has been added to allow exporting a 3 kHz portion of a
wideband data file as a standard WSJT-X *.wav file.
- CTRL+click on QMAP's upper waterfall sends an integer kHz dial
frequency request to WSJT-X.
- With focus on the WSJT-X main window, hit Alt+A on the keyboard to
clear the Active Stations window.
- Many minor enhancements to the User Interface.
WSJT-X:
- Enable decoding of MSK144 from the jt9[.exe] executable.
- Several changes to reduce problems experienced when (contrary to
our recommendations) messages with short (10-bit) callsign hashes
are used in standard FT4/FT8 sub-bands.
- Enhancements useful for Fox operators.
Release: WSJT-X 2.7.0-rc3
January 1, 2024
-------------------------

125
Network/FoxVerifier.cpp Normal file
View File

@ -0,0 +1,125 @@
#include "FoxVerifier.hpp"
#include "Logger.hpp"
FoxVerifier::FoxVerifier(QString user_agent, QNetworkAccessManager *manager,QString base_url, QString callsign, QDateTime timestamp, QString code, unsigned int hz=750) : QObject(nullptr)
{
manager_ = manager;
finished_ = false;
errored_ = false;
callsign_ = callsign;
code_ = code;
ts_ = timestamp;
hz_ = hz;
// make sure we URLencode the callsign, for things like E51D/MM
QString encodedCall = QString::fromUtf8(QUrl::toPercentEncoding(callsign));
QString url = QString("%1/check/").arg(base_url) + encodedCall + QString("/%1/%2.text").arg(timestamp.toString(Qt::ISODate)).arg(code);
LOG_INFO(QString("FoxVerifier: url %1").arg(url).toStdString());
q_url_ = QUrl(url);
if (manager_ == nullptr) {
LOG_INFO("FoxVerifier: manager is null, creating new one");
manager_ = new QNetworkAccessManager(this);
manager_->deleteLater();
}
if (q_url_.isValid()) {
request_ = QNetworkRequest(q_url_);
request_.setRawHeader( "User-Agent" , user_agent.toUtf8());
request_.setRawHeader( "Accept" , "*/*" );
request_.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
request_.setTransferTimeout(FOXVERIFIER_DEFAULT_TIMEOUT_MSEC);
#endif
reply_ = manager_->get(request_);
connect(reply_, &QNetworkReply::finished, this, &FoxVerifier::httpFinished);
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
connect(reply_, &QNetworkReply::errorOccurred, this, &FoxVerifier::errorOccurred);
#endif
connect(reply_, &QNetworkReply::redirected, this, &FoxVerifier::httpRedirected);
connect(reply_, &QNetworkReply::encrypted, this, &FoxVerifier::httpEncrypted);
#if QT_CONFIG(ssl)
connect(reply_, &QNetworkReply::sslErrors, this, &FoxVerifier::sslErrors);
#else
LOG_INFO("FoxVerifier: ssl not supported");
#endif
} else {
LOG_INFO(QString("FoxVerifier: url invalid ! %1").arg(url).toStdString());
}
}
FoxVerifier::~FoxVerifier() {
}
bool FoxVerifier::finished() {
return finished_;
}
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
void FoxVerifier::errorOccurred(QNetworkReply::NetworkError code)
{
int status = reply_->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString reason = reply_->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
errored_ = true;
error_reason_ = reply_->errorString();
if (reply_->error() != QNetworkReply::NoError) {
LOG_INFO(QString("FoxVerifier: errorOccurred status %1 error [%2][%3] isFinished %4 isrunning %5 code %6").arg(status).arg(
reason).arg(error_reason_).arg(reply_->isFinished()).arg(reply_->isRunning()).arg(code).toStdString());
return;
}
// TODO emit
}
#endif
void FoxVerifier::httpFinished()
{
int status = reply_->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString reason = reply_->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
if (reply_->error() != QNetworkReply::NoError) {
LOG_INFO(QString("FoxVerifier: httpFinished error:[%1 - %2] msg:[%3]").arg(status).arg(reason).arg(reply_->errorString()).toStdString());
reply_->abort();
emit verifyError(status, ts_, callsign_, code_, hz_, reply_->errorString());
}
return_value = reply_->read(1024); // limit amount we get
LOG_INFO(QString("FoxVerifier: httpFinished status:[%1 - %2] body:[%3] ").arg(status).arg(reason).arg(return_value).toStdString());
finished_ = true;
reply_->deleteLater();
if (status >= 200 && status <= 299) {
emit verifyComplete(status, ts_, callsign_, code_, hz_, return_value);
}
}
void FoxVerifier::sslErrors(const QList<QSslError> &)
{
LOG_INFO(QString("FoxVerifier: sslErrors").toStdString());
reply_->ignoreSslErrors();
}
void FoxVerifier::httpRedirected(const QUrl &url) {
LOG_INFO(QString("FoxVerifier: redirected to %1").arg(url.toString()).toStdString());
}
void FoxVerifier::httpEncrypted() {
LOG_INFO("FoxVerifier: httpEncrypted");
}
QString FoxVerifier::formatDecodeMessage(QDateTime ts, QString callsign, unsigned int hz_, QString const& verify_message) {
//"172100 -00 0.0 750 ~ K8R VERIFIED"
QTime rx_time = ts.time();
QString hz=QString("%1").arg(hz_, 4, 10 ); // insert Hz
if (verify_message.endsWith(" VERIFIED")) {
return QString("%1 0 0.0 %2 ~ %3 verified").arg(rx_time.toString("hhmmss")).arg(hz).arg(callsign);
} else
if (verify_message.endsWith(" INVALID"))
{
return QString("%1 0 0.0 %2 ~ %3 invalid").arg(rx_time.toString("hhmmss")).arg(hz).arg(callsign);
}
else
return QString{};
}
QString FoxVerifier::default_url() {
return QString(FOXVERIFIER_DEFAULT_BASE_URL);
}

63
Network/FoxVerifier.hpp Normal file
View File

@ -0,0 +1,63 @@
#ifndef WSJTX2_FOXVERIFIER_HPP
#define WSJTX2_FOXVERIFIER_HPP
#include <QObject>
#include <QString>
#include <QPointer>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply>
#include <QMutex>
#define FOXVERIFIER_DEFAULT_TIMEOUT_MSEC 5000
#define FOXVERIFIER_DEFAULT_BASE_URL "https://www.9dx.cc"
class FoxVerifier : public QObject {
Q_OBJECT
QMutex mutex_;
public:
explicit FoxVerifier(QString user_agent, QNetworkAccessManager *manager, QString base_url, QString callsign, QDateTime timestamp, QString code, unsigned int);
~FoxVerifier();
QString return_value;
bool finished();
static QString formatDecodeMessage(QDateTime ts, QString callsign, unsigned int hz, QString const& verify_message);
static QString default_url();
private:
QNetworkAccessManager* manager_;
QNetworkReply* reply_;
QNetworkRequest request_;
QUrl q_url_;
bool finished_;
bool errored_;
unsigned int hz_;
QString error_reason_;
QDateTime ts_;
QString callsign_;
QString code_;
private slots:
void httpFinished();
void httpRedirected(const QUrl &url);
void httpEncrypted();
#ifndef QT_NO_SSL
void sslErrors(const QList<QSslError> &);
#endif
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
void errorOccurred(QNetworkReply::NetworkError code);
#endif
//signals:
//void results(QString verify_response);
//void error(QString const& reason) const;
public slots:
signals:
void verifyComplete(int status, QDateTime ts, QString callsign, QString code, unsigned int hz, QString const& response);
void verifyError(int status, QDateTime ts, QString callsign, QString code, unsigned int hz, QString const& response);
};
#endif //WSJTX2_FOXVERIFIER_HPP

View File

@ -392,7 +392,22 @@ void MessageClient::impl::parse_message (QByteArray const& msg)
}
break;
default:
case NetworkMessage::AnnotationInfo: {
QByteArray dx_call;
bool sort_order_provided{false};
quint32 sort_order{std::numeric_limits<quint32>::max()};
in >> dx_call >> sort_order_provided >> sort_order;
TRACE_UDP ("External Callsign Info:" << dx_call << "sort_order_provided:" << sort_order_provided
<< "sort_order:" << sort_order);
if (sort_order > 50000) sort_order = 50000;
if (check_status(in) != Fail) {
Q_EMIT
self_->annotation_info(QString::fromUtf8(dx_call), sort_order_provided, sort_order);
}
}
break;
default:
// Ignore
//
// Note that although server heartbeat messages are not

View File

@ -123,7 +123,10 @@ public:
, bool fast_mode, quint32 tr_period, quint32 rx_df, QString const& dx_call
, QString const& dx_grid, bool generate_messages);
// this signal is emitted when network errors occur or if a host
// this signal is emitted if the server has sent information about a callsign
Q_SIGNAL void annotation_info (QString const& dx_call, bool sort_order_provided, quint32 sort_order);
// this signal is emitted when network errors occur or if a host
// lookup fails
Q_SIGNAL void error (QString const&) const;

21
Network/Network.pri Normal file
View File

@ -0,0 +1,21 @@
SOURCES += \
Network/FileDownload.cpp \
Network/FoxVerifier.cpp \
Network/LotWUsers.cpp \
Network/MessageClient.cpp \
Network/NetworkAccessManager.cpp \
Network/NetworkMessage.cpp \
Network/NetworkServerLookup.cpp \
Network/PSKReporter.cpp \
Network/wsprnet.cpp
HEADERS += \
Network/FileDownload.hpp \
Network/FoxVerifier.hpp \
Network/LotWUsers.hpp \
Network/MessageClient.hpp \
Network/NetworkAccessManager.hpp \
Network/NetworkMessage.hpp \
Network/NetworkServerLookup.hpp \
Network/PSKReporter.hpp \
Network/wsprnet.h

View File

@ -462,6 +462,14 @@
* decoding may be impacted. A rough rule of thumb might be too
* limit the number of active highlighting requests to no more
* than 100.
*
* Using a callsign of "CLEARALL!" and anything for the
* color values will clear the internal highlighting data. It will
* NOT remove the highlighting on the screen, however. The exclamation
* symbol is used to avoid accidental clearing of all highlighting
* data via a decoded callsign, since an exclamation symbol is not
* a valid character in a callsign.
*
* The "Highlight last" field allows the sender to request that
* all instances of "Callsign" in the last period only, instead
@ -494,7 +502,33 @@
* fields an empty value implies no change, for the quint32 Rx DF
* and Frequency Tolerance fields the maximum quint32 value
* implies no change. Invalid or unrecognized values will be
* silently ignored.
* silently ignored. NOTE that if a mode/submode change occurs and
* the current frequency is NOT in the frequency table for that
* mode, a frequency change (to the default frequency for that band
* and mode) may occur.
*
* AnnotationInfo In 16 quint32
* Id (unique key) utf8
* DX Call utf8
* Sort Order Provided bool
* Sort Order quint32
*
* The server may send this message at any time. Sort orders can be used
* for sorting hound callers when in Fox mode. A typical usage is to
* "score" callsigns based on number of bands and/or modes worked using
* an external logging program during a DXpedition, to be able to give
* preference to calls that have not been worked before on any other
* band or mode. An external program can watch decodes from wsjt-x,
* then use this message to annotate the calls with a sort order. The
* hound queue can be displayed by that sort order. *
*
* If 'sort order provided' is true, the message also specifies a numeric
* sort order for the DX call.
*
* Invalid or unrecognized values will be silently ignored. A sort-order of
* ffffffff will remove the sort-order value from the internal table.
* Callsigns without a sort order will be valued at zero for sorting purposes
* in the hound display.
*/
#include <QDataStream>
@ -526,6 +560,7 @@ namespace NetworkMessage
HighlightCallsign,
SwitchConfiguration,
Configure,
AnnotationInfo,
maximum_message_type_ // ONLY add new message types
// immediately before here
};

View File

@ -11,6 +11,251 @@
Copyright 2001 - 2024 by Joe Taylor, K1JT, and the WSJT Development Team
Release: WSJT-X 2.7.0-rc7
September 30, 2024
-------------------------
WSJT-X 2.7.0 Release Candidate 7 brings significant improvements for
the new SuperFox mode. It introduces a new verification system which
replaces the previous one, and works for both the SuperFox mode and
for old-style Fox and Hound operation. All code for SuperFox
operation is now open source.
IMPORTANT: OpenSSL v1.1.1 or higher is required for the real-time
verification of Fox and SuperFox messages.
Enhancements to the SuperFox decoder:
- Performance of the SuperFox decoder has been further improved.
- You can now set individual FTol values and tune the decoder to
the exact sync frequency of the SuperFox signal if it is not exactly
750 Hz. Both result in a better decodability in certain situations.
- Important: The Rx frequency must be set close to the sync frequency
+/- FTol, for example 750 +/- 50 Hz.
Introduction of a new Fox verification system:
- The new Fox verification system uses one time passwords (OTPs), and
works for the SuperFox mode as well as for old-style Fox and Hound
operation. It can be enabled by the new OTP checkbox on the Advanced
tab of the Settings dialog.
- Fox or SuperFox stations send individual OTPs via radio. Hounds
automatically check the validity of the received OTPs in real time
from a server when there is an internet connection. Otherwise, the
validity can also be queried manually later. OTP verifications can
only be retrieved once the transmission has already taken place.
- You may optionally display the received OTP values by checking
the box "Show OTP messages".
- If the Fox or SuperFox callsign is verified by receipt of the
correct OTP, the background color of the Hound or Super Hound label
switches to green.
- Theoretically, DXpeditions can set up their own OTP server, however,
we recommend using the server at https://www.9dx.cc.
- Use of the new Fox verification system requires an OTP key. The
system uses open source code and standard encryption
technology. For testing purposes, non-verified SuperFox
transmissions are now possible without a key.
Improvements to SuperFox/Hound operation:
- SuperHounds must now first decode the SuperFox before they can
call, and a QSO must be started by double-clicking on a SuperFox
decode. (Note that calling the Fox blindly not only leads to
unnecessary band utilization, but can also significantly reduce the
QSO rate due to unanswered (Super)Fox replies.)
- Switching to SuperHound mode automatically sets the Rx frequency to
750 Hz. The previously selected frequency is saved and restored
afterwards.
- Right-clicking on the H button now activates/deactivates SuperFox mode.
- A flaw resulting in sub-optimal SuperFox QSO rates has been
corrected.
- SuperFox decoder now does a more thorough job of rejecting QRM from
non-SuperFox signals.
- Fields in the SuperFox payload not otherwise used in a particular
transmission are now set to known nonzero values. Do NOT use RC6 or
earlier versions to decode SuperFox transmissions from RC7 or
later.
- Old-style Fox stations can now transmit free text messages (up to
13 characters) by using an available stream.
- Some enhancements useful for Fox operators: Active Station Window now
shows band activity. Hound callsigns can be highlighted via UDP API, and
assigned a score for sorting via UDP API. Fox Tx frequency is preserved
when switching in/out of Fox mode.
- UDP Status Update messages now include information on how many callsigns
have highlighting applied, and how many callsigns have a score assigned.
Other enhancements and fixes:
- In FT8 mode, the Settings dialog no longer resets the VFO frequency
to band/mode default unless really needed.
- Several code improvements specifically for macOS.
- Updated CTY.DAT and Hamlib.
Release: WSJT-X 2.7.0-rc6
July 19, 2024
-------------------------
WSJT-X 2.7.0 Release Candidate 6 is a bug-fix release primarily
affecting the new SuperFox mode. The following bugs have been fixed:
- Strong signals from Superfox too frequently failed to decode.
- SuperFox sometimes sent incorrect signal reports and an invalid
digital signature.
- A Fortran bounds error could sometimes occur in the SuperFox
decoder.
- For SuperFox operator, the "age" displayed for Hound callers
became garbled after the 0000 UTC date change.
- Decodes of SuperFox transmissions were not posted to PSK Reporter.
- Some SuperFox-related messages were posted incorrectly to ALL.TXT.
- Logic for turning the SuperHound label green was flawed in some
circumstances.
Release Candidate 6 also includes updates to Hamlib and the Chinese
user interface translation.
Release: WSJT-X 2.7.0-rc5
July 1, 2024
-------------------------
WSJT-X 2.7.0 Release Candidate 5 introduces "SuperFox" mode, a
powerful new tool designed to help DXpeditions make digital QSOs at
very high rates. RC5 also brings several other improvements and bug
fixes.
SuperFox mode:
- The SuperFox mode behaves operationally like the present Fox and
Hounds mode but uses a constant envelope waveform for Fox's
transmissions rather than sending concurrent streams of up to five
normal FT8 signals. This approach means that up to 9 messages can
be transmitted simultaneously with no signal-strength penalty,
resulting in a system gain of about +10 dB compared to the
conventional Fox/Hound operation with 5 slots.
- IMPORTANT: Older revisions of WSJT-X and derivative programs will
not be able to decode SuperFox transmissions. Hounds must use
WSJT-X 2.7.0-rc5 (or a later release, when available) to receive
SuperFox messages.
- Hounds chasing the DX station will transmit normal FT8 signals, as
in the old-style Fox and Hound mode. QSOs will be logged as FT8
mode.
- When using SuperFox mode, Hound stations may call at any frequency
in Fox's received passband, including the range 0 - 1000 Hz.
Hounds do not QSY to a lower frequency for their final
transmission.
- SuperFox Operation requires the Fox operator to use a valid digital
key. Keys will be issued in advance to legitimate DXpeditions by
the Northern California DX Foundation, and will be kept secret.
- Every SuperFox transmission includes a unique digital signature.
Hounds receiving a SuperFox message will see a "<callsign> verified"
flag if the transmitted signature is valid, and the on-screen
"Super Hound" label will turn from red to green.
- Hound operation should begin by selecting "Special operating
activity", "Hound", and "SuperFox mode" on the Settings -> Advanced
tab. Alternatively, right-clicking on the FT8 button toggles
SuperFox mode on/off for either Fox or Hound, allowing quick
transitions between SuperFox and old-style Fox and Hound operation.
- SuperFox stations can send free text messages of up to 26 characters
together with messages to as many as 4 Hounds.
Other enhancements:
- Corrected a flaw that caused "Log automatically" to not work for
the ARRL Digi Contest.
- Control elements for special operating activities are now disabled
(grayed out) if the respective function is not applicable.
- Corrected a longstanding flaw that caused "Start new period
decodes at top" to stop working properly after some time.
- Right-click mouse press events are now less error-prone.
- Improved the readability of the first line when "Start new period
decodes at top" is checked.
- 4-digit grids are now logged for certain contest modes to ensure that
the log complies with contest rules.
- The Fox Tx frequency is now saved and restored separately.
Release: WSJT-X 2.7.0-rc4
March 11, 2024
-------------------------
WSJT-X 2.7.0 Release Candidate 4 brings some improvements for Fox-mode
operators, new features for companion program QMAP, and a number of
relatively minor enhancements and bug fixes.
QMAP enhancements -- of particular interest to EME operators:
- QMAP now decodes Q65 submodes with both 60-second and 30-second T/R
sequence lengths. Clicking on a resulting line in the WSJT-X Active
Stations window automatically sets dial frequency and working
submode as needed to call that station.
- QMAP operates in 60-second receive sequences, and its Q65 decoder
starts at t=19.5, 30.0, 49.5, and 58.5 s into the sequence. Most
decoded messages are displayed well before the end of the relevant
time slot.
- A new, more compact file format is now used for wideband data
files. A "Save decoded" option has been added to the Save menu.
- An option has been added to allow exporting a 3 kHz portion of a
wideband data file as a standard WSJT-X *.wav file.
- CTRL+click on QMAP's upper waterfall sends an integer kHz dial
frequency request to WSJT-X.
- With focus on the WSJT-X main window, hit Alt+A on the keyboard to
clear the Active Stations window.
- Many minor enhancements to the User Interface.
WSJT-X:
- Enable decoding of MSK144 from the jt9[.exe] executable.
- Several changes to reduce problems experienced when (contrary to
our recommendations) messages with short (10-bit) callsign hashes
are used in standard FT4/FT8 sub-bands.
- Enhancements useful for Fox operators.
Release: WSJT-X 2.7.0-rc3
January 1, 2024
-------------------------

View File

@ -619,6 +619,12 @@ int HamlibTransceiver::do_start ()
CAT_TRACE ("starting: " << rig_get_caps_cptr (m_->model_, RIG_CAPS_MFG_NAME_CPTR)
<< ": " << rig_get_caps_cptr (m_->model_, RIG_CAPS_MODEL_NAME_CPTR));
token_t token = rig_token_lookup (m_->rig_.data (), "client");
if (RIG_CONF_END != token) // only set if valid for rig model
{
rig_set_conf (m_->rig_.data (), token, "WSJTX");
}
m_->error_check (rig_open (m_->rig_.data ()), tr ("opening connection to rig"));
// reset dynamic state

View File

@ -64,6 +64,9 @@ typedef struct dec_data {
char mygrid[6];
char hiscall[12];
char hisgrid[6];
bool b_even_seq;
bool b_superfox;
int yymmdd;
} params;
} dec_data_t;
@ -91,6 +94,9 @@ extern struct {
int i3bit[5];
char cmsg[5][40];
char mycall[12];
char textMsg[26];
bool bMoreCQs;
bool bSendMsg;
} foxcom_;
#ifdef __cplusplus

3751
cty.dat

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,7 @@ FT8 11101000010011100001000010011000100000
FT8/VHF 11101000010011100001000010011000100000
FT8/Fox 11101000010011100001000000000010000000
FT8/Hound 11101000010011100001000000000011000000
FT8/SupHou 11111000010011100001000000000011000000
-------------------------------------------------
1 2 3
01234567890123456789012345678901234567

View File

@ -29,8 +29,8 @@ the following copyright notice prominently:
*The algorithms, source code, look-and-feel of _{prog}_ and related
programs, and protocol specifications for the modes FSK441, FST4,
FST4W, FT4, FT8, JT4, JT6M, JT9, JT44, JT65, JTMS, Q65, QRA64, ISCAT,
and MSK144 are Copyright (C) 2001-2021 by one or more of the following
and MSK144 are Copyright (C) 2001-2024 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.*
K9AN; Nico Palermo, IV3NWV; Uwe Risse, DG2YCB; Brian Moran, N9ADG;
Greg Beam, KI7MT; Michael Black, W9MDB; Edson Pereira, PY2SDR; Philip
Karn, KA9Q; and other members of the WSJT Development Group.*

View File

@ -94,8 +94,8 @@ d). Edit lines as needed. Keeping them in alphabetic order help see dupes.
:sourceforge-jtsdk: https://sourceforge.net/projects/jtsdk[SourceForge JTSDK]
:ubuntu_sdk: https://launchpad.net/~ubuntu-sdk-team/+archive/ppa[Ubuntu SDK Notice]
:win_openssl_packages: https://slproweb.com/products/Win32OpenSSL.html[Windows OpenSSL Packages]
:win32_openssl: https://slproweb.com/download/Win32OpenSSL_Light-1_1_1s.msi[Win32 OpenSSL Light Package]
:win64_openssl: https://slproweb.com/download/Win64OpenSSL_Light-1_1_1s.msi[Win64 OpenSSL Light Package]
:win32_openssl: https://sourceforge.net/projects/wsjt-x-improved/files/Additional%20Files/OpenSSL/Win32OpenSSL_Light-1_1_1a.msi/download[Win32 OpenSSL Light Package]
:win64_openssl: https://sourceforge.net/projects/wsjt-x-improved/files/Additional%20Files/OpenSSL/Win64OpenSSL_Light-1_1_1a.msi[Win64 OpenSSL Light Package]
:writelog: https://writelog.com/[Writelog]
:wsjtx_group: https://groups.io/g/wsjtgroup[WSJT GROUP User Forum]
:wsjtx_group2: https://groups.io/g/wsjtgroup/join[join the group]

View File

@ -4,8 +4,10 @@ Download and execute the package file {win32} (Windows 7 or later,
32-bit) or {win64} (Windows 7 or later, 64-bit) following these
instructions:
* Install _WSJT-X_ into its own directory, for example `C:\WSJTX` or `C:\WSJT\WSJTX`, rather than the conventional location `C:\Program
Files ...\WSJTX`.
* Install _WSJT-X_ into its own directory, for example
`C:\WSJTX` or `C:\WSJT\WSJTX`, rather than the conventional location
`C:\Program Files ...\WSJTX`. Do not use a directory path that
includes an embedded blank.
* All program files relating to _WSJT-X_ are stored in the chosen
installation directory and its subdirectories.

View File

@ -1,11 +1,12 @@
[[NEW_FEATURES]]
=== New in Version {VERSION_MAJOR}.{VERSION_MINOR}
_WSJT-X 2.7_ introduces a new program called *QMAP*, a new Special
Operating Activity *Q65 Pileup*, an option to *Update Hamlib* at the
click of a button, and a number of other enhancements and bug fixes.
_WSJT-X 2.7_ introduces a new program called *QMAP*, new Special
Operating Activities *Q65 Pileup* and *SuperFox mode*, an option to
*Update Hamlib* at the click of a button, and a number of other
enhancements and bug fixes.
- QMAP and Q65 Pileup mode are of particular interest to those engaged
- *QMAP* and *Q65 Pileup* mode are of particular interest to those engaged
in Earth-Moon-Earth (EME) communication, but other applications may
be found for them as well. QMAP is currently available for Windows
only; it is derived from MAP65, an older program used since 2007 for
@ -19,6 +20,15 @@ click of a button, and a number of other enhancements and bug fixes.
Quick-Start guide posted here:
https://wsjt.sourceforge.io/Quick_Start_WSJT-X_2.7_QMAP.pdf
- *SuperFox mode* behaves operationally like the old-style Fox and
Hounds mode but uses a new constant envelope waveform for Fox's
transmissions. Messages can be transmitted simultaneously to as many
as 9 Hounds with no signal-strength penalty, resulting in a system
gain of about +10 dB compared to the older Fox-and-Hound operation
with 5 slots. Further details on SuperFox mode can be found in the
Quick-Start guide posted here:
https://wsjt.sourceforge.io/SuperFox_User_Guide.pdf
- A button *Update Hamlib* now appears on the *Settings -> Radio* tab.
On Windows it allows the user to automatically download and install
the latest version of the rig-control features in Hamlib. The

View File

@ -330,7 +330,7 @@ comparable to tone spacing.
[width="100%",cols="h,5*^",frame=topbot,options="header"]
|===
|T/R Period (s) |A Spacing Width (Hz)|B Spacing Width (Hz)|C Spacing Width (Hz)|D Spacing Width (Hz)|E Spacing Width (Hz)
|15|6.67 &#160; &#160; 4.33|13.33 &#160; &#160; 867|26.67 &#160; &#160; 1733|N/A|N/A
|15|6.67 &#160; &#160; 433|13.33 &#160; &#160; 867|26.67 &#160; &#160; 1733|N/A|N/A
|30|3.33 &#160; &#160; 217|6.67 &#160; &#160; 433|13.33 &#160; &#160; 867| 26.67 &#160; &#160; 1733| N/A
|60|1.67 &#160; &#160; 108|3.33 &#160; &#160; 217|6.67 &#160; &#160; 433|13.33 &#160; &#160; 867|26.67 &#160; &#160; 1733
|120|0.75 &#160; &#160; 49|1.50 &#160; &#160; 98|3.00 &#160; &#160; 195|6.00 &#160; &#160; 390| 12.00 &#160; &#160; 780

235
lib/cwsim.f90 Normal file
View File

@ -0,0 +1,235 @@
program cwsim
! Generate simulated audio for a CW message sent repeatedly for 60 seconds
use wavhdr
parameter (NMAX=60*12000)
type(hdr) h !Header for the .wav file
integer*2 iwave(NMAX) !Generated waveform (no noise)
integer icw(500) !Encoded CW message bits
complex cspread(0:NMAX-1) !Complex amplitude for Rayleigh fading
complex cdat(0:NMAX-1) !Complex waveform
real dat(NMAX) !Audio waveform
real*4 xnoise(NMAX) !Generated random noise
character*60 message
character*12 arg
nargs=iargc()
if(nargs.ne.6) then
print*,'Usage: cwsim "message" freq bw wpm fspread snr'
print*,'Example: cwsim "CQ CQ CQ DE K1JT K1JT K1JT" 700 100 20 100 -10'
go to 999
endif
call getarg(1,message)
call getarg(2,arg)
read(arg,*) ifreq !Audio frequency (Hz)
call getarg(3,arg)
read(arg,*) bw !Bandwidth (Hz)
call getarg(4,arg)
read(arg,*) wpm !CW speed, words per minute
call getarg(5,arg)
read(arg,*) fspread !Doppler spread in Hz
call getarg(6,arg)
read(arg,*) snrdb !S/N in dB (2500 hz reference BW)
rms=500.0
bandwidth_ratio=2500.0/6000.0
sig=sqrt(2*bandwidth_ratio)*10.0**(0.05*snrdb)
twopi=8.0*atan(1.0)
h=default_header(12000,NMAX)
open(10,file='000000_0000.wav',access='stream',status='unknown')
do i=1,NMAX !Generate gaussian noise
xnoise(i)=gran()
enddo
itone=0
call morse(message,icw,ncw)
call cwsig(icw,ncw,ifreq,wpm,sig,cdat)
nfft=NMAX
if(fspread.ne.0) then !Apply specified Doppler spread
nh=nfft/2
df=12000.0/nfft
cspread(0)=1.0
cspread(nh)=0.
b=6.0 !Use truncated Lorenzian shape for fspread
do i=1,nh
f=i*df
x=b*f/fspread
z=0.
a=0.
if(x.lt.3.0) then !Cutoff beyond x=3
a=sqrt(1.111/(1.0+x*x)-0.1) !Lorentzian amplitude
phi1=twopi*rran() !Random phase
z=a*cmplx(cos(phi1),sin(phi1))
endif
cspread(i)=z
z=0.
if(x.lt.3.0) then !Same thing for negative freqs
phi2=twopi*rran()
z=a*cmplx(cos(phi2),sin(phi2))
endif
cspread(nfft-i)=z
enddo
call four2a(cspread,nfft,1,1,1) !Transform to time domain
sum=0.
do i=0,nfft-1
p=real(cspread(i))**2 + aimag(cspread(i))**2
sum=sum+p
enddo
avep=sum/nfft
fac=sqrt(1.0/avep)
cspread=fac*cspread !Normalize to constant avg power
cdat=cspread*cdat !Apply Rayleigh fading
endif
dat=aimag(cdat) + xnoise
cdat=dat
call four2a(cdat,nfft,1,-1,1) !c2c to frequency domain
ia=max(250/df,(ifreq-0.5*bw)/df)
ib=ia+bw/df
cdat(0:ia)=0.
cdat(ib:)=0.
call four2a(cdat,nfft,1,+1,1) !c2c to time domain
fac=sqrt(5000/bw)/nfft
dat=fac*real(cdat)
iwave=nint(rms*dat)
write(10) h,iwave
close(10)
999 end program cwsim
subroutine cwsig(icw,ncw,ifreq,wpm,sig,cdat)
parameter(NMAX=60*12000)
integer icw(ncw)
complex cdat(NMAX)
complex z(NMAX)
real x(NMAX)
real y(NMAX)
real*8 dt,twopi,phi,dphi,fsample,tdit,t
nspd=nint(1.2*12000.0/wpm)
fsample=12000.d0 !Sample rate (Hz)
dt=1.d0/fsample !Sample interval (s)
tdit=nspd*dt
twopi=8.d0*atan(1.d0)
dphi=twopi*ifreq*dt
phi=0.
k=12000 !Start audio at t = 1.0 s
t=0.
npts=59*12000
x=0.
do i=1,npts
t=t+dt
j=nint(t/tdit) + 1
j=mod(j-1,ncw) + 1
phi=phi + dphi
if(phi.gt.twopi) phi=phi-twopi
xphi=phi
k=k+1
x(k)=icw(j)
z(k)=cmplx(cos(xphi),sin(xphi))
if(t.ge.59.5) exit
enddo
nadd=0.004/dt
call smo(x,npts,y,nadd)
y=y/nadd
cdat=sig*y*z
return
end subroutine cwsig
subroutine morse(msg,idat,n)
! Convert ascii message to a Morse code bit string.
! Dash = 3 dots
! Space between dots, dashes = 1 dot
! Space between letters = 3 dots
! Space between words = 7 dots
character*(*) msg
integer idat(500)
integer*1 ic(21,38)
data ic/ &
1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,20, &
1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,0,0,18, &
1,0,1,0,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,16, &
1,0,1,0,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,14, &
1,0,1,0,1,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0,12, &
1,0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,10, &
1,1,1,0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,12, &
1,1,1,0,1,1,1,0,1,0,1,0,1,0,0,0,0,0,0,0,14, &
1,1,1,0,1,1,1,0,1,1,1,0,1,0,1,0,0,0,0,0,16, &
1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,0,0,0,18, &
1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 6, &
1,1,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,10, &
1,1,1,0,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,12, &
1,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, 8, &
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2, &
1,0,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,10, &
1,1,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,10, &
1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, 8, &
1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 4, &
1,0,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,14, &
1,1,1,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,10, &
1,0,1,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,10, &
1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, 8, &
1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 6, &
1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0,12, &
1,0,1,1,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,12, &
1,1,1,0,1,1,1,0,1,0,1,1,1,0,0,0,0,0,0,0,14, &
1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, 8, &
1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 6, &
1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 4, &
1,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, 8, &
1,0,1,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,10, &
1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,10, &
1,1,1,0,1,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0,12, &
1,1,1,0,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,14, &
1,1,1,0,1,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,12, &
1,1,1,0,1,0,1,0,1,1,1,0,1,0,0,0,0,0,0,0,14, &
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2/ !Incremental word space
save
msglen=len(trim(msg))
idat=0
n=6
do k=1,msglen
jj=ichar(msg(k:k))
if(jj.ge.97 .and. jj.le.122) jj=jj-32 !Convert lower to upper case
if(jj.ge.48 .and. jj.le.57) j=jj-48 !Numbers
if(jj.ge.65 .and. jj.le.90) j=jj-55 !Letters
if(jj.eq.47) j=36 !Slash (/)
if(jj.eq.32) j=37 !Word space
j=j+1
! Insert this character
nmax=ic(21,j)
if (n + nmax + 4 .gt. size (idat)) exit
do i=1,nmax
n=n+1
idat(n)=ic(i,j)
enddo
! Insert character space of 2 dit lengths:
n=n+1
idat(n)=0
n=n+1
idat(n)=0
enddo
! Insert word space at end of message
do j=1,4
n=n+1
idat(n)=0
enddo
return
end subroutine morse

View File

@ -67,7 +67,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
ntr0=params%ntr
rms=sqrt(dot_product(float(id2(1:180000)), &
float(id2(1:180000)))/180000.0)
if(rms.lt.3.0) go to 800
if(rms.lt.0.5) go to 800
!cast C character arrays to Fortran character strings
datetime=transfer(params%datetime, datetime)
@ -124,8 +124,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
if(params%nmode.eq.8) then
! We're in FT8 mode
if(ncontest.eq.6) then
if(ncontest.eq.6) then !Fox=6, Hound=7
! Fox mode: initialize and open houndcallers.txt
inquire(file=trim(temp_dir)//'/houndcallers.txt',exist=ex)
if(.not.ex) then
@ -140,27 +139,36 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
open(19,file=trim(temp_dir)//'/houndcallers.txt',status='unknown')
endif
call timer('decft8 ',0)
newdat=params%newdat
if(params%emedelay.ne.0.0) then
id2(1:156000)=id2(24001:180000) ! Drop the first 2 seconds of data
id2(156001:180000)=0
endif
call my_ft8%decode(ft8_decoded,id2,params%nQSOProgress,params%nfqso, &
params%nftx,newdat,params%nutc,params%nfa,params%nfb, &
params%nzhsym,params%ndepth,params%emedelay,ncontest, &
logical(params%nagain),logical(params%lft8apon), &
logical(params%lapcqonly),params%napwid,mycall,hiscall, &
params%ndiskdat)
call timer('decft8 ',1)
if(nfox.gt.0) then
n30min=minval(n30fox(1:nfox))
n30max=maxval(n30fox(1:nfox))
if(ncontest.eq.7 .and. params%b_superfox .and. params%b_even_seq) then
if(params%nzhsym.lt.50) go to 800
! Call the superFox decoder
call sfrx_sub(params%yymmdd,params%nutc,params%nfqso,params%ntol,id2)
else
call timer('decft8 ',0)
newdat=params%newdat
if(params%emedelay.ne.0.0) then
id2(1:156000)=id2(24001:180000) ! Drop the first 2 seconds of data
id2(156001:180000)=0
endif
call my_ft8%decode(ft8_decoded,id2,params%nQSOProgress,params%nfqso, &
params%nftx,newdat,params%nutc,params%nfa,params%nfb, &
params%nzhsym,params%ndepth,params%emedelay,ncontest, &
logical(params%nagain),logical(params%lft8apon), &
logical(params%lapcqonly),params%napwid,mycall,hiscall, &
params%ndiskdat)
call timer('decft8 ',1)
endif
j=0
if(ncontest.eq.6) then
! Fox mode: save decoded Hound calls for possible selection by FoxOp
n=params%nutc
n30=(3600*(n/10000) + 60*mod((n/100),100) + mod(n,100))/30
if(n30.lt.n30z) nwrap=nwrap+2880 !New UTC day, handle the wrap
n30z=n30
n30=n30+nwrap
rewind 19
if(nfox.eq.0) then
endfile 19
@ -168,21 +176,23 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
else
do i=1,nfox
n=n30fox(i)
if(n30max-n30fox(i).le.4) then
nage=min(99,mod(n30-n+288000,2880))
if(nage.le.4) then
j=j+1
c2fox(j)=c2fox(i)
g2fox(j)=g2fox(i)
nsnrfox(j)=nsnrfox(i)
nfreqfox(j)=nfreqfox(i)
n30fox(j)=n
m=n30max-n
! nage=min(99,mod(n30-n+288000,2880))
if(len(trim(g2fox(j))).eq.4) then
call azdist(mygrid,g2fox(j)//' ',0.d0,nAz,nEl,nDmiles, &
nDkm,nHotAz,nHotABetter)
else
nDkm=9999
endif
write(19,1004) c2fox(j),g2fox(j),nsnrfox(j),nfreqfox(j),nDkm,m
write(19,1004) c2fox(j),g2fox(j),nsnrfox(j),nfreqfox(j), &
nDkm,nage
1004 format(a12,1x,a4,i5,i6,i7,i3)
endif
enddo
@ -661,10 +671,10 @@ contains
endif
b1=i3-i2.eq.5 .and. isgrid4(g2)
b2=i3-i2.eq.1
if(b0 .and. (b1.or.b2) .and. nint(freq).ge.1000) then
if(b0 .and. (b1.or.b2) .and. (nint(freq).ge.1000 .or. params%b_superfox)) then
n=params%nutc
n30=(3600*(n/10000) + 60*mod((n/100),100) + mod(n,100))/30
if(n30.lt.n30z) nwrap=nwrap+5760 !New UTC day, handle the wrap
if(n30.lt.n30z) nwrap=nwrap+2880 !New UTC day, handle the wrap
n30z=n30
n30=n30+nwrap
if(nfox.lt.MAXFOX) nfox=nfox+1

View File

@ -26,8 +26,8 @@ program ft4code
'LDPC(174,91) encoding,'
print*,'bit and symbol ordering, and other details of the FT4 protocol.'
print*
print*,'Usage: ft4code [-c grid] "message" # Results for specified message'
print*,' ft4code -t # Examples of all message types'
print*,'Usage: ft4code "message" # Results for specified message'
print*,' ft4code -t # Examples of all message types'
go to 999
endif

View File

@ -1,4 +1,4 @@
subroutine foxgen(bSuperFox)
subroutine foxgen(bSuperFox,fname)
! Called from MainWindow::foxTxSequencer() to generate the Tx waveform in
! FT8 Fox mode. The Tx message can contain up to 5 "slots", each carrying
@ -17,8 +17,10 @@ subroutine foxgen(bSuperFox)
parameter (NN=79,ND=58,NSPS=4*1920)
parameter (NWAVE=(160+2)*134400*4) !the biggest waveform we generate (FST4-1800 at 48kHz)
parameter (NFFT=614400,NH=NFFT/2)
logical*1 bSuperFox
character*40 cmsg
logical*1 bSuperFox,bMoreCQs,bSendMsg
character*(*) fname
character*40 cmsg,cmsg2
character*26 textMsg
character*37 msg,msgsent
integer itone(79)
integer*1 msgbits(77),msgbits2
@ -26,15 +28,26 @@ subroutine foxgen(bSuperFox)
real x(NFFT)
real*8 dt,twopi,f0,fstep,dfreq,phi,dphi
complex cx(0:NH)
common/foxcom/wave(NWAVE),nslots,nfreq,i3bit(5),cmsg(5),mycall(12)
common/foxcom/wave(NWAVE),nslots,nfreq,i3bit(5),cmsg(5),mycall(12), &
textMsg,bMoreCQs,bSendMsg
common/foxcom2/itone2(NN),msgbits2(77)
common/foxcom3/nslots2,cmsg2(5),itone3(151)
equivalence (x,cx),(y,cy)
if(bSuperFox) then
call foxgen2(nslots,cmsg)
return
n=nslots
if(bMoreCQs) cmsg(1)(40:40)='1' !Set flag to include a CQ
if(bSendMsg) then
n=min(nslots+1,3)
cmsg(n)=textMsg
cmsg(n)(39:39)='1' !Set flag for text message
nslots=n
endif
nslots2=nslots
cmsg2=cmsg
go to 999
endif
fstep=60.d0
dfreq=6.25d0
dt=1.d0/48000.d0
@ -72,7 +85,7 @@ subroutine foxgen(bSuperFox)
peak3=maxval(abs(wave))
wave=wave/peak3
return
999 return
end subroutine foxgen
! include 'plotspec.f90'

View File

@ -2,12 +2,12 @@ subroutine foxgen_wrap(msg40,msgbits,itone)
parameter (NN=79,ND=58,KK=77,NSPS=4*1920)
parameter (NWAVE=(160+2)*134400*4) !the biggest waveform we generate (FST4-1800)
logical*1 bMoreCQs
character*40 msg40,cmsg
character*12 mycall12
integer*1 msgbits(KK),msgbits2
integer itone(NN)
common/foxcom/wave(NWAVE),nslots,nfreq,i3bit(5),cmsg(5),mycall12
common/foxcom/wave(NWAVE),nslots,nfreq,i3bit(5),cmsg(5),mycall12,bMoreCQs
common/foxcom2/itone2(NN),msgbits2(KK)
nslots=1

View File

@ -1,6 +1,6 @@
module ft8_a7
parameter(MAXDEC=100)
parameter(MAXDEC=200)
! For the following three arrays
! First index i=decode number in this sequence
@ -43,7 +43,7 @@ subroutine ft8_a7_save(nutc,dt,f,msg)
! Add this decode to current table for this sequence
ndec(j,1)=ndec(j,1)+1 !Number of decodes in this sequence
i=ndec(j,1) !i is index of a new table entry
if(i.ge.MAXDEC-1) return !Prevent table overflow
if(i.gt.MAXDEC) return !Prevent table overflow (indexes start at 1)
dt0(i,j,1)=dt !Save dt in table
f0(i,j,1)=f !Save f in table

View File

@ -8,10 +8,10 @@ subroutine ft8_downsample(dd,newdat,f0,c1)
logical newdat,first
complex c1(0:NFFT2-1)
complex cx(0:NFFT1/2)
real dd(NMAX),x(NFFT1),taper(0:100)
equivalence (x,cx)
real dd(NMAX),x(NFFT1+2),taper(0:100)
data first/.true./
save cx,first,taper
save x,cx,first,taper
equivalence (x,cx)
if(first) then
pi=4.0*atan(1.0)
@ -23,11 +23,10 @@ subroutine ft8_downsample(dd,newdat,f0,c1)
if(newdat) then
! Data in dd have changed, recompute the long FFT
x(1:NMAX)=dd
x(NMAX+1:NFFT1)=0. !Zero-pad the x array
x(NMAX+1:NFFT1+2)=0. !Zero-pad the x array
call four2a(cx,NFFT1,1,-1,0) !r2c FFT to freq domain
newdat=.false.
endif
df=12000.0/NFFT1
baud=12000.0/NSPS
i0=nint(f0/df)

View File

@ -23,9 +23,9 @@ program ft8code
'LDPC(174,91) encoding,'
print*,'bit and symbol ordering, and other details of the FT8 protocol.'
print*
print*,'Usage: ft8code [-c grid] "message" # Results for specified message'
print*,' ft8code -T # Examples of all message types'
print*,' ft8code -t # Short format examples'
print*,'Usage: ft8code "message" # Results for specified message'
print*,' ft8code -T # Examples of all message types'
print*,' ft8code -t # Short format examples'
go to 999
endif

View File

@ -42,7 +42,7 @@ program ft8d
j2=index(infile,'.wav')
read(infile(j2-6:j2-1),*) nutc
datetime=infile(j2-13:j2-1)
call sync8(iwave,nfa,nfb,nfqso,s,candidate,ncand)
call sync8(iwave,NMAX,nfa,nfb,nfqso,s,candidate,ncand)
syncmin=2.0
dd=iwave
do icand=1,ncand

View File

@ -101,14 +101,24 @@ program ft8sim_gfsk
wave=imag(c)
peak=maxval(abs(wave))
nslots=1
psig=0.
pnoise=0.
if(snrdb.lt.90) then
do i=1,NMAX !Add gaussian noise at specified SNR
xnoise=gran()
if(i.ge.6001 .and. i.le.157692) then
psig=psig + wave(i)*wave(i) !Signal power
pnoise=pnoise + xnoise*xnoise !Noise power in signal interval
endif
wave(i)=wave(i) + xnoise
enddo
endif
! Noise power in signal interval and 2500 Hz bandwidth:
pnoise=bandwidth_ratio*pnoise
snr_2500=db(psig/pnoise) !SNR in 2500 Hz bandwidth
gain=100.0
if(snrdb.lt.90.0) then
wave=gain*wave
@ -125,7 +135,7 @@ program ft8sim_gfsk
open(10,file=fname,status='unknown',access='stream')
write(10) h,iwave !Save to *.wav file
close(10)
write(*,1110) ifile,xdt,f0,snrdb,fname
1110 format(i4,f7.2,f8.2,f7.1,2x,a17)
write(*,1110) ifile,xdt,f0,snrdb,fname,snr_2500
1110 format(i4,f7.2,f8.2,f7.1,2x,a17,f8.2)
enddo
999 end program ft8sim_gfsk

View File

@ -1,4 +1,4 @@
subroutine sync8(dd,nfa,nfb,syncmin,nfqso,maxcand,candidate,ncand,sbase)
subroutine sync8(dd,npts,nfa,nfb,syncmin,nfqso,maxcand,candidate,ncand,sbase)
include 'ft8_params.f90'
parameter (MAXPRECAND=1000)
@ -9,13 +9,13 @@ subroutine sync8(dd,nfa,nfb,syncmin,nfqso,maxcand,candidate,ncand,sbase)
real s(NH1,NHSYM)
real savg(NH1)
real sbase(NH1)
real x(NFFT1)
real x(NFFT1+2)
real sync2d(NH1,-JZ:JZ)
real red(NH1)
real red2(NH1)
real candidate0(3,MAXPRECAND)
real candidate(3,maxcand)
real dd(NMAX)
real dd(npts)
integer jpeak(NH1)
integer jpeak2(NH1)
integer indx(NH1)

View File

@ -24,7 +24,7 @@ subroutine watterson(c,npts,nsig,fs,delay,fspread)
do i=0,npts-1
f=i*df
if(i.gt.npts/2) f=(i-npts)*df
x=(f/(0.5*fspread))**2
x=(f/fspread)**2
a=0.
if(x.le.50.0) then
a=exp(-x)

View File

@ -44,23 +44,23 @@ contains
class(ft8_decoder), intent(inout) :: this
procedure(ft8_decode_callback) :: callback
parameter (MAXCAND=600,MAX_EARLY=100)
parameter (MAXCAND=600,MAX_EARLY=200,NPTS=15*12000)
real*8 tsec,tseq
real sbase(NH1)
real candidate(3,MAXCAND)
real dd(15*12000),dd1(15*12000)
real dd(NPTS),dd1(NPTS)
logical, intent(in) :: lft8apon,lapcqonly,nagain
logical newdat,lsubtract,ldupe,lrefinedt
logical*1 ldiskdat
logical lsubtracted(MAX_EARLY)
character*12 mycall12,hiscall12,call_1,call_2
character*4 grid4
integer*2 iwave(15*12000)
integer*2 iwave(NPTS)
integer apsym2(58),aph10(10)
character datetime*13,msg37*37
character*37 allmessages(200)
character*37 allmessages(MAX_EARLY)
character*12 ctime
integer allsnrs(200)
integer allsnrs(MAX_EARLY)
integer itone(NN)
integer itone_save(NN,MAX_EARLY)
real f1_save(MAX_EARLY)
@ -192,7 +192,7 @@ contains
endif
call timer('sync8 ',0)
maxc=MAXCAND
call sync8(dd,ifa,ifb,syncmin,nfqso,maxc,candidate,ncand,sbase)
call sync8(dd,NPTS,ifa,ifb,syncmin,nfqso,maxc,candidate,ncand,sbase)
call timer('sync8 ',1)
do icand=1,ncand
sync=candidate(3,icand)
@ -215,6 +215,9 @@ contains
if(msg37.eq.allmessages(id)) ldupe=.true.
enddo
if(.not.ldupe) then
if(ndecodes.ge.MAX_EARLY) then
cycle
endif
ndecodes=ndecodes+1
allmessages(ndecodes)=msg37
allsnrs(ndecodes)=nsnr

View File

@ -19,9 +19,10 @@ subroutine hspec(id2,k,nutc0,ntrpdepth,nrxfreq,ntol,bmsk144, &
! jh index of most recent data in green(), s()
parameter (JZ=703)
character*80 line1
character*(*) line1
character*80 line0
character*(*) datadir
character*12 mycall,hiscall
character*(*) mycall,hiscall
integer*2 id2(0:120*12000-1)
logical*1 bmsk144,bshmsg,btrain,bswl
real green(0:JZ-1)
@ -96,7 +97,12 @@ subroutine hspec(id2,k,nutc0,ntrpdepth,nrxfreq,ntol,bmsk144, &
tt2=sum(float(abs(id2(k0:k0+3583))))
if(tt1.ne.0.0 .and. tt2.ne.0) then
call mskrtd(id2(k-7168+1:k),nutc0,tsec,ntol,nrxfreq,ndepth, &
mycall,hiscall,bshmsg,btrain,pcoeffs,bswl,datadir,line1)
mycall,hiscall,bshmsg,btrain,pcoeffs,bswl,datadir,line0)
if(line0(1:1).eq.char(0)) then
line1(1:1)=char(0)
else
line1(1:62)=line0(1:62)
endif
endif
endif
endif

View File

@ -47,6 +47,9 @@
character(kind=c_char) :: mygrid(6)
character(kind=c_char) :: hiscall(12)
character(kind=c_char) :: hisgrid(6)
logical(c_bool) :: b_even_seq
logical(c_bool) :: b_superfox
integer(c_int) :: yymmdd
end type params_block
type, bind(C) :: dec_data

View File

@ -16,8 +16,8 @@ subroutine mskrtd(id2,nutc0,tsec,ntol,nrxfreq,ndepth,mycall,hiscall, &
character*4 decsym !"&" for mskspd or "^" for long averages
character*37 msgreceived !Decoded message
character*37 msglast,msglastswl !Used for dupechecking
character*80 line !Formatted line with UTC dB T Freq Msg
character*12 mycall,hiscall
character*(*) line !Formatted line with UTC dB T Freq Msg
character*(*) mycall,hiscall
character*37 recent_shmsgs(NSHMEM)
character*(*) datadir
@ -70,15 +70,19 @@ subroutine mskrtd(id2,nutc0,tsec,ntol,nrxfreq,ndepth,mycall,hiscall, &
msglastswl=' '
nsnrlast=-99
nsnrlastswl=-99
mycall13=mycall//' '
dxcall13=hiscall//' '
! mycall13=mycall//' '
! dxcall13=hiscall//' '
mycall13=' '
dxcall13=' '
mycall13(1:12)=mycall(1:12)
dxcall13(1:12)=hiscall(1:12)
first=.false.
endif
fc=nrxfreq
! Reset if mycall or dxcall changes
if(mycall13(1:12).ne.mycall .or. dxcall13(1:12).ne.hiscall) first=.true.
if(mycall13(1:12).ne.mycall(1:12) .or. dxcall13(1:12).ne.hiscall(1:12)) first=.true.
! Dupe checking setup
if(nutc00.ne.nutc0 .or. tsec.lt.tsec0) then ! reset dupe checker
@ -90,7 +94,7 @@ subroutine mskrtd(id2,nutc0,tsec,ntol,nrxfreq,ndepth,mycall,hiscall, &
endif
tframe=float(NSPM)/12000.0
line=char(0)
line(1:1)=char(0)
msgreceived=' '
max_iterations=10
niterations=0

View File

@ -222,14 +222,20 @@ program q65sim
fac=sqrt(1.0/avep)
cspread=fac*cspread !Normalize to constant avg power
cdat=cspread*cdat !Apply Rayleigh fading
! do i=0,nfft-1
! p=real(cspread(i))**2 + aimag(cspread(i))**2
! write(14,3010) i,p,cspread(i)
!3010 format(i8,3f12.6)
! enddo
endif
! psig=0.
! pnoise=0.
! do i=1,npts
! if(i.gt.12000 .and. i.lt.624000) then
! psig=psig + aimag(cdat(i))**2
! pnoise=pnoise + xnoise(i)*xnoise(i)
! endif
! enddo
! pnoise=pnoise*bandwidth_ratio
! snr_2500=db(psig/pnoise) !Calibration confirmation!
! print*,'SNR_2500:',snr_2500
dat=aimag(cdat) + xnoise !Add generated AWGN noise
fac=32767.0
if(snrdb.ge.90.0) iwave(1:npts)=nint(fac*dat(1:npts))

View File

@ -1,20 +1,25 @@
subroutine foxgen2(nslots,cmsg)
subroutine foxgen2(nslots,cmsg,line,foxcall)
! Parse old-style Fox messages to extract the necessary pieces for a SuperFox
! transmission.
use packjt77
character*40 cmsg(5)
character*120 line
character*40 cmsg(5) !Old-style Fox messages are here
character*37 msg
character*22 sfmsg
character*12 mycall
character*26 sfmsg
character*13 mycall
character*11 foxcall
character*4 mygrid
character*6 hiscall_1,hiscall_2
character*4 rpt_1,rpt_2
character*4 rpt1,rpt2
character*13 w(19)
integer nw(19)
integer ntype !Message type: 0 Free Text
! 1 CQ MyCall MyGrid
! 2 Call_1 MyCall RR73
! 3 Call_1 MyCall rpt_1
! 4 Call_1 RR73; Call_2 <MyCall> rpt_2
! 3 Call_1 MyCall rpt1
! 4 Call_1 RR73; Call_2 <MyCall> rpt2
if(nslots.lt.1 .or. nslots.gt.5) return
k=0
@ -23,8 +28,8 @@ subroutine foxgen2(nslots,cmsg)
hiscall_2=''
mycall=''
mygrid=''
rpt_1=''
rpt_2=''
rpt1=''
rpt2=''
msg=cmsg(i)(1:37)
call split77(msg,nwords,nw,w)
ntype=0
@ -36,105 +41,35 @@ subroutine foxgen2(nslots,cmsg)
ntype=4
hiscall_1=w(1)(1:6)
hiscall_2=w(3)(1:6)
rpt_1='RR73'
rpt_2=w(5)(1:4)
rpt1='RR73'
rpt2=w(5)(1:4)
mycall=w(4)(2:nw(4)-1)
else if(index(msg,' RR73').gt.0) then
ntype=2
hiscall_1=w(1)(1:6)
mycall=w(2)(1:12)
rpt_1='RR73'
rpt1='RR73'
else if(nwords.eq.3 .and. nw(3).eq.3 .and. &
(w(3)(1:1).eq.'-' .or. w(3)(1:1).eq.'+')) then
ntype=3
hiscall_1=w(1)(1:6)
mycall=w(2)(1:12)
rpt_1=w(3)(1:4)
rpt1=w(3)(1:4)
endif
! write(*,3001) ntype,cmsg(i),hiscall_1,rpt_1,hiscall_2,rpt_2, &
! mycall(1:6),mygrid
!3001 format(i1,2x,a37,1x,a6,1x,a4,1x,a6,1x,a4,1x,a6,1x,a4)
k=k+1
if(ntype.le.3) call sfox_assemble(ntype,k,msg(1:22),mycall,mygrid)
if(ntype.le.3) call sfox_assemble(ntype,k,msg(1:26),mycall,mygrid,line)
if(ntype.eq.4) then
sfmsg=w(1)(1:nw(1))//' '//mycall(1:len(trim(mycall))+1)//'RR73'
call sfox_assemble(2,k,sfmsg,mycall,mygrid)
call sfox_assemble(2,k,sfmsg,mycall,mygrid,line)
sfmsg=w(3)(1:nw(3))//' '//mycall(1:len(trim(mycall))+1)//w(5)(1:3)
k=k+1
call sfox_assemble(3,k,sfmsg,mycall,mygrid)
call sfox_assemble(3,k,sfmsg,mycall,mygrid,line)
endif
enddo
call sfox_assemble(ntype,11,msg(1:22),mycall,mygrid) !k=11 to finish up
call sfox_assemble(ntype,11,msg(1:26),mycall,mygrid,line) !k=11 to finish up
foxcall=mycall(1:11)
return
end subroutine foxgen2
subroutine sfox_assemble(ntype,k,msg,mycall0,mygrid0)
character*22 msg
character*22 msg0,msg1,msg2(10),msg3(5)
character*12 mycall0,mycall
character*4 mygrid0,mygrid
integer ntype !Message type: 0 Free Text
! 1 CQ MyCall MyGrid
! 2 Call_1 MyCall RR73
! 3 Call_1 MyCall rpt
integer nmsg(0:3) !Number of messages of type ntype
data nmsg/0,0,0,0/,nbits/0/,ntx/0/
save
! save mycall,mygrid,nmsg,nbits,ntx
if(mycall0(1:1).ne.' ') mycall=mycall0
if(mygrid0(1:1).ne.' ') mygrid=mygrid0
if(k.le.10) then
if(ntype.eq.0) then
if(nbits.le.262) then
nmsg(ntype)=nmsg(ntype)+1
nbits=nbits+71
msg0=msg
endif
else if(ntype.eq.1) then
if(nbits.le.290) then
nmsg(ntype)=nmsg(ntype)+1
nbits=nbits+43
msg1=msg
endif
else if(ntype.eq.2) then
if(nbits.le.305) then
nmsg(ntype)=nmsg(ntype)+1
nbits=nbits+28
j=nmsg(ntype)
msg2(j)=msg
endif
else
if(nbits.le.300) then
nmsg(ntype)=nmsg(ntype)+1
nbits=nbits+33
j=nmsg(ntype)
msg3(j)=msg
endif
endif
return
endif
if(k.ge.11) then
ntx=ntx+1 !Transmission number
write(*,3002) ntx,ntype,nmsg(0:3),nbits
3002 format(i3,i5,2x,4i3,i6)
if(nmsg(0).ge.1) write(*,3010) ntx,msg0
3010 format(i3,2x,a22)
if(nmsg(1).ge.1) write(*,3010) ntx,msg1
do i=1,nmsg(2)
write(*,3010) ntx,msg2(i)
enddo
do i=1,nmsg(3)
write(*,3010) ntx,msg3(i)
enddo
nmsg=0
nbits=0
endif
return
end subroutine sfox_assemble

View File

@ -0,0 +1,12 @@
! LDPC (174,91) code
parameter (KK=91) !Information bits (77 + CRC14)
parameter (ND=58) !Data symbols
parameter (NS=21) !Sync symbols (3 @ Costas 7x7)
parameter (NN=NS+ND) !Total channel symbols (79)
parameter (NSPS=1920) !Samples per symbol at 12000 S/s
parameter (NZ=NSPS*NN) !Samples in full 15 s waveform (151,680)
parameter (NMAX=15*12000) !Samples in iwave (180,000)
parameter (NFFT1=2*NSPS, NH1=NFFT1/2) !Length of FFTs for symbol spectra
parameter (NSTEP=NSPS/4) !Rough time-sync step size
parameter (NHSYM=NMAX/NSTEP-3) !Number of symbol spectra (1/4-sym steps)
parameter (NDOWN=60) !Downsample factor

3
lib/superfox/gtag.f90 Normal file
View File

@ -0,0 +1,3 @@
integer ntag
data ntag/z"1234567"/
!-----------------------------------------------------------------------

39
lib/superfox/julian.f90 Normal file
View File

@ -0,0 +1,39 @@
module julian
contains
integer*8 function itime8()
implicit integer (a-z)
! 1 2 3 4 5 6 7
integer it(8) !y m d nmin h m s
integer*8 secday
data secday/86400/
call date_and_time(values=it)
iyr=it(1)
imo=it(2)
iday=it(3)
days=JD(iyr,imo,iday) - 2440588 !Days since epoch Jan 1, 1970
ih=it(5)
im=it(6)-it(4) !it(4) corrects for time zone
is=it(7)
nsec=3600*ih + 60*im + is
itime8=days*secday + nsec
return
end function itime8
integer function JD(I,J,K)
! Return Julian Date for I=year, J=month, K=day
! Reference: Fliegel and Van Flandern, Comm. ACM 11, 10, 1968
JD = K - 32075 + 1461*(I + 4800 + (J - 14)/12)/4 &
+ 367*(J - 2 - (J - 14)/12*12)/12 - 3 &
*((I + 4900 + (J - 14)/12)/100)/4
return
end function JD
end module julian

View File

@ -0,0 +1,103 @@
!*******************************************************************************
!>
! A simple module for `popen`.
module popen_module
use,intrinsic :: iso_c_binding
implicit none
private
! interfaces to C functions
interface
function popen(command, mode) bind(C,name='popen')
!! initiate pipe streams to or from a process
import :: c_char, c_ptr
implicit none
character(kind=c_char),dimension(*) :: command
character(kind=c_char),dimension(*) :: mode
type(c_ptr) :: popen
end function popen
function fgets(s, siz, stream) bind(C,name='fgets')
!! get a string from a stream
import :: c_char, c_ptr, c_int
implicit none
type (c_ptr) :: fgets
character(kind=c_char),dimension(*) :: s
integer(kind=c_int),value :: siz
type(c_ptr),value :: stream
end function fgets
function pclose(stream) bind(C,name='pclose')
!! close a pipe stream to or from a process
import :: c_ptr, c_int
implicit none
integer(c_int) :: pclose
type(c_ptr),value :: stream
end function pclose
end interface
public :: c2f_string, get_command_as_string
contains
!*******************************************************************************
!>
! Convert a C string to a Fortran string.
function c2f_string(c) result(f)
character(len=*),intent(in) :: c !! C string
character(len=:),allocatable :: f !! Fortran string
integer :: i
i = index(c,c_null_char)
if (i<=0) then
f = c
else if (i==1) then
f = ''
else if (i>1) then
f = c(1:i-1)
end if
end function c2f_string
!*******************************************************************************
!>
! Return the result of the command as a string.
function get_command_as_string(command) result(str)
character(len=*),intent(in) :: command !! the command to run
character(len=:),allocatable :: str !! the result of that command
integer,parameter :: buffer_length = 1000 !! read stream in chunks of this size
type(c_ptr) :: h !! for `popen`
integer(c_int) :: istat !! `pclose` status
character(kind=c_char,len=buffer_length) :: line !! buffer to read from `fgets`
str = ''
h = c_null_ptr
h = popen(command//c_null_char,'r'//c_null_char)
if (c_associated(h)) then
do while (c_associated(fgets(line,buffer_length,h)))
str = str//c2f_string(line)
end do
istat = pclose(h)
end if
end function get_command_as_string
!*******************************************************************************
end module popen_module
!*******************************************************************************

View File

@ -0,0 +1,67 @@
// ------------------------------------------------------------------------------
// dbgprintf.c
// Functions for printing debug information
//
// (c) 2024 - Nico Palermo, IV3NWV - Microtelecom Srl, Italy
// ------------------------------------------------------------------------------
//
// This source is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this source distribution.
// If not, see <http://www.gnu.org/licenses/>.
// ------------------------------------------------------------------------------
#include "dbgprintf.h"
// print functions for debug purposes
void dbgprintf_vector_uchar(const char* name, const unsigned char* v, int vsize)
{
int k;
printf("%s=", name);
for (k = 0; k < vsize; k++) {
if ((k & 0x0F) == 0)
printf("\n");
printf("%02X ", v[k]);
}
printf("\n");
}
void dbgprintf_vector_float(const char* name, const float* v, int vsize)
{
int k;
printf("%s=", name);
for (k = 0; k < vsize; k++) {
if ((k & 0x07) == 0)
printf("\n");
printf("%10.3f ", v[k]);
}
printf("\n");
}
void dbgprintf_rows_float(const char* name, const float* v, int vsize, int nrows)
{
int k;
int j;
printf("%s=\n", name);
for (j = 0; j < nrows; j++) {
printf("r%d:", j);
for (k = 0; k < vsize; k++) {
if ((k & 0x07) == 0)
printf("\n");
printf("%7.3f ", v[k]);
}
printf("\n");
v += vsize;
}
}

View File

@ -0,0 +1,64 @@
// ------------------------------------------------------------------------------
// dbgprintf.h
// Functions for printing debug information
//
// (c) 2024 - Nico Palermo, IV3NWV - Microtelecom Srl, Italy
// ------------------------------------------------------------------------------
//
// This source is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this source distribution.
// If not, see <http://www.gnu.org/licenses/>.
// ------------------------------------------------------------------------------
#ifndef _dbgprintf_h_
#define _dbgprintf_h_
// Define DBGPRINTF_ANYWAY
// in order to print debug information also
// when _DEBUG is not defined
#define DBGPRINTF_ANYWAY
#ifdef _DEBUG
#define DBG_PRINTF
#else
#ifdef DBGPRINTF_ANYWAY
#define DBG_PRINTF
#endif
#endif
#include <stdio.h>
// print functions for debug purposes
#ifdef DBG_PRINTF
#ifdef __cplusplus
extern "C" {
#endif
void dbgprintf_vector_uchar(const char* name, const unsigned char* v, int vsize);
void dbgprintf_vector_float(const char* name, const float* v, int vsize);
void dbgprintf_rows_float(const char* name, const float* v, int vsize, int nrows);
#ifdef __cplusplus
}
#endif
#else
#define dbgprintf_vector_uchar(a,b)
#define dbgprintf_vector_float(a,b)
#define dbgprintf_rows_float(a, b, c, d)
#endif
#endif // _dbgprintf_h_

383
lib/superfox/qpc/nhash2.c Normal file
View File

@ -0,0 +1,383 @@
/*
File name: nhash2.c
*------------------------------------------------------------------------------
*
* This file is part of the WSPR application, Weak Signal Propogation Reporter
*
* File Name: nhash.c
* Description: Functions to produce 32-bit hashes for hash table lookup
*
* Copyright (C) 2008-2014 Joseph Taylor, K1JT
* License: GNU GPL v3+
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
* Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Files: lookup3.c
* Copyright: Copyright (C) 2006 Bob Jenkins <bob_jenkins@burtleburtle.net>
* License: public-domain
* You may use this code any way you wish, private, educational, or commercial.
* It's free.
*
*-------------------------------------------------------------------------------
*/
/*
These are functions for producing 32-bit hashes for hash table lookup.
hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final()
are externally useful functions. Routines to test the hash are included
if SELF_TEST is defined. You can use this free for any purpose. It's in
the public domain. It has no warranty.
You probably want to use hashlittle(). hashlittle() and hashbig()
hash byte arrays. hashlittle() is is faster than hashbig() on
little-endian machines. Intel and AMD are little-endian machines.
On second thought, you probably want hashlittle2(), which is identical to
hashlittle() except it returns two 32-bit hashes for the price of one.
You could implement hashbig2() if you wanted but I haven't bothered here.
If you want to find a hash of, say, exactly 7 integers, do
a = i1; b = i2; c = i3;
mix(a,b,c);
a += i4; b += i5; c += i6;
mix(a,b,c);
a += i7;
final(a,b,c);
then use c as the hash value. If you have a variable length array of
4-byte integers to hash, use hashword(). If you have a byte array (like
a character string), use hashlittle(). If you have several byte arrays, or
a mix of things, see the comments above hashlittle().
Why is this so big? I read 12 bytes at a time into 3 4-byte integers,
then mix those integers. This is fast (you can do a lot more thorough
mixing with 12*3 instructions on 3 integers than you can with 3 instructions
on 1 byte), but shoehorning those bytes into integers efficiently is messy.
*/
#define SELF_TEST 1
#include <stdio.h> /* defines printf for tests */
#include <time.h> /* defines time_t for timings in the test */
#include "nhash2.h"
//#include <sys/param.h> /* attempt to define endianness */
//#ifdef linux
//# include <endian.h> /* attempt to define endianness */
//#endif
#define HASH_LITTLE_ENDIAN 1
#define hashsize(n) ((uint32_t)1<<(n))
#define hashmask(n) (hashsize(n)-1)
#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
/*
-------------------------------------------------------------------------------
mix -- mix 3 32-bit values reversibly.
This is reversible, so any information in (a,b,c) before mix() is
still in (a,b,c) after mix().
If four pairs of (a,b,c) inputs are run through mix(), or through
mix() in reverse, there are at least 32 bits of the output that
are sometimes the same for one pair and different for another pair.
This was tested for:
* pairs that differed by one bit, by two bits, in any combination
of top bits of (a,b,c), or in any combination of bottom bits of
(a,b,c).
* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
is commonly produced by subtraction) look like a single 1-bit
difference.
* the base values were pseudorandom, all zero but one bit set, or
all zero plus a counter that starts at zero.
Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that
satisfy this are
4 6 8 16 19 4
9 15 3 18 27 15
14 9 3 7 17 3
Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing
for "differ" defined as + with a one-bit base and a two-bit delta. I
used http://burtleburtle.net/bob/hash/avalanche.html to choose
the operations, constants, and arrangements of the variables.
This does not achieve avalanche. There are input bits of (a,b,c)
that fail to affect some output bits of (a,b,c), especially of a. The
most thoroughly mixed value is c, but it doesn't really even achieve
avalanche in c.
This allows some parallelism. Read-after-writes are good at doubling
the number of bits affected, so the goal of mixing pulls in the opposite
direction as the goal of parallelism. I did what I could. Rotates
seem to cost as much as shifts on every machine I could lay my hands
on, and rotates are much kinder to the top and bottom bits, so I used
rotates.
-------------------------------------------------------------------------------
*/
#define mix(a,b,c) \
{ \
a -= c; a ^= rot(c, 4); c += b; \
b -= a; b ^= rot(a, 6); a += c; \
c -= b; c ^= rot(b, 8); b += a; \
a -= c; a ^= rot(c,16); c += b; \
b -= a; b ^= rot(a,19); a += c; \
c -= b; c ^= rot(b, 4); b += a; \
}
/*
-------------------------------------------------------------------------------
final -- final mixing of 3 32-bit values (a,b,c) into c
Pairs of (a,b,c) values differing in only a few bits will usually
produce values of c that look totally different. This was tested for
* pairs that differed by one bit, by two bits, in any combination
of top bits of (a,b,c), or in any combination of bottom bits of
(a,b,c).
* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
is commonly produced by subtraction) look like a single 1-bit
difference.
* the base values were pseudorandom, all zero but one bit set, or
all zero plus a counter that starts at zero.
These constants passed:
14 11 25 16 4 14 24
12 14 25 16 4 14 24
and these came close:
4 8 15 26 3 22 24
10 8 15 26 3 22 24
11 8 15 26 3 22 24
-------------------------------------------------------------------------------
*/
#define final(a,b,c) \
{ \
c ^= b; c -= rot(b,14); \
a ^= c; a -= rot(c,11); \
b ^= a; b -= rot(a,25); \
c ^= b; c -= rot(b,16); \
a ^= c; a -= rot(c,4); \
b ^= a; b -= rot(a,14); \
c ^= b; c -= rot(b,24); \
}
/*
-------------------------------------------------------------------------------
hashlittle() -- hash a variable-length key into a 32-bit value
k : the key (the unaligned variable-length array of bytes)
length : the length of the key, counting by bytes
initval : can be any 4-byte value
Returns a 32-bit value. Every bit of the key affects every bit of
the return value. Two keys differing by one or two bits will have
totally different hash values.
The best hash table sizes are powers of 2. There is no need to do
mod a prime (mod is sooo slow!). If you need less than 32 bits,
use a bitmask. For example, if you need only 10 bits, do
h = (h & hashmask(10));
In which case, the hash table should have hashsize(10) elements.
If you are hashing n strings (uint8_t **)k, do it like this:
for (i=0, h=0; i<n; ++i) h = hashlittle( k[i], len[i], h);
By Bob Jenkins, 2006. bob_jenkins@burtleburtle.net. You may use this
code any way you wish, private, educational, or commercial. It's free.
Use for hash table lookup, or anything where one collision in 2^^32 is
acceptable. Do NOT use for cryptographic purposes.
-------------------------------------------------------------------------------
*/
uint32_t nhash2( const void *key, uint64_t length, uint32_t initval)
//int nhash( const char *key, int length, int initval)
{
uint32_t a,b,c; /* internal state */
union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */
/* Set up the internal state */
a = b = c = 0xdeadbeef + ((uint32_t)length) + initval;
u.ptr = key;
if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */
/*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
while (length > 12)
{
a += k[0];
b += k[1];
c += k[2];
mix(a,b,c);
length -= 12;
k += 3;
}
// printf("AAA %x %d %x %d\n",c,c,c&32767,c&32767);
/*----------------------------- handle the last (probably partial) block */
/*
* "k[2]&0xffffff" actually reads beyond the end of the string, but
* then masks off the part it's not allowed to read. Because the
* string is aligned, the masked-off tail is in the same word as the
* rest of the string. Every machine with memory protection I've seen
* does it on word boundaries, so is OK with this. But VALGRIND will
* still catch it and complain. The masking trick does make the hash
* noticably faster for short strings (like English words).
*/
#ifndef VALGRIND
switch(length)
{
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break;
case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break;
case 8 : b+=k[1]; a+=k[0]; break;
case 7 : b+=k[1]&0xffffff; a+=k[0]; break;
case 6 : b+=k[1]&0xffff; a+=k[0]; break;
case 5 : b+=k[1]&0xff; a+=k[0]; break;
case 4 : a+=k[0]; break;
case 3 : a+=k[0]&0xffffff; break;
case 2 : a+=k[0]&0xffff; break;
case 1 : a+=k[0]&0xff; break;
case 0 : return c; /* zero length strings require no mixing */
}
#else /* make valgrind happy */
k8 = (const uint8_t *)k;
switch(length)
{
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
case 10: c+=((uint32_t)k8[9])<<8; /* fall through */
case 9 : c+=k8[8]; /* fall through */
case 8 : b+=k[1]; a+=k[0]; break;
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */
case 5 : b+=k8[4]; /* fall through */
case 4 : a+=k[0]; break;
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */
case 1 : a+=k8[0]; break;
case 0 : return c;
}
#endif /* !valgrind */
} else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */
const uint8_t *k8;
/*--------------- all but last block: aligned reads and different mixing */
while (length > 12)
{
a += k[0] + (((uint32_t)k[1])<<16);
b += k[2] + (((uint32_t)k[3])<<16);
c += k[4] + (((uint32_t)k[5])<<16);
mix(a,b,c);
length -= 12;
k += 6;
}
/*----------------------------- handle the last (probably partial) block */
k8 = (const uint8_t *)k;
switch(length)
{
case 12: c+=k[4]+(((uint32_t)k[5])<<16);
b+=k[2]+(((uint32_t)k[3])<<16);
a+=k[0]+(((uint32_t)k[1])<<16);
break;
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
case 10: c+=k[4];
b+=k[2]+(((uint32_t)k[3])<<16);
a+=k[0]+(((uint32_t)k[1])<<16);
break;
case 9 : c+=k8[8]; /* fall through */
case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
a+=k[0]+(((uint32_t)k[1])<<16);
break;
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
case 6 : b+=k[2];
a+=k[0]+(((uint32_t)k[1])<<16);
break;
case 5 : b+=k8[4]; /* fall through */
case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
break;
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
case 2 : a+=k[0];
break;
case 1 : a+=k8[0];
break;
case 0 : return c; /* zero length requires no mixing */
}
} else { /* need to read the key one byte at a time */
const uint8_t *k = (const uint8_t *)key;
/*--------------- all but the last block: affect some 32 bits of (a,b,c) */
while (length > 12)
{
a += k[0];
a += ((uint32_t)k[1])<<8;
a += ((uint32_t)k[2])<<16;
a += ((uint32_t)k[3])<<24;
b += k[4];
b += ((uint32_t)k[5])<<8;
b += ((uint32_t)k[6])<<16;
b += ((uint32_t)k[7])<<24;
c += k[8];
c += ((uint32_t)k[9])<<8;
c += ((uint32_t)k[10])<<16;
c += ((uint32_t)k[11])<<24;
mix(a,b,c);
length -= 12;
k += 12;
}
/*-------------------------------- last block: affect all 32 bits of (c) */
switch(length) /* all the case statements fall through */
{
case 12: c+=((uint32_t)k[11])<<24;
/* fall through */
case 11: c+=((uint32_t)k[10])<<16;
/* fall through */
case 10: c+=((uint32_t)k[9])<<8;
/* fall through */
case 9 : c+=k[8];
/* fall through */
case 8 : b+=((uint32_t)k[7])<<24;
/* fall through */
case 7 : b+=((uint32_t)k[6])<<16;
/* fall through */
case 6 : b+=((uint32_t)k[5])<<8;
/* fall through */
case 5 : b+=k[4];
/* fall through */
case 4 : a+=((uint32_t)k[3])<<24;
/* fall through */
case 3 : a+=((uint32_t)k[2])<<16;
/* fall through */
case 2 : a+=((uint32_t)k[1])<<8;
/* fall through */
case 1 : a+=k[0];
break;
case 0 : return c;
}
}
final(a,b,c);
return c;
}

22
lib/superfox/qpc/nhash2.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef NHASH_H_
#define NHASH_H_
#ifdef Win32
#include "win_stdint.h" /* defines uint32_t etc */
#else
#include <stddef.h>
#include <stdint.h> /* defines uint32_t etc */
#endif
#ifdef __cplusplus
extern "C" {
#endif
uint32_t nhash( const void * key, uint64_t length, uint32_t initval);
//int nhash(const char *key, int length, int initval);
#ifdef __cplusplus
}
#endif
#endif

329
lib/superfox/qpc/np_qpc.c Normal file
View File

@ -0,0 +1,329 @@
// ------------------------------------------------------------------------------
// np_qpc.h
// Q-Ary Polar Codes encoding/decoding functions
//
// (c) 2024 - Nico Palermo, IV3NWV - Microtelecom Srl, Italy
// ------------------------------------------------------------------------------
//
// This source is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this source distribution.
// If not, see <http://www.gnu.org/licenses/>.
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include "dbgprintf.h"
#include "qpc_fwht.h"
#include "np_qpc.h"
// static constant / functions
static const float knorm = 1.0f / QPC_Q;
static float* pdf_conv(float *dst, float* pdf1, float* pdf2)
{
// convolution between two pdf
float fwht_pdf1[QPC_Q];
float fwht_pdf2[QPC_Q];
int k;
qpc_fwht(fwht_pdf1, pdf1);
qpc_fwht(fwht_pdf2, pdf2);
for (k = 0; k < QPC_Q; k++)
fwht_pdf1[k] *= fwht_pdf2[k];
qpc_fwht(dst, fwht_pdf1);
for (k = 0; k < QPC_Q; k++)
dst[k] *= knorm;
return dst;
}
static void pdfarray_conv(float* dstarray, float* pdf1array, float* pdf2array, int numrows)
{
int k;
// convolutions between rows of pdfs
for (k = 0; k < numrows; k++) {
pdf_conv(dstarray, pdf1array, pdf2array);
dstarray += QPC_Q;
pdf1array += QPC_Q;
pdf2array += QPC_Q;
}
}
static float _pdfuniform[QPC_Q];
static const float* _pdf_uniform1();
static const float* _pdf_uniform0();
typedef const float*(*ptr_pdfuniform)(void);
static ptr_pdfuniform _ptr_pdf_uniform = _pdf_uniform0;
static const float* _pdf_uniform1()
{
return _pdfuniform;
};
static const float* _pdf_uniform0()
{
// compute uniform pdf once for all
int k;
for (k = 0; k < QPC_Q; k++)
_pdfuniform[k] = knorm;
// next call to _qpc_pdfuniform
// will be handled directly by _pqc_pdfuniform1
_ptr_pdf_uniform = _pdf_uniform1;
return _pdfuniform;
};
static const float* pdf_uniform()
{
return _ptr_pdf_uniform();
}
static float * pdf_mul(float *dst, float* pdf1, float* pdf2)
{
int k;
float v;
float norm = 0;
for (k = 0; k < QPC_Q; k++) {
v = pdf1[k] * pdf2[k];
dst[k] = v;
norm += v;
}
// if norm of the result is not positive
// return in dst a uniform distribution
if (norm <= 0)
memcpy(dst, pdf_uniform(), QPC_Q * sizeof(float));
else {
norm = 1.0f / norm;
for (k = 0; k < QPC_Q; k++)
dst[k] = dst[k] * norm;
}
return dst;
}
static void pdfarray_mul(float* dstarray, float* pdf1array, float* pdf2array, int numrows)
{
int k;
// products between rows of pdfs
for (k = 0; k < numrows; k++) {
pdf_mul(dstarray, pdf1array, pdf2array);
dstarray += QPC_Q;
pdf1array += QPC_Q;
pdf2array += QPC_Q;
}
}
static float* pdf_convhard(float* dst, const float* pdf, unsigned char hd)
{
// convolution between a pdf and a hard-decision feedback
int k;
for (k=0;k<QPC_Q;k++)
dst[k] = pdf[k^hd];
return dst;
}
static void pdfarray_convhard(float* dstarray, const float* pdfarray, const unsigned char *hdarray, int numrows)
{
int k;
// hard convolutions between rows
for (k = 0; k < numrows; k++) {
pdf_convhard(dstarray, pdfarray, hdarray[k]);
dstarray += QPC_Q;
pdfarray += QPC_Q;
}
}
static unsigned char pdf_max(const float* pdf)
{
int k;
unsigned char imax = 0;
float pdfmax = pdf[0];
for (k=1;k<QPC_Q;k++)
if (pdf[k] > pdfmax) {
pdfmax = pdf[k];
imax = k;
}
return imax;
}
// local stack functions ---------------------------------------
static float _qpc_stack[QPC_N * QPC_Q * 2];
static float* _qpc_stack_base = _qpc_stack;
static float* _qpc_stack_push(int numfloats)
{
float* addr = _qpc_stack_base;
_qpc_stack_base += numfloats;
return addr;
}
static void _qpc_stack_pop(int numfloats)
{
_qpc_stack_base -= numfloats;
}
// qpc encoder function (internal use) ----------------------------------------------------------
unsigned char* _qpc_encode(unsigned char* y, unsigned char* x)
{
// Non recursive polar encoder
// Same architecture of a fast fourier transform
// in which the fft butteflies are replaced by the polar transform
// butterflies
int k, j, m;
int groups;
int bfypergroup;
int stepbfy;
int stepgroup;
int basegroup;
int basebfy;
memcpy(y, x, QPC_N);
for (k = 0; k < QPC_LOG2N; k++) {
groups = 1 << (QPC_LOG2N - 1 - k);
stepbfy = bfypergroup = 1 << k;
stepgroup = stepbfy << 1;
basegroup = 0;
for (j = 0; j < groups; j++) {
basebfy = basegroup;
for (m = 0; m < bfypergroup; m++) {
// polar transform
y[basebfy + stepbfy] = y[basebfy + stepbfy] ^ y[basebfy];
basebfy = basebfy + 1;
}
basegroup = basegroup + stepgroup;
}
}
return y;
}
// qpc polar decoder (internal use )--------------------------------------------------
void _qpc_decode(unsigned char* xdec, unsigned char* ydec, const float* py, const unsigned char* f, const unsigned char* fsize, const int numrows)
{
if (numrows == 1) {
if (fsize[0] == 0) {
// dbgprintf_vector_float("py", py, QPC_Q);
// frozen symbol
xdec[0] = pdf_max(py);
ydec[0] = f[0];
}
else {
// fsize = 1 => information symbol
xdec[0] = pdf_max(py);
ydec[0] = xdec[0];
}
}
else {
int k;
int nextrows = numrows >> 1;
int size = nextrows << QPC_LOG2Q;
// upper block variables
unsigned char* xdech = xdec + nextrows;
unsigned char* ydech = ydec + nextrows;
const unsigned char* fh = f + nextrows;
const unsigned char* fsizeh = fsize + nextrows;
// Step 1.
// stack and init variables used in the recursion
float* pyl = _qpc_stack_push(size);
memcpy(pyl, py, size * sizeof(float));
float* pyh = _qpc_stack_push(size);
memcpy(pyh, py + size, size * sizeof(float));
// Step 2. Recursion on upper block
// Forward pdf convolutions for the upper block
// (place in the lower part of py the convolution of lower and higher blocks)
// float* pyh = py + size;
// pdfarray_conv(py, pyl, pyh, nextrows); // convolution overwriting the lower block of py which is not needed
pdfarray_conv(pyh, pyl, pyh, nextrows);
_qpc_decode(xdech, ydech, pyh, fh, fsizeh, nextrows);
// Step 3. compute pdfs in the lower block
pdfarray_convhard(pyh, py+size, ydech,nextrows); // dst ptr must be different form src ptr
pdfarray_mul(pyl, pyl, pyh, nextrows);
// we don't need pyh anymore
_qpc_stack_pop(size);
// Step 4. Recursion on the lower block
_qpc_decode(xdec, ydec, pyl, f, fsize, nextrows);
// we don't need pyl anymore
_qpc_stack_pop(size);
// Step 5. Update backward results
// xdec is already ok, we need just to update ydech
for (k = 0; k < nextrows; k++)
ydech[k] = ydech[k] ^ ydec[k];
}
}
// Public encoding/decoding functions ------------------------------------------------
void qpc_encode(unsigned char* y, const unsigned char* x)
{
// map information symbols
int kk, pos;
for (kk = 0; kk < QPC_K; kk++) {
pos = qpccode.xpos[kk];
qpccode.f[pos] = x[kk];
}
// do polar encoding
_qpc_encode(y, qpccode.f);
}
void qpc_decode(unsigned char* xdec, unsigned char* ydec, float* py)
{
int k;
unsigned char x[QPC_N];
// set the first py row with know frozen (punctured) symbol
if (qpccode.np < qpccode.n) {
// assume that we punctured only the first output symbol
memset(py, 0, QPC_Q * sizeof(float));
py[qpccode.f[0]] = 1.0f;
}
// decode
_qpc_decode(x, ydec, py, qpccode.f, qpccode.fsize, QPC_N);
// demap information symbols
for (k = 0; k < QPC_K; k++)
xdec[k] = x[qpccode.xpos[k]];
}

62
lib/superfox/qpc/np_qpc.h Normal file
View File

@ -0,0 +1,62 @@
// ------------------------------------------------------------------------------
// np_qpc.h
// Q-Ary Polar Codes encoding/decoding functions
//
// (c) 2024 - Nico Palermo, IV3NWV - Microtelecom Srl, Italy
// ------------------------------------------------------------------------------
//
// This source is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this source distribution.
// If not, see <http://www.gnu.org/licenses/>.
#ifndef _np_qpc_h_
#define _np_qpc_h_
#define QPC_LOG2N 7 // log2(codeword length) (not punctured)
#define QPC_N (1<<QPC_LOG2N) // codeword length (not punctured)
#define QPC_LOG2Q 7 // bits per symbol
#define QPC_Q (1<<QPC_LOG2Q) // alphabet size
#define QPC_K 50 // number of information symbols
typedef struct {
int n; // codeword length (unpunctured)
int np; // codeword length (punctured)
int k; // number of information symbols
int q; // alphabet size
int xpos[QPC_N]; // info symbols mapping/demapping tables
unsigned char f[QPC_N]; // frozen symbols values
unsigned char fsize[QPC_N]; // frozen symbol flag (fsize==0 => frozen)
} qpccode_ds;
#ifdef __cplusplus
extern "C"
{
#endif
void qpc_encode(unsigned char* y, const unsigned char* x);
void qpc_decode(unsigned char* xdec, unsigned char* ydec, float* py);
unsigned char* _qpc_encode(unsigned char* y, unsigned char* x);
void _qpc_decode(unsigned char* xdec, unsigned char* ydec,
const float* py, const unsigned char* f, const unsigned char* fsize,
const int numrows);
extern qpccode_ds qpccode;
#ifdef __cplusplus
}
#endif
#endif // _np_qpc_h_

135
lib/superfox/qpc/np_rnd.c Normal file
View File

@ -0,0 +1,135 @@
// ------------------------------------------------------------------------------
// np_rnd.c
// Functions to generate random numbers with uniform/gaussian probability distributions
//
// (c) 2024 - Nico Palermo, IV3NWV - Microtelecom Srl, Italy
// ------------------------------------------------------------------------------
//
// This source is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this source distribution.
// If not, see <http://www.gnu.org/licenses/>.
#include "np_rnd.h"
#if _WIN32 // note the underscore: without it, it's not msdn official!
// Windows (x64 and x86)
#include <windows.h> // required only for GetTickCount(...)
#define K_RAND_MAX UINT_MAX
#elif _SVID_SOURCE || _XOPEN_SOURCE || __unix__ || (defined (__APPLE__) && defined(__MACH__)) /* POSIX or Unix or Apple */
#include <stdlib.h>
#define rand_s(x) (*x)=(unsigned int)lrand48() // returns unsigned integers in the range 0..0x7FFFFFFF
#define K_RAND_MAX 0x7FFFFFFF // that's the max number
// generated by lrand48
#else
#error "No good quality PRNG found"
#endif
void np_normrnd_real(float *dst, int nitems, float mean, float stdev)
{
// for odd or even nitems
unsigned int r;
float phi=0, u=0;
int set = 0;
float scalephi = (M_2PI / (1.0f + K_RAND_MAX));
float scaleu = (1.0f / (1.0f + K_RAND_MAX));
while (nitems--)
if (set==1) {
// generate a second normally distributed number
*dst++ = sinf(phi)*u*stdev+mean;
set = 0;
}
else {
// generate a uniform distributed phase phi in the range [0,2*PI)
rand_s((unsigned int*)&r); phi = scalephi * r;
// generate a uniform distributed random number u in the range (0,1]
rand_s((unsigned int*)&r); u = scaleu * (1.0f + r);
// generate normally distributed number
u = (float)sqrt(-2.0f * log(u));
*dst++ = cosf(phi) * u * stdev + mean;
set=1;
}
}
void np_normrnd_cpx(float* dst, int nitems, float mean, float stdev)
{
// as qpc_normrnd_real, but generates always nitems complex numbers (2*nitems reals)
unsigned int r;
float phi = 0, u = 0;
// JHT int set = 0;
float scalephi = (M_2PI / (1.0f + K_RAND_MAX));
float scaleu = (1.0f / (1.0f + K_RAND_MAX));
while (nitems--) {
// generate a uniform distributed phase phi in the range [0,2*PI)
rand_s((unsigned int*)&r); phi = scalephi * r;
// generate a uniform distributed random number u in the range (0,1]
rand_s((unsigned int*)&r); u = scaleu * (1.0f + r);
// generate normally distributed real and imaginary parts
u = (float)sqrt(-2.0f * log(u));
*dst++ = cosf(phi) * u * stdev + mean;
*dst++ = sinf(phi) * u * stdev + mean;
}
}
void np_unidrnd(unsigned int* dst, int nitems, unsigned int nsetsize)
{
// generate uniform unsigned int random numbers in the range [0..nsetsize)
unsigned int r;
float u;
float scaleu = (1.0f / (1.0f + K_RAND_MAX));
while (nitems--) {
rand_s((unsigned int*)&r); u = scaleu * nsetsize * r;
*dst++ = (unsigned int)floorf(u);
}
}
void np_unidrnd_uc(unsigned char* dst, int nitems, unsigned char nsetsize)
{
// generate uniform unsigned char random numbers in the range [0..nsetsize)
unsigned int r;
float u;
float scaleu = (1.0f / (1.0f + K_RAND_MAX));
while (nitems--) {
rand_s((unsigned int*)&r); u = scaleu * nsetsize * r;
*dst++ = (unsigned char)floorf(u);
}
}
void np_unifrnd(float* dst, int nitems, float fmax)
{
// generate uniform float random numbers in the range [0..fmax)
unsigned int r;
float u;
float scaleu = (1.0f / (1.0f + K_RAND_MAX));
while (nitems--) {
rand_s((unsigned int*)&r); u = scaleu * fmax * r;
*dst++ = u;
}
}

59
lib/superfox/qpc/np_rnd.h Normal file
View File

@ -0,0 +1,59 @@
// ------------------------------------------------------------------------------
// np_rnd.h
// Functions to generate random numbers with uniform/gaussian probability distributions
//
// (c) 2024 - Nico Palermo, IV3NWV - Microtelecom Srl, Italy
// ------------------------------------------------------------------------------
//
// This source is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this source distribution.
// If not, see <http://www.gnu.org/licenses/>.
#ifndef _np_rnd_h_
#define _np_rnd_h_
#define _CRT_RAND_S
#include <stdlib.h>
#define _USE_MATH_DEFINES
#include <math.h>
#define M_2PI (2.0f*(float)M_PI)
#ifdef __cplusplus
extern "C" {
#endif
// generate a random array of real numbers with a gaussian distribution of given mean and stdev
void np_normrnd_real(float *dst, int nitems, float mean, float stdev);
// generate a random array of nitems complex numbers with a gaussian distribution of given mean and stdev
void np_normrnd_cpx(float* dst, int nitems, float mean, float stdev);
// generate a random array of nitems unsigned int numbers with uniform distribution
// in the range [0 .. nsetsize)
void np_unidrnd(unsigned int* dst, int nitems, unsigned int nsetsize);
// generate a random array of nitems unsigned chars numbers with uniform distribution
// in the range [0 .. nsetsize)
void np_unidrnd_uc(unsigned char* dst, int nitems, unsigned char nsetsize);
// generate a random array of nitems float numbers with uniform distribution
// in the range [0 .. fmax)
void np_unifrnd(float* dst, int nitems, float fmax);
#ifdef __cplusplus
}
#endif
#endif // _np_rnd_h_

233
lib/superfox/qpc/qpc_fwht.c Normal file
View File

@ -0,0 +1,233 @@
// ------------------------------------------------------------------------------
// qpc_fwht.c
// Fast Walsh-Hadamard Transforms for q-ary polar codes
//
// (c) 2024 - Nico Palermo, IV3NWV - Microtelecom Srl, Italy
// ------------------------------------------------------------------------------
//
// This source is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this source distribution.
// If not, see <http://www.gnu.org/licenses/>.
#include "qpc_fwht.h"
static void _qpc_sumdiff8_16(float* y, float* t)
{
y[0] = t[0] + t[16];
y[16] = t[0] - t[16];
y[1] = t[1] + t[17];
y[17] = t[1] - t[17];
y[2] = t[2] + t[18];
y[18] = t[2] - t[18];
y[3] = t[3] + t[19];
y[19] = t[3] - t[19];
y[4] = t[4] + t[20];
y[20] = t[4] - t[20];
y[5] = t[5] + t[21];
y[21] = t[5] - t[21];
y[6] = t[6] + t[22];
y[22] = t[6] - t[22];
y[7] = t[7] + t[23];
y[23] = t[7] - t[23];
}
static void _qpc_sumdiff8_32(float* y, float* t)
{
y[0] = t[0] + t[32];
y[32] = t[0] - t[32];
y[1] = t[1] + t[33];
y[33] = t[1] - t[33];
y[2] = t[2] + t[34];
y[34] = t[2] - t[34];
y[3] = t[3] + t[35];
y[35] = t[3] - t[35];
y[4] = t[4] + t[36];
y[36] = t[4] - t[36];
y[5] = t[5] + t[37];
y[37] = t[5] - t[37];
y[6] = t[6] + t[38];
y[38] = t[6] - t[38];
y[7] = t[7] + t[39];
y[39] = t[7] - t[39];
}
static void _qpc_sumdiff8_64(float* y, float* t)
{
y[0] = t[0] + t[64];
y[64] = t[0] - t[64];
y[1] = t[1] + t[65];
y[65] = t[1] - t[65];
y[2] = t[2] + t[66];
y[66] = t[2] - t[66];
y[3] = t[3] + t[67];
y[67] = t[3] - t[67];
y[4] = t[4] + t[68];
y[68] = t[4] - t[68];
y[5] = t[5] + t[69];
y[69] = t[5] - t[69];
y[6] = t[6] + t[70];
y[70] = t[6] - t[70];
y[7] = t[7] + t[71];
y[71] = t[7] - t[71];
}
float* qpc_fwht8(float* y, float* x)
{
float t[8];
// first stage
y[0] = x[0] + x[1];
y[1] = x[0] - x[1];
y[2] = x[2] + x[3];
y[3] = x[2] - x[3];
y[4] = x[4] + x[5];
y[5] = x[4] - x[5];
y[6] = x[6] + x[7];
y[7] = x[6] - x[7];
// second stage
t[0] = y[0] + y[2];
t[2] = y[0] - y[2];
t[1] = y[1] + y[3];
t[3] = y[1] - y[3];
t[4] = y[4] + y[6];
t[6] = y[4] - y[6];
t[5] = y[5] + y[7];
t[7] = y[5] - y[7];
// third stage
y[0] = t[0] + t[4];
y[4] = t[0] - t[4];
y[1] = t[1] + t[5];
y[5] = t[1] - t[5];
y[2] = t[2] + t[6];
y[6] = t[2] - t[6];
y[3] = t[3] + t[7];
y[7] = t[3] - t[7];
return y;
}
float* qpc_fwht16(float* y, float* x)
{
float t[16];
qpc_fwht8(t, x);
qpc_fwht8(t + 8, x + 8);
y[0] = t[0] + t[8];
y[8] = t[0] - t[8];
y[1] = t[1] + t[9];
y[9] = t[1] - t[9];
y[2] = t[2] + t[10];
y[10] = t[2] - t[10];
y[3] = t[3] + t[11];
y[11] = t[3] - t[11];
y[4] = t[4] + t[12];
y[12] = t[4] - t[12];
y[5] = t[5] + t[13];
y[13] = t[5] - t[13];
y[6] = t[6] + t[14];
y[14] = t[6] - t[14];
y[7] = t[7] + t[15];
y[15] = t[7] - t[15];
return y;
}
float* qpc_fwht32(float* y, float* x)
{
float t[32];
qpc_fwht16(t, x);
qpc_fwht16(t + 16, x + 16);
_qpc_sumdiff8_16(y, t);
_qpc_sumdiff8_16(y + 8, t + 8);
return y;
}
float* qpc_fwht64(float* y, float* x)
{
float t[64];
qpc_fwht32(t, x);
qpc_fwht32(t + 32, x + 32);
_qpc_sumdiff8_32(y, t);
_qpc_sumdiff8_32(y + 8, t + 8);
_qpc_sumdiff8_32(y + 16, t + 16);
_qpc_sumdiff8_32(y + 24, t + 24);
return y;
}
float* qpc_fwht128(float* y, float* x)
{
float t[128];
qpc_fwht64(t, x);
qpc_fwht64(t + 64, x + 64);
_qpc_sumdiff8_64(y, t);
_qpc_sumdiff8_64(y + 8, t + 8);
_qpc_sumdiff8_64(y + 16, t + 16);
_qpc_sumdiff8_64(y + 24, t + 24);
_qpc_sumdiff8_64(y + 32, t + 32);
_qpc_sumdiff8_64(y + 40, t + 40);
_qpc_sumdiff8_64(y + 48, t + 48);
_qpc_sumdiff8_64(y + 56, t + 56);
return y;
}
// functions over pdfs used by the decoder -----------------------------------------------------------

View File

@ -0,0 +1,57 @@
// ------------------------------------------------------------------------------
// qpc_fwht.h
// Fast Walsh-Hadamard Transforms for q-ary polar codes
//
// (c) 2024 - Nico Palermo, IV3NWV - Microtelecom Srl, Italy
// ------------------------------------------------------------------------------
//
// This source is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this source distribution.
// If not, see <http://www.gnu.org/licenses/>.
#ifndef _qpc_fwht_h_
#define _qpc_fwht_h_
#include "np_qpc.h"
#if QPC_LOG2Q==7
#define qpc_fwht(a,b) qpc_fwht128(a,b)
#endif
#if QPC_LOG2Q==6
#define qpc_fwht(a,b) qpc_fwht64(a,b)
#endif
#if QPC_LOG2Q==5
#define qpc_fwht(a,b) qpc_fwht32(a,b)
#endif
#if QPC_LOG2Q==4
#define qpc_fwht(a,b) qpc_fwht16(a,b)
#endif
// Note that it makes no sense to use fast convolutions
// for transforms that are less than 16 symbols in size.
// For such cases direct convolutions are faster.
#if QPC_LOG2Q==3
#define qpc_fwht(a,b) qpc_fwht8(a,b)
#endif
#ifdef __cplusplus
extern "C" {
#endif
float* qpc_fwht8(float* y, float* x);
float* qpc_fwht16(float* y, float* x);
float* qpc_fwht32(float* y, float* x);
float* qpc_fwht64(float* y, float* x);
float* qpc_fwht128(float* y, float* x);
#ifdef __cplusplus
}
#endif
#endif // _qpc_fwht_h_

View File

@ -0,0 +1,198 @@
// ------------------------------------------------------------------------------
// qpc_main.cpp
//
// Test the WER performance of the QPC (127,50) Q=128 code
//
// (c) 2024 - Nico Palermo, IV3NWV - Microtelecom Srl, Italy
// ------------------------------------------------------------------------------
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include "dbgprintf.h"
#include "qpc_fwht.h"
#include "np_qpc.h"
// for random numbers generation and NCFSK Rayleigh channel simulation
#include "np_rnd.h"
void qpc_channel(float* yout, unsigned char* y, float EsNo)
{
// compute channel outputs amplitudes
int k;
// generate noise samples -----------------------------------------
float sigman = 1.0f / sqrtf(2.0f);
np_normrnd_cpx(yout, QPC_N * QPC_Q, 0, sigman);
// dbgprintf_rows_float("yout", yout, QPC_Q*2, QPC_N);
// generate rayleigh distributed signal amplitudes -----------------
float symamps[QPC_N * 2];
np_normrnd_cpx(symamps, QPC_N, 0, sigman);
// dbgprintf_vector_float("symamps", symamps, QPC_N*2);
// normalize signal amps to unity ----------------------------------
float pwr = 0.0f;
float* psymamps = symamps;
// compute sig power
for (k = 0; k < QPC_N; k++) {
pwr += psymamps[0] * psymamps[0] + psymamps[1] * psymamps[1];
psymamps += 2;
}
pwr = pwr / QPC_N;
// normalize to avg EsNo
float norm = sqrtf(EsNo/pwr);
psymamps = symamps;
for (k = 0; k < QPC_N; k++) {
psymamps[0] *= norm;
psymamps[1] *= norm;
psymamps += 2;
}
// dbgprintf_vector_float("symamps norm", symamps, QPC_N * 2);
// add signal amplitudes to noise -----------------------------------
float *pyout = yout;
psymamps= symamps;
for (k = 0; k < QPC_N; k++) {
pyout[y[k]<<1] += psymamps[0];
pyout[(y[k]<<1)+1] += psymamps[1];
pyout += (QPC_Q*2);
psymamps += 2;
}
// dbgprintf_rows_float("s+n out", yout, QPC_Q * 2, QPC_N);
return;
}
void qpc_likelihoods(float* py, float* yout, float EsNo, float No)
{
// compute symbols likelihoods
// (rayleigh channel)
int k, j;
float norm = EsNo / (EsNo + 1) / No;
// compute likelihoods from energies ----------------------------
float* pybase;
float* ppyout = yout;
float normpwr;
float normpwrmax;
float pynorm;
for (k = 0; k < QPC_N; k++) {
// compute loglikelihoods and largest one from energies
pybase = py + k * QPC_Q;
normpwrmax = 0.0f;
for (j = 0; j < QPC_Q; j++) {
normpwr = norm * (ppyout[0] * ppyout[0] + ppyout[1] * ppyout[1]);
pybase[j] = normpwr;
if (normpwr > normpwrmax)
normpwrmax = normpwr;
ppyout += 2;
}
// subtract largest exponent
pynorm = 0.0f;
for (j = 0; j < QPC_Q; j++) {
pybase[j] = expf(pybase[j] - normpwrmax);
pynorm += pybase[j];
}
// normalize to probabilities
pynorm = 1.0f / pynorm;
for (j = 0; j < QPC_Q; j++)
pybase[j] = pybase[j] * pynorm;
}
return;
}
int main()
{
int k;
int NT = 20000; // number of transmissions to simultate
float EbNodB = 3.7f; // Eb/No to simulate
int kc = qpccode.k;
int np = qpccode.np;
float Rc = 1.0f * kc / np;
float Tm = 10.0f; // message duration
float Rb = 1.0f / Tm * (QPC_K - 2) * QPC_LOG2Q; // Bit rate assuming two symbols for CRC
float EsNodB = EbNodB + 10.0f * log10f(Rc * QPC_LOG2Q);
static unsigned char xin[QPC_K]; // input information symbols
static unsigned char xdec[QPC_K]; // decoded information symbols
static unsigned char y[QPC_N]; // encoded codeword
static unsigned char ydec[QPC_N]; // decoded codeword
static float yout[QPC_N * QPC_Q * 2]; // channel complex amplitutes output
static float py[QPC_N * QPC_Q]; // channel output probabilities
float EsNo = powf(10.0f, EsNodB / 10.0f);
float No = 1.0f;
//JHT static float we;
static float wer;
int kk;
printf("QPC Word Error Rate Test\n");
printf("Polar Code (%d,%d) Q=%d for the Rayleigh channel\n", qpccode.np, qpccode.k, qpccode.q);
printf("Eb/No = %.1f dB\n", EbNodB);
printf("Es/No = %.1f dB\n", EsNodB);
printf("Tmsg = %.1f s\n", Tm);
printf("Bit Rate = %.1f bit/s\n", Rb);
printf("SNR(2500) = %.1f dB\n\n", EbNodB + 10.0f * log10f(Rb/ 2500));
for (k = 0; k < NT; k++) {
np_unidrnd_uc(xin, QPC_K, QPC_Q); // generate random information symbols
qpc_encode(y, xin); // encode
// compute channel outputs and probabilities
// Note that if the code is punctured (i.e. N=127)
// the first codeword symbol must not be transmitted over the channel
// Here, in order to avoid useless copies,
// the vector of likelihoods py continues to be a QPC_N*QPC_Q vector of floats.
// The first received symbol likelihoods should start always at offset QPC_Q.
// The first QPC_Q positions of py will be ignored (and set) by the decoder.
qpc_channel(yout, y, EsNo);
// The decoder can't estimate the EsNo easily
// so we assume that in any case it is 5 dB
float EsNoDec = 3.16;
qpc_likelihoods(py, yout, EsNoDec, No);
qpc_decode(xdec, ydec, py); // decode
// count words in errors
for (kk = 0; kk < QPC_K; kk++)
if (xin[kk] ^ xdec[kk]) {
wer += 1;
break;
}
// show the decoder performance every 200 codewords transmissions
if ((k % 200) == 0 && k>0) {
printf("k=%6d/%6d wer = %8.2E\n", k, NT, wer / k);
fflush(stdout);
}
}
// show the final result
printf("k=%6d/%6d wer = %8.2E\n", k, NT, wer / k);
printf("\nAll done.\n");
return 0;
}

View File

@ -0,0 +1,38 @@
module qpc_mod
interface
integer(c_int32_t) function nhash2 (xin, length, initval) bind(C, &
name="nhash2")
use iso_c_binding, only: c_signed_char, c_int64_t, c_int32_t
integer(c_int64_t), intent(in), value :: length
integer(c_signed_char), intent(in) :: xin(length)
integer(c_int32_t), intent(in), value :: initval
end function nhash2
end interface
interface
subroutine qpc_encode(y, xin) bind(C,name="qpc_encode")
use iso_c_binding, only: c_ptr, c_signed_char
integer(c_signed_char), intent(out) :: y(127)
integer(c_signed_char), intent(in) :: xin(50)
end subroutine qpc_encode
end interface
interface
subroutine qpc_channel(yout, y, EsNo) bind(C,name="qpc_channel")
use iso_c_binding, only: c_float_complex, c_float, c_signed_char
complex(c_float_complex), intent(out) :: yout(128,128)
integer(c_signed_char), intent(out) :: y(127)
real(c_float), intent(in), value :: EsNo
end subroutine qpc_channel
end interface
interface
subroutine qpc_decode(xdec, ydec, py) bind(C,name="qpc_decode")
use iso_c_binding, only: c_float, c_signed_char
real(c_float), intent(in) :: py(128,128)
integer(c_signed_char), intent(out) :: ydec(127)
integer(c_signed_char), intent(out) :: xdec(50)
end subroutine qpc_decode
end interface
end module qpc_mod

View File

@ -0,0 +1,60 @@
// ------------------------------------------------------------------------------
// qpc_n127k50q128.c
//
// Defines the parameters of the q-ary polar code (127,50) Q=128
// for WSJT-X
// ------------------------------------------------------------------------------
// (c) 2024 - Nico Palermo, IV3NWV - Microtelecom Srl, Italy
// ------------------------------------------------------------------------------
//
// WARNING:
// This source is NOT free software and it is licensed only for use with WSJT-X.
// No derived work is authorized to use this code without the written
// permission of his author (Nico Palermo / IV3NWV) who owns all the rights
// of this IP (intellectual property).
//
// This file is distributed ONLY for the purpose of documenting and making of
// public domain the encoding scheme used in WSJT-X so that the transmitted
// messages can be decoded by anybody.
// Anyway this does not imply that one could use the following tables in a
// derived work without an explicit and written authorization from his author.
// Any unauthorized use, as for any intellectual property, is simply
// illegal.
// -------------------------------------------------------------------------------
#include "np_qpc.h"
qpccode_ds qpccode = {
128, //n
127, //np
50, //k
128, //q
{
1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 16, 32, 17, 18, 64, 20,
33, 34, 24, 7, 11, 36, 13, 19, 14, 65, 40, 21, 66, 22, 35, 68,
25, 48, 37, 26, 72, 15, 38, 28, 41, 67, 23, 80, 42, 69, 49, 96,
44, 27, 70, 50, 73, 39, 29, 52, 74, 30, 56, 81, 76, 43, 82, 84,
97, 45, 71, 88, 98, 46, 100, 51, 104, 53, 75, 112, 54, 57, 99, 119,
92, 77, 58, 117, 59, 83, 106, 31, 85, 108, 115, 116, 122, 125, 124, 91,
61, 90, 89, 111, 78, 93, 94, 126, 86, 107, 110, 118, 121, 62, 120, 87,
105, 55, 114, 60, 127, 63, 103, 101, 123, 95, 102, 47, 109, 79, 113, 0
},
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
},
{
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0,
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}
};

115
lib/superfox/qpc/qpc_subs.c Normal file
View File

@ -0,0 +1,115 @@
// ------------------------------------------------------------------------------
// qpc_test.cpp
//
// Test the WER performance of the QPC (127,50) Q=128 code
//
// (c) 2024 - Nico Palermo, IV3NWV - Microtelecom Srl, Italy
// ------------------------------------------------------------------------------
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include <time.h>
#include "dbgprintf.h"
#include "qpc_fwht.h"
#include "np_qpc.h"
#include "nhash2.h"
// for random numbers generation and NCFSK Rayleigh channel simulation
#include "np_rnd.h"
void qpc_channel(float* yout, unsigned char* y, float EsNo)
{
// compute channel outputs amplitudes
int k;
// generate noise samples -----------------------------------------
float sigman = 1.0f / sqrtf(2.0f);
np_normrnd_cpx(yout, QPC_N * QPC_Q, 0, sigman);
// dbgprintf_rows_float("yout", yout, QPC_Q*2, QPC_N);
// generate rayleigh distributed signal amplitudes -----------------
float symamps[QPC_N * 2];
np_normrnd_cpx(symamps, QPC_N, 0, sigman);
// dbgprintf_vector_float("symamps", symamps, QPC_N*2);
// normalize signal amps to unity ----------------------------------
float pwr = 0.0f;
float* psymamps = symamps;
// compute sig power
for (k = 0; k < QPC_N; k++) {
pwr += psymamps[0] * psymamps[0] + psymamps[1] * psymamps[1];
psymamps += 2;
}
pwr = pwr / QPC_N;
// normalize to avg EsNo
float norm = sqrtf(EsNo/pwr);
psymamps = symamps;
for (k = 0; k < QPC_N; k++) {
psymamps[0] *= norm;
psymamps[1] *= norm;
psymamps += 2;
}
// dbgprintf_vector_float("symamps norm", symamps, QPC_N * 2);
// add signal amplitudes to noise -----------------------------------
float *pyout = yout;
psymamps= symamps;
for (k = 0; k < QPC_N; k++) {
pyout[y[k]<<1] += psymamps[0];
pyout[(y[k]<<1)+1] += psymamps[1];
pyout += (QPC_Q*2);
psymamps += 2;
}
// dbgprintf_rows_float("s+n out", yout, QPC_Q * 2, QPC_N);
return;
}
void qpc_likelihoods(float* py, float* yout, float EsNo, float No)
{
// compute symbols likelihoods
// (rayleigh channel)
int k, j;
float norm = EsNo / (EsNo + 1) / No;
// compute likelihoods from energies ----------------------------
float* pybase;
float* ppyout = yout;
float normpwr;
float normpwrmax;
float pynorm;
for (k = 0; k < QPC_N; k++) {
// compute loglikelihoods and largest one from energies
pybase = py + k * QPC_Q;
normpwrmax = 0.0f;
for (j = 0; j < QPC_Q; j++) {
normpwr = norm * (ppyout[0] * ppyout[0] + ppyout[1] * ppyout[1]);
pybase[j] = normpwr;
if (normpwr > normpwrmax)
normpwrmax = normpwr;
ppyout += 2;
}
// subtract largest exponent
pynorm = 0.0f;
for (j = 0; j < QPC_Q; j++) {
pybase[j] = expf(pybase[j] - normpwrmax);
pynorm += pybase[j];
}
// normalize to probabilities
pynorm = 1.0f / pynorm;
for (j = 0; j < QPC_Q; j++)
pybase[j] = pybase[j] * pynorm;
}
return;
}

View File

@ -0,0 +1,150 @@
subroutine qpc_decode2(c0,fsync,ftol,xdec,ndepth,dth,damp,crc_ok, &
snrsync,fbest,tbest,snr)
use qpc_mod
parameter(NMAX=15*12000,NFT=365,NZ=100)
complex c0(NMAX) !Signal as received
complex c(NMAX) !Signal as received
real py(0:127,0:127) !Probabilities for received synbol values
real py0(0:127,0:127) !Probabilities for strong signal
real pyd(0:127,0:127) !Dithered values for py
real s2(0:127,0:151) !Symbol spectra, including sync
real s3(0:127,0:127) !Synchronized symbol spectra
real No
integer crc_chk,crc_sent
integer*8 n47
integer idf(NZ),idt(NZ)
integer nseed(33)
integer*1 xdec(0:49) !Decoded message
integer*1 ydec(0:127) !Decoded symbols
logical crc_ok
integer maxdither(8)
integer isync(24) !Symbol numbers for sync tones
data isync/1,2,4,7,11,16,22,29,37,39,42,43,45,48,52,57,63,70,78,80,83, &
84,86,89/
data n47/47/,maxdither/20,50,100,200,500,1000,2000,5000/
data nseed/ &
321278106, -658879006, 1239150429, -941466001, -698554454, &
1136210962, 1633585627, 1261915021, -1134191465, -487888229, &
2131958895, -1429290834, -1802468092, 1801346659, 1966248904, &
402671397, -1961400750, -1567227835, 1895670987, -286583128, &
-595933665, -1699285543, 1518291336, 1338407128, 838354404, &
-2081343776, -1449416716, 1236537391, -133197638, 337355509, &
-460640480, 1592689606, 0/
data idf/0, 0, -1, 0, -1, 1, 0, -1, 1, -2, 0, -1, 1, -2, 2, &
0, -1, 1, -2, 2, -3, 0, -1, 1, -2, 2, -3, 3, 0, -1, &
1, -2, 2, -3, 3, -4, 0, -1, 1, -2, 2, -3, 3, -4, 4, &
0, -1, 1, -2, 2, -3, 3, -4, 4, -5, -1, 1, -2, 2, -3, &
3, -4, 4, -5, 1, -2, 2, -3, 3, -4, 4, -5, -2, 2, -3, &
3, -4, 4, -5, 2, -3, 3, -4, 4, -5, -3, 3, -4, 4, -5, &
3, -4, 4, -5, -4, 4, -5, 4, -5, -5/
data idt/0 , -1, 0, 1, -1, 0, -2, 1, -1, 0, 2, -2, 1, -1, 0, &
-3, 2, -2, 1, -1, 0, 3, -3, 2, -2, 1, -1, 0, -4, 3, &
-3, 2, -2, 1, -1, 0, 4, -4, 3, -3, 2, -2, 1, -1, 0, &
-5, 4, -4, 3, -3, 2, -2, 1, -1, 0, -5, 4, -4, 3, -3, &
2, -2, 1, -1, -5, 4, -4, 3, -3, 2, -2, 1, -5, 4, -4, &
3, -3, 2, -2, -5, 4, -4, 3, -3, 2, -5, 4, -4, 3, -3, &
-5, 4, -4, 3, -5, 4, -4, -5, 4, -5/
fsample=12000.0
baud=12000.0/1024.0
nstype=1
n47=47
mask21=2**21 - 1
crc_ok=.false.
call qpc_sync(c0,fsample,isync,fsync,ftol,f2,t2,snrsync)
f00=1500.0 + f2
t00=t2
fbest=f00
tbest=t00
maxd=1
if(ndepth.gt.0) maxd=maxdither(ndepth)
maxft=NZ
if(snrsync.lt.4.0 .or. ndepth.le.0) maxft=1
do idith=1,maxft
if(idith.ge.2) maxd=1
deltaf=idf(idith)*0.5
deltat=idt(idith)*8.0/1024.0
f=f00+deltaf
t=t00+deltat
fshift=1500.0 - (f+baud) !Shift frequencies down by f + 1 bin
call twkfreq2(c0,c,NMAX,fsample,fshift)
a=1.0
b=0.0
do kk=1,4
if(kk.eq.2) b=0.4
if(kk.eq.3) b=0.5
if(kk.eq.4) b=0.6
call sfox_demod(c,1500.0,t,isync,s2,s3) !Compute s2 and s3
if(b.gt.0.0) then
do j=0,127
call smo121a(s3(:,j),128,a,b)
enddo
endif
call pctile(s3,128*128,50,base3)
s3=s3/base3
EsNoDec=3.16
No=1.
py0=s3
call qpc_likelihoods2(py,s3,EsNoDec,No) !For weak signals
call random_seed(put=nseed)
do kkk=1,maxd
if(kkk.eq.1) then
pyd=py0
else
pyd=0.
if(kkk.gt.2) then
call random_number(pyd)
pyd=2.0*(pyd-0.5)
endif
where(py.gt.dth) pyd=0. !Don't perturb large likelihoods
pyd=py*(1.0 + damp*pyd) !Compute dithered likelihood
endif
do j=0,127
ss=sum(pyd(:,j))
if(ss.gt.0.0) then
pyd(:,j)=pyd(:,j)/ss
else
pyd(:,j)=0.0
endif
enddo
call qpc_decode(xdec,ydec,pyd)
xdec=xdec(49:0:-1)
crc_chk=iand(nhash2(xdec,n47,571),mask21) !Compute crc_chk
crc_sent=128*128*xdec(47) + 128*xdec(48) + xdec(49)
crc_ok=crc_chk.eq.crc_sent
if(crc_ok) then
call qpc_snr(s3,ydec,snr)
if(snr.lt.-16.5) crc_ok=.false.
! write(61,3061) idith,kk,kkk,idf(idith),idt(idith),a,b
!3061 format(5i5,2f8.3)
return
endif
enddo !kk: dither of smoothing weights
enddo !kkk: dither of probabilities
enddo !idith: dither of frequency and time
return
end subroutine qpc_decode2
subroutine smo121a(x,nz,a,b)
real x(nz)
fac=1.0/(a+2*b)
x0=x(1)
do i=2,nz-1
x1=x(i)
x(i)=fac*(a*x(i) + b*(x0+x(i+1)))
x0=x1
enddo
return
end subroutine smo121a

View File

@ -0,0 +1,28 @@
subroutine qpc_likelihoods2(py,s3,EsNo,No)
integer QQ,QN
parameter(QQ=128,QN=128)
real py(0:QQ-1,0:QN-1)
real s3(0:QQ-1,0:QN-1)
real No,norm,normpwr,normpwrmax
norm=(EsNo/(EsNo+1.0))/No
! Compute likelihoods for symbol values, from the symbol power spectra
do k=0,QN-1
normpwrmax=0.
do j=0,QQ-1
normpwr=norm*s3(j,k)
py(j,k)=normpwr
normpwrmax=max(normpwr,normpwrmax)
enddo
pynorm=0.
do j=0,QQ-1
py(j,k)=exp(py(j,k)-normpwrmax)
pynorm=pynorm + py(j,k)
enddo
py(0:QQ-1,k)=py(0:QQ-1,k)/pynorm !Normalize to probabilities
enddo
return
end subroutine qpc_likelihoods2

17
lib/superfox/qpc_snr.f90 Normal file
View File

@ -0,0 +1,17 @@
subroutine qpc_snr(s3,y,snr)
use qpc_mod
! real s2(0:NQ-1,0:151) !Symbol spectra, including sync
real s3(0:127,0:127) !Synchronized symbol spectra
integer*1 y(0:127) !Encoded symbols
! integer isync(24)
p=0.
do j=1,127
i=y(j)
p=p + s3(i,j)
enddo
snr=db(p/127.0) - db(127.0) - 4.0
return
end subroutine qpc_snr

101
lib/superfox/qpc_sync.f90 Normal file
View File

@ -0,0 +1,101 @@
subroutine qpc_sync(crcvd0,fsample,isync,fsync,ftol,f2,t2,snrsync)
parameter(N9SEC=9*12000,NMAX=15*12000,NDOWN=16,NZ=N9SEC/NDOWN)
complex crcvd0(NMAX) !Signal as received
complex c0(0:N9SEC-1) !For long FFT
complex c1(0:NZ-1)
complex c1sum(0:NZ-1)
complex z
real s(N9SEC/4)
real p(-1125:1125)
integer ipk(1)
integer isync(24)
baud=12000.0/1024.0
df2=fsample/N9SEC
fac=1.0/N9SEC
c0=fac*crcvd0(1:N9SEC)
call four2a(c0,N9SEC,1,-1,1) !Forward c2c FFT
iz=N9SEC/4
do i=1,iz
s(i)=real(c0(i))**2 + aimag(c0(i))**2
enddo
do i=1,4 !Smooth the spectrum a bit
call smo121(s,iz)
enddo
ia=nint((fsync-ftol)/df2)
ib=nint((fsync+ftol)/df2)
ipk=maxloc(s(ia:ib))
i0=ipk(1) + ia - 1
f2=df2*i0-750.0 ! f2 is the offset from nominal 750 Hz.
ia=nint(i0-baud/df2)
ib=nint(i0+baud/df2)
s1=0.0
s0=0.0
do i=ia,ib
s0=s0+s(i)
s1=s1+(i-i0)*s(i)
enddo
delta=s1/s0
i0=nint(i0+delta)
f2=i0*df2-750.0
c1=0.
ia=nint(i0-baud/df2)
ib=nint(i0+baud/df2)
do i=ia,ib
j=i-i0
if(j.ge.0) c1(j)=c0(i)
if(j.lt.0) c1(j+NZ)=c0(i)
enddo
call four2a(c1,NZ,1,1,1) !Reverse c2c FFT: back to time domain
c1sum(0)=c1(0)
do i=1,NZ-1
c1sum(i)=c1sum(i-1) + c1(i)
enddo
nspsd=1024/NDOWN
dt=NDOWN/12000.0
lagmax=1.5/dt
i0=nint(0.5*fsample/NDOWN) !Nominal start time is 0.5 s
pmax=0.
lagpk=0
do lag=-lagmax,lagmax
sp=0.
do j=1,24
i1=i0 + (isync(j)-1)*nspsd + lag
i2=i1 + nspsd
if(i1.lt.0 .or. i1.gt.NZ-1) cycle
if(i2.lt.0 .or. i2.gt.NZ-1) cycle
z=c1sum(i2)-c1sum(i1)
sp=sp + real(z)**2 + aimag(z)**2
enddo
if(sp.gt.pmax) then
pmax=sp
lagpk=lag
endif
p(lag)=sp
enddo
t2=lagpk*dt
snrsync=0.
sp=0.
sq=0.
nsum=0
tsym=1024/12000.0
do lag=-lagmax,lagmax
t=(lag-lagpk)*dt
if(abs(t).lt.tsym) cycle
nsum=nsum+1
sp=sp + p(lag)
sq=sq + p(lag)*p(lag)
enddo
ave=sp/nsum
rms=sqrt(sq/nsum-ave*ave)
snrsync=(pmax-ave)/rms
return
end subroutine qpc_sync

28
lib/superfox/ran1.f90 Normal file
View File

@ -0,0 +1,28 @@
FUNCTION ran1(idum)
INTEGER idum,IA,IM,IQ,IR,NTAB,NDIV
REAL ran1,AM,EPS,RNMX
PARAMETER (IA=16807,IM=2147483647,AM=1./IM,IQ=127773,IR=2836, &
NTAB=32,NDIV=1+(IM-1)/NTAB,EPS=1.2e-7,RNMX=1.-EPS)
INTEGER j,k,iv(NTAB),iy
SAVE iv,iy
DATA iv /NTAB*0/, iy /0/
if (idum.le.0.or.iy.eq.0) then
idum=max(-idum,1)
do j=NTAB+8,1,-1
k=idum/IQ
idum=IA*(idum-k*IQ)-IR*k
if (idum.lt.0) idum=idum+IM
if (j.le.NTAB) iv(j)=idum
enddo
iy=iv(1)
endif
k=idum/IQ
idum=IA*(idum-k*IQ)-IR*k
if (idum.lt.0) idum=idum+IM
j=1+iy/NDIV
iy=iv(j)
iv(j)=idum
ran1=min(AM*iy,RNMX)
return
END FUNCTION ran1

17
lib/superfox/sfox_ana.f90 Normal file
View File

@ -0,0 +1,17 @@
subroutine sfox_ana(dd,npts,c0,npts2)
real dd(npts) !Raw data at 12000 Hz
complex c0(0:npts2-1) !Complex data at 12000 Hz
save
nfft1=npts
nfft2=nfft1
fac=2.0/(32767.0*nfft1)
c0(0:npts-1)=fac*dd(1:npts)
call four2a(c0,nfft1,1,-1,1) !Forward c2c FFT
c0(nfft2/2+1:nfft2-1)=0. !Remove negative frequencies
c0(0)=0.5*c0(0) !Scale the DC term to 1/2
call four2a(c0,nfft2,1,1,1) !Inverse c2c FFT; c0 is analytic sig
return
end subroutine sfox_ana

View File

@ -0,0 +1,92 @@
subroutine sfox_assemble(ntype,k,msg,mycall0,mygrid0,line)
! In subsequent calls, assemble all necessary information for a SuperFox
! transmission.
character*120 line
character*26 msg
character*26 msg0,msg1,msg2(5),msg3(5)
character*4 rpt2(5)
character*6 hiscall(10)
character*13 mycall0,mycall
character*4 mygrid0,mygrid
integer ntype !Message type: 0 Free Text
! 1 CQ MyCall MyGrid
! 2 Call_1 MyCall RR73
! 3 Call_1 MyCall rpt
integer nmsg(0:3) !Number of messages of type ntype
data nmsg/0,0,0,0/,nbits/0/,ntx/0/,nb_mycall/0/
save
if(mycall0(1:1).ne.' ') mycall=mycall0
if(mygrid0(1:1).ne.' ') mygrid=mygrid0
if(ntype.ge.1) nb_mycall=28 !### Allow for nonstandard MyCall ###
if(sum(nmsg).eq.0) then
hiscall=' '
rpt2=' '
endif
if(k.le.10) then
if(ntype.eq.0) then
if(nbits+nb_mycall.le.191) then !Enough room for a free text message?
nmsg(ntype)=nmsg(ntype)+1
nbits=nbits+142
msg0=msg
endif
else if(ntype.eq.1) then
if(nbits+nb_mycall.le.318) then !Enough room for a CQ ?
nmsg(ntype)=nmsg(ntype)+1
nbits=nbits+15
msg1=msg
endif
else if(ntype.eq.2) then
if(nbits+nb_mycall.le.305) then !Enough room for a RR73 message?
nmsg(ntype)=nmsg(ntype)+1
nbits=nbits+28
j=nmsg(ntype)
msg2(j)=msg
i1=index(msg,' ')
hiscall(j+5)=msg(1:i1-1)
endif
else if(ntype.eq.3) then
if(nbits+nb_mycall.le.300) then !Enough room for a message with report?
nmsg(ntype)=nmsg(ntype)+1
nbits=nbits+33
j=nmsg(ntype)
msg3(j)=msg
i1=index(msg,' ')
hiscall(j)=msg(1:i1-1)
i1=max(index(msg,'-'),index(msg,'+'))
rpt2(j)=msg(i1:i1+3)
endif
endif
return
endif
if(k.ge.11) then
! All pieces are now available. Put them into a command line for external
! program sfox_tx.
ntx=ntx+1 !Transmission number
nbits=nbits+nb_mycall !Add bits for MyCall
if(nmsg(1).ge.1) then
line=msg1
else
line=trim(mycall)
do i=1,nmsg(3)
line=trim(line)//' '//trim(hiscall(i))//' '//rpt2(i)
enddo
do i=1,nmsg(2)
line=trim(line)//' '//trim(hiscall(i+5))
enddo
endif
nmsg=0
nbits=0
nb_mycall=0
hiscall=' '
rpt2=' '
endif
return
end subroutine sfox_assemble

View File

@ -0,0 +1,79 @@
subroutine sfox_demod(crcvd,f,t,isync,s2,s3)
use sfox_mod
complex crcvd(NMAX) !Signal as received
complex c(0:NSPS-1) !Work array, one symbol long
real s2(0:NQ-1,0:151) !Symbol spectra, including sync
real s3(0:NQ-1,0:NN) !Synchronized symbol spectra
integer isync(24)
integer ipk(1)
integer hist1(0:NQ-1),hist2(0:NQ-1)
j0=nint(12000.0*(t+0.5))
df=12000.0/NSPS
i0=nint(f/df)-NQ/2
k2=0
s2(:,0)=0. !The punctured symbol
s3(:,0)=0. !The punctured symbol
do n=1,NDS !Loop over all symbols
jb=n*NSPS + j0
ja=jb-NSPS+1
k2=k2+1
if(ja.lt.1 .or. jb.gt.NMAX) cycle
c=crcvd(ja:jb)
call four2a(c,NSPS,1,-1,1) !Compute symbol spectrum
do i=0,NQ-1
s2(i,k2)=real(c(i0+i))**2 + aimag(c(i0+i))**2
enddo
enddo
call pctile(s2,NQ*151,50,base2)
s2=s2/base2
hist1=0
hist2=0
do j=0,151
ipk=maxloc(s2(1:NQ-1,j)) !Find the spectral peak
i=ipk(1)-1
hist1(i)=hist1(i)+1
enddo
hist1(0)=0 !Don't treat sync tone as a birdie
do i=0,123
hist2(i)=sum(hist1(i:i+3))
enddo
ipk=maxloc(hist1)
i1=ipk(1)-1
m1=maxval(hist1)
ipk=maxloc(hist2)
i2=ipk(1)-1
m2=maxval(hist2)
if(m1.gt.12) then
do i=0,127
if(hist1(i).gt.12) then
s2(i,:)=1.0
endif
enddo
endif
if(m2.gt.20) then
if(i2.ge.1) i2=i2-1
if(i2.gt.120) i2=120
s2(i2:i2+7,:)=1.0
endif
k3=0
do n=1,NDS !Copy symbol spectra from s2 into s3
if(any(isync(1:NS).eq.n)) cycle !Skip the sync symbols
k3=k3+1
s3(:,k3)=s2(:,n)
enddo
call pctile(s3,NQ*NN,50,base3)
s3=s3/base3
return
end subroutine sfox_demod

View File

@ -0,0 +1,86 @@
subroutine sfox_gen_gfsk(idat,f0,isync,itone,cdat)
parameter (NSPS=1024)
parameter (NDS=151)
parameter (NN=127) !NN = number of code symbols
parameter (NS=24) !NS = number of sync symbols
parameter (NMAX=15*12000)
parameter (NPTS=(NDS+2)*NSPS) !# of samples in waveform at 12000 samples/sec
parameter (BT=8) !GFSK time-bandwidth product
complex cdat(NMAX)
complex w, wstep
integer idat(NN)
integer isync(NS)
integer itone(NDS)
real*8 dt,twopi,phi,dphi_peak
real*8 dphi(0:NPTS-1)
real pulse(3*NSPS)
logical first/.true./
save first,twopi,dt,hmod,dphi_peak,pulse
if(first) then
twopi=8.d0*atan(1.0)
fsample=12000.0
dt=1.0/fsample
hmod=1.0
dphi_peak=twopi*hmod/real(NSPS)
do i=1,3*NSPS
tt=(i-1.5*NSPS)/real(NSPS)
pulse(i)=gfsk_pulse(BT,tt)
enddo
first=.false.
endif
wave=0.
! Create the itone sequence: data symbols and interspersed sync symbols
j=1
k=0
do i=1,NDS
if(j.le.NS .and. i.eq.isync(j)) then
if(j.lt.NS) j=j+1 !Index for next sync symbol
itone(i)=0 !Insert sync symbol at tone 0
else
k=k+1
itone(i)=idat(k) + 1 !Symbol value 0 is transmitted at tone 1, etc.
endif
enddo
! Generate the SuperFox waveform.
dphi=0.d0
do j=1,NDS
ib=(j-1)*NSPS
ie=ib+3*NSPS-1
dphi(ib:ie)=dphi(ib:ie)+dphi_peak*pulse(1:3*NSPS)*itone(j)
enddo
dphi(0:2*NSPS-1)=dphi(0:2*NSPS-1)+dphi_peak*itone(1)*pulse(NSPS+1:3*NSPS)
dphi(NDS*NSPS:(NDS+2)*NSPS-1)=dphi(NDS*NSPS:(NDS+2)*NSPS-1)+dphi_peak*itone(NDS)*pulse(1:2*NSPS)
phi=0.d0
dphi=dphi+twopi*f0*dt
k=0
do j=1,NSPS*(NDS+2)-1
k=k+1
cdat(k)=cmplx(cos(phi),sin(phi))
phi=phi+dphi(j)
enddo
! Add raised cosine ramps at the beginning and end of the waveform.
! Since the modulator expects an integral number of symbols, dummy
! symbols are added to the beginning and end of the waveform to
! hold the ramps. All but nramp of the samples in each dummy
! symbol will be zero.
nramp=NSPS/BT
cdat(1:NSPS-nramp)=cmplx(0.0,0.0)
cdat(NSPS-nramp+1:NSPS)=cdat(NSPS-nramp+1:NSPS) * &
(1.0-cos(twopi*(/(i,i=0,nramp-1)/)/(2.0*nramp)))/2.0
k1=(NDS+1)*NSPS+1
cdat(k1:k1+nramp-1)=cdat(k1:k1+nramp-1) * &
(1.0+cos(twopi*(/(i,i=0,nramp-1)/)/(2.0*nramp)))/2.0
cdat(k1+nramp:NPTS)=0.0
return
end subroutine sfox_gen_gfsk

73
lib/superfox/sfox_mod.f90 Normal file
View File

@ -0,0 +1,73 @@
module sfox_mod
parameter (NMAX=15*12000) !Samples in iwave (180,000)
integer MM,NQ,NN,KK,NS,NDS,NFZ,NSPS,NSYNC,NZ,NFFT1
real baud,tsym,bw
contains
subroutine sfox_init(mm0,nn0,kk0,itu,fspread,delay,fsample,ns0)
character*2 itu
integer isps(54)
integer iloc(1)
data isps/ 896, 960, 972, 980,1000,1008,1024,1029,1050,1080, &
1120,1125,1134,1152,1176,1200,1215,1225,1250,1260, &
1280,1296,1323,1344,1350,1372,1400,1440,1458,1470, &
1500,1512,1536,1568,1575,1600,1620,1680,1701,1715, &
1728,1750,1764,1792,1800,1875,1890,1920,1944,1960, &
2000,2016,2025,2048/
MM=mm0 !Bits per symbol
NQ=2**MM !Q, number of MFSK tones
NN=nn0 !Codeword length
KK=kk0 !Number of information symbols
NS=ns0 !Number of sync symbols
NDS=NN+NS !Total number of channel symbols
NFZ=3 !First zero
jsps=nint(12.8*fsample/NDS)
iloc=minloc(abs(isps-jsps))
NSPS=isps(iloc(1)) !Samples per symbol
NSYNC=NS*NSPS !Samples in sync waveform
NZ=NSPS*NDS !Samples in full Tx waveform
NFFT1=2*NSPS !Length of FFTs for symbol spectra
baud=fsample/NSPS
tsym=1.0/baud
bw=NQ*baud
fspread=0.0
delay=0.0
if(itu.eq.'LQ') then
fspread=0.5
delay=0.5
else if(itu.eq.'LM') then
fspread=1.5
delay=2.0
else if(itu.eq.'LD') then
fspread=10.0
delay=6.0
else if(itu.eq.'MQ') then
fspread=0.1
delay=0.5
else if(itu.eq.'MM') then
fspread=0.5
delay=1.0
else if(itu.eq.'MD') then
fspread=1.0
delay=2.0
else if(itu.eq.'HQ') then
fspread=0.5
delay=1.0
else if(itu.eq.'HM') then
fspread=10.0
delay=3.0
else if(itu.eq.'HD') then
fspread=30.0
delay=7.0
endif
return
end subroutine sfox_init
end module sfox_mod

178
lib/superfox/sfox_pack.f90 Normal file
View File

@ -0,0 +1,178 @@
subroutine sfox_pack(line,ckey,bMoreCQs,bSendMsg,freeTextMsg,xin)
use qpc_mod
use packjt
use packjt77
use julian
parameter (NQU1RKS=203514677)
integer*8 n47,n58,now
integer*1 xin(0:49) !Packed message as 7-bit symbols
logical*1 bMoreCQs,bSendMsg
logical text,allz
character*120 line !SuperFox message pieces
character*10 ckey
character*26 freeTextMsg
character*13 w(16)
character*11 c11
character*329 msgbits !Packed message as bits
character*38 c
data c/' 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ/'/
i0=index(line,'/')
i3=0 !Default to i3=0, standard message
nh1=0 !Number of Hound calls with RR73
nh2=0 !Number of Hound calls with report
! Split the command line into words
w=' '
i1=1
do j=1,16
do i=i1,min(i1+12,120)
if(line(i:i).eq.' ') exit
enddo
i2=i-1
w(j)=line(i1:i2)
do i=i2+1,120
if(line(i:i).ne.' ') exit
enddo
i1=i
if(i1.ge.120) exit
enddo
nwords=j
do i=1,nwords
if(w(i)(1:1).eq.' ') then
nwords=i-1
exit
endif
enddo
do i=1,329 !Set all msgbits to '0'
msgbits(i:i)='0'
enddo
now=itime8()/30
now=30*now
read(ckey(5:10),*) notp
write(msgbits(307:326),'(b20.20)') notp !Insert the digital signature
if(w(1)(1:3).eq.'CQ ') then
i3=3
c11=w(2)(1:11)
n58=0
do i=1,11
n58=n58*38 + index(c,c11(i:i)) - 1
enddo
write(msgbits(1:58),'(b58.58)') n58
call packgrid(w(3)(1:4),n15,text)
write(msgbits(59:73),'(b15.15)') n15
write(msgbits(327:329),'(b3.3)') i3 !Message type i3=3
go to 800
endif
call pack28(w(1),n28) !Fox call
write(msgbits(1:28),'(b28.28)') n28
! Default report is RR73 if we're also sending a free text message.
if(bSendMsg) msgbits(141:160)='11111111111111111111'
j=29
! Process callsigns with RR73
do i=2,nwords
if(w(i)(1:1).eq.'+' .or. w(i)(1:1).eq.'-') cycle !Skip report words
i1=min(i+1,nwords)
if(w(i1)(1:1) .eq.'+' .or. w(i1)(1:1).eq.'-') cycle !Skip if i+1 is report
call pack28(w(i),n28)
write(msgbits(j:j+27),1002) n28 !Insert this call for RR73 message
1002 format(b28.28)
j=j+28
nh1=nh1+1
if(nh1.ge.5) exit !At most 5 RR73 callsigns
enddo
! Process callsigns with a report
j=169
j2=281
if(bSendMsg) then
i3=2
j=29 + 28*nh1
j2=141 + 5*nh1
endif
do i=2,nwords
i1=min(i+1,nwords)
if(w(i1)(1:1).eq.'+' .or. w(i1)(1:1).eq.'-') then
call pack28(w(i),n28)
write(msgbits(j:j+27),1002) n28 !Insert this call
read(w(i1),*) n !Valid reports are -18 to +12, plus RR73
if(n.lt.-18) n=-18 !... Even numbers only ...
if(n.gt.12) n=12
write(msgbits(j2:j2+4),1000) n+18
1000 format(b5.5)
w(i1)=""
nh2=nh2+1
! print*,'C',i3,i,j,n,w(i)
if( nh2.ge.4 .or. (nh1+nh2).ge.9 ) exit ! At most 4 callsigns w/reports
j=j+28
j2=j2+5
endif
enddo
800 if(bSendMsg) then
i1=26
do i=1,26
if(freeTextMsg(i:i).ne.' ') i1=i
enddo
do i=i1+1,26
freeTextMsg(i:i)='.'
enddo
if(i3.eq.3) then
call packtext77(freeTextMsg(1:13),msgbits(74:144))
call packtext77(freeTextMsg(14:26),msgbits(145:215))
elseif(i3.eq.2) then
call packtext77(freeTextMsg(1:13),msgbits(161:231))
call packtext77(freeTextMsg(14:26),msgbits(232:302))
endif
write(msgbits(327:329),'(b3.3)') i3 !Message type i3=2
endif
if(bMoreCQs) msgbits(306:306)='1'
read(msgbits(327:329),'(b3)') i3
if(i3.eq.0) then
do i=1,9
i0=i*28 + 1
read(msgbits(i0:i0+27),'(b28)') n28
if(n28.eq.0) write(msgbits(i0:i0+27),'(b28.28)') NQU1RKS
enddo
else if(i3.eq.3) then
allz=.true.
do i=0,6
i0=i*32 + 74
read(msgbits(i0:i0+31),'(b32)') n32
if(n32.ne.0) allz=.false.
enddo
if(allz) then
do i=0,6
i0=i*32 + 74
write(msgbits(i0:i0+31),'(b32.32)') NQU1RKS
enddo
endif
endif
read(msgbits,1004) xin(0:46)
1004 format(47b7)
mask21=2**21 - 1
n47=47
ncrc21=iand(nhash2(xin,n47,571),mask21) !Compute 21-bit CRC
xin(47)=ncrc21/16384 !First 7 of 21 bits
xin(48)=iand(ncrc21/128,127) !Next 7 bits
xin(49)=iand(ncrc21,127) !Last 7 bits
xin=xin(49:0:-1) !Reverse the symbol order
! NB: CRC is now in first three symbols, fox call in the last four.
return
end subroutine sfox_pack

View File

@ -0,0 +1,55 @@
subroutine sfox_prob(s3,rxdat,rxprob,rxdat2,rxprob2)
! Demodulate the 64-bin spectra for each of 63 symbols in a frame.
! Parameters
! rxdat most reliable symbol value
! rxdat2 second most likely symbol value
! rxprob probability that rxdat was the transmitted value
! rxprob2 probability that rxdat2 was the transmitted value
use sfox_mod
implicit real*8 (a-h,o-z)
real*4 s3(0:NQ-1,0:NN-1)
integer rxdat(0:NN-1),rxprob(0:NN-1),rxdat2(0:NN-1),rxprob2(0:NN-1)
afac=1.1
! scale=255.999
scale=2047.999
! Compute average spectral value
ave=sum(s3)/(NQ*ND)
i1=1 !Silence warning
i2=1
! Compute probabilities for most reliable symbol values
do j=0,NN-1 !Loop over all symbols
s1=-1.e30
psum=0.
do i=0,NQ-1 !Loop over frequency bins
x=min(afac*s3(i,j)/ave,50.d0)
psum=psum+s3(i,j)
if(s3(i,j).gt.s1) then
s1=s3(i,j) !Find max signal+noise power
i1=i !Find most reliable symbol value
endif
enddo
if(psum.eq.0.0) psum=1.e-6 !Guard against zero signal+noise
s2=-1.e30
do i=0,NQ-1
if(i.ne.i1 .and. s3(i,j).gt.s2) then
s2=s3(i,j) !Second largest signal+noise power
i2=i !Bin number for second largest power
endif
enddo
p1=s1/psum !p1, p2 are symbol metrics for ftrsd
p2=s2/psum
rxdat(j)=i1
rxdat2(j)=i2
rxprob(j)=scale*p1 !Scaled probabilities, 0 - 255
rxprob2(j)=scale*p2
enddo
return
end subroutine sfox_prob

View File

@ -0,0 +1,213 @@
subroutine sfox_remove_ft8(dd,npts)
use packjt77
include 'ft8_params.f90'
parameter (MAXCAND=100)
parameter (NP2=2812)
integer itone(NN)
integer iloc(1), ip(1)
integer icos7(0:6)
integer graymap(0:7)
integer*1 cw(174),apmask(174)
integer*1 message91(91)
integer*1 message77(77)
character*77 c77
character*37 msg37
real s8(0:7,NN)
real s2(0:7)
real ss(9)
real candidate(3,MAXCAND)
real sbase(NH1)
real dd(npts)
real bmeta(174),bmetd(174)
real llra(174),llrd(174)
complex cd0(0:3199)
complex csymb(32)
complex ctwk(32)
complex cs(0:7,NN)
data icos7/3,1,4,0,6,5,2/
logical first,newdat
logical one(0:7,0:2)
logical unpk77_success
data first/.true./
data graymap/0,1,3,2,5,6,4,7/
save one,first,twopi
if(first) then
one=.false.
do i=0,7
do j=0,2
if(iand(i,2**j).ne.0) one(i,j)=.true.
enddo
enddo
first=.false.
twopi=8.0*atan(1.0)
endif
fs2=12000.0/NDOWN
dt2=1.0/fs2
nfa=500
nfb=2500
syncmin=1.5
nfqso=750
call sync8(dd,npts,nfa,nfb,syncmin,nfqso,MAXCAND,candidate,ncand,sbase)
newdat=.true.
do icand=1,ncand
f1=candidate(1,icand)
xdt=candidate(2,icand)
xbase=10.0**(0.1*(sbase(nint(f1/3.125))-40.0))
call ft8_downsample(dd,newdat,f1,cd0)
newdat=.false.
i0=nint((xdt+0.5)*fs2)
smax=0.0
do idt=i0-10,i0+10
call sync8d(cd0,idt,ctwk,0,sync)
if(sync.gt.smax) then
smax=sync
ibest=idt
endif
enddo
smax=0.0
delfbest=0.0
do ifr=-5,5 !Search over +/- 2.5 Hz
delf=ifr*0.5
dphi=twopi*delf*dt2
phi=0.0
do i=1,32
ctwk(i)=cmplx(cos(phi),sin(phi))
phi=mod(phi+dphi,twopi)
enddo
call sync8d(cd0,ibest,ctwk,1,sync)
if( sync .gt. smax ) then
smax=sync
delfbest=delf
endif
enddo
f1=f1+delfbest !Improved estimate of DF
call ft8_downsample(dd,newdat,f1,cd0) !Mix f1 to baseband and downsample
smax=0.0
do idt=-4,4 !Search over +/- one quarter symbol
call sync8d(cd0,ibest+idt,ctwk,0,sync)
ss(idt+5)=sync
enddo
smax=maxval(ss)
iloc=maxloc(ss)
ibest=iloc(1)-5+ibest
xdt=(ibest-1)*dt2
sync=smax
do k=1,NN
i1=ibest+(k-1)*32
csymb=cmplx(0.0,0.0)
if( i1.ge.0 .and. i1+31 .le. NP2-1 ) csymb=cd0(i1:i1+31)
call four2a(csymb,32,1,-1,1)
cs(0:7,k)=csymb(1:8)/1e3
s8(0:7,k)=abs(csymb(1:8))
enddo
! sync quality check
is1=0
is2=0
is3=0
do k=1,7
ip=maxloc(s8(:,k))
if(icos7(k-1).eq.(ip(1)-1)) is1=is1+1
ip=maxloc(s8(:,k+36))
if(icos7(k-1).eq.(ip(1)-1)) is2=is2+1
ip=maxloc(s8(:,k+72))
if(icos7(k-1).eq.(ip(1)-1)) is3=is3+1
enddo
! hard sync sum - max is 21
nsync=is1+is2+is3
if(nsync .le. 6) then ! bail out
nbadcrc=1
cycle
endif
nsym=1
nt=2**(3*nsym)
do ihalf=1,2
do k=1,29,nsym
if(ihalf.eq.1) ks=k+7
if(ihalf.eq.2) ks=k+43
amax=-1.0
do i=0,nt-1
i3=iand(i,7)
s2(i)=abs(cs(graymap(i3),ks))
enddo
i32=1+(k-1)*3+(ihalf-1)*87
ibmax=2
do ib=0,ibmax
bm=maxval(s2(0:nt-1),one(0:nt-1,ibmax-ib)) - &
maxval(s2(0:nt-1),.not.one(0:nt-1,ibmax-ib))
if(i32+ib .gt.174) cycle
bmeta(i32+ib)=bm
den=max(maxval(s2(0:nt-1),one(0:nt-1,ibmax-ib)), &
maxval(s2(0:nt-1),.not.one(0:nt-1,ibmax-ib)))
if(den.gt.0.0) then
cm=bm/den
else ! erase it
cm=0.0
endif
bmetd(i32+ib)=cm
enddo
enddo
enddo
call normalizebmet(bmeta,174)
call normalizebmet(bmetd,174)
scalefac=2.83
llra=scalefac*bmeta
llrd=scalefac*bmetd
cw=0
dmin=0
norder=2
maxosd=-1
Keff=91
apmask=0
message91=0
cw=0
call decode174_91(llra,Keff,maxosd,norder,apmask,message91,cw, &
ntype,nharderrors,dmin)
if(nharderrors.ge.0) then
message77=message91(1:77)
else
cycle
endif
if(count(cw.eq.0).eq.174) cycle
write(c77,'(77i1)') message77
read(c77(72:74),'(b3)') n3
read(c77(75:77),'(b3)') i3
if(i3.gt.5 .or. (i3.eq.0.and.n3.gt.6)) cycle
if(i3.eq.0 .and. n3.eq.2) cycle
call unpack77(c77,1,msg37,unpk77_success)
! write(77,*) 'FT8 interference: ',msg37
if(.not.unpk77_success) cycle
! Message structure: S7 D29 S7 D29 S7
itone(1:7)=icos7
itone(36+1:36+7)=icos7
itone(NN-6:NN)=icos7
k=7
do j=1,ND
i=3*j -2
k=k+1
if(j.eq.30) k=k+7
indx=cw(i)*4 + cw(i+1)*2 + cw(i+2)
itone(k)=graymap(indx)
enddo
call subtractft8(dd,itone,f1,xdt,.true.)
! return
enddo
return
end subroutine sfox_remove_ft8

View File

@ -0,0 +1,95 @@
subroutine sfox_remove_tone(c0,fsync)
parameter (NMAX=15*12000)
parameter (NFILT=8000)
complex c0(NMAX)
complex cwindow(15*12000)
complex cref(NMAX)
complex cfilt(NMAX)
real window(-NFILT/2:NFILT/2)
! real endcorrection(NFILT/2+1)
real s(NMAX/4)
integer ipk(1)
logical first
data first/.true./
save cwindow,first,pi
if(first) then
pi=4.0*atan(1.0)
fac=1.0/float(NMAX)
sumw=0.0
do j=-NFILT/2,NFILT/2
window(j)=cos(pi*j/NFILT)**2
sumw=sumw+window(j)
enddo
cwindow=0.
cwindow(1:NFILT+1)=window/sumw
cwindow=cshift(cwindow,NFILT/2+1)
call four2a(cwindow,NMAX,1,-1,1)
cwindow=cwindow*fac ! frequency domain smoothing filter
first=.false.
endif
fsample=12000.0
baud=fsample/1024.0
df=fsample/NMAX
fac=1.0/NMAX
do it=1,1 ! Remove 1 tone, if present
cfilt=fac*c0
call four2a(cfilt,NMAX,1,-1,1) ! fourier transform of input data
iz=NMAX/4
do i=1,iz
s(i)=real(cfilt(i))**2 + aimag(cfilt(i))**2
enddo
ia=nint((fsync-50.0)/df)
ib=nint((fsync+1500.0+50.0)/df)
ipk=maxloc(s(ia:ib))
i0=ipk(1) + ia - 1
nbaud=nint(baud/df)
ia=i0-nbaud
ib=i0+nbaud
s0=0.0
s1=0.0
s2=0.0
do i=ia,ib
s0=s0+s(i)
s1=s1+(i-i0)*s(i)
enddo
delta=s1/s0
i0=nint(i0+delta)
f2=i0*df
ia=i0-nbaud
ib=i0+nbaud
do i=ia,ib
s2=s2 + s(i)*(i-i0)**2
enddo
sigma=sqrt(s2/s0)*df
! write(*,*) 'frequency, spectral width ',f2,sigma
if(sigma .gt. 2.5) exit
! write(*,*) 'remove_tone - frequency: ',f2
dt=1.0/fsample
do i=1, NMAX
arg=2*pi*f2*i*dt
cref(i)=cmplx(cos(arg),sin(arg))
enddo
cfilt=c0*conjg(cref) ! baseband to be filtered
call four2a(cfilt,NMAX,1,-1,1)
cfilt=cfilt*cwindow
call four2a(cfilt,NMAX,1,1,1)
nframe=50*3456
do i=1,nframe
cref(i)=cfilt(i)*cref(i)
c0(i)=c0(i)-cref(i)
enddo
enddo
return
end subroutine sfox_remove_tone

View File

@ -0,0 +1,119 @@
subroutine sfox_unpack(nutc,x,nsnr,f0,dt0,foxcall,notp)
use packjt77
parameter (NQU1RKS=203514677)
integer*1 x(0:49)
integer*8 n58
logical success
character*336 msgbits
character*22 msg(10) !### only msg(1) is used ??? ###
character*13 foxcall,c13
character*10 ssignature
character*4 crpt(5),grid4
character*26 freeTextMsg
character*38 c
logical use_otp
data c/' 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ/'/
ncq=0
if (notp.eq.0) then
use_otp = .FALSE.
else
use_otp = .TRUE.
endif
write(msgbits,1000) x(0:46)
1000 format(47b7.7)
read(msgbits(327:329),'(b6)') i3 !Message type
read(msgbits(1:28),'(b28)') n28 !Standard Fox call
call unpack28(n28,foxcall,success)
if(i3.eq.1) then !Compound Fox callsign
! read(msgbits(87:101),'(b15)') n15
! call unpackgrid(n15,grid4)
! msg(1)='CQ '//trim(foxcall)//' '//grid4
! write(*,1100) nutc,nsnr,dt0,nint(f0),trim(msg(1))
! go to 100
else if(i3.eq.2) then !Up to 4 Hound calls and free text
call unpacktext77(msgbits(161:231),freeTextMsg(1:13))
call unpacktext77(msgbits(232:302),freeTextMsg(14:26))
do i=26,1,-1
if(freeTextMsg(i:i).ne.'.') exit
freeTextMsg(i:i)=' '
enddo
write(*,1100) nutc,nsnr,dt0,nint(f0),freeTextMsg
1100 format(i6.6,i4,f5.1,i5,1x,"~",2x,a)
else if(i3.eq.3) then !CQ FoxCall Grid
read(msgbits(1:58),'(b58)') n58 !FoxCall
do i=11,1,-1
j=mod(n58,38)+1
foxcall(i:i)=c(j:j)
n58=n58/38
enddo
foxcall(12:13)=' '
read(msgbits(59:73),'(b15)') n15
call unpackgrid(n15,grid4)
msg(1)='CQ '//trim(foxcall)//' '//grid4
write(*,1100) nutc,nsnr,dt0,nint(f0),trim(msg(1))
read(msgbits(74:105),'(b32)') n32
if(n32.eq.NQU1RKS) go to 100
call unpacktext77(msgbits(74:144),freeTextMsg(1:13))
call unpacktext77(msgbits(145:215),freeTextMsg(14:26))
do i=26,1,-1
if(freeTextMsg(i:i).ne.'.') exit
freeTextMsg(i:i)=' '
enddo
if(len(trim(freeTextMsg)).gt.0) write(*,1100) nutc,nsnr,dt0,&
nint(f0),freeTextMsg
go to 100
endif
j=281
iz=4 !Max number of reports
if(i3.eq.2) j=141
do i=1,iz !Extract the reports
read(msgbits(j:j+4),'(b5)') n
if(n.eq.31) then
crpt(i)='RR73'
else
write(crpt(i),1006) n-18
1006 format(i3.2)
if(crpt(i)(1:1).eq.' ') crpt(i)(1:1)='+'
endif
j=j+5
enddo
! Unpack Hound callsigns and format user-level messages:
iz=9 !Max number of hound calls
if(i3.eq.2 .or. i3.eq.3) iz=4
do i=1,iz
j=28*i + 1
read(msgbits(j:j+27),'(b28)') n28
call unpack28(n28,c13,success)
if(n28.eq.0 .or. n28.eq.NQU1RKS) cycle
msg(i)=trim(c13)//' '//trim(foxcall)
if(msg(i)(1:3).eq.'CQ ') then
ncq=ncq+1
else
if(i3.eq.2) then
msg(i)=trim(msg(i))//' '//crpt(i)
else
if(i.le.5) msg(i)=trim(msg(i))//' RR73'
if(i.gt.5) msg(i)=trim(msg(i))//' '//crpt(i-5)
endif
endif
if(ncq.le.1 .or. msg(i)(1:3).ne.'CQ ') then
write(*,1100) nutc,nsnr,dt0,nint(f0),trim(msg(i))
endif
enddo
if(msgbits(306:306).eq.'1' .and. ncq.lt.1) then
write(*,1100) nutc,nsnr,dt0,nint(f0),'CQ '//foxcall
endif
100 read(msgbits(307:326),'(b20)') notp
if (use_otp) then
write(ssignature,'(I6.6)') notp
write(*,1100) nutc,nsnr,dt0,nint(f0),'$VERIFY$ '//trim(foxcall)//' '//trim(ssignature)
endif
return
end subroutine sfox_unpack

View File

@ -0,0 +1,40 @@
subroutine sfox_wave(fname)
! Called by WSJT-X when it's time for SuperFox to transmit. Reads array
! itone(1:151) from disk file 'sfox_2.dat' in the writable data directory.
parameter (NWAVE=(160+2)*134400*4) !Max WSJT-X waveform (FST4-1800 at 48kHz)
parameter (NN=151,NSPS=1024)
character*(*) fname
integer itone(151)
real*8 dt,twopi,f0,baud,phi,dphi
common/foxcom/wave(NWAVE)
wave=0.
open(25,file=trim(fname),status='unknown',err=999)
read(25,'(20i4)',err=999,end=999) itone
close(25)
if(itone(1).lt.0 .or. itone(1).gt.128) go to 999
! Generate the SuperFox waveform.
dt=1.d0/48000.d0
twopi=8.d0*atan(1.d0)
f0=750.0d0
phi=0.d0
baud=12000.d0/NSPS
k=0
do j=1,NN
f=f0 + baud*mod(itone(j),128)
dphi=twopi*f*dt
do ii=1,4*NSPS
k=k+1
phi=phi+dphi
xphi=phi
wave(k)=sin(xphi)
enddo
enddo
999 return
end subroutine sfox_wave

View File

@ -0,0 +1,77 @@
subroutine sfox_wave_gfsk()
! Called by WSJT-X when it's time for SuperFox to transmit. Reads array
! itone(1:151) from disk file 'sfox_2.dat' in the writable data directory.
! Generates a GFSK waveform with short ramp-up and ramp-down symbols of
! duration NSPS/BT at the beginning and end of the waveform.
parameter (NWAVE=(160+2)*134400*4) !Max WSJT-X waveform (FST4-1800 at 48kHz)
parameter (NSYM=151,NSPS=1024*4)
parameter (NPTS=(NSYM+2)*NSPS)
parameter (BT=8)
character*40 cmsg2
integer itone(151)
real*8 dt,twopi,f0,phi,dphi_peak
real*8 dphi(0:NPTS-1)
real*8 pulse(3*NSPS)
logical first/.true./
common/foxcom/wave(NWAVE)
common/foxcom3/nslots2,cmsg2(5),itone3(151)
save first,twopi,dt,hmod,dphi_peak,pulse
if(first) then
fsample=48000.0
twopi=8.d0*atan(1.d0)
dt=1.d0/fsample
hmod=1.0
dphi_peak=twopi*hmod/real(NSPS)
do i=1,3*NSPS
tt=(i-1.5*NSPS)/real(NSPS)
pulse(i)=gfsk_pulse(BT,tt)
enddo
first=.false.
endif
wave=0.
itone=itone3
if(itone(1).lt.0 .or. itone(1).gt.128) go to 999
! Generate the SuperFox waveform.
dphi=0.d0
do j=1,NSYM
ib=(j-1)*NSPS
ie=ib+3*NSPS-1
dphi(ib:ie)=dphi(ib:ie)+dphi_peak*pulse(1:3*NSPS)*itone(j)
enddo
dphi(0:2*NSPS-1)=dphi(0:2*NSPS-1)+dphi_peak*itone(1)*pulse(NSPS+1:3*NSPS)
dphi(NSYM*NSPS:(NSYM+2)*NSPS-1)=dphi(NSYM*NSPS:(NSYM+2)*NSPS-1)+dphi_peak*itone(NSYM)*pulse(1:2*NSPS)
phi=0.d0
f0=750.0d0
dphi=dphi+twopi*f0*dt
k=0
do j=1,NSPS*(NSYM+2)-1
k=k+1
wave(k)=sin(phi)
phi=phi+dphi(j)
enddo
! Add raised cosine ramps at the beginning and end of the waveform.
! Since the modulator expects an integral number of symbols, dummy
! symbols are added to the beginning and end of the waveform to
! hold the ramps. All but nramp of the samples in each dummy
! symbol will be zero.
nramp=NSPS/BT
wave(1:NSPS-nramp)=0.0
wave(NSPS-nramp+1:NSPS)=wave(NSPS-nramp+1:NSPS) * &
(1.0-cos(twopi*(/(i,i=0,nramp-1)/)/(2.0*nramp)))/2.0
k1=(NSYM+1)*NSPS+1
wave(k1:k1+nramp-1)=wave(k1:k1+nramp-1) * &
(1.0+cos(twopi*(/(i,i=0,nramp-1)/)/(2.0*nramp)))/2.0
wave(k1+nramp:NPTS)=0.0
999 return
end subroutine sfox_wave_gfsk

164
lib/superfox/sfoxsim.f90 Normal file
View File

@ -0,0 +1,164 @@
program sfoxsim
! - Generate complex-valued SuperFox waveform, cdat.
! - Pass cdat through Watterson channel simulator
! - Add noise to the imaginary part of cdat and write to wav file.
use wavhdr
use qpc_mod
use sfox_mod
type(hdr) h !Header for .wav file
logical*1 bMoreCQs !Include a CQ when space available?
logical*1 bSendMsg !Send a Free text message
integer*2 iwave(NMAX) !Generated i*2 waveform
integer isync(24) !Indices of sync symbols
integer itone(151) !Symbol values, data and sync
integer*1 xin(0:49)
integer*1 y(0:127)
real*4 xnoise(NMAX) !Random noise
real*4 dat(NMAX) !Generated real data
complex cdat(NMAX) !Generated complex waveform
complex crcvd(NMAX) !Signal as received
real, allocatable :: s3(:,:) !Symbol spectra: will be s3(NQ,NN)
integer, allocatable :: msg0(:) !Information symbols
integer, allocatable :: chansym(:) !Encoded data, 7-bit integers
character fname*17,arg*12,channel*2,foxcall*11
character*10 ckey
character*26 text_msg
character*120 line !SuperFox message pieces
character*40 cmsg(5)
data ckey/'0000000000'/
data cmsg/'W0AAA RR73; W5FFF <K1JT> -18', &
'W1BBB RR73; W6GGG <K1JT> -15', &
'W2CCC RR73; W7HHH <K1JT> -12', &
'W3DDD RR73; W8III <K1JT> -09', &
'W4EEE RR73; W9JJJ <K1JT> -06'/
data text_msg/'0123456789ABCDEFGHIJKLMNOP'/
data isync/1,2,4,7,11,16,22,29,37,39,42,43,45,48,52,57,63,70,78,80, &
83,84,86,89/
nargs=iargc()
if(nargs.ne.10) then
print*,'Usage: sfoxsim f0 DT Chan FoxC H1 H2 CQ FT nfiles snr'
print*,'Example: sfoxsim 750 0.0 MM K1JT 5 1 0 0 10 -15'
print*,' f0=0 to dither f0 and DT'
print*,' Chan Channel type AW LQ LM LD MQ MM MD HQ HM HD'
print*,' FoxC Fox callsign'
print*,' key'
print*,' H1 number of Hound calls with RR73'
print*,' H2 number of Hound calls with reports'
print*,' CQ=1 to include a CQ message'
print*,' FT=1 to include a Free Text message'
go to 999
endif
call getarg(1,arg)
read(arg,*) f0
call getarg(2,arg)
read(arg,*) xdt
call getarg(3,channel)
call getarg(4,foxcall)
call getarg(5,arg)
read(arg,*) nh1
call getarg(6,arg)
read(arg,*) nh2
call getarg(7,arg)
read(arg,*) ncq
bMoreCQs=ncq.ne.0
call getarg(8,arg)
read(arg,*) nft
bSendMsg=nft.ne.0
call getarg(9,arg)
read(arg,*) nfiles
call getarg(10,arg)
read(arg,*) snr
fspread=0.0
delay=0.0
fsample=12000.0 !Sample rate (Hz)
call sfox_init(7,127,50,channel,fspread,delay,fsample,24)
txt=(NN+NS)*NSPS/fsample
write(*,1000) f0,xdt,channel,snr
1000 format('sfoxsim: f0= ',f5.1,' dt= ',f4.2,' Channel: ',a2,' snr: ',f5.1,' dB')
! Allocate storage for arrays that depend on code parameters.
allocate(s3(0:NQ-1,0:NN-1))
allocate(msg0(1:KK))
allocate(chansym(0:NN-1))
if(nft.ne.0) then
open(10,file='text_msg.txt',status='old',err=2)
read(10,*) text_msg
endif
2 idum=-1
rms=100.
baud=fsample/nsps !Keying rate, 11.719 baud for nsps=1024
bandwidth_ratio=2500.0/fsample
do i=1,5
cmsg(i)=cmsg(i)(1:19)//trim(foxcall)//cmsg(i)(24:28)
if(i.gt.nh1 .and. i.gt.nh2) then
cmsg(i)=''
elseif(i.gt.nh1) then
cmsg(i)=cmsg(i)(13:18)//trim(foxcall)//cmsg(i)(25:28)
elseif(i.gt.nh2) then
cmsg(i)=cmsg(i)(1:6)//trim(foxcall)//' RR73'
endif
! write(*,*) 'Debug ',cmsg(i)
enddo
if((nh1+nh2).eq.0 .and. bMoreCQs) cmsg(1)='CQ '//trim(foxcall)//' FN20'
! Generate a SuperFox message
nslots=5
call foxgen2(nslots,cmsg,line,foxcall) !Parse old-style Fox messages
call sfox_pack(line,ckey,bMoreCQs,bSendMsg,text_msg,xin)
call qpc_encode(y,xin)
y=cshift(y,1)
y(127)=0
chansym=y(0:126)
sig=sqrt(2*bandwidth_ratio)*10.0**(0.05*snr)
sigr=sqrt(2.)*sig
if(snr.gt.90.0) sig=1.0
do ifile=1,nfiles
xnoise=0.
if(snr.lt.90) then
do i=1,NMAX
xnoise(i)=gran() !Gaussian noise
enddo
endif
f1=f0
if(f0.eq.0.0) then
f1=750 + 20.0*(ran1(idum)-0.5)
xdt=ran1(idum)-0.5
endif
! Generate cdat, the SuperFox waveform
call sfox_gen_gfsk(chansym,f1,isync,itone,cdat)
crcvd=0.
crcvd(1:NMAX)=cshift(cdat(1:NMAX),-nint((0.5+xdt)*fsample))
if(fspread.ne.0 .or. delay.ne.0) call watterson(crcvd,NMAX,NZ,fsample,&
delay,fspread)
dat=aimag(sigr*crcvd(1:NMAX)) + xnoise !Add generated AWGN noise
fac=32767.0
if(snr.ge.90.0) iwave(1:NMAX)=nint(fac*dat(1:NMAX))
if(snr.lt.90.0) iwave(1:NMAX)=nint(rms*dat(1:NMAX))
h=default_header(12000,NMAX)
fname='000000_000001.wav'
nsec=(ifile-1)*30
nhr=nsec/3600
nmin=(nsec-nhr*3600)/60
nsec=mod(nsec,60)
write(fname(8:13),'(3i2.2)') nhr,nmin,nsec
open(10,file=trim(fname),access='stream',status='unknown')
write(10) h,iwave(1:NMAX) !Save the .wav file
close(10)
enddo ! ifile
999 end program sfoxsim

59
lib/superfox/sfrx.f90 Normal file
View File

@ -0,0 +1,59 @@
program sfrx
! Command-line SuperFox decoder
use sfox_mod
use julian
integer*2 iwave(NMAX)
integer ihdr(11)
character*120 fname
include 'gtag.f90'
narg=iargc()
if(narg.lt.1) then
print*,'Usage: sfrx fsync ftol infile [...]'
print*,' sfrx 775 10 240811_102400.wav'
print*,'Reads one or more .wav files and calls SuperFox decoder on each.'
print '(" Git tag: ",z9)',ntag
go to 999
endif
call getarg(1,fname)
read(fname,*,err=1) fsync
call getarg(2,fname)
read(fname,*,err=1) ftol
nfqso=nint(fsync)
ntol=nint(ftol)
1 nf=0
nd=0
nv=0
do ifile=3,narg
call getarg(ifile,fname)
write(72,*) ifile,narg,fname
open(10,file=trim(fname),status='old',access='stream',err=4)
go to 5
4 print*,'Cannot open file ',trim(fname)
go to 999
5 read(10) ihdr,iwave
close(10)
nz=len(trim(fname))
nyymmdd=ihdr(1)
nutc=ihdr(2)
if(fname(nz-3:nz).eq.'.wav') then
read(fname(nz-16:nz-11),*) nyymmdd
read(fname(nz-9:nz-4),*) nutc
endif
call sfrx_sub(nyymmdd,nutc,nfqso,ntol,iwave)
nf=nf+1
enddo
999 end program sfrx

54
lib/superfox/sfrx_sub.f90 Normal file
View File

@ -0,0 +1,54 @@
subroutine sfrx_sub(nyymmdd,nutc,nfqso,ntol,iwave)
use sfox_mod
use julian
integer*2 iwave(NMAX)
integer*8 secday,ntime8
integer*1 xdec(0:49)
character*13 foxcall
complex c0(NMAX) !Complex form of signal as received
real dd(NMAX)
logical crc_ok
data secday/86400/
fsync=nfqso
ftol=ntol
fsample=12000.0
call sfox_init(7,127,50,'no',fspread,delay,fsample,24)
npts=15*12000
if(nyymmdd.eq.-1) then
ntime8=itime8()/30
ntime8=30*ntime8
else
iyr=2000+nyymmdd/10000
imo=mod(nyymmdd/100,100)
iday=mod(nyymmdd,100)
ih=nutc/10000
im=mod(nutc/100,100)
is=mod(nutc,100)
ntime8=secday*(JD(iyr,imo,iday)-2440588) + 3600*ih + 60*im + is
endif
dd=iwave
call sfox_remove_ft8(dd,npts)
call sfox_ana(dd,npts,c0,npts)
call sfox_remove_tone(c0,fsync) ! Needs testing
ndepth=3
dth=0.5
damp=1.0
call qpc_decode2(c0,fsync,ftol, xdec,ndepth,dth,damp,crc_ok, &
snrsync,fbest,tbest,snr)
if(crc_ok) then
nsnr=nint(snr)
nsignature = 1
call sfox_unpack(nutc,xdec,nsnr,fbest-750.0,tbest,foxcall,nsignature)
endif
return
end subroutine sfrx_sub

107
lib/superfox/sftx.f90 Normal file
View File

@ -0,0 +1,107 @@
program sftx
! This program is required in order to create a SuperFox transmission.
! The present version goes through the following steps:
! 1. Read old-style Fox messages from file 'sfox_1.dat' in the WSJT-X
! writable data directory.
! 2. Parse up to NSlots=5 messages to extract MyCall, up to 9 Hound
! calls, and the report or RR73 to be sent to each Hound.
! 3. Assemble and encode a single SuperFox message to produce itone(1:151),
! the array of channel symbol values.
! 4. Write the contents of array itone to file 'sfox_2.dat'.
use qpc_mod
use sfox_mod
character*120 fname !Corrected path for sfox_1.dat
character*120 line !List of SuperFox message pieces
character*40 cmsg(5) !Old-style Fox messages
character*26 freeTextMsg
character*2 arg
character*10 ckey
! character*9 foxkey
character*11 foxcall0,foxcall
logical*1 bMoreCQs,bSendMsg
logical crc_ok
real py(0:127,0:127) !Probabilities for received synbol values
integer*8 n47
integer itone(151) !SuperFox channel-symbol values
integer*1 xin(0:49) !Packed message as 7-bit symbols
integer*1 xdec(0:49) !Decoded message
integer*1 y(0:127) !Encoded symbols as i*1 integers
integer*1 ydec(0:127) !Decoded codeword
integer*1 yy(0:10)
integer chansym0(127) !Transmitted symbols, data only
integer chansym(127) !Received symbols, data only
integer isync(24) !Symbol numbers for sync tones
data isync/1,2,4,7,11,16,22,29,37,39,42,43,45,48,52,57,63,70,78,80, &
83,84,86,89/
include 'gtag.f90'
narg=iargc()
if(narg.ne.3) then
print '(" Git tag: ",z9)',ntag
go to 999
endif
! sftx <message_file_name> <foxcall> <ckey>
call getarg(1,fname)
do i=1,len(trim(fname))
if(fname(i:i).eq.'\\') fname(i:i)='/'
enddo
call getarg(2,foxcall0)
call getarg(3,ckey)
! if((foxkey(foxcall0).ne.ckey).and.(INDEX(ckey,'OTP:').eq.0)) then ! neither kind
! itone=-99
! go to 100
! endif
fsample=12000.0
call sfox_init(7,127,50,'no',fspread,delay,fsample,24)
open(25,file=trim(fname),status='unknown')
do i=1,5
read(25,1000,end=10) cmsg(i)
1000 format(a40)
enddo
i=6
10 close(25)
nslots=i-1
freeTextMsg=' '
bMoreCQs=cmsg(1)(40:40).eq.'1'
bSendMsg=cmsg(nslots)(39:39).eq.'1'
if(bSendMsg) then
freeTextMsg=cmsg(nslots)(1:26)
if(nslots.gt.2) nslots=2
endif
call foxgen2(nslots,cmsg,line,foxcall) !Parse old-style Fox messages
! Pack message information and CRC into xin(0:49)
call sfox_pack(line,ckey,bMoreCQs,bSendMsg,freeTextMsg,xin)
call qpc_encode(y,xin) !Encode the message to 128 symbols
y=cshift(y,1) !Puncture the code by removing y(0)
y(127)=0
chansym0=y(0:126)
! Create the full itone sequence containing both data and sync symbols
j=1
k=0
do i=1,NDS
if(j.le.NS .and. i.eq.isync(j)) then
if(j.lt.NS) j=j+1 !Index for next sync symbol
itone(i)=0 !Insert sync symbol at tone 0
else
k=k+1
itone(i)=chansym0(k) + 1 !Symbol value 0 transmitted as tone 1, etc.
endif
enddo
100 i1=max(index(fname,'sfox_1'),1)
fname(i1:i1+9)='sfox_2.dat'
open(25,file=trim(fname),status='unknown')
write(25,1100) itone
1100 format(20i4)
close(25)
999 end program sftx

65
lib/superfox/sftx_sub.f90 Normal file
View File

@ -0,0 +1,65 @@
subroutine sftx_sub(ckey0)
! This routine is required in order to create a SuperFox transmission.
! The present version goes through the following steps:
! 1. Read old-style Fox messages from file 'sfox_1.dat' in the WSJT-X
! writable data directory.
! 2. Parse up to NSlots=5 messages to extract MyCall, up to 9 Hound
! calls, and the report or RR73 to be sent to each Hound.
! 3. Assemble and encode a single SuperFox message to produce itone(1:151),
! the array of channel symbol values.
! 4. Write the contents of array itone to file 'sfox_2.dat'.
use qpc_mod
use sfox_mod
character*120 line !List of SuperFox message pieces
character*40 cmsg !Old-style Fox messages
character*26 freeTextMsg
character*(*) ckey0
character*10 ckey
character*11 foxcall
logical*1 bMoreCQs,bSendMsg
integer*1 xin(0:49) !Packed message as 7-bit symbols
integer*1 y(0:127) !Encoded symbols as i*1 integers
integer chansym0(127) !Transmitted symbols, data only
integer isync(24) !Symbol numbers for sync tones
common/foxcom3/nslots,cmsg(5),itone(151)
data isync/1,2,4,7,11,16,22,29,37,39,42,43,45,48,52,57,63,70,78,80, &
83,84,86,89/
ckey=ckey0
fsample=12000.0
call sfox_init(7,127,50,'no',fspread,delay,fsample,24)
freeTextMsg=' '
bMoreCQs=cmsg(1)(40:40).eq.'1'
bSendMsg=cmsg(nslots)(39:39).eq.'1'
if(bSendMsg) then
freeTextMsg=cmsg(nslots)(1:26)
if(nslots.gt.4) nslots=4
endif
call foxgen2(nslots,cmsg,line,foxcall) !Parse old-style Fox messages
! Pack message information and CRC into xin(0:49)
call sfox_pack(line,ckey,bMoreCQs,bSendMsg,freeTextMsg,xin)
call qpc_encode(y,xin) !Encode the message to 128 symbols
y=cshift(y,1) !Puncture the code by removing y(0)
y(127)=0
chansym0=y(0:126)
! Create the full itone sequence containing both data and sync symbols
j=1
k=0
do i=1,NDS
if(j.le.NS .and. i.eq.isync(j)) then
if(j.lt.NS) j=j+1 !Index for next sync symbol
itone(i)=0 !Insert sync symbol at tone 0
else
k=k+1
itone(i)=chansym0(k) + 1 !Symbol value 0 transmitted as tone 1, etc.
endif
enddo
end subroutine sftx_sub

View File

@ -0,0 +1,66 @@
Bit packing of SuperFox QPC Messages
-----------------------------------------------------------------------------
The IV3NWV Q-ary Polar Code has parameters (n,k) = (127,50). The last
three 7-bit information symbols convey a 21-bit CRC based on the first
47 symbols. Thus, each Super Fox transmission carries a payload of
47*7=329 bits. On a modern x86 processor the decoder executes in
deterministic time around 5 ms per decode, and always produces a
result. The CRC test rejects all but around 1 in two million false
decodes.
Bit fields are labeled with tags as defined in the QEX article "The
FT4 and FT8 Communication Protocols" by Franke, Somerville, and Taylor
in QEX for July/August 2020, available on the WSJT web site here:
https://wsjt.sourceforge.io/FT4_FT8_QEX.pdf. As one example, the tag
'c28' denotes a standard callsign, which requires 28 bits.
=============================================================================
i3 = 0: Standard message: FoxCall, up to 9 HoundCalls, up to 4 signal
reports, "MoreCQs" flag, a digital signature, and a 3-bit message type.
-----------------------------------------------------------------------------
F H1 H2 H3 H4 H5 H6 H7 H8 H9 R6 R7 R8 R9 U Q D M Type
c28 c28 c28 c28 c28 c28 c28 c28 c28 c28 r5 r5 r5 r5 u5 q1 d20 i3=0 Std Msg
280 300 305 326 329
=============================================================================
i3 = 1: If Fox uses a compound callsign we have space for only 8 Hound calls.
Otherwise like type i3=0.
-----------------------------------------------------------------------------
FC H1 H2 H2 H4 H5 H6 H7 H8 R5 R6 R7 R8 U Q D M
c58 c28 c28 c28 c28 c28 c28 c28 c28 r5 r5 r5 r5 u3 q1 d20 i3=1
58 282 302 305 326 329
=============================================================================
i3 = 2: A free text message with up to 26 characters can be transmitted along
with messages to as many as 4 Hounds conveying either reports or RR73s.
-----------------------------------------------------------------------------
F H1 H2 H3 H4 R1 R2 R3 R4 T T U Q D M Type
c28 c28 c28 c28 c28 r5 r5 r5 r5 t71 t71 u3 q1 d20 i3=2 FT+4H
140 160 302 305 326 329
=============================================================================
i3 = 3: Message "CQ FoxCall Grid <Free text>"
-----------------------------------------------------------------------------
FC G T T U Q D M Type
c58 g15 t71 t71 u90 q1 d20 i3=3 CQ FT
58 73 144 215 305 326 329
=============================================================================
D Digital signature (20 bits)
F Fox call (28 bits)
FC Compound Fox call (58 bits)
G Grid locator (15 bits)
H Hound call (28 bits)
M Message type (3 bits)
Q MoreCQs flag
R Report, (5 bits: -18 to +12 dB, or RR73)
T Free text, up to 26 characters total
U Unused bits
Unused callsign slots are set to the numerical value for "QU1RKS", and
ignored when received. Similarly for unused t71 slots. Unused report
slots are set to 0 (-20 dB). "CQ FoxCall" will be displayed along
with other messages if the "q1" bit is 1.
The SuperFox decoder displays its results with a separate line for each Hound.
Thus, the old-style message "K1ABC RR73; W9XYZ <VP8PJ> -14" becomes
K1ABC VP8PJ RR73
W9XYZ VP8PJ -14

19
lib/superfox/twkfreq2.f90 Normal file
View File

@ -0,0 +1,19 @@
subroutine twkfreq2(c3,c4,npts,fsample,fshift)
! Adjust frequency of complex waveform
complex c3(npts)
complex c4(npts)
complex w,wstep
data twopi/6.283185307/
w=1.0
dphi=fshift*twopi/fsample
wstep=cmplx(cos(dphi),sin(dphi))
do i=1,npts
w=w*wstep
c4(i)=w*c3(i)
enddo
return
end subroutine twkfreq2

View File

@ -9,7 +9,6 @@
#include "pimpl_h.hpp"
class Configuration;
class QDateTime;
class QSqlTableModel;
class QTextStream;
class AD1CCty;

109
otpgenerator.cpp Normal file
View File

@ -0,0 +1,109 @@
#include "otpgenerator.h"
#include <QMessageAuthenticationCode>
#include <QtEndian>
#include <QDateTime>
#include <QtMath>
// FROM https://github.com/RikudouSage/QtOneTimePassword/
/*
MIT License
Copyright (c) 2023 Dominik Chrástecký
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
OTPGenerator::OTPGenerator(QObject *parent)
: QObject{parent}
{
}
QByteArray OTPGenerator::generateHOTP(const QByteArray &rawSecret, quint64 counter, int length)
{
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
counter = qToBigEndian(counter);
#endif
QByteArray data;
data.reserve(8);
for (int i = 7; i >= 0; --i) {
data.append(counter & 0xff);
counter >>= 8;
}
QMessageAuthenticationCode mac(QCryptographicHash::Sha1);
mac.setKey(rawSecret);
mac.addData(data);
QByteArray hmac = mac.result();
int offset = hmac.at(hmac.length() - 1) & 0xf;
quint32 truncatedHash = ((hmac.at(offset) & 0x7f) << 24)
| ((hmac.at(offset + 1) & 0xff) << 16)
| ((hmac.at(offset + 2) & 0xff) << 8)
| (hmac.at(offset + 3) & 0xff);
int modulus = int(qPow(10, length));
return QByteArray::number(truncatedHash % modulus, 10).rightJustified(length, '0');
}
QString OTPGenerator::generateHOTP(const QString &secret, quint64 counter, int length)
{
return generateHOTP(fromBase32(secret), counter, length);
}
QByteArray OTPGenerator::generateTOTP(const QByteArray &rawSecret, int length)
{
const qint64 counter = QDateTime::currentDateTime().toMSecsSinceEpoch() / 30000;
return generateHOTP(rawSecret, counter, length);
}
QString OTPGenerator::generateTOTP(const QString &secret, int length)
{
return generateTOTP(fromBase32(secret), length);
}
QString OTPGenerator::generateTOTP(const QString &secret, QDateTime dt, int length)
{
const qint64 counter = dt.toMSecsSinceEpoch() / 30000;
return generateHOTP(fromBase32(secret), counter, length);
}
QByteArray OTPGenerator::fromBase32(const QString &input)
{
QByteArray result;
result.reserve((input.length() * 5 + 7) / 8);
int buffer = 0;
int bitsLeft = 0;
for (int i = 0; i < input.length(); i++) {
int ch = input[i].toLatin1();
int value;
if (ch >= 'A' && ch <= 'Z')
value = ch - 'A';
else if (ch >= '2' && ch <= '7')
value = 26 + ch - '2';
else
continue;
buffer = (buffer << 5) | value;
bitsLeft += 5;
if (bitsLeft >= 8) {
result.append(buffer >> (bitsLeft - 8));
bitsLeft -= 8;
}
}
return result;
}

50
otpgenerator.h Normal file
View File

@ -0,0 +1,50 @@
#ifndef OTPGENERATOR_H
#define OTPGENERATOR_H
/*
MIT License
Copyright (c) 2023 Dominik Chrástecký
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include <QObject>
#define BASE32_CHARSET "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
class OTPGenerator : public QObject
{
Q_OBJECT
public:
explicit OTPGenerator(QObject *parent = nullptr);
QByteArray generateHOTP(const QByteArray &rawSecret, quint64 counter, int length);
Q_INVOKABLE QString generateHOTP(const QString &secret, quint64 counter, int length);
QByteArray generateTOTP(const QByteArray &rawSecret, int length);
Q_INVOKABLE QString generateTOTP(const QString &secret, QDateTime dt, int length);
Q_INVOKABLE QString generateTOTP(const QString &secret, int length);
private:
QByteArray fromBase32(const QString &input);
signals:
};
#endif // OTPGENERATOR_H

View File

@ -1,7 +1,7 @@
subroutine decode0(dd,ss,savg)
use timer_module, only: timer
parameter (NSMAX=60*96000)
parameter (NSMAX=60*96000,NFFT=32768)
real*4 dd(2,NSMAX),ss(400,NFFT),savg(NFFT)
real*8 fcenter
@ -11,7 +11,7 @@ subroutine decode0(dd,ss,savg)
character mycall*12,hiscall*12,mygrid*6,hisgrid*6,datetime*20
character mycall0*12,hiscall0*12,hisgrid0*6
character*64 result
common/decodes/ndecodes,ncand,nQDecoderDone,nWDecoderBusy, &
common/decodes/ndecodes,ncand2,nQDecoderDone,nWDecoderBusy, &
nWTransmitting,kHzRequested,result(50)
common/npar/fcenter,nutc,fselected,mousedf,mousefqso,nagain, &
ndepth,ndiskdat,ntx60,newdat,nfa,nfb,nfcal,nfshift, &

View File

@ -1,5 +1,5 @@
subroutine getcand2(ss,savg0,nts_q65,nagain,nhsym,ntx30a,ntx30b, &
ntol,f0_selected,bAlso30,cand,ncand)
ntol,f0_selected,bAlso30,cand,ncand2)
! Get candidates for Q65 decodes, based on presence of sync tone.
@ -110,7 +110,7 @@ subroutine getcand2(ss,savg0,nts_q65,nagain,nhsym,ntx30a,ntx30b, &
endif
enddo
ncand=j !Total number of candidates found
ncand2=j !Total number of candidates found
return
end subroutine getcand2

View File

@ -31,7 +31,7 @@ subroutine q65b(nutc,nqd,fcenter,nfcal,nfsample,ikhz,mousedf,ntol, &
character*17 fname
character*64 result,ctmp
character*20 datetime,datetime1
common/decodes/ndecodes,ncand,nQDecoderDone,nWDecoderBusy, &
common/decodes/ndecodes,ncand2,nQDecoderDone,nWDecoderBusy, &
nWTransmitting,kHzRequested,result(50)
common/cacb/ca
data ifile/0/

View File

@ -21,7 +21,7 @@ subroutine q65c
character*6 mygrid,hisgrid
character*20 datetime
character*64 result
common/decodes/ndecodes,ncand,nQDecoderDone,nWDecoderBusy, &
common/decodes/ndecodes,ncand2,nQDecoderDone,nWDecoderBusy, &
nWTransmitting,kHzRequested,result(50)
common/datcom2/dd(2,5760000),ss(400,NFFT),savg(NFFT),nparams0
common/savecom/revision,fname
@ -90,7 +90,7 @@ subroutine q65c
endif
endif
999 return
return
end subroutine q65c
subroutine all_done

View File

@ -35,7 +35,7 @@ subroutine qmapa(dd,ss,savg,newdat,nutc,fcenter,ntol,nfa,nfb, &
type(good_decode) found(MAX_CANDIDATES)
character*64 result
character*20 datetime
common/decodes/ndecodes,ncand,nQDecoderDone,nWDecoderBusy, &
common/decodes/ndecodes,ncand2,nQDecoderDone,nWDecoderBusy, &
nWTransmitting,kHzRequested,result(50)
save
@ -52,7 +52,7 @@ subroutine qmapa(dd,ss,savg,newdat,nutc,fcenter,ntol,nfa,nfb, &
call timer('get_cand',0)
! Get a list of decoding candidates
call getcand2(ss,savg,nts_q65,nagain,nhsym,ntx30a,ntx30b,ntol, &
f0_selected,bAlso30,cand,ncand)
f0_selected,bAlso30,cand,ncand2)
call timer('get_cand',1)
endif
@ -69,11 +69,11 @@ subroutine qmapa(dd,ss,savg,newdat,nutc,fcenter,ntol,nfa,nfb, &
call timer('fftbig ',1)
if(nagain.ge.2) then
ncand=1
ncand2=1
fqso=fselected
endif
do icand=1,ncand !Attempt to decode each candidate
do icand=1,ncand2 !Attempt to decode each candidate
tsec=sec_midn() - tsec0
if(ndiskdat.eq.0) then
! No more realtime decode attempts if it's nearly too late, already

View File

@ -318,7 +318,7 @@
<message>
<location filename="../widgets/colorhighlighting.ui" line="150"/>
<source>New Call</source>
<translation>Nou Indicatiu</translation>
<translation>Indicatiu nou</translation>
</message>
<message>
<location filename="../widgets/colorhighlighting.ui" line="157"/>
@ -2238,12 +2238,12 @@ Error(%2): %3</translation>
<message>
<location filename="../widgets/mainwindow.ui" line="1683"/>
<source>Maximum drift rate in units of symbol rate per transmission.</source>
<translation type="unfinished"></translation>
<translation>Taxa de deriva màxima en unitats de taxa de símbols per transmissió.</translation>
</message>
<message>
<location filename="../widgets/mainwindow.ui" line="1686"/>
<source>Max Drift </source>
<translation type="unfinished"></translation>
<translation>Deriva màxima </translation>
</message>
<message>
<location filename="../widgets/mainwindow.ui" line="2604"/>
@ -3658,7 +3658,7 @@ La llista es pot mantenir a la configuració (F2).</translation>
<message>
<location filename="../widgets/mainwindow.ui" line="3429"/>
<source>Quick-Start Guide to WSJT-X 2.5.0 and MAP65 3.0</source>
<translation type="unfinished"></translation>
<translation>Guia d&apos;inici ràpid de WSJT-X 2.5.0 i MAP65 3.0</translation>
</message>
<message>
<location filename="../widgets/mainwindow.cpp" line="258"/>
@ -3685,7 +3685,7 @@ La llista es pot mantenir a la configuració (F2).</translation>
<message>
<location filename="../widgets/mainwindow.cpp" line="523"/>
<source>Scanned ADIF log, %1 worked-before records created. CTY: %2</source>
<translation>Log ADIF escanejat, %1 funcionava abans de la creació de registres</translation>
<translation>Log ADIF escanejat, %1 funcionava abans de la creació de registres. CTY: %2</translation>
</message>
<message>
<location filename="../widgets/mainwindow.cpp" line="631"/>

View File

@ -2480,17 +2480,17 @@ Error(%2): %3</translation>
<message>
<location filename="../widgets/mainwindow.ui" line="1683"/>
<source>Maximum drift rate in units of symbol rate per transmission.</source>
<translation type="unfinished"></translation>
<translation>Tasa de deriva máxima en unidades de tasa de símbolos por transmisión.</translation>
</message>
<message>
<location filename="../widgets/mainwindow.ui" line="1686"/>
<source>Max Drift </source>
<translation type="unfinished"></translation>
<translation>Máxima deriva </translation>
</message>
<message>
<location filename="../widgets/mainwindow.ui" line="3416"/>
<source>Quick-Start Guide to Q65</source>
<translation>Guía de inicio rápido de Q65</translation>
<translation>Guía de inicio rápido de Q65 (inglés)</translation>
</message>
<message>
<location filename="../widgets/mainwindow.ui" line="3424"/>
@ -2500,7 +2500,7 @@ Error(%2): %3</translation>
<message>
<location filename="../widgets/mainwindow.ui" line="3429"/>
<source>Quick-Start Guide to WSJT-X 2.5.0 and MAP65 3.0</source>
<translation type="unfinished"></translation>
<translation>Guía de inicio rápido para WSJT-X 2.5.0 y MAP65 3.0 (inglés)</translation>
</message>
<message>
<location filename="../widgets/mainwindow.ui" line="1588"/>
@ -2703,7 +2703,7 @@ Amarillo cuando esta muy bajo.</translation>
<message>
<location filename="../widgets/mainwindow.ui" line="876"/>
<source>&amp;Lookup</source>
<translation>Buscar</translation>
<translation>Buscar (&amp;L)</translation>
</message>
<message>
<location filename="../widgets/mainwindow.ui" line="988"/>
@ -3044,7 +3044,7 @@ No está disponible para los titulares de indicativo no estándar.</translatorco
<location filename="../widgets/mainwindow.ui" line="1215"/>
<source>Best S+P</source>
<translatorcomment>El mejor S+P </translatorcomment>
<translation>Mejor S+P (&amp;B)</translation>
<translation>Mejor S+P</translation>
</message>
<message>
<location filename="../widgets/mainwindow.ui" line="1225"/>
@ -3181,7 +3181,8 @@ Cuando no está marcado, puede verse los resultados de la calibración.</transla
Double click to toggle the use of the Tx1 message to start a QSO with a station (not allowed for type 1 compound call holders)</source>
<translatorcomment>Enviar este mensaje en el siguiente intervalo de transmisión.
Haz doble clic para alternar el uso del mensaje TX1 para iniciar un QSO con una estación (no está permitido para titulares de indicativos compuestos de tipo 1).</translatorcomment>
<translation>Enviar este mensaje en el siguiente intervalo de TX. Doble clic para alternar el uso del mensaje TX1 para iniciar un QSO con una estación (no está permitido para titulares de indicativos compuestos de tipo 1).</translation>
<translation>Enviar este mensaje en el siguiente intervalo de TX.
Doble clic para alternar el uso del mensaje TX1 para iniciar un QSO con una estación (no está permitido para titulares de indicativos compuestos de tipo 1).</translation>
</message>
<message>
<location filename="../widgets/mainwindow.ui" line="1826"/>
@ -3246,7 +3247,8 @@ Haz doble clic para alternar el uso del mensaje TX1 para iniciar un QSO con una
<location filename="../widgets/mainwindow.ui" line="2035"/>
<source>Send this message in next Tx interval
Double-click to reset to the standard 73 message</source>
<translation>Enviar este mensaje en el siguiente intervalo de TX. Doble clic para restablecer el mensaje 73 estándar.</translation>
<translation>Enviar este mensaje en el siguiente intervalo de TX.
Doble clic para restablecer el mensaje 73 estándar.</translation>
</message>
<message>
<location filename="../widgets/mainwindow.ui" line="2045"/>
@ -3300,7 +3302,9 @@ RR73 messages should only be used when you are reasonably confident that no mess
<translatorcomment>Cambia a este mensaje de TX AHORA.
Haz doble clic para alternar entre los mensajes RRR y RR73 en TX4 (no está permitido para titulares de indicativos compuestos de tipo 2).
Los mensajes RR73 solo deben usarse cuando esté razonablemente seguro de que no se requerirán repeticiones de mensajes.</translatorcomment>
<translation>Cambiar a este mensaje de TX AHORA. Doble clic para alternar entre los mensajes RRR y RR73 en TX4 (no está permitido para titulares de indicativos compuestos de tipo 2). Los mensajes RR73 solo deben usarse cuando esté razonablemente seguro de que no se requerirán repeticiones de mensajes.</translation>
<translation>Cambiar a este mensaje de TX AHORA.
Doble clic para alternar entre los mensajes RRR y RR73 en TX4 (no está permitido para titulares de indicativos compuestos de tipo 2).
Los mensajes RR73 solo deben usarse cuando esté razonablemente seguro de que no se requerirán repeticiones de mensajes.</translation>
</message>
<message>
<location filename="../widgets/mainwindow.ui" line="1951"/>
@ -3397,7 +3401,7 @@ predefinida. La lista se puede modificar en &quot;Ajustes&quot; (F2).</translati
<message>
<location filename="../widgets/mainwindow.ui" line="3358"/>
<source>Quick-Start Guide to FST4 and FST4W</source>
<translation>Guía de inicio rápido a FST4 y FST4W</translation>
<translation>Guía de inicio rápido a FST4 y FST4W (inglés)</translation>
</message>
<message>
<location filename="../widgets/mainwindow.ui" line="3384"/>
@ -4239,7 +4243,7 @@ predefinida. La lista se puede modificar en &quot;Ajustes&quot; (F2).</translati
<location filename="../widgets/mainwindow.cpp" line="523"/>
<source>Scanned ADIF log, %1 worked-before records created. CTY: %2</source>
<translatorcomment>Log ADIF escaneado, %1 funcionaba antes de la creación de registros</translatorcomment>
<translation>Log ADIF escaneado, %1 registros trabajados B4 creados</translation>
<translation>Log ADIF escaneado, %1 registros trabajados B4 creados. CTY: %2</translation>
</message>
<message>
<location filename="../widgets/mainwindow.cpp" line="631"/>
@ -4912,7 +4916,7 @@ ya está en CALL3.TXT, ¿desea reemplazarlo?</translation>
<location filename="../widgets/mainwindow.cpp" line="8593"/>
<source>Confirm Reset</source>
<translatorcomment>Confirmar reinicio</translatorcomment>
<translation>Confirmar restablecer</translation>
<translation>Confirmar borrado</translation>
</message>
<message>
<location filename="../widgets/mainwindow.cpp" line="6841"/>
@ -5354,7 +5358,7 @@ Error(%2): %3</translation>
<message>
<location filename="../SampleDownloader.cpp" line="112"/>
<source>Base URL for samples:</source>
<translation>Enlace para muestras:</translation>
<translation>Enlace de las muestras:</translation>
</message>
<message>
<location filename="../SampleDownloader.cpp" line="113"/>
@ -5483,7 +5487,7 @@ Error(%2): %3</translation>
<message>
<location filename="../Audio/soundout.cpp" line="95"/>
<source>No audio output device configured.</source>
<translation>No hay dispositivo de salida de audio configurado</translation>
<translation>No hay dispositivo de salida de audio configurado.</translation>
</message>
<message>
<location filename="../Audio/soundout.cpp" line="184"/>
@ -5974,7 +5978,7 @@ Error(%2): %3</translation>
<location filename="../Configuration.ui" line="237"/>
<source>Font...</source>
<translatorcomment>Letra...</translatorcomment>
<translation>Tipo de letra para la aplicación</translation>
<translation>Tipo de letra para la aplicación..</translation>
</message>
<message>
<location filename="../Configuration.ui" line="244"/>
@ -6220,7 +6224,7 @@ período de silencio cuando se ha realizado la decodificación.</translation>
<message>
<location filename="../Configuration.ui" line="628"/>
<source>4800</source>
<translation></translation>
<translation>4800</translation>
</message>
<message>
<location filename="../Configuration.ui" line="633"/>
@ -6832,7 +6836,7 @@ Haz clic derecho para acciones específicas del artículo.
Clic, Mayúsculas+Clic y, CTRL+Clic para seleccionar elementos.</translatorcomment>
<translation>Arrastre y suelte elementos para reorganizar el orden
Clic derecho para acciones específicas del elemento.
Clic, Mayús+Clic y CTRL+Clic para seleccionar elementos.</translation>
Clic, Mayús+Clic y CTRL+Clic para seleccionar elementos</translation>
</message>
<message>
<location filename="../Configuration.ui" line="1709"/>
@ -7559,7 +7563,7 @@ Clic derecho para insertar y eliminar opciones.</translation>
<location filename="../Configuration.ui" line="2970"/>
<source>Waterfall spectra</source>
<translatorcomment>Espectros de la cascada</translatorcomment>
<translation>Espectro de la cascada (waterfall)</translation>
<translation>Cascada (Waterfall)</translation>
</message>
<message>
<location filename="../Configuration.ui" line="2976"/>

View File

@ -89,7 +89,7 @@
</message>
<message>
<location filename="../widgets/activeStations.ui" line="141"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Check tis box to show only stations ready to be called.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Check this box to show only stations ready to be called.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Seleziona questa casella per visualizzare solo le stazioni pronte per essere chiamate.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -40,6 +40,26 @@ void ActiveStations::changeFont (QFont const& font)
updateGeometry ();
}
void ActiveStations::clearStations() {
m_textbuffer.clear();
m_decodes_by_frequency.clear();
}
void ActiveStations::addLine(QString line) {
QString m_textbuffer = "";
// "012700 -1 0.2 210 ~ KJ7COA JA2HGF -14"
unsigned freq = line.mid(16, 4).toUInt();
m_decodes_by_frequency[freq] = line;
// show them in frequency order
QMap<int, QString>::const_iterator i = m_decodes_by_frequency.constBegin();
m_textbuffer.clear();
while (i != m_decodes_by_frequency.constEnd()) {
m_textbuffer.append(i.value());
++i;
}
this->displayRecentStations(m_mode, m_textbuffer);
}
void ActiveStations::read_settings ()
{
SettingsGroup group {settings_, "ActiveStations"};
@ -60,8 +80,7 @@ void ActiveStations::write_settings ()
settings_->setValue("WantedOnly",ui->cbWantedOnly->isChecked());
}
void ActiveStations::displayRecentStations(QString mode, QString const& t)
{
void ActiveStations::setupUi(QString mode) {
if(mode!=m_mode) {
m_mode=mode;
ui->cbReadyOnly->setText(" Ready only");
@ -71,24 +90,37 @@ void ActiveStations::displayRecentStations(QString mode, QString const& t)
ui->cbReadyOnly->setText("* CQ only");
} else if(m_mode=="Q65-pileup") {
ui->header_label2->setText(" N Freq Call Grid El Age(h)");
ui->cbWantedOnly->setText(QCoreApplication::translate("ActiveStations", "Wanted only", nullptr));
} else if(m_mode=="Fox Mode" || m_mode=="SuperFox Mode" ) {
ui->header_label2->setText(" UTC dB DT Freq " + tr("Message"));
ui->cbWantedOnly->setText(QCoreApplication::translate("ActiveStations", "My call only", nullptr));
this->setClickOK(true);
} else {
ui->header_label2->setText(" N Call Grid Az S/N Freq Tx Age Pts");
ui->label->setText("Rate:");
ui->cbWantedOnly->setText(QCoreApplication::translate("ActiveStations", "Wanted only", nullptr));
}
bool b=(m_mode.left(3)=="Q65");
ui->bandChanges->setVisible(!b);
ui->cbReadyOnly->setVisible(m_mode!="Q65-pileup");
ui->cbWantedOnly->setVisible(m_mode!="Q65-pileup");
ui->label_2->setVisible(!b);
ui->label_3->setVisible(!b);
ui->score->setVisible(!b);
ui->sbMaxRecent->setVisible(!b);
bool is_fox_mode =(m_mode=="Fox Mode");
ui->bandChanges->setVisible(!b && !is_fox_mode);
ui->cbReadyOnly->setVisible(m_mode != "Q65-pileup" && !is_fox_mode);
ui->cbWantedOnly->setVisible(m_mode != "Q65-pileup"); // this is used for "My call only" in Fox mode
ui->label_2->setVisible(!b && !is_fox_mode);
ui->label_3->setVisible(!b && !is_fox_mode);
ui->score->setVisible(!b && !is_fox_mode);
ui->sbMaxRecent->setVisible(!b && !is_fox_mode);
b=(m_mode!="Q65-pileup");
b=(m_mode!="Q65-pileup" && !is_fox_mode);
ui->sbMaxAge->setVisible(b);
ui->label->setVisible(b);
ui->rate->setVisible(b);
}
}
void ActiveStations::displayRecentStations(QString mode, QString const& t)
{
setupUi(mode);
bool bClickOK=m_clickOK;
m_clickOK=false;
ui->RecentStationsPlainTextEdit->setPlainText(t);
@ -143,7 +175,10 @@ void ActiveStations::on_textEdit_clicked()
if(text!="") {
int nline=text.left(2).toInt();
if(QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier)) nline=-nline;
emit callSandP(nline);
if (!m_mode.contains("fox", Qt::CaseInsensitive))
emit callSandP(nline);
else
emit queueActiveWindowHound(text);
}
}
}

Some files were not shown because too many files have changed in this diff Show More