diff --git a/CMakeLists.txt b/CMakeLists.txt index bff2f543a..3e7e816bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -322,14 +322,12 @@ set (wsjtx_CXXSRCS set (wsjt_CXXSRCS lib/crc10.cpp - lib/crc12.cpp lib/crc13.cpp lib/crc14.cpp ) # deal with a GCC v6 UB error message set_source_files_properties ( lib/crc10.cpp - lib/crc12.cpp lib/crc13.cpp lib/crc14.cpp PROPERTIES COMPILE_FLAGS -fpermissive) @@ -384,13 +382,11 @@ set (wsjt_FSRCS lib/ft8/baseline.f90 lib/bpdecode40.f90 lib/bpdecode128_90.f90 - lib/ft8/bpdecode174.f90 lib/ft8/bpdecode174_91.f90 lib/baddata.f90 lib/calibrate.f90 lib/ccf2.f90 lib/ccf65.f90 - lib/ft8/chkcrc12a.f90 lib/ft8/chkcrc13a.f90 lib/ft8/chkcrc14a.f90 lib/chkcall.f90 @@ -508,7 +504,6 @@ set (wsjt_FSRCS lib/msk144sim.f90 lib/mskrtd.f90 lib/77bit/my_hash.f90 - lib/ft8/osd174.f90 lib/wsprd/osdwspr.f90 lib/ft8/osd174_91.f90 lib/pctile.f90 diff --git a/doc/common/links.adoc b/doc/common/links.adoc index 754b93570..158400854 100644 --- a/doc/common/links.adoc +++ b/doc/common/links.adoc @@ -67,7 +67,7 @@ d). Edit lines as needed. Keeping them in alphabetic order help see dupes. :fmt_group: https://groups.yahoo.com/neo/groups/FMT-nuts/info[FMT Group] :fmt_k5cm: http://www.k5cm.com/[FMT Event Info] :fmt_wspr: http://www.physics.princeton.edu/pulsar/K1JT/FMT_User.pdf[Accurate Frequency Measurements with your WSPR Setup] -:ft8_tips: http://www.physics.princeton.edu/pulsar/K1JT/FT8_Operating_Tips.pdf[here] +:ft8_tips: http://www.g4ifb.com/FT8_Hinson_tips_for_HF_DXers.pdf[FT8 Operating Guide] :ft8_DXped: http://physics.princeton.edu/pulsar/k1jt/FT8_DXpedition_Mode.pdf[FT8 DXpedition Mode] :gnu_gpl: http://www.gnu.org/licenses/gpl-3.0.txt[GNU General Public License] :homepage: http://physics.princeton.edu/pulsar/K1JT/[WSJT Home Page] diff --git a/doc/user_guide/en/images/colors.png b/doc/user_guide/en/images/colors.png index 7c6813529..8845ada9c 100644 Binary files a/doc/user_guide/en/images/colors.png and b/doc/user_guide/en/images/colors.png differ diff --git a/doc/user_guide/en/new_features.adoc b/doc/user_guide/en/new_features.adoc index aed97945a..2ed33ffd2 100644 --- a/doc/user_guide/en/new_features.adoc +++ b/doc/user_guide/en/new_features.adoc @@ -13,7 +13,7 @@ added to _WSJT-X_ since Version 1.9.1: * Integration with N1MM+ and WriteLog for contesting -* IMproved support for compound and nonstandard callsigns +* Improved support for compound and nonstandard callsigns * Nearly equal (or better) sensitivity compared to old protocols diff --git a/doc/user_guide/en/settings-colors.adoc b/doc/user_guide/en/settings-colors.adoc index 3a67d228a..fc2f748bc 100644 --- a/doc/user_guide/en/settings-colors.adoc +++ b/doc/user_guide/en/settings-colors.adoc @@ -1,7 +1,10 @@ image::colors.png[align="center",alt="Colors Screen"] -_WSJT-X_ uses colors to highlight decoded messages containing -information of particular interest. Check the box to select any -that interest you. Drag any line up or down to raise or lower -its logical priority. Right-click any line to select a new -foreground or background color. +_WSJT-X_ uses colors to highlight decoded CQ messages of particular +interest. Check the box *Show DXCC, grid, and worked-before status* +on the *Settings | General* tab, and any boxes of interest to you on +the *Colors* tab. You can drag any line up or down to raise or lower +its logical priority. Right-click any line to set a new foreground or +background color. Foreground and background colors are applied +separately, and careful choices of foreground, background, and +priority can provide two indications of worked-before status. diff --git a/doc/user_guide/en/settings-frequencies.adoc b/doc/user_guide/en/settings-frequencies.adoc index bebf6a313..5cdf26dbd 100644 --- a/doc/user_guide/en/settings-frequencies.adoc +++ b/doc/user_guide/en/settings-frequencies.adoc @@ -4,9 +4,9 @@ image::settings-frequencies.png[align="center",alt="Frequency Screen"] _Working Frequencies_: By default the *Working Frequencies* table -contains a list of frequencies conventionally used for modes JT4, JT9, -JT65, MSK144, WSPR, and Echo. Conventions may change with time or -by user preference; you can modify the frequency table as desired. +contains a list of frequencies conventionally used for modes FT8, JT4, +JT9, JT65, MSK144, WSPR, and Echo. Conventions may change with time +or by user preference; you can modify the frequency table as desired. - To change an existing entry, double-click to edit it, type a desired frequency in MHz or select from the drop down list of options, then diff --git a/doc/user_guide/en/tutorial-example3.adoc b/doc/user_guide/en/tutorial-example3.adoc index 3f2ee03f6..931067760 100644 --- a/doc/user_guide/en/tutorial-example3.adoc +++ b/doc/user_guide/en/tutorial-example3.adoc @@ -46,13 +46,14 @@ when double-clicking. NOTE: To avoid QRM from competing callers, it is frequently desirable to answer a CQ on a different frequency from that of the CQing station. The same is true when you tail-end another QSO. Choose a Tx -frequency that appears to be not in use. +frequency that appears to be not in use. You might want to check the +box *Hold Tx Freq*. NOTE: Keyboard shortcuts *Shift+F11* and *Shift+F12* provide an easy way to move your Tx frequency down or up in 60 Hz steps. -NOTE: Further helpful tips on FT8 operating procedures are available -{ft8_tips}. Thanks to ZL2IFB! +NOTE: An online {ft8_tips} by ZL2IFB offers many helpful tips on +operating procedures. .FT8 DXpedition Mode: diff --git a/doc/user_guide/en/wsjtx-main.adoc b/doc/user_guide/en/wsjtx-main.adoc index aa4a9aa57..704ad74c4 100644 --- a/doc/user_guide/en/wsjtx-main.adoc +++ b/doc/user_guide/en/wsjtx-main.adoc @@ -1,5 +1,5 @@ // This is a comment line, anything with // is ignored at process time. -= _WSJT-X_ User Guide += _WSJT-X 2.0_ User Guide Joseph H Taylor, Jr, K1JT :revnumber: {VERSION} // For web-pages, adding :badges: is ok, but is a security issue for diff --git a/lib/crc.f90 b/lib/crc.f90 index a36e364f9..f0cd17e32 100644 --- a/lib/crc.f90 +++ b/lib/crc.f90 @@ -34,22 +34,6 @@ module crc integer (c_int), value :: length end function crc13_check - function crc12 (data, length) bind (C, name="crc12") - use, intrinsic :: iso_c_binding, only: c_short, c_ptr, c_int - implicit none - integer (c_short) :: crc12 - type (c_ptr), value :: data - integer (c_int), value :: length - end function crc12 - - function crc12_check (data, length) bind (C, name="crc12_check") - use, intrinsic :: iso_c_binding, only: c_bool, c_ptr, c_int - implicit none - logical (c_bool) :: crc12_check - type (c_ptr), value :: data - integer (c_int), value :: length - end function crc12_check - function crc10 (data, length) bind (C, name="crc10") use, intrinsic :: iso_c_binding, only: c_short, c_ptr, c_int implicit none diff --git a/lib/crc12.cpp b/lib/crc12.cpp deleted file mode 100644 index 44e50fe71..000000000 --- a/lib/crc12.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include - -extern "C" -{ - short crc12 (unsigned char const * data, int length); - bool crc12_check (unsigned char const * data, int length); -} - -#define POLY 0xc06 - -#ifdef BOOST_NO_CXX11_CONSTEXPR -#define TRUNCATED_POLYNOMIAL POLY -#else -namespace -{ - unsigned long constexpr TRUNCATED_POLYNOMIAL = POLY; -} -#endif - -// assumes CRC is last 16 bits of the data and is set to zero -// caller should assign the returned CRC into the message in big endian byte order -short crc12 (unsigned char const * data, int length) -{ - return boost::augmented_crc<12, TRUNCATED_POLYNOMIAL> (data, length); -} - -bool crc12_check (unsigned char const * data, int length) -{ - return !boost::augmented_crc<12, TRUNCATED_POLYNOMIAL> (data, length); -} diff --git a/lib/decoder.f90 b/lib/decoder.f90 index e1fb40436..730c59d12 100644 --- a/lib/decoder.f90 +++ b/lib/decoder.f90 @@ -470,8 +470,8 @@ contains real, intent(in) :: dt real, intent(in) :: freq character(len=37), intent(in) :: decoded - character c1*12,c2*12,g2*4,w*4,ctmp*12 - integer i0,i1,i2,i3,i4,i5,i6,n30,nwrap + character c1*12,c2*12,g2*4,w*4 + integer i0,i1,i2,i3,i4,i5,n30,nwrap integer, intent(in) :: nap real, intent(in) :: qual character*2 annot diff --git a/lib/fmtmsg.f90 b/lib/fmtmsg.f90 index 2ceb81554..81789e2a9 100644 --- a/lib/fmtmsg.f90 +++ b/lib/fmtmsg.f90 @@ -1,16 +1,16 @@ subroutine fmtmsg(msg,iz) - character*22 msg + character*(*) msg ! Convert all letters to upper case - iz=22 - do i=1,22 + iz=len(msg) + do i=1,iz if(msg(i:i).ge.'a' .and. msg(i:i).le.'z') & msg(i:i)= char(ichar(msg(i:i))+ichar('A')-ichar('a')) if(msg(i:i).ne.' ') iz=i enddo - do iter=1,5 !Collapse multiple blanks into one + do iter=1,37 !Collapse multiple blanks into one ib2=index(msg(1:iz),' ') if(ib2.lt.1) go to 100 msg=msg(1:ib2)//msg(ib2+2:) diff --git a/lib/ft8/bpdecode174.f90 b/lib/ft8/bpdecode174.f90 deleted file mode 100644 index 9442cc4a1..000000000 --- a/lib/ft8/bpdecode174.f90 +++ /dev/null @@ -1,401 +0,0 @@ -subroutine bpdecode174(llr,apmask,maxiterations,decoded,cw,nharderror,iter) -! -! A log-domain belief propagation decoder for the (174,87) code. -! -integer, parameter:: N=174, K=87, M=N-K -integer*1 codeword(N),cw(N),apmask(N) -integer colorder(N) -integer*1 decoded(K) -integer Nm(7,M) ! 5, 6, or 7 bits per check -integer Mn(3,N) ! 3 checks per bit -integer synd(M) -real tov(3,N) -real toc(7,M) -real tanhtoc(7,M) -real zn(N) -real llr(N) -real Tmn -integer nrw(M) - -data colorder/ & - 0, 1, 2, 3, 30, 4, 5, 6, 7, 8, 9, 10, 11, 32, 12, 40, 13, 14, 15, 16,& - 17, 18, 37, 45, 29, 19, 20, 21, 41, 22, 42, 31, 33, 34, 44, 35, 47, 51, 50, 43,& - 36, 52, 63, 46, 25, 55, 27, 24, 23, 53, 39, 49, 59, 38, 48, 61, 60, 57, 28, 62,& - 56, 58, 65, 66, 26, 70, 64, 69, 68, 67, 74, 71, 54, 76, 72, 75, 78, 77, 80, 79,& - 73, 83, 84, 81, 82, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,& - 100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,& - 120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,& - 140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,& - 160,161,162,163,164,165,166,167,168,169,170,171,172,173/ - -data Mn/ & - 1, 25, 69, & - 2, 5, 73, & - 3, 32, 68, & - 4, 51, 61, & - 6, 63, 70, & - 7, 33, 79, & - 8, 50, 86, & - 9, 37, 43, & - 10, 41, 65, & - 11, 14, 64, & - 12, 75, 77, & - 13, 23, 81, & - 15, 16, 82, & - 17, 56, 66, & - 18, 53, 60, & - 19, 31, 52, & - 20, 67, 84, & - 21, 29, 72, & - 22, 24, 44, & - 26, 35, 76, & - 27, 36, 38, & - 28, 40, 42, & - 30, 54, 55, & - 34, 49, 87, & - 39, 57, 58, & - 45, 74, 83, & - 46, 62, 80, & - 47, 48, 85, & - 59, 71, 78, & - 1, 50, 53, & - 2, 47, 84, & - 3, 25, 79, & - 4, 6, 14, & - 5, 7, 80, & - 8, 34, 55, & - 9, 36, 69, & - 10, 43, 83, & - 11, 23, 74, & - 12, 17, 44, & - 13, 57, 76, & - 15, 27, 56, & - 16, 28, 29, & - 18, 19, 59, & - 20, 40, 63, & - 21, 35, 52, & - 22, 54, 64, & - 24, 62, 78, & - 26, 32, 77, & - 30, 72, 85, & - 31, 65, 87, & - 33, 39, 51, & - 37, 48, 75, & - 38, 70, 71, & - 41, 42, 68, & - 45, 67, 86, & - 46, 81, 82, & - 49, 66, 73, & - 58, 60, 66, & - 61, 65, 85, & - 1, 14, 21, & - 2, 13, 59, & - 3, 67, 82, & - 4, 32, 73, & - 5, 36, 54, & - 6, 43, 46, & - 7, 28, 75, & - 8, 33, 71, & - 9, 49, 76, & - 10, 58, 64, & - 11, 48, 68, & - 12, 19, 45, & - 15, 50, 61, & - 16, 22, 26, & - 17, 72, 80, & - 18, 40, 55, & - 20, 35, 51, & - 23, 25, 34, & - 24, 63, 87, & - 27, 39, 74, & - 29, 78, 83, & - 30, 70, 77, & - 31, 69, 84, & - 22, 37, 86, & - 38, 41, 81, & - 42, 44, 57, & - 47, 53, 62, & - 52, 56, 79, & - 60, 75, 81, & - 1, 39, 77, & - 2, 16, 41, & - 3, 31, 54, & - 4, 36, 78, & - 5, 45, 65, & - 6, 57, 85, & - 7, 14, 49, & - 8, 21, 46, & - 9, 15, 72, & - 10, 20, 62, & - 11, 17, 71, & - 12, 34, 47, & - 13, 68, 86, & - 18, 23, 43, & - 19, 64, 73, & - 24, 48, 79, & - 25, 70, 83, & - 26, 80, 87, & - 27, 32, 40, & - 28, 56, 69, & - 29, 63, 66, & - 30, 42, 50, & - 33, 37, 82, & - 35, 60, 74, & - 38, 55, 84, & - 44, 52, 61, & - 51, 53, 72, & - 58, 59, 67, & - 47, 56, 76, & - 1, 19, 37, & - 2, 61, 75, & - 3, 8, 66, & - 4, 60, 84, & - 5, 34, 39, & - 6, 26, 53, & - 7, 32, 57, & - 9, 52, 67, & - 10, 12, 15, & - 11, 51, 69, & - 13, 14, 65, & - 16, 31, 43, & - 17, 20, 36, & - 18, 80, 86, & - 21, 48, 59, & - 22, 40, 46, & - 23, 33, 62, & - 24, 30, 74, & - 25, 42, 64, & - 27, 49, 85, & - 28, 38, 73, & - 29, 44, 81, & - 35, 68, 70, & - 41, 63, 76, & - 45, 49, 71, & - 50, 58, 87, & - 48, 54, 83, & - 13, 55, 79, & - 77, 78, 82, & - 1, 2, 24, & - 3, 6, 75, & - 4, 56, 87, & - 5, 44, 53, & - 7, 50, 83, & - 8, 10, 28, & - 9, 55, 62, & - 11, 29, 67, & - 12, 33, 40, & - 14, 16, 20, & - 15, 35, 73, & - 17, 31, 39, & - 18, 36, 57, & - 19, 46, 76, & - 21, 42, 84, & - 22, 34, 59, & - 23, 26, 61, & - 25, 60, 65, & - 27, 64, 80, & - 30, 37, 66, & - 32, 45, 72, & - 38, 51, 86, & - 41, 77, 79, & - 43, 56, 68, & - 47, 74, 82, & - 40, 52, 78, & - 54, 61, 71, & - 46, 58, 69/ - -data Nm/ & - 1, 30, 60, 89, 118, 147, 0, & - 2, 31, 61, 90, 119, 147, 0, & - 3, 32, 62, 91, 120, 148, 0, & - 4, 33, 63, 92, 121, 149, 0, & - 2, 34, 64, 93, 122, 150, 0, & - 5, 33, 65, 94, 123, 148, 0, & - 6, 34, 66, 95, 124, 151, 0, & - 7, 35, 67, 96, 120, 152, 0, & - 8, 36, 68, 97, 125, 153, 0, & - 9, 37, 69, 98, 126, 152, 0, & - 10, 38, 70, 99, 127, 154, 0, & - 11, 39, 71, 100, 126, 155, 0, & - 12, 40, 61, 101, 128, 145, 0, & - 10, 33, 60, 95, 128, 156, 0, & - 13, 41, 72, 97, 126, 157, 0, & - 13, 42, 73, 90, 129, 156, 0, & - 14, 39, 74, 99, 130, 158, 0, & - 15, 43, 75, 102, 131, 159, 0, & - 16, 43, 71, 103, 118, 160, 0, & - 17, 44, 76, 98, 130, 156, 0, & - 18, 45, 60, 96, 132, 161, 0, & - 19, 46, 73, 83, 133, 162, 0, & - 12, 38, 77, 102, 134, 163, 0, & - 19, 47, 78, 104, 135, 147, 0, & - 1, 32, 77, 105, 136, 164, 0, & - 20, 48, 73, 106, 123, 163, 0, & - 21, 41, 79, 107, 137, 165, 0, & - 22, 42, 66, 108, 138, 152, 0, & - 18, 42, 80, 109, 139, 154, 0, & - 23, 49, 81, 110, 135, 166, 0, & - 16, 50, 82, 91, 129, 158, 0, & - 3, 48, 63, 107, 124, 167, 0, & - 6, 51, 67, 111, 134, 155, 0, & - 24, 35, 77, 100, 122, 162, 0, & - 20, 45, 76, 112, 140, 157, 0, & - 21, 36, 64, 92, 130, 159, 0, & - 8, 52, 83, 111, 118, 166, 0, & - 21, 53, 84, 113, 138, 168, 0, & - 25, 51, 79, 89, 122, 158, 0, & - 22, 44, 75, 107, 133, 155, 172, & - 9, 54, 84, 90, 141, 169, 0, & - 22, 54, 85, 110, 136, 161, 0, & - 8, 37, 65, 102, 129, 170, 0, & - 19, 39, 85, 114, 139, 150, 0, & - 26, 55, 71, 93, 142, 167, 0, & - 27, 56, 65, 96, 133, 160, 174, & - 28, 31, 86, 100, 117, 171, 0, & - 28, 52, 70, 104, 132, 144, 0, & - 24, 57, 68, 95, 137, 142, 0, & - 7, 30, 72, 110, 143, 151, 0, & - 4, 51, 76, 115, 127, 168, 0, & - 16, 45, 87, 114, 125, 172, 0, & - 15, 30, 86, 115, 123, 150, 0, & - 23, 46, 64, 91, 144, 173, 0, & - 23, 35, 75, 113, 145, 153, 0, & - 14, 41, 87, 108, 117, 149, 170, & - 25, 40, 85, 94, 124, 159, 0, & - 25, 58, 69, 116, 143, 174, 0, & - 29, 43, 61, 116, 132, 162, 0, & - 15, 58, 88, 112, 121, 164, 0, & - 4, 59, 72, 114, 119, 163, 173, & - 27, 47, 86, 98, 134, 153, 0, & - 5, 44, 78, 109, 141, 0, 0, & - 10, 46, 69, 103, 136, 165, 0, & - 9, 50, 59, 93, 128, 164, 0, & - 14, 57, 58, 109, 120, 166, 0, & - 17, 55, 62, 116, 125, 154, 0, & - 3, 54, 70, 101, 140, 170, 0, & - 1, 36, 82, 108, 127, 174, 0, & - 5, 53, 81, 105, 140, 0, 0, & - 29, 53, 67, 99, 142, 173, 0, & - 18, 49, 74, 97, 115, 167, 0, & - 2, 57, 63, 103, 138, 157, 0, & - 26, 38, 79, 112, 135, 171, 0, & - 11, 52, 66, 88, 119, 148, 0, & - 20, 40, 68, 117, 141, 160, 0, & - 11, 48, 81, 89, 146, 169, 0, & - 29, 47, 80, 92, 146, 172, 0, & - 6, 32, 87, 104, 145, 169, 0, & - 27, 34, 74, 106, 131, 165, 0, & - 12, 56, 84, 88, 139, 0, 0, & - 13, 56, 62, 111, 146, 171, 0, & - 26, 37, 80, 105, 144, 151, 0, & - 17, 31, 82, 113, 121, 161, 0, & - 28, 49, 59, 94, 137, 0, 0, & - 7, 55, 83, 101, 131, 168, 0, & - 24, 50, 78, 106, 143, 149, 0/ - -data nrw/ & - 6,6,6,6,6,6,6,6,6,6, & - 6,6,6,6,6,6,6,6,6,6, & - 6,6,6,6,6,6,6,6,6,6, & - 6,6,6,6,6,6,6,6,6,7, & - 6,6,6,6,6,7,6,6,6,6, & - 6,6,6,6,6,7,6,6,6,6, & - 7,6,5,6,6,6,6,6,6,5, & - 6,6,6,6,6,6,6,6,6,6, & - 5,6,6,6,5,6,6/ - -ncw=3 - -decoded=0 -toc=0 -tov=0 -tanhtoc=0 -! initialize messages to checks -do j=1,M - do i=1,nrw(j) - toc(i,j)=llr((Nm(i,j))) - enddo -enddo - -ncnt=0 - -do iter=0,maxiterations - -! Update bit log likelihood ratios (tov=0 in iteration 0). - do i=1,N - if( apmask(i) .ne. 1 ) then - zn(i)=llr(i)+sum(tov(1:ncw,i)) - else - zn(i)=llr(i) - endif - enddo - -! Check to see if we have a codeword (check before we do any iteration). - cw=0 - where( zn .gt. 0. ) cw=1 - ncheck=0 - do i=1,M - synd(i)=sum(cw(Nm(1:nrw(i),i))) - if( mod(synd(i),2) .ne. 0 ) ncheck=ncheck+1 -! if( mod(synd(i),2) .ne. 0 ) write(*,*) 'check ',i,' unsatisfied' - enddo -! write(*,*) 'number of unsatisfied parity checks ',ncheck - if( ncheck .eq. 0 ) then ! we have a codeword - reorder the columns and return it - codeword=cw(colorder+1) - decoded=codeword(M+1:N) - nerr=0 - do i=1,N - if( (2*cw(i)-1)*llr(i) .lt. 0.0 ) nerr=nerr+1 - enddo - nharderror=nerr - return - endif - - if( iter.gt.0 ) then ! this code block implements an early stopping criterion -! if( iter.gt.10000 ) then ! this code block implements an early stopping criterion - nd=ncheck-nclast - if( nd .lt. 0 ) then ! # of unsatisfied parity checks decreased - ncnt=0 ! reset counter - else - ncnt=ncnt+1 - endif -! write(*,*) iter,ncheck,nd,ncnt - if( ncnt .ge. 5 .and. iter .ge. 10 .and. ncheck .gt. 15) then - nharderror=-1 - return - endif - endif - nclast=ncheck - -! Send messages from bits to check nodes - do j=1,M - do i=1,nrw(j) - ibj=Nm(i,j) - toc(i,j)=zn(ibj) - do kk=1,ncw ! subtract off what the bit had received from the check - if( Mn(kk,ibj) .eq. j ) then - toc(i,j)=toc(i,j)-tov(kk,ibj) - endif - enddo - enddo - enddo - -! send messages from check nodes to variable nodes - do i=1,M - tanhtoc(1:7,i)=tanh(-toc(1:7,i)/2) - enddo - - do j=1,N - do i=1,ncw - ichk=Mn(i,j) ! Mn(:,j) are the checks that include bit j - Tmn=product(tanhtoc(1:nrw(ichk),ichk),mask=Nm(1:nrw(ichk),ichk).ne.j) - call platanh(-Tmn,y) -! y=atanh(-Tmn) - tov(i,j)=2*y - enddo - enddo - -enddo -nharderror=-1 -return -end subroutine bpdecode174 diff --git a/lib/ft8/chkcrc12a.f90 b/lib/ft8/chkcrc12a.f90 deleted file mode 100644 index fc4291907..000000000 --- a/lib/ft8/chkcrc12a.f90 +++ /dev/null @@ -1,24 +0,0 @@ -subroutine chkcrc12a(decoded,nbadcrc) - - use crc - integer*1 decoded(87) - integer*1, target:: i1Dec8BitBytes(11) - character*87 cbits - -! Write decoded bits into cbits: 75-bit message plus 12-bit CRC - write(cbits,1000) decoded -1000 format(87i1) - read(cbits,1001) i1Dec8BitBytes -1001 format(11b8) - read(cbits,1002) ncrc12 !Received CRC12 -1002 format(75x,b12) - - i1Dec8BitBytes(10)=iand(i1Dec8BitBytes(10),128+64+32) - i1Dec8BitBytes(11)=0 - icrc12=crc12(c_loc(i1Dec8BitBytes),11) !CRC12 computed from 75 msg bits - - nbadcrc=1 - if(ncrc12.eq.icrc12) nbadcrc=0 - - return -end subroutine chkcrc12a diff --git a/lib/ft8/foxgen.f90 b/lib/ft8/foxgen.f90 index 806b20648..7492a6f70 100644 --- a/lib/ft8/foxgen.f90 +++ b/lib/ft8/foxgen.f90 @@ -20,7 +20,6 @@ subroutine foxgen() character*37 msg,msgsent integer itone(79) integer*1 msgbits(77),msgbits2 - integer*1, target:: i1Msg8BitBytes(11) integer*1, target:: mycall real x(NFFT) real*8 dt,twopi,f0,fstep,dfreq,phi,dphi diff --git a/lib/ft8/ft8apset.f90 b/lib/ft8/ft8apset.f90 index 2fac41969..15eddd057 100644 --- a/lib/ft8/ft8apset.f90 +++ b/lib/ft8/ft8apset.f90 @@ -4,7 +4,6 @@ subroutine ft8apset(mycall12,hiscall12,apsym) character*37 msg character*12 mycall12,hiscall12,hiscall integer apsym(58) - integer*1 msgbits(77) logical nohiscall if(len(trim(mycall12)).eq.0) then diff --git a/lib/ft8/ft8b.f90 b/lib/ft8/ft8b.f90 index 0f075aad2..5db48341a 100644 --- a/lib/ft8/ft8b.f90 +++ b/lib/ft8/ft8b.f90 @@ -7,12 +7,10 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, & use packjt77 include 'ft8_params.f90' parameter(NP2=2812) - character*37 msg37,msgsent37 + character*37 msg37 character*12 mycall12,hiscall12,hiscall12_0 character*77 c77 - character*6 mycall6,hiscall6,c1,c2 character*13 c13 - character*87 cbits real a(5) real s8(0:7,NN) real s2(0:511),s2l(0:511) @@ -28,7 +26,6 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, & integer nappasses(0:5) !Number of decoding passes to use for each QSO state integer naptypes(0:5,4) ! (nQSOProgress, decoding pass) maximum of 4 passes for now integer ncontest,ncontest0 - integer*1, target:: i1hiscall(12) logical one(0:511,0:8) integer graymap(0:7) complex cd0(0:3199) diff --git a/lib/ft8/ft8code.f90 b/lib/ft8/ft8code.f90 index c20aaaa38..cbafd34be 100644 --- a/lib/ft8/ft8code.f90 +++ b/lib/ft8/ft8code.f90 @@ -8,14 +8,11 @@ program ft8code include 'ft8_testmsg.f90' parameter (NWAVE=NN*NSPS) - character*77 c77 character*37 msg,msgsent character*9 comment - character bad*1,msgtype*16 - character*91 cbits + character bad*1,msgtype*18 integer itone(NN) integer*1 msgbits(77) - logical unpk77_success ! Get command-line argument(s) nargs=iargc() @@ -69,10 +66,10 @@ program ft8code if(msg.ne.msgsent) bad="*" if(n3.ge.0) then write(*,1020) imsg,msg,msgsent,bad,i3,n3,msgtype,comment -1020 format(i2,'.',1x,a37,1x,a37,1x,a1,2x,i1,'.',i1,1x,a16,1x,a9) +1020 format(i2,'.',1x,a37,1x,a37,1x,a1,2x,i1,'.',i1,1x,a18,1x,a9) else write(*,1022) imsg,msg,msgsent,bad,i3,msgtype,comment -1022 format(i2,'.',1x,a37,1x,a37,1x,a1,2x,i1,'.',1x,1x,a16,1x,a9) +1022 format(i2,'.',1x,a37,1x,a37,1x,a1,2x,i1,'.',1x,1x,a18,1x,a9) endif enddo diff --git a/lib/ft8/ft8sim.f90 b/lib/ft8/ft8sim.f90 index a1de4061f..e43850daf 100644 --- a/lib/ft8/ft8sim.f90 +++ b/lib/ft8/ft8sim.f90 @@ -9,7 +9,7 @@ program ft8sim parameter (NWAVE=NN*NSPS) type(hdr) h !Header for .wav file character arg*12,fname*17 - character msg37*37,msgsent37*37,msg40*40 + character msg37*37,msgsent37*37 character c77*77 complex c0(0:NMAX-1) complex c(0:NMAX-1) diff --git a/lib/ft8/osd174.f90 b/lib/ft8/osd174.f90 deleted file mode 100644 index 45d7faa4b..000000000 --- a/lib/ft8/osd174.f90 +++ /dev/null @@ -1,365 +0,0 @@ -subroutine osd174(llr,apmask,ndeep,decoded,cw,nhardmin,dmin) -! -! An ordered-statistics decoder for the (174,87) code. -! -include "ldpc_174_87_params.f90" - -integer*1 apmask(N),apmaskr(N) -integer*1 gen(K,N) -integer*1 genmrb(K,N),g2(N,K) -integer*1 temp(K),m0(K),me(K),mi(K),misub(K),e2sub(N-K),e2(N-K),ui(N-K) -integer*1 r2pat(N-K) -integer indices(N),nxor(N) -integer*1 cw(N),ce(N),c0(N),hdec(N) -integer*1 decoded(K) -integer indx(N) -real llr(N),rx(N),absrx(N) -logical first,reset -data first/.true./ -save first,gen - -if( first ) then ! fill the generator matrix - gen=0 - do i=1,M - do j=1,22 - read(g(i)(j:j),"(Z1)") istr - do jj=1, 4 - irow=(j-1)*4+jj - if( btest(istr,4-jj) ) gen(irow,i)=1 - enddo - enddo - enddo - do irow=1,K - gen(irow,M+irow)=1 - enddo -first=.false. -endif - -! Re-order received vector to place systematic msg bits at the end. -rx=llr(colorder+1) -apmaskr=apmask(colorder+1) - -! Hard decisions on the received word. -hdec=0 -where(rx .ge. 0) hdec=1 - -! Use magnitude of received symbols as a measure of reliability. -absrx=abs(rx) -call indexx(absrx,N,indx) - -! Re-order the columns of the generator matrix in order of decreasing reliability. -do i=1,N - genmrb(1:K,i)=gen(1:K,indx(N+1-i)) - indices(i)=indx(N+1-i) -enddo - -! Do gaussian elimination to create a generator matrix with the most reliable -! received bits in positions 1:K in order of decreasing reliability (more or less). -do id=1,K ! diagonal element indices - do icol=id,K+20 ! The 20 is ad hoc - beware - iflag=0 - if( genmrb(id,icol) .eq. 1 ) then - iflag=1 - if( icol .ne. id ) then ! reorder column - temp(1:K)=genmrb(1:K,id) - genmrb(1:K,id)=genmrb(1:K,icol) - genmrb(1:K,icol)=temp(1:K) - itmp=indices(id) - indices(id)=indices(icol) - indices(icol)=itmp - endif - do ii=1,K - if( ii .ne. id .and. genmrb(ii,id) .eq. 1 ) then - genmrb(ii,1:N)=ieor(genmrb(ii,1:N),genmrb(id,1:N)) - endif - enddo - exit - endif - enddo -enddo - -g2=transpose(genmrb) - -! The hard decisions for the K MRB bits define the order 0 message, m0. -! Encode m0 using the modified generator matrix to find the "order 0" codeword. -! Flip various combinations of bits in m0 and re-encode to generate a list of -! codewords. Return the member of the list that has the smallest Euclidean -! distance to the received word. - -hdec=hdec(indices) ! hard decisions from received symbols -m0=hdec(1:K) ! zero'th order message -absrx=absrx(indices) -rx=rx(indices) -apmaskr=apmaskr(indices) - -call mrbencode(m0,c0,g2,N,K) -nxor=ieor(c0,hdec) -nhardmin=sum(nxor) -dmin=sum(nxor*absrx) - -cw=c0 -ntotal=0 -nrejected=0 - -if(ndeep.eq.0) goto 998 ! norder=0 -if(ndeep.gt.5) ndeep=5 -if( ndeep.eq. 1) then - nord=1 - npre1=0 - npre2=0 - nt=40 - ntheta=12 -elseif(ndeep.eq.2) then - nord=1 - npre1=1 - npre2=0 - nt=40 - ntheta=12 -elseif(ndeep.eq.3) then - nord=1 - npre1=1 - npre2=1 - nt=40 - ntheta=12 - ntau=14 -elseif(ndeep.eq.4) then - nord=2 - npre1=1 - npre2=0 - nt=40 - ntheta=12 - ntau=19 -elseif(ndeep.eq.5) then - nord=2 - npre1=1 - npre2=1 - nt=40 - ntheta=12 - ntau=19 -endif - -do iorder=1,nord - misub(1:K-iorder)=0 - misub(K-iorder+1:K)=1 - iflag=K-iorder+1 - do while(iflag .ge.0) - if(iorder.eq.nord .and. npre1.eq.0) then - iend=iflag - else - iend=1 - endif - do n1=iflag,iend,-1 - mi=misub - mi(n1)=1 - if(any(iand(apmaskr(1:K),mi).eq.1)) cycle - ntotal=ntotal+1 - me=ieor(m0,mi) - if(n1.eq.iflag) then - call mrbencode(me,ce,g2,N,K) - e2sub=ieor(ce(K+1:N),hdec(K+1:N)) - e2=e2sub - nd1Kpt=sum(e2sub(1:nt))+1 - d1=sum(ieor(me(1:K),hdec(1:K))*absrx(1:K)) - else - e2=ieor(e2sub,g2(K+1:N,n1)) - nd1Kpt=sum(e2(1:nt))+2 - endif - if(nd1Kpt .le. ntheta) then - call mrbencode(me,ce,g2,N,K) - nxor=ieor(ce,hdec) - if(n1.eq.iflag) then - dd=d1+sum(e2sub*absrx(K+1:N)) - else - dd=d1+ieor(ce(n1),hdec(n1))*absrx(n1)+sum(e2*absrx(K+1:N)) - endif - if( dd .lt. dmin ) then - dmin=dd - cw=ce - nhardmin=sum(nxor) - nd1Kptbest=nd1Kpt - endif - else - nrejected=nrejected+1 - endif - enddo -! Get the next test error pattern, iflag will go negative -! when the last pattern with weight iorder has been generated. - call nextpat(misub,k,iorder,iflag) - enddo -enddo - -if(npre2.eq.1) then - reset=.true. - ntotal=0 - do i1=K,1,-1 - do i2=i1-1,1,-1 - ntotal=ntotal+1 - mi(1:ntau)=ieor(g2(K+1:K+ntau,i1),g2(K+1:K+ntau,i2)) - call boxit(reset,mi(1:ntau),ntau,ntotal,i1,i2) - enddo - enddo - - ncount2=0 - ntotal2=0 - reset=.true. -! Now run through again and do the second pre-processing rule - misub(1:K-nord)=0 - misub(K-nord+1:K)=1 - iflag=K-nord+1 - do while(iflag .ge.0) - me=ieor(m0,misub) - call mrbencode(me,ce,g2,N,K) - e2sub=ieor(ce(K+1:N),hdec(K+1:N)) - do i2=0,ntau - ntotal2=ntotal2+1 - ui=0 - if(i2.gt.0) ui(i2)=1 - r2pat=ieor(e2sub,ui) -778 continue - call fetchit(reset,r2pat(1:ntau),ntau,in1,in2) - if(in1.gt.0.and.in2.gt.0) then - ncount2=ncount2+1 - mi=misub - mi(in1)=1 - mi(in2)=1 - if(sum(mi).lt.nord+npre1+npre2.or.any(iand(apmaskr(1:K),mi).eq.1)) cycle - me=ieor(m0,mi) - call mrbencode(me,ce,g2,N,K) - nxor=ieor(ce,hdec) - dd=sum(nxor*absrx) - if( dd .lt. dmin ) then - dmin=dd - cw=ce - nhardmin=sum(nxor) - endif - goto 778 - endif - enddo - call nextpat(misub,K,nord,iflag) - enddo -endif - -998 continue -! Re-order the codeword to place message bits at the end. -cw(indices)=cw -hdec(indices)=hdec -decoded=cw(M+1:N) -cw(colorder+1)=cw ! put the codeword back into received-word order -return -end subroutine osd174 - -subroutine mrbencode(me,codeword,g2,N,K) -integer*1 me(K),codeword(N),g2(N,K) -! fast encoding for low-weight test patterns - codeword=0 - do i=1,K - if( me(i) .eq. 1 ) then - codeword=ieor(codeword,g2(1:N,i)) - endif - enddo -return -end subroutine mrbencode - -subroutine nextpat(mi,k,iorder,iflag) - integer*1 mi(k),ms(k) -! generate the next test error pattern - ind=-1 - do i=1,k-1 - if( mi(i).eq.0 .and. mi(i+1).eq.1) ind=i - enddo - if( ind .lt. 0 ) then ! no more patterns of this order - iflag=ind - return - endif - ms=0 - ms(1:ind-1)=mi(1:ind-1) - ms(ind)=1 - ms(ind+1)=0 - if( ind+1 .lt. k ) then - nz=iorder-sum(ms) - ms(k-nz+1:k)=1 - endif - mi=ms - do i=1,k ! iflag will point to the lowest-index 1 in mi - if(mi(i).eq.1) then - iflag=i - exit - endif - enddo - return -end subroutine nextpat - -subroutine boxit(reset,e2,ntau,npindex,i1,i2) - integer*1 e2(1:ntau) - integer indexes(4000,2),fp(0:525000),np(4000) - logical reset - common/boxes/indexes,fp,np - - if(reset) then - patterns=-1 - fp=-1 - np=-1 - sc=-1 - indexes=-1 - reset=.false. - endif - - indexes(npindex,1)=i1 - indexes(npindex,2)=i2 - ipat=0 - do i=1,ntau - if(e2(i).eq.1) then - ipat=ipat+ishft(1,ntau-i) - endif - enddo - - ip=fp(ipat) ! see what's currently stored in fp(ipat) - if(ip.eq.-1) then - fp(ipat)=npindex - else - do while (np(ip).ne.-1) - ip=np(ip) - enddo - np(ip)=npindex - endif - return -end subroutine boxit - -subroutine fetchit(reset,e2,ntau,i1,i2) - integer indexes(4000,2),fp(0:525000),np(4000) - integer lastpat - integer*1 e2(ntau) - logical reset - common/boxes/indexes,fp,np - save lastpat,inext - - if(reset) then - lastpat=-1 - reset=.false. - endif - - ipat=0 - do i=1,ntau - if(e2(i).eq.1) then - ipat=ipat+ishft(1,ntau-i) - endif - enddo - index=fp(ipat) - - if(lastpat.ne.ipat .and. index.gt.0) then ! return first set of indices - i1=indexes(index,1) - i2=indexes(index,2) - inext=np(index) - elseif(lastpat.eq.ipat .and. inext.gt.0) then - i1=indexes(inext,1) - i2=indexes(inext,2) - inext=np(inext) - else - i1=-1 - i2=-1 - inext=-1 - endif - lastpat=ipat - return -end subroutine fetchit - diff --git a/lib/msk144code.f90 b/lib/msk144code.f90 index 6c8963d01..81a185159 100644 --- a/lib/msk144code.f90 +++ b/lib/msk144code.f90 @@ -5,7 +5,7 @@ program msk144code use packjt77 character*77 c77 - character msg*37,msgsent*37,decoded,bad*1,msgtype*16 + character msg*37,msgsent*37,decoded,bad*1,msgtype*18 integer*4 i4tone(144) include 'msk144_testmsg.f90' @@ -61,13 +61,13 @@ program msk144code if(msg.ne.msgsent) bad="*" if(i3.eq.0.and.n3.ge.0) then write(*,1020) imsg,msg,msgsent,bad,i3,n3,msgtype -1020 format(i2,'.',1x,a37,1x,a37,1x,a1,2x,i1,'.',i1,1x,a16) +1020 format(i2,'.',1x,a37,1x,a37,1x,a1,2x,i1,'.',i1,1x,a18) elseif(i3.ge.1) then write(*,1022) imsg,msg,msgsent,bad,i3,msgtype -1022 format(i2,'.',1x,a37,1x,a37,1x,a1,2x,i1,'.',1x,1x,a16) +1022 format(i2,'.',1x,a37,1x,a37,1x,a1,2x,i1,'.',1x,1x,a18) elseif(i3.lt.0) then write(*,1024) imsg,msg,msgsent,bad,msgtype -1024 format(i2,'.',1x,a37,1x,a37,1x,a1,6x,a16) +1024 format(i2,'.',1x,a37,1x,a37,1x,a1,6x,a18) endif enddo diff --git a/lib/msk144decodeframe.f90 b/lib/msk144decodeframe.f90 index de039aadc..19da84937 100644 --- a/lib/msk144decodeframe.f90 +++ b/lib/msk144decodeframe.f90 @@ -100,7 +100,7 @@ subroutine msk144decodeframe(c,softbits,msgreceived,nsuccess) if( nharderror .ge. 0 .and. nharderror .lt. 18 ) then nsuccess=1 write(c77,'(77i1)') decoded77 - read(c77(72:77),'(2b3)'),n3,i3 + read(c77(72:77),'(2b3)') n3,i3 if( (i3.eq.0.and.(n3.eq.1 .or. n3.eq.3 .or. n3.eq.4 .or. n3.gt.5)) .or. i3.eq.3 .or. i3.gt.4 ) then nsuccess=0 else diff --git a/lib/msk144sim.f90 b/lib/msk144sim.f90 index 7b2a8a00b..3472d8827 100644 --- a/lib/msk144sim.f90 +++ b/lib/msk144sim.f90 @@ -5,7 +5,6 @@ program msk144sim real pings(0:NMAX-1) real waveform(0:NMAX-1) character arg*8,msg*37,msgsent*37,fname*40 - character*77 c77 real wave(0:NMAX-1) !Simulated received waveform real*8 twopi,freq,phi,dphi0,dphi1,dphi type(hdr) h !Header for .wav file diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index b265ad7ba..d54b8f1c9 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -955,17 +955,12 @@ void MainWindow::not_GA_warning_message () QDateTime timeout=QDateTime(QDate(2018,12,31)); MessageBox::critical_message (this, - "This version of WSJT-X is a beta-level Release Candidate.\n\n" - "IMPORTANT: WSJT-X 2.0 cannot communicate with other\n" - "stations using the FT8 or MSK144 protocols in WSJT-X v1.9.1\n" - "or earlier.\n\n" - "On December 10, 2018, the new FT8 and MSK144 protocols\n" - "will become the standard. Everyone should upgrade to\n" - "WSJT-X 2.0 by January 1, 2019.\n\n" - "On-the-air use carries an obligation to report problems\n" - "to the WSJT Development group and to upgrade to a GA\n" - "(General Availability) release when it becomes available.\n\n" - "This version cannot be used after December 31, 2018.\n\n"); + "IMPORTANT: New protocols for the FT8 and MSK144 modes\n" + "became the world-wide standards on December 10, 2019.\n\n" + "WSJT-X 2.0 cannot communicate in these modes with other\n" + "stations using WSJT-X v1.9.1 or earlier.\n\n" + "Please help by urging everyone to upgrade to WSJT-X 2.0\n" + "no later than January 1, 2019.\n"); if(now.daysTo(timeout) < 0) Q_EMIT finished(); } @@ -4777,29 +4772,17 @@ void MainWindow::abortQSO() ui->txrb6->setChecked(true); } -bool MainWindow::stdCall(QString w) +bool MainWindow::stdCall(QString const& w) { - int n=w.trimmed().length(); -//Treat /P and /R as special cases: strip them off for this test. - if(w.mid(n-2,2)=="/P") w=w.left(n-2); - if(w.mid(n-2,2)=="/R") w=w.left(n-2); - n=w.trimmed().length(); - if(n>6) return false; //Callsigns longer than 6 chars are nonstandard - w=w.toUpper(); - int i1=99; // index of first letter - int i2=-1; // index of last digit - for(int i=0; i="A" and c<="Z")) i1=i; - if(c>="0" and c<="9") i2=i; - } - if(i1!=0 and i1!=1) return false; //One of the firat two characters must be a letter - if(i2>2) return false; //No digits allowed after the 3rd character - for(int i=i2+1; i"Z") return false; //Anything after final digit must be a letter - } - return true; + static QRegularExpression standard_call_re { + R"( + ^\s* # optional leading spaces + ( [A-Z]{0,2} | [A-Z][0-9] | [0-9][A-Z] ) # part 1 + ( [0-9][A-Z]{0,3} ) # part 2 + (/R | /P)? # optional suffix + \s*$ # optional trailing spaces + )", QRegularExpression::CaseInsensitiveOption | QRegularExpression::ExtendedPatternSyntaxOption}; + return standard_call_re.match (w).hasMatch (); } void MainWindow::genStdMsgs(QString rpt, bool unconditional) diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index 6a2527440..428ea6890 100644 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -305,7 +305,7 @@ private slots: void not_GA_warning_message (); void checkMSK144ContestType(); int setTxMsg(int n); - bool stdCall(QString w); + bool stdCall(QString const& w); private: Q_SIGNAL void initializeAudioOutputStream (QAudioDeviceInfo,