From 37e05f6074c99cd8131010af5c3117c8f731392a Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Fri, 31 Jul 2020 14:15:49 -0500 Subject: [PATCH 01/18] Set unpk77_success=.false. for messages with i3=0 and n3>6. --- lib/77bit/packjt77.f90 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/77bit/packjt77.f90 b/lib/77bit/packjt77.f90 index cd17e8b47..83d848f1f 100644 --- a/lib/77bit/packjt77.f90 +++ b/lib/77bit/packjt77.f90 @@ -278,6 +278,7 @@ subroutine unpack77(c77,nrx,msg,unpk77_success) read(c77(72:77),'(2b3)') n3,i3 msg=repeat(' ',37) + if(i3.eq.0 .and. n3.eq.0) then ! 0.0 Free text call unpacktext77(c77(1:71),msg(1:13)) @@ -421,7 +422,10 @@ subroutine unpack77(c77,nrx,msg,unpk77_success) if(.not.unpkg4_success) unpk77_success=.false. msg=trim(call_1)//' '//grid6 endif - + + else if(i3.eq.0 .and. n3.gt.6) then + unpk77_success=.false. + else if(i3.eq.1 .or. i3.eq.2) then ! Type 1 (standard message) or Type 2 ("/P" form for EU VHF contest) read(c77,1000) n28a,ipa,n28b,ipb,ir,igrid4,i3 From cdbe425e565223b853e962eb518c2387886b661e Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Sat, 1 Aug 2020 10:58:21 -0500 Subject: [PATCH 02/18] Use squared metric for fst4 - works better on fading channel. --- lib/fst4/get_fst4_bitmetrics.f90 | 2 +- lib/fst4/get_fst4_bitmetrics2.f90 | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/fst4/get_fst4_bitmetrics.f90 b/lib/fst4/get_fst4_bitmetrics.f90 index 76a00dc2e..125777568 100644 --- a/lib/fst4/get_fst4_bitmetrics.f90 +++ b/lib/fst4/get_fst4_bitmetrics.f90 @@ -105,7 +105,7 @@ subroutine get_fst4_bitmetrics(cd,nss,hmod,nmax,nhicoh,bitmetrics,s4,badsync) csum=csum+cs(graymap(ntone),ks+j)*cterm cterm=cterm*conjg(cp(graymap(ntone))) enddo - s2(i)=abs(csum) + s2(i)=abs(csum)**2 enddo ipt=1+(ks-1)*2 if(nsym.eq.1) ibmax=1 diff --git a/lib/fst4/get_fst4_bitmetrics2.f90 b/lib/fst4/get_fst4_bitmetrics2.f90 index da0a6a230..6a669bd4c 100644 --- a/lib/fst4/get_fst4_bitmetrics2.f90 +++ b/lib/fst4/get_fst4_bitmetrics2.f90 @@ -49,21 +49,21 @@ subroutine get_fst4_bitmetrics2(cd,nss,hmod,nsizes,bitmetrics,s4hmod,badsync) i1=(k-1)*NSS csymb=cd(i1:i1+NSS-1) do itone=0,3 - s4(itone,k,1)=abs(sum(csymb*conjg(c1(:,itone)))) - s4(itone,k,2)=abs(sum(csymb( 1:nss/2)*conjg(c1( 1:nss/2,itone)))) + & - abs(sum(csymb(nss/2+1: nss)*conjg(c1(nss/2+1: nss,itone)))) - s4(itone,k,3)=abs(sum(csymb( 1: nss/4)*conjg(c1( 1: nss/4,itone)))) + & - abs(sum(csymb( nss/4+1: nss/2)*conjg(c1( nss/4+1: nss/2,itone)))) + & - abs(sum(csymb( nss/2+1:3*nss/4)*conjg(c1( nss/2+1:3*nss/4,itone)))) + & - abs(sum(csymb(3*nss/4+1: nss)*conjg(c1(3*nss/4+1: nss,itone)))) - s4(itone,k,4)=abs(sum(csymb( 1: nss/8)*conjg(c1( 1: nss/8,itone)))) + & - abs(sum(csymb( nss/8+1: nss/4)*conjg(c1( nss/8+1: nss/4,itone)))) + & - abs(sum(csymb( nss/4+1:3*nss/8)*conjg(c1( nss/4+1:3*nss/8,itone)))) + & - abs(sum(csymb(3*nss/8+1: nss/2)*conjg(c1(3*nss/8+1: nss/2,itone)))) + & - abs(sum(csymb( nss/2+1:5*nss/8)*conjg(c1( nss/2+1:5*nss/8,itone)))) + & - abs(sum(csymb(5*nss/8+1:3*nss/4)*conjg(c1(5*nss/8+1:3*nss/4,itone)))) + & - abs(sum(csymb(3*nss/4+1:7*nss/8)*conjg(c1(3*nss/4+1:7*nss/8,itone)))) + & - abs(sum(csymb(7*nss/8+1: nss)*conjg(c1(7*nss/8+1: nss,itone)))) + s4(itone,k,1)=abs(sum(csymb*conjg(c1(:,itone))))**2 + s4(itone,k,2)=abs(sum(csymb( 1:nss/2)*conjg(c1( 1:nss/2,itone))))**2 + & + abs(sum(csymb(nss/2+1: nss)*conjg(c1(nss/2+1: nss,itone))))**2 + s4(itone,k,3)=abs(sum(csymb( 1: nss/4)*conjg(c1( 1: nss/4,itone))))**2 + & + abs(sum(csymb( nss/4+1: nss/2)*conjg(c1( nss/4+1: nss/2,itone))))**2 + & + abs(sum(csymb( nss/2+1:3*nss/4)*conjg(c1( nss/2+1:3*nss/4,itone))))**2 + & + abs(sum(csymb(3*nss/4+1: nss)*conjg(c1(3*nss/4+1: nss,itone))))**2 + s4(itone,k,4)=abs(sum(csymb( 1: nss/8)*conjg(c1( 1: nss/8,itone))))**2 + & + abs(sum(csymb( nss/8+1: nss/4)*conjg(c1( nss/8+1: nss/4,itone))))**2 + & + abs(sum(csymb( nss/4+1:3*nss/8)*conjg(c1( nss/4+1:3*nss/8,itone))))**2 + & + abs(sum(csymb(3*nss/8+1: nss/2)*conjg(c1(3*nss/8+1: nss/2,itone))))**2 + & + abs(sum(csymb( nss/2+1:5*nss/8)*conjg(c1( nss/2+1:5*nss/8,itone))))**2 + & + abs(sum(csymb(5*nss/8+1:3*nss/4)*conjg(c1(5*nss/8+1:3*nss/4,itone))))**2 + & + abs(sum(csymb(3*nss/4+1:7*nss/8)*conjg(c1(3*nss/4+1:7*nss/8,itone))))**2 + & + abs(sum(csymb(7*nss/8+1: nss)*conjg(c1(7*nss/8+1: nss,itone))))**2 enddo enddo From 9d2bde71805ecbc2ed006e107e5f8dc8e6647100 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Tue, 4 Aug 2020 09:15:44 -0500 Subject: [PATCH 03/18] Fix SNR calculation for B,C,D submodes. --- lib/fst4/get_fst4_bitmetrics.f90 | 2 +- lib/fst4/get_fst4_bitmetrics2.f90 | 11 ++++------- lib/fst4_decode.f90 | 2 +- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/lib/fst4/get_fst4_bitmetrics.f90 b/lib/fst4/get_fst4_bitmetrics.f90 index 125777568..9cf1e2470 100644 --- a/lib/fst4/get_fst4_bitmetrics.f90 +++ b/lib/fst4/get_fst4_bitmetrics.f90 @@ -52,7 +52,7 @@ subroutine get_fst4_bitmetrics(cd,nss,hmod,nmax,nhicoh,bitmetrics,s4,badsync) do itone=0,3 cs(itone,k)=sum(csymb*conjg(c1(:,itone))) enddo - s4(0:3,k)=abs(cs(0:3,k)) + s4(0:3,k)=abs(cs(0:3,k))**2 enddo ! Sync quality check diff --git a/lib/fst4/get_fst4_bitmetrics2.f90 b/lib/fst4/get_fst4_bitmetrics2.f90 index 6a669bd4c..9badef231 100644 --- a/lib/fst4/get_fst4_bitmetrics2.f90 +++ b/lib/fst4/get_fst4_bitmetrics2.f90 @@ -1,4 +1,4 @@ -subroutine get_fst4_bitmetrics2(cd,nss,hmod,nsizes,bitmetrics,s4hmod,badsync) +subroutine get_fst4_bitmetrics2(cd,nss,hmod,nsizes,bitmetrics,s4snr,badsync) include 'fst4_params.f90' complex cd(0:NN*nss-1) @@ -15,7 +15,7 @@ subroutine get_fst4_bitmetrics2(cd,nss,hmod,nsizes,bitmetrics,s4hmod,badsync) logical badsync real bitmetrics(2*NN,4) real s2(0:65535) - real s4(0:3,NN,4),s4hmod(0:3,NN) + real s4(0:3,NN,4),s4snr(0:3,NN) data isyncword1/0,1,3,2,1,0,2,3/ data isyncword2/2,3,1,0,3,2,0,1/ data graymap/0,1,3,2/ @@ -121,11 +121,8 @@ subroutine get_fst4_bitmetrics2(cd,nss,hmod,nsizes,bitmetrics,s4hmod,badsync) call normalizebmet(bitmetrics(:,3),2*NN) call normalizebmet(bitmetrics(:,4),2*NN) -! Return the s4 array corresponding to N=1/hmod. Will be used for SNR calculation - if(hmod.eq.1) s4hmod(:,:)=s4(:,:,1) - if(hmod.eq.2) s4hmod(:,:)=s4(:,:,2) - if(hmod.eq.4) s4hmod(:,:)=s4(:,:,3) - if(hmod.eq.8) s4hmod(:,:)=s4(:,:,4) +! Return the s4 array corresponding to N=1. Will be used for SNR calculation + s4snr(:,:)=s4(:,:,1) return end subroutine get_fst4_bitmetrics2 diff --git a/lib/fst4_decode.f90 b/lib/fst4_decode.f90 index caf9a4b4f..72041bc3f 100644 --- a/lib/fst4_decode.f90 +++ b/lib/fst4_decode.f90 @@ -550,7 +550,7 @@ contains endif xsig=0 do i=1,NN - xsig=xsig+s4(itone(i),i)**2 + xsig=xsig+s4(itone(i),i) enddo arg=600.0*(xsig/base)-1.0 if(arg.gt.0.0) then From b191e0c5ef3a41b6d36db9728d68b343c8056cf7 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Tue, 4 Aug 2020 09:15:44 -0500 Subject: [PATCH 04/18] Fix SNR calculation for B,C,D submodes. --- lib/fst4_decode.f90 | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/lib/fst4_decode.f90 b/lib/fst4_decode.f90 index 72041bc3f..d32873c42 100644 --- a/lib/fst4_decode.f90 +++ b/lib/fst4_decode.f90 @@ -49,7 +49,7 @@ contains complex, allocatable :: cframe(:) complex, allocatable :: c_bigfft(:) !Complex waveform real llr(240),llra(240),llrb(240),llrc(240),llrd(240) - real candidates(100,4) + real candidates(200,4) real bitmetrics(320,4) real s4(0:3,NN) real minsync @@ -253,6 +253,7 @@ contains call four2a(c_bigfft,nfft1,1,-1,0) !r2c ! call blank2(nfa,nfb,nfft1,c_bigfft,iwave) + nhicoh=0 if(hmod.eq.1) then if(fMHz.lt.2.0) then nsyncoh=8 ! Use N=8 for sync @@ -277,7 +278,7 @@ contains if(hmod.eq.1) then if(ntrperiod.eq.15) minsync=1.15 - if(ntrperiod.gt.15) minsync=1.20 + if(ntrperiod.gt.15) minsync=1.25 elseif(hmod.gt.1) then minsync=1.2 endif @@ -410,7 +411,7 @@ contains ns4=count(hbits(229:244).eq.(/1,1,1,0,0,1,0,0,1,0,1,1,0,0,0,1/)) ns5=count(hbits(305:320).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) nsync_qual=ns1+ns2+ns3+ns4+ns5 -! if(nsync_qual.lt. 46) cycle !### Value ?? ### + if(nsync_qual.lt. 46) cycle !### Value ?? ### scalefac=2.83 llra( 1: 60)=bitmetrics( 17: 76, 1) llra( 61:120)=bitmetrics( 93:152, 1) @@ -457,7 +458,7 @@ contains if(itry.gt.nblock) then llr=llra if(nblock.gt.1) then - if(hmod.eq.1) llr=llrd + if(hmod.eq.1) llr=llrc if(hmod.eq.2) llr=llrb if(hmod.eq.4) llr=llrc if(hmod.eq.8) llr=llrd @@ -737,7 +738,7 @@ contains complex c_bigfft(0:nfft1/2) !Full length FFT of raw data integer hmod !Modulation index (submode) integer im(1) !For maxloc - real candidates(100,4) !Candidate list + real candidates(200,4) !Candidate list real, allocatable :: s(:) !Low resolution power spectrum real, allocatable :: s2(:) !CCF of s() with 4 tones real xdb(-3:3) !Model 4-tone CCF peaks @@ -794,17 +795,18 @@ contains ! Find candidates, using the CLEAN algorithm to remove a model of each one ! from s2() after it has been found. pval=99.99 - do while(ncand.lt.100) + do while(ncand.lt.200) im=maxloc(s2(ia:ib)) iploc=ia+im(1)-1 !Index of CCF peak pval=s2(iploc) !Peak value if(pval.lt.minsync) exit - do i=-3,+3 !Remove 0.9 of a model CCF at - k=iploc+2*hmod*i !this frequency from s2() - if(k.ge.ia .and. k.le.ib) then - s2(k)=max(0.,s2(k)-0.9*pval*xdb(i)) - endif - enddo +! do i=-3,+3 !Remove 0.9 of a model CCF at +! k=iploc+2*hmod*i !this frequency from s2() +! if(k.ge.ia .and. k.le.ib) then +! s2(k)=max(0.,s2(k)-0.9*pval*xdb(i)) +! endif +! enddo + s2(max(1,iploc-2*hmod*3):min(nnw,iploc+2*hmod*3))=0.0 ncand=ncand+1 candidates(ncand,1)=df2*iploc !Candidate frequency candidates(ncand,2)=pval !Rough estimate of SNR From 8b7db6556cf8d489ff8efcc913d5f6053dd28ce3 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Tue, 4 Aug 2020 10:25:09 -0500 Subject: [PATCH 05/18] Changes to the llrs that are used as the basis for AP decoding. --- lib/fst4_decode.f90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/fst4_decode.f90 b/lib/fst4_decode.f90 index d32873c42..88572dfb7 100644 --- a/lib/fst4_decode.f90 +++ b/lib/fst4_decode.f90 @@ -459,9 +459,9 @@ contains llr=llra if(nblock.gt.1) then if(hmod.eq.1) llr=llrc - if(hmod.eq.2) llr=llrb - if(hmod.eq.4) llr=llrc - if(hmod.eq.8) llr=llrd + if(hmod.eq.2) llr=llra + if(hmod.eq.4) llr=llrb + if(hmod.eq.8) llr=llrc endif iaptype=naptypes(nQSOProgress,itry-nblock) if(lapcqonly) iaptype=1 From 6838a6b4847f017b3bafe1d9540605cee5012949 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Tue, 4 Aug 2020 11:56:32 -0500 Subject: [PATCH 06/18] Remove some unneeded code. --- lib/fst4_decode.f90 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/fst4_decode.f90 b/lib/fst4_decode.f90 index 88572dfb7..e56fa27a8 100644 --- a/lib/fst4_decode.f90 +++ b/lib/fst4_decode.f90 @@ -149,8 +149,7 @@ contains if(i3.ne.1 .or. (msg.ne.msgsent) .or. .not.unpk77_success) go to 10 read(c77,'(77i1)') message77 message77=mod(message77+rvec,2) - call encode174_91(message77,cw) - apbits=2*cw-1 + apbits(1:77)=2*message77-1 if(nohiscall) apbits(30)=99 10 continue From ade1eb861d4322419a134f79c0d8800d5d166628 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Mon, 10 Aug 2020 09:31:44 -0400 Subject: [PATCH 07/18] User Guide edits from Dave, KC3GPM. --- doc/user_guide/en/install-from-source.adoc | 6 +- doc/user_guide/en/install-linux.adoc | 18 +++--- doc/user_guide/en/install-mac.adoc | 8 +-- doc/user_guide/en/introduction.adoc | 10 ++-- doc/user_guide/en/logging.adoc | 24 ++++---- doc/user_guide/en/make-qso.adoc | 8 +-- doc/user_guide/en/measurement_tools.adoc | 66 +++++++++++----------- doc/user_guide/en/protocols.adoc | 21 ++++--- 8 files changed, 84 insertions(+), 77 deletions(-) diff --git a/doc/user_guide/en/install-from-source.adoc b/doc/user_guide/en/install-from-source.adoc index f106aa59b..b70e89c55 100644 --- a/doc/user_guide/en/install-from-source.adoc +++ b/doc/user_guide/en/install-from-source.adoc @@ -1,7 +1,7 @@ -// Status=review +// Status=edited Source code for _WSJT-X_ is available from a public repository at -{devrepo}. To compile the program you will need to install at least the +{devrepo}. To compile the program, at a minimum you must install the following packages: - Git @@ -19,7 +19,7 @@ cd wsjtx git checkout wsjtx-{VERSION} ===== -and for the current development branch, +and for the current development branch: ===== git clone git://git.code.sf.net/p/wsjt/wsjtx diff --git a/doc/user_guide/en/install-linux.adoc b/doc/user_guide/en/install-linux.adoc index ad905f32d..6461ac77e 100644 --- a/doc/user_guide/en/install-linux.adoc +++ b/doc/user_guide/en/install-linux.adoc @@ -1,16 +1,14 @@ -// Status=review +// Status=edited Debian, Ubuntu, and other Debian-based systems including Raspbian: -NOTE: The project team release binary installer packages for Linux -when a new _WSJT-X_ release is announced. These are built to -target one contemporary version of a Linux distribution. Although -these may work on newer Linux versions or even different -distributions, it is unlikely that they will work on older -versions. Check the notes provided with the release for details of the -targeted Linux distributions and versions. If the binary package is -not compatible with your Linux distribution or version you must build -the application from sources. +NOTE: The project team release binary installer packages targeted for +one contemporary version of a Linux distribution. Although these may +work on newer Linux versions or even different distributions, it is +unlikely that they work on older versions. Check the notes provided +with the release for details of the targeted Linux distributions and +versions. If the binary package is not compatible with your Linux +distribution or version, you must build the application from sources. * 32-bit: {debian32} - To install: diff --git a/doc/user_guide/en/install-mac.adoc b/doc/user_guide/en/install-mac.adoc index 26384805f..6595ba1c9 100644 --- a/doc/user_guide/en/install-mac.adoc +++ b/doc/user_guide/en/install-mac.adoc @@ -1,12 +1,12 @@ // These instructions are up-to-date for WSJT-X v2.2 -*OS X 10.12* and later: Download the file {osx} to your desktop, -double-click on it and consult its `ReadMe` file for important +*macOS10.13* and later: Download the file {osx} to your desktop, +double-click it and consult its `ReadMe` file for important installation notes. If you have already installed a previous version, you can retain it by -changing its name in the *Applications* folder (say, from _WSJT-X_ to -_WSJT-X_2.1_). You can then proceed to the installation phase. +changing its name in the *Applications* folder (such as from _WSJT-X_ to +_WSJT-X_2.2_). You can then proceed to the installation phase. Take note also of the following: diff --git a/doc/user_guide/en/introduction.adoc b/doc/user_guide/en/introduction.adoc index a592e5325..f172b5d35 100644 --- a/doc/user_guide/en/introduction.adoc +++ b/doc/user_guide/en/introduction.adoc @@ -4,7 +4,7 @@ _WSJT-X_ is a computer program designed to facilitate basic amateur radio communication using very weak signals. The first four letters in the program name stand for "`**W**eak **S**ignal communication by K1**JT**,`" while the suffix "`-X`" indicates that _WSJT-X_ started as -an e**Xt**ended and e**X**perimental branch of the program _WSJT_, +an extended and experimental branch of the program _WSJT_, first released in 2001. Bill Somerville, G4WJS, and Steve Franke, K9AN, have been major contributors to program development since 2013 and 2015, respectively. @@ -16,7 +16,7 @@ making reliable QSOs under weak-signal conditions. They use nearly identical message structure and source encoding. JT65 and QRA64 were designed for EME ("`moonbounce`") on the VHF/UHF bands and have also proven very effective for worldwide QRP communication on the HF bands. -QRA64 has a some advantages over JT65, including better performance +QRA64 has some advantages over JT65, including better performance for EME on the higher microwave bands. JT9 was originally designed for the LF, MF, and lower HF bands. Its submode JT9A is 2 dB more sensitive than JT65 while using less than 10% of the bandwidth. JT4 @@ -27,7 +27,7 @@ reception, so a minimal QSO takes four to six minutes — two or three transmissions by each station, one sending in odd UTC minutes and the other even. FT8 is operationally similar but four times faster (15-second T/R sequences) and less sensitive by a few dB. FT4 is -faster still (7.5 s T/R sequences) and especially well suited for +faster still (7.5 s T/R sequences) and especially well-suited for radio contesting. On the HF bands, world-wide QSOs are possible with any of these modes using power levels of a few watts (or even milliwatts) and compromise antennas. On VHF bands and higher, QSOs @@ -45,7 +45,7 @@ protocols designed to take advantage of brief signal enhancements from ionized meteor trails, aircraft scatter, and other types of scatter propagation. These modes use timed sequences of 5, 10, 15, or 30 s duration. User messages are transmitted repeatedly at high rate (up -to 250 characters per second, for MSK144) to make good use of the +to 250 characters per second for MSK144) to make good use of the shortest meteor-trail reflections or "`pings`". ISCAT uses free-form messages up to 28 characters long, while MSK144 uses the same structured messages as the slow modes and optionally an abbreviated @@ -80,4 +80,4 @@ be beta releases leading up to the final release of v2.1.0. Release candidates should be used _only_ during a short testing period. They carry an implied obligation to provide feedback to the program development group. Candidate releases should not be used on -the air after a full release with the same number has been made. +the air after a full release with the same number is made. diff --git a/doc/user_guide/en/logging.adoc b/doc/user_guide/en/logging.adoc index 4176a2a40..a3193ba25 100644 --- a/doc/user_guide/en/logging.adoc +++ b/doc/user_guide/en/logging.adoc @@ -1,7 +1,9 @@ +//status: edited + A basic logging facility in _WSJT-X_ saves QSO information to files named `wsjtx.log` (in comma-separated text format) and `wsjtx_log.adi` (in standard ADIF format). These files can be imported directly into -other programs, for example spreadsheets and popular logging programs. +other programs (such as spreadsheets and popular logging programs). As described in the <> and <> sections, different operating systems may place your local log files in different locations. You can always navigate to @@ -12,30 +14,32 @@ applications like {jtalert}, which can log QSOs automatically to other applications including {hrd}, {dxlsuite}, and {log4om}. The program option *Show DXCC entity and worked before status* -(selectable on the *Settings | General* tab) is intended mostly for +(selectable on the *File | Settings | General* tab) is intended mostly for use on non-Windows platforms, where {jtalert} is not available. When -this option is checked _WSJT-X_ appends some additional information to +this option is checked, _WSJT-X_ appends some additional information to all CQ messages displayed in the _Band Activity_ window. The name of the DXCC entity is shown, abbreviated if necessary. Your "`worked before`" status for this callsign (according to log file `wsjtx_log.adi`) is indicated by highlighting colors, if that option -has been selected. +is selected. _WSJT-X_ includes a built-in `cty.dat` file containing DXCC prefix information. Updated files can be downloaded from the {cty_dat} web -site when required. If an updated `cty.dat` is present in the logs -folder and readable, it will be used in preference to the built-in -one. +site when required. If an updated and readable `cty.dat` file is +present in the logs folder, it is used in preference to the +built-in file. The log file `wsjtx_log.adi` is updated whenever you log a QSO from -_WSJT-X_. (Keep in mind that if you erase this file you will lose all +_WSJT-X_. (Keep in mind that if you erase this file, you lose all "`worked before`" information.) You can append or overwrite the `wsjtx_log.adi` file by exporting your QSO history as an ADIF file from another logging program. Turning *Show DXCC entity and worked -before status* off and then on again will cause _WSJT-X_ to re-read +before status* off and then on again causes _WSJT-X_ to re-read the log file. Very large log files may cause _WSJT-X_ to slow down -when searching for calls. If the ADIF log file has been changed +when searching for calls. If the ADIF log file has been changed outside of _WSJT-X_ you can force _WSJT-X_ to reload the file from the *Settings | Colors* tab using the *Rescan ADIF Log* button, see <>. +Additional features are provided for *Contest* and *Fox* logging. +(more to come, here ...) diff --git a/doc/user_guide/en/make-qso.adoc b/doc/user_guide/en/make-qso.adoc index 03f02fd46..725bafe73 100644 --- a/doc/user_guide/en/make-qso.adoc +++ b/doc/user_guide/en/make-qso.adoc @@ -37,7 +37,7 @@ assigns more reliable numbers to relatively strong signals. NOTE: Signals become visible on the waterfall around S/N = –26 dB and audible (to someone with very good hearing) around –15 dB. Thresholds for decodability are around -20 dB for FT8, -23 dB for JT4, –25 dB for -JT65, –27 dB for JT9. +JT65, and –27 dB for JT9. NOTE: Several options are available for circumstances where fast QSOs are desirable. Double-click the *Tx1* control under _Now_ or _Next_ @@ -75,7 +75,7 @@ When calling CQ you may also choose to check the box *Call 1st*. _WSJT-X_ will then respond automatically to the first decoded responder to your CQ. -NOTE: When *Auto-Seq* is enabled the program de-activates *Enable Tx* +NOTE: When *Auto-Seq* is enabled, the program de-activates *Enable Tx* at the end of each QSO. It is not intended that _WSJT-X_ should make fully automated QSOs. @@ -259,7 +259,7 @@ that a second callsign is never permissible in these messages. NOTE: During a transmission your outgoing message is displayed in the first label on the *Status Bar* and shown exactly as another station -will receive it. You can check to see that you are actually +receives it. You can check to see that you are actually transmitting the message you wish to send. QSOs involving *Type 2* compound callsigns might look like either @@ -287,7 +287,7 @@ standard structured messages without callsign prefix or suffix. TIP: If you are using a compound callsign, you may want to experiment with the option *Message generation for type 2 compound -callsign holders* on the *Settings | General* tab, so that messages +callsign holders* on the *File | Settings | General* tab, so that messages will be generated that best suit your needs. === Pre-QSO Checklist diff --git a/doc/user_guide/en/measurement_tools.adoc b/doc/user_guide/en/measurement_tools.adoc index 766939e7c..fe501d650 100644 --- a/doc/user_guide/en/measurement_tools.adoc +++ b/doc/user_guide/en/measurement_tools.adoc @@ -1,6 +1,8 @@ +//Status: edited + === Frequency Calibration -Many _WSJT-X_ capabilities depend on signal-detection bandwidths no +Many _WSJT-X_ capabilities depend on signal-detection bandwidths of no more than a few Hz. Frequency accuracy and stability are therefore unusually important. We provide tools to enable accurate frequency calibration of your radio, as well as precise frequency measurement of @@ -11,11 +13,11 @@ measuring the error in dial frequency for each signal. You will probably find it convenient to define and use a special <> dedicated to frequency calibration. -Then complete the following steps, as appropriate for your system. +Then complete the following steps, as appropriate, for your system. - Switch to FreqCal mode -- In the _Working Frequencies_ box on the *Settings -> Frequencies* +- In the _Working Frequencies_ box on the *File | Settings | Frequencies* tab, delete any default frequencies for *FreqCal* mode that are not relevant for your location. You may want to replace some of them with reliably known frequencies receivable at your location. @@ -29,14 +31,14 @@ of WWV at 2.500, 5.000, 10.000, 15.000, and 20.000 MHz, and CHU at 3.330, 7.850, and 14.670 MHz. Similar shortwave signals are available in other parts of the world. -- In most cases you will want to start by deleting any existing file -`fmt.all` in the directory where your log files are kept. +- In most cases, start by deleting any existing file `fmt.all` in the +directory where your log files are kept. - To cycle automatically through your chosen list of calibration frequencies, check *Execute frequency calibration cycle* on the *Tools* menu. _WSJT-X_ will spend 30 seconds at each frequency. Initially no measurement data is saved to the `fmt.all` -file although it is displayed on screen, this allows you to check your +file although it is displayed on screen; this allows you to check your current calibration parameters. - During the calibration procedure, the radio's USB dial frequency is @@ -61,7 +63,7 @@ the nominal frequency itself (in MHz). For example, the 20 MHz measurement for WWV shown above produced a measured tone offset of 24.6 Hz, displayed in the _WSJT-X_ decoded text window. The resulting calibration constant is 24.6/20=1.23 parts per million. This number -may be entered as *Slope* on the *settings -> Frequencies* tab. +may be entered as *Slope* on the *File | Settings | Frequencies* tab. A more precise calibration can be effected by fitting the intercept and slope of a straight line to the whole sequence of calibration @@ -81,19 +83,19 @@ After running *Execute frequency calibration cycle* at least once with good results, check and edit the file `fmt.all` in the log directory and delete any spurious or outlier measurements. The line-fitting procedure can then be carried out automatically by clicking *Solve for -calibration parameters* on the *Tools* menu. The results will be +calibration parameters* on the *Tools* menu. The results are displayed as in the following screen shot. Estimated uncertainties are included for slope and intercept; `N` is the number of averaged frequency measurements included in the fit, and `StdDev` is the root mean square deviation of averaged measurements from the fitted -straight line. If the solution seems valid you will be offered an -*Apply* button to push that will automatically set the calibration -parameters in *Settings -> Frequencies -> Frequency Calibration*. +straight line. If the solution seems valid, you are offered an +*Apply* button to push that automatically sets the calibration +parameters in *File | Settings | Frequencies | Frequency Calibration*. image::FreqCal_Results.png[align="center",alt="FreqCal_Results"] For a quick visual check of the resulting calibration, stay in -*FreqCal* mode with the *Measure* option cleared. _WSJT-X_ will show +*FreqCal* mode with the *Measure* option cleared. _WSJT-X_ shows the adjusted results directly on the waterfall and the displayed records. @@ -103,8 +105,8 @@ _WSJT-X_ provides a tool that can be used to determine the detailed shape of your receiver's passband. Disconnect your antenna or tune to a quiet frequency with no signals. With _WSJT-X_ running in one of the slow modes, select *Measure reference spectrum* from the *Tools* -menu. Wait for about a minute and then hit the *Stop* button. A file -named `refspec.dat` will appear in your log directory. When you check +menu. Wait for about a minute and then click *Stop*. A file +named `refspec.dat` appears in your log directory. When you check *Ref Spec* on the *Wide Graph*, the recorded reference spectrum will then be used to flatten your overall effective passband. @@ -122,39 +124,39 @@ response* generates an undistorted audio waveform equal to the one generated by the transmitting station. Its Fourier transform is then used as a frequency-dependent phase reference to compare with the phase of the received frame's Fourier coefficients. Phase differences -between the reference spectrum and received spectrum will include +between the reference spectrum and received spectrum include contributions from the originating station's transmit filter, the propagation channel, and filters in the receiver. If the received frame originates from a station known to transmit signals having -little phase distortion (say, a station known to use a properly -adjusted software-defined-transceiver) and if the received signal is +little phase distortion (such as a station known to use a properly +adjusted software-defined transceiver), and if the received signal is relatively free from multipath distortion so that the channel phase is close to linear, the measured phase differences will be representative of the local receiver's phase response. Complete the following steps to generate a phase equalization curve: -- Record a number of wav files that contain decodable signals from -your chosen reference station. Best results will be obtained when the +- Record a number of `wav` files that contain decodable signals from +your chosen reference station. Best results are obtained when the signal-to-noise ratio of the reference signals is 10 dB or greater. - Enter the callsign of the reference station in the DX Call box. - Select *Measure phase response* from the *Tools* menu, and open each -of the wav files in turn. The mode character on decoded text lines -will change from `&` to `^` while _WSJT-X_ is measuring the phase -response, and it will change back to `&` after the measurement is +of the `wav` files in turn. The mode character on decoded text lines +changes from `&` to `^` while _WSJT-X_ is measuring the phase +response, and it changes back to `&` after the measurement is completed. The program needs to average a number of high-SNR frames to accurately estimate the phase, so it may be necessary to process -several wav files. The measurement can be aborted at any time by +several `wav` files. The measurement can be aborted at any time by selecting *Measure phase response* again to toggle the phase measurement off. + -When the measurement is complete _WSJT-X_ will save the measured +When the measurement is complete, _WSJT-X_ saves the measured phase response in the *Log directory*, in a file with suffix -".pcoeff". The filename will contain the callsign of the reference +".pcoeff". The filename contains the callsign of the reference station and a timestamp, for example `K0TPP_170923_112027.pcoeff`. - Select *Equalization tools ...* under the *Tools* menu and click the @@ -165,23 +167,23 @@ the proposed phase equalization curve. It's a good idea to repeat the phase measurement several times, using different wav files for each measurement, to ensure that your measurements are repeatable. -- Once you are satisfied with a fitted curve, push the *Apply* button -to save the proposed response. The red curve will be replaced with a +- Once you are satisfied with a fitted curve, click the *Apply* button +to save the proposed response. The red curve is replaced with a light green curve labeled "Current" to indicate that the phase equalization curve is now being applied to the received data. Another -curve labeled "Group Delay" will appear. The "Group Delay" curve shows +curve labeled "Group Delay" appears. The "Group Delay" curve shows the group delay variation across the passband, in ms. Click the *Discard Measured* button to remove the captured data from the plot, leaving only the applied phase equalization curve and corresponding group delay curve. -- To revert to no phase equalization, push the *Restore Defaults* +- To revert to no phase equalization, click the *Restore Defaults* button followed by the *Apply* button. The three numbers printed at the end of each MSK144 decode line can be used to assess the improvement provided by equalization. These numbers are: `N` = Number of frames averaged, `H` = Number of hard bit errors -corrected, `E` = Size of MSK eye diagram opening. +corrected, and `E` = Size of MSK eye diagram opening. Here is a decode of K0TPP obtained while *Measure phase response* was measuring the phase response: @@ -196,7 +198,7 @@ scale. Here's how the same decode looks after phase equalization: 103900 17 6.5 1493 & WA8CLT K0TPP +07 1 0 1.6 -In this case, equalization has increased the eye opening from 1.2 to +In this case, equalization has increased the eye-opening from 1.2 to 1.6. Larger positive eye openings are associated with reduced likelihood of bit errors and higher likelihood that a frame will be successfully decoded. In this case, the larger eye-opening tells us @@ -206,7 +208,7 @@ equalization curve is going to improve decoding of signals other than those from the reference station, K0TPP. It's a good idea to carry out before and after comparisons using a -large number of saved wav files with signals from many different +large number of saved `wav` files with signals from many different stations, to help decide whether your equalization curve improves decoding for most signals. When doing such comparisons, keep in mind that equalization may cause _WSJT-X_ to successfully decode a frame diff --git a/doc/user_guide/en/protocols.adoc b/doc/user_guide/en/protocols.adoc index d9a7d8ada..e22911266 100644 --- a/doc/user_guide/en/protocols.adoc +++ b/doc/user_guide/en/protocols.adoc @@ -1,3 +1,5 @@ +//status: edited + [[PROTOCOL_OVERVIEW]] === Overview @@ -30,17 +32,17 @@ of 4-digit Maidenhead grid locators on earth is 180×180 = 32,400, which is less than 2^15^ = 32,768; so a grid locator requires 15 bits. Some 6 million of the possible 28-bit values are not needed for -callsigns. A few of these slots have been assigned to special message +callsigns. A few of these slots are assigned to special message components such as `CQ`, `DE`, and `QRZ`. `CQ` may be followed by three digits to indicate a desired callback frequency. (If K1ABC transmits -on a standard calling frequency, say 50.280, and sends `CQ 290 K1ABC +on a standard calling frequency such as 50.280, and sends `CQ 290 K1ABC FN42`, it means that s/he will listen on 50.290 and respond there to any replies.) A numerical signal report of the form `–nn` or `R–nn` can be sent in place of a grid locator. (As originally defined, numerical signal reports `nn` were required to fall between -01 -and -30 dB. Program versions 2.3 and later accommodate reports between --50 and +50 dB.) A country prefix or portable suffix may be -attached to one of the callsigns. When this feature is used the +and -30 dB. Recent program versions 2.3 and later accommodate reports between +-50 and +49 dB.) A country prefix or portable suffix may be +attached to one of the callsigns. When this feature is used, the additional information is sent in place of the grid locator or by encoding additional information into some of the 6 million available slots mentioned above. @@ -147,7 +149,8 @@ following pseudo-random sequence: The synchronizing tone is normally sent in each interval having a "`1`" in the sequence. Modulation is 65-FSK at 11025/4096 = 2.692 baud. Frequency spacing between tones is equal to the keying rate for -JT65A, and 2 and 4 times larger for JT65B and JT65C. For EME QSOs the +JT65A, and 2 and 4 times larger for JT65B and JT65C, respectively. +For EME QSOs the signal report OOO is sometimes used instead of numerical signal reports. It is conveyed by reversing sync and data positions in the transmitted sequence. Shorthand messages for RO, RRR, and 73 dispense @@ -155,7 +158,7 @@ with the sync vector entirely and use time intervals of 16384/11025 = 1.486 s for pairs of alternating tones. The lower frequency is the same as that of the sync tone used in long messages, and the frequency separation is 110250/4096 = 26.92 Hz multiplied by n for JT65A, with n -= 2, 3, 4 used to convey the messages RO, RRR, and 73. += 2, 3, 4 used to convey the messages RO, RRR, and 73, respectively. [[QRA64_PROTOCOL]] ==== QRA64 @@ -225,7 +228,7 @@ the sync bit. [[SLOW_SUMMARY]] ==== Summary -Table 7 provides a brief summary parameters for the slow modes in +Table 7 provides a brief summary of parameters for the slow modes in _WSJT-X_. Parameters K and r specify the constraint length and rate of the convolutional codes; n and k specify the sizes of the (equivalent) block codes; Q is the alphabet size for the @@ -305,7 +308,7 @@ available character set is: Transmissions consist of sequences of 24 symbols: a synchronizing pattern of four symbols at tone numbers 0, 1, 3, and 2, followed by two symbols with tone number corresponding to (message length) and -(message length + 5), and finally 18 symbols conveying the user's +(message length + 5), and, finally, 18 symbols conveying the user's message, sent repeatedly character by character. The message always starts with `@`, the beginning-of-message symbol, which is not displayed to the user. The sync pattern and message-length indicator From bf06193c108616a3a271bad59b6b2aabb120145c Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Mon, 17 Aug 2020 14:12:08 -0500 Subject: [PATCH 08/18] Add timer call for bit metric calculation. Improve some comments. Make fort.21 ntype parameter more informative. --- lib/fst4/decode240_101.f90 | 2 +- lib/fst4/decode240_74.f90 | 2 +- lib/fst4/get_fst4_bitmetrics.f90 | 2 +- lib/fst4_decode.f90 | 8 +++++--- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/fst4/decode240_101.f90 b/lib/fst4/decode240_101.f90 index 80e42eeb0..e924f00ec 100644 --- a/lib/fst4/decode240_101.f90 +++ b/lib/fst4/decode240_101.f90 @@ -141,7 +141,7 @@ subroutine decode240_101(llr,Keff,maxosd,norder,apmask,message101,cw,ntype,nhard where(llr .ge. 0) hdec=1 nxor=ieor(hdec,cw) dmin=sum(nxor*abs(llr)) - ntype=2 + ntype=1+nosd return endif enddo diff --git a/lib/fst4/decode240_74.f90 b/lib/fst4/decode240_74.f90 index 3f8a6a952..224a2860d 100644 --- a/lib/fst4/decode240_74.f90 +++ b/lib/fst4/decode240_74.f90 @@ -141,7 +141,7 @@ subroutine decode240_74(llr,Keff,maxosd,norder,apmask,message74,cw,ntype,nharder where(llr .ge. 0) hdec=1 nxor=ieor(hdec,cw) dmin=sum(nxor*abs(llr)) - ntype=2 + ntype=1+nosd return endif enddo diff --git a/lib/fst4/get_fst4_bitmetrics.f90 b/lib/fst4/get_fst4_bitmetrics.f90 index 9cf1e2470..f248171f0 100644 --- a/lib/fst4/get_fst4_bitmetrics.f90 +++ b/lib/fst4/get_fst4_bitmetrics.f90 @@ -84,7 +84,7 @@ subroutine get_fst4_bitmetrics(cd,nss,hmod,nmax,nhicoh,bitmetrics,s4,badsync) endif bitmetrics=0.0 - do nseq=1,nmax !Try coherent sequences of 1, 2, and 4 symbols + do nseq=1,nmax !Try coherent sequences of 1,2,3,4 or 1,2,4,8 symbols if(nseq.eq.1) nsym=1 if(nseq.eq.2) nsym=2 if(nhicoh.eq.0) then diff --git a/lib/fst4_decode.f90 b/lib/fst4_decode.f90 index e56fa27a8..9a6683fe4 100644 --- a/lib/fst4_decode.f90 +++ b/lib/fst4_decode.f90 @@ -395,11 +395,13 @@ contains if(is0.lt.0) cycle cframe=c2(is0:is0+160*nss-1) bitmetrics=0 + call timer('bitmetrc',0) if(hmod.eq.1) then call get_fst4_bitmetrics(cframe,nss,hmod,nblock,nhicoh,bitmetrics,s4,badsync) else call get_fst4_bitmetrics2(cframe,nss,hmod,nblock,bitmetrics,s4,badsync) endif + call timer('bitmetrc',1) if(badsync) cycle hbits=0 @@ -410,7 +412,8 @@ contains ns4=count(hbits(229:244).eq.(/1,1,1,0,0,1,0,0,1,0,1,1,0,0,0,1/)) ns5=count(hbits(305:320).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) nsync_qual=ns1+ns2+ns3+ns4+ns5 - if(nsync_qual.lt. 46) cycle !### Value ?? ### + + if(nsync_qual.lt. 46) cycle !### Value ?? ### scalefac=2.83 llra( 1: 60)=bitmetrics( 17: 76, 1) llra( 61:120)=bitmetrics( 93:152, 1) @@ -768,7 +771,7 @@ contains nnw=nint(48000.*nsps*2./fs) allocate (s(nnw)) - s=0. !Compute low-resloution power spectrum + s=0. !Compute low-resolution power spectrum do i=ina,inb ! noise analysis window includes signal analysis window j0=nint(i*df2/df1) do j=j0-ndh,j0+ndh @@ -785,7 +788,6 @@ contains enddo call pctile(s2(ina+hmod*3:inb-hmod*3),inb-ina+1-hmod*6,30,base) s2=s2/base !Normalize wrt noise level - ncand=0 candidates=0 if(ia.lt.3) ia=3 From 7cb5511ed091a26ccdf1a9662f0d3aa0d079b094 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Wed, 19 Aug 2020 09:20:48 -0500 Subject: [PATCH 09/18] Simplify some code in fst4_decode.f90 - no functional change. --- lib/fst4_decode.f90 | 49 +++++++++++++++++---------------------------- 1 file changed, 18 insertions(+), 31 deletions(-) diff --git a/lib/fst4_decode.f90 b/lib/fst4_decode.f90 index 9a6683fe4..6f3e36105 100644 --- a/lib/fst4_decode.f90 +++ b/lib/fst4_decode.f90 @@ -48,7 +48,7 @@ contains complex, allocatable :: c2(:) complex, allocatable :: cframe(:) complex, allocatable :: c_bigfft(:) !Complex waveform - real llr(240),llra(240),llrb(240),llrc(240),llrd(240) + real llr(240),llrs(240,4) real candidates(200,4) real bitmetrics(320,4) real s4(0:3,NN) @@ -415,28 +415,15 @@ contains if(nsync_qual.lt. 46) cycle !### Value ?? ### scalefac=2.83 - llra( 1: 60)=bitmetrics( 17: 76, 1) - llra( 61:120)=bitmetrics( 93:152, 1) - llra(121:180)=bitmetrics(169:228, 1) - llra(181:240)=bitmetrics(245:304, 1) - llra=scalefac*llra - llrb( 1: 60)=bitmetrics( 17: 76, 2) - llrb( 61:120)=bitmetrics( 93:152, 2) - llrb(121:180)=bitmetrics(169:228, 2) - llrb(181:240)=bitmetrics(245:304, 2) - llrb=scalefac*llrb - llrc( 1: 60)=bitmetrics( 17: 76, 3) - llrc( 61:120)=bitmetrics( 93:152, 3) - llrc(121:180)=bitmetrics(169:228, 3) - llrc(181:240)=bitmetrics(245:304, 3) - llrc=scalefac*llrc - llrd( 1: 60)=bitmetrics( 17: 76, 4) - llrd( 61:120)=bitmetrics( 93:152, 4) - llrd(121:180)=bitmetrics(169:228, 4) - llrd(181:240)=bitmetrics(245:304, 4) - llrd=scalefac*llrd + do il=1,4 + llrs( 1: 60,il)=bitmetrics( 17: 76, il) + llrs( 61:120,il)=bitmetrics( 93:152, il) + llrs(121:180,il)=bitmetrics(169:228, il) + llrs(181:240,il)=bitmetrics(245:304, il) + enddo + llrs=scalefac*llrs - apmag=maxval(abs(llra))*1.1 + apmag=maxval(abs(llrs(:,1)))*1.1 ntmax=nblock+nappasses(nQSOProgress) if(lapcqonly) ntmax=nblock+1 if(ndepth.eq.1) ntmax=nblock @@ -448,22 +435,22 @@ contains endif do itry=1,ntmax - if(itry.eq.1) llr=llra - if(itry.eq.2.and.itry.le.nblock) llr=llrb - if(itry.eq.3.and.itry.le.nblock) llr=llrc - if(itry.eq.4.and.itry.le.nblock) llr=llrd + if(itry.eq.1) llr=llrs(:,1) + if(itry.eq.2.and.itry.le.nblock) llr=llrs(:,2) + if(itry.eq.3.and.itry.le.nblock) llr=llrs(:,3) + if(itry.eq.4.and.itry.le.nblock) llr=llrs(:,4) if(itry.le.nblock) then apmask=0 iaptype=0 endif if(itry.gt.nblock) then - llr=llra + llr=llrs(:,1) if(nblock.gt.1) then - if(hmod.eq.1) llr=llrc - if(hmod.eq.2) llr=llra - if(hmod.eq.4) llr=llrb - if(hmod.eq.8) llr=llrc + if(hmod.eq.1) llr=llrs(:,3) + if(hmod.eq.2) llr=llrs(:,1) + if(hmod.eq.4) llr=llrs(:,2) + if(hmod.eq.8) llr=llrs(:,4) endif iaptype=naptypes(nQSOProgress,itry-nblock) if(lapcqonly) iaptype=1 From 782c779392bf9751c6b8ed213f5e2c721c0d64e1 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Wed, 19 Aug 2020 14:10:28 -0500 Subject: [PATCH 10/18] Reconfigure to optimize decoder for MF/LF (high coherence) channels. --- lib/fst4/get_fst4_bitmetrics.f90 | 2 +- lib/fst4_decode.f90 | 22 +++++++++------------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/lib/fst4/get_fst4_bitmetrics.f90 b/lib/fst4/get_fst4_bitmetrics.f90 index f248171f0..f224854e2 100644 --- a/lib/fst4/get_fst4_bitmetrics.f90 +++ b/lib/fst4/get_fst4_bitmetrics.f90 @@ -105,7 +105,7 @@ subroutine get_fst4_bitmetrics(cd,nss,hmod,nmax,nhicoh,bitmetrics,s4,badsync) csum=csum+cs(graymap(ntone),ks+j)*cterm cterm=cterm*conjg(cp(graymap(ntone))) enddo - s2(i)=abs(csum)**2 + s2(i)=abs(csum) enddo ipt=1+(ks-1)*2 if(nsym.eq.1) ibmax=1 diff --git a/lib/fst4_decode.f90 b/lib/fst4_decode.f90 index 6f3e36105..448e699c3 100644 --- a/lib/fst4_decode.f90 +++ b/lib/fst4_decode.f90 @@ -275,12 +275,8 @@ contains fb=min(4800,nfb) endif - if(hmod.eq.1) then - if(ntrperiod.eq.15) minsync=1.15 - if(ntrperiod.gt.15) minsync=1.25 - elseif(hmod.gt.1) then - minsync=1.2 - endif + minsync=1.2 + if(ntrperiod.eq.15) minsync=1.15 ! Get first approximation of candidate frequencies call get_candidates_fst4(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & @@ -788,13 +784,13 @@ contains iploc=ia+im(1)-1 !Index of CCF peak pval=s2(iploc) !Peak value if(pval.lt.minsync) exit -! do i=-3,+3 !Remove 0.9 of a model CCF at -! k=iploc+2*hmod*i !this frequency from s2() -! if(k.ge.ia .and. k.le.ib) then -! s2(k)=max(0.,s2(k)-0.9*pval*xdb(i)) -! endif -! enddo - s2(max(1,iploc-2*hmod*3):min(nnw,iploc+2*hmod*3))=0.0 + do i=-3,+3 !Remove 0.9 of a model CCF at + k=iploc+2*hmod*i !this frequency from s2() + if(k.ge.ia .and. k.le.ib) then + s2(k)=max(0.,s2(k)-0.9*pval*xdb(i)) + endif + enddo +! s2(max(1,iploc-2*hmod*3):min(nnw,iploc+2*hmod*3))=0.0 ncand=ncand+1 candidates(ncand,1)=df2*iploc !Candidate frequency candidates(ncand,2)=pval !Rough estimate of SNR From e02850ae5a9c1ce7ae394180c3624b2808043c9a Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Thu, 20 Aug 2020 09:48:32 -0500 Subject: [PATCH 11/18] Streamline fst4_decode. Add timer for downsampling. --- lib/decoder.f90 | 4 +- lib/fst4/get_fst4_bitmetrics.f90 | 19 ++++ lib/fst4_decode.f90 | 162 +++++++++++++------------------ 3 files changed, 88 insertions(+), 97 deletions(-) diff --git a/lib/decoder.f90 b/lib/decoder.f90 index 86725928d..e7b9ebfa2 100644 --- a/lib/decoder.f90 +++ b/lib/decoder.f90 @@ -196,7 +196,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample) params%nQSOProgress,params%nfqso,params%nfa,params%nfb, & params%nsubmode,ndepth,params%ntr,params%nexp_decode, & params%ntol,params%emedelay, & - logical(params%lapcqonly),mycall,hiscall,params%nfsplit,iwspr) + logical(params%lapcqonly),mycall,hiscall,iwspr) call timer('dec240 ',1) go to 800 endif @@ -210,7 +210,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample) params%nQSOProgress,params%nfqso,params%nfa,params%nfb, & params%nsubmode,ndepth,params%ntr,params%nexp_decode, & params%ntol,params%emedelay, & - logical(params%lapcqonly),mycall,hiscall,params%nfsplit,iwspr) + logical(params%lapcqonly),mycall,hiscall,iwspr) call timer('dec240 ',1) go to 800 endif diff --git a/lib/fst4/get_fst4_bitmetrics.f90 b/lib/fst4/get_fst4_bitmetrics.f90 index f224854e2..f34cb9322 100644 --- a/lib/fst4/get_fst4_bitmetrics.f90 +++ b/lib/fst4/get_fst4_bitmetrics.f90 @@ -11,6 +11,7 @@ subroutine get_fst4_bitmetrics(cd,nss,hmod,nmax,nhicoh,bitmetrics,s4,badsync) integer graymap(0:3) integer ip(1) integer hmod + integer hbits(2*NN) logical one(0:65535,0:15) ! 65536 8-symbol sequences, 16 bits logical first logical badsync @@ -122,10 +123,28 @@ subroutine get_fst4_bitmetrics(cd,nss,hmod,nmax,nhicoh,bitmetrics,s4,badsync) enddo enddo + hbits=0 + where(bitmetrics(:,1).ge.0) hbits=1 + ns1=count(hbits( 1: 16).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) + ns2=count(hbits( 77: 92).eq.(/1,1,1,0,0,1,0,0,1,0,1,1,0,0,0,1/)) + ns3=count(hbits(153:168).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) + ns4=count(hbits(229:244).eq.(/1,1,1,0,0,1,0,0,1,0,1,1,0,0,0,1/)) + ns5=count(hbits(305:320).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) + nsync_qual=ns1+ns2+ns3+ns4+ns5 + + if(nsync_qual.lt. 46) then + badsync=.true. + return + endif + call normalizebmet(bitmetrics(:,1),2*NN) call normalizebmet(bitmetrics(:,2),2*NN) call normalizebmet(bitmetrics(:,3),2*NN) call normalizebmet(bitmetrics(:,4),2*NN) + + scalefac=2.83 + bitmetrics=scalefac*bitmetrics + return end subroutine get_fst4_bitmetrics diff --git a/lib/fst4_decode.f90 b/lib/fst4_decode.f90 index 448e699c3..8a116bbbf 100644 --- a/lib/fst4_decode.f90 +++ b/lib/fst4_decode.f90 @@ -31,7 +31,7 @@ contains subroutine decode(this,callback,iwave,nutc,nQSOProgress,nfqso, & nfa,nfb,nsubmode,ndepth,ntrperiod,nexp_decode,ntol, & - emedelay,lapcqonly,mycall,hiscall,nfsplit,iwspr) + emedelay,lapcqonly,mycall,hiscall,iwspr) use timer_module, only: timer use packjt77 @@ -252,29 +252,10 @@ contains call four2a(c_bigfft,nfft1,1,-1,0) !r2c ! call blank2(nfa,nfb,nfft1,c_bigfft,iwave) - nhicoh=0 - if(hmod.eq.1) then - if(fMHz.lt.2.0) then - nsyncoh=8 ! Use N=8 for sync - nhicoh=1 ! Use N=1,2,4,8 for symbol estimation - else - nsyncoh=4 ! Use N=4 for sync - nhicoh=0 ! Use N=1,2,3,4 for symbol estimation - endif - else - if(hmod.eq.2) nsyncoh=1 - if(hmod.eq.4) nsyncoh=-2 - if(hmod.eq.8) nsyncoh=-4 - endif - - if( single_decode ) then - fa=max(100,nint(nfqso+1.5*hmod*baud-ntol)) - fb=min(4800,nint(nfqso+1.5*hmod*baud+ntol)) - else - fa=max(100,nfa) - fb=min(4800,nfb) - endif - + nhicoh=1 + nsyncoh=8 + fa=max(100,nint(nfqso+1.5*hmod*baud-ntol)) + fb=min(4800,nint(nfqso+1.5*hmod*baud+ntol)) minsync=1.2 if(ntrperiod.eq.15) minsync=1.15 @@ -296,54 +277,15 @@ contains ! Output array c2 is complex baseband sampled at 12000/ndown Sa/sec. ! The size of the downsampled c2 array is nfft2=nfft1/ndown + call timer('dwnsmpl ',0) call fst4_downsample(c_bigfft,nfft1,ndown,fc0,sigbw,c2) + call timer('dwnsmpl ',1) call timer('sync240 ',0) - fc1=0.0 - if(emedelay.lt.0.1) then ! search offsets from 0 s to 2 s - is0=1.5*nspsec - ishw=1.5*nspsec - else ! search plus or minus 1.5 s centered on emedelay - is0=nint((emedelay+1.0)*nspsec) - ishw=1.5*nspsec - endif - - smax=-1.e30 - do if=-12,12 - fc=fc1 + 0.1*baud*if - do istart=max(1,is0-ishw),is0+ishw,4*hmod - call sync_fst4(c2,istart,fc,hmod,nsyncoh,nfft2,nss, & - ntrperiod,fs2,sync) - if(sync.gt.smax) then - fc2=fc - isbest=istart - smax=sync - endif - enddo - enddo - - fc1=fc2 - is0=isbest - ishw=4*hmod - isst=1*hmod - - smax=0.0 - do if=-7,7 - fc=fc1 + 0.02*baud*if - do istart=max(1,is0-ishw),is0+ishw,isst - call sync_fst4(c2,istart,fc,hmod,nsyncoh,nfft2,nss, & - ntrperiod,fs2,sync) - if(sync.gt.smax) then - fc2=fc - isbest=istart - smax=sync - endif - enddo - enddo - + call fst4_sync_search(c2,nfft2,hmod,fs2,nss,ntrperiod,nsyncoh,emedelay,sbest,fcbest,isbest) call timer('sync240 ',1) - fc_synced = fc0 + fc2 + fc_synced = fc0 + fcbest dt_synced = (isbest-fs2)*dt2 !nominal dt is 1 second so frame starts at sample fs2 candidates(icand,3)=fc_synced candidates(icand,4)=isbest @@ -382,7 +324,11 @@ contains isbest=nint(candidates(icand,4)) xdt=(isbest-nspsec)/fs2 if(ntrperiod.eq.15) xdt=(isbest-real(nspsec)/2.0)/fs2 + + call timer('dwnsmpl ',0) call fst4_downsample(c_bigfft,nfft1,ndown,fc_synced,sigbw,c2) + call timer('dwnsmpl ',1) + do ijitter=0,jittermax if(ijitter.eq.0) ioffset=0 if(ijitter.eq.1) ioffset=1 @@ -392,32 +338,16 @@ contains cframe=c2(is0:is0+160*nss-1) bitmetrics=0 call timer('bitmetrc',0) - if(hmod.eq.1) then - call get_fst4_bitmetrics(cframe,nss,hmod,nblock,nhicoh,bitmetrics,s4,badsync) - else - call get_fst4_bitmetrics2(cframe,nss,hmod,nblock,bitmetrics,s4,badsync) - endif + call get_fst4_bitmetrics(cframe,nss,hmod,nblock,nhicoh,bitmetrics,s4,badsync) call timer('bitmetrc',1) if(badsync) cycle - hbits=0 - where(bitmetrics(:,1).ge.0) hbits=1 - ns1=count(hbits( 1: 16).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) - ns2=count(hbits( 77: 92).eq.(/1,1,1,0,0,1,0,0,1,0,1,1,0,0,0,1/)) - ns3=count(hbits(153:168).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) - ns4=count(hbits(229:244).eq.(/1,1,1,0,0,1,0,0,1,0,1,1,0,0,0,1/)) - ns5=count(hbits(305:320).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) - nsync_qual=ns1+ns2+ns3+ns4+ns5 - - if(nsync_qual.lt. 46) cycle !### Value ?? ### - scalefac=2.83 do il=1,4 llrs( 1: 60,il)=bitmetrics( 17: 76, il) llrs( 61:120,il)=bitmetrics( 93:152, il) llrs(121:180,il)=bitmetrics(169:228, il) llrs(181:240,il)=bitmetrics(245:304, il) enddo - llrs=scalefac*llrs apmag=maxval(abs(llrs(:,1)))*1.1 ntmax=nblock+nappasses(nQSOProgress) @@ -440,14 +370,8 @@ contains iaptype=0 endif - if(itry.gt.nblock) then - llr=llrs(:,1) - if(nblock.gt.1) then - if(hmod.eq.1) llr=llrs(:,3) - if(hmod.eq.2) llr=llrs(:,1) - if(hmod.eq.4) llr=llrs(:,2) - if(hmod.eq.8) llr=llrs(:,4) - endif + if(itry.gt.nblock) then ! do ap passes + llr=llrs(:,nblock) ! Use largest blocksize as the basis for AP passes iaptype=naptypes(nQSOProgress,itry-nblock) if(lapcqonly) iaptype=1 if(iaptype.ge.2 .and. apbits(1).gt.1) cycle ! No, or nonstandard, mycall @@ -486,7 +410,7 @@ contains if(iwspr.eq.0) then maxosd=2 Keff=91 - norder=3 + norder=4 call timer('d240_101',0) call decode240_101(llr,Keff,maxosd,norder,apmask,message101, & cw,ntype,nharderrors,dmin) @@ -556,8 +480,8 @@ contains fsig=fc_synced - 1.5*hmod*baud if(ex) then write(21,3021) nutc,icand,itry,nsyncoh,iaptype, & - ijitter,ntype,nsync_qual,nharderrors,dmin, & - sync,xsnr,xdt,fsig,w50,trim(msg) + ijitter,ntype,nsync_qual,nharderrors,dmin, & + sync,xsnr,xdt,fsig,w50,trim(msg) 3021 format(i6.6,6i3,2i4,f6.1,f7.2,f6.1,f6.2,f7.1,f7.3,1x,a) flush(21) endif @@ -799,6 +723,54 @@ contains return end subroutine get_candidates_fst4 + subroutine fst4_sync_search(c2,nfft2,hmod,fs2,nss,ntrperiod,nsyncoh,emedelay,sbest,fcbest,isbest) + complex c2(0:nfft2-1) + integer hmod + nspsec=int(fs2) + baud=fs2/real(nss) + fc1=0.0 + if(emedelay.lt.0.1) then ! search offsets from 0 s to 2 s + is0=1.5*nspsec + ishw=1.5*nspsec + else ! search plus or minus 1.5 s centered on emedelay + is0=nint((emedelay+1.0)*nspsec) + ishw=1.5*nspsec + endif + + sbest=-1.e30 + do if=-12,12 + fc=fc1 + 0.1*baud*if + do istart=max(1,is0-ishw),is0+ishw,4*hmod + call sync_fst4(c2,istart,fc,hmod,nsyncoh,nfft2,nss, & + ntrperiod,fs2,sync) + if(sync.gt.sbest) then + fcbest=fc + isbest=istart + sbest=sync + endif + enddo + enddo + + fc1=fcbest + is0=isbest + ishw=4*hmod + isst=1*hmod + + sbest=0.0 + do if=-7,7 + fc=fc1 + 0.02*baud*if + do istart=max(1,is0-ishw),is0+ishw,isst + call sync_fst4(c2,istart,fc,hmod,nsyncoh,nfft2,nss, & + ntrperiod,fs2,sync) + if(sync.gt.sbest) then + fcbest=fc + isbest=istart + sbest=sync + endif + enddo + enddo + end subroutine fst4_sync_search + subroutine dopspread(itone,iwave,nsps,nmax,ndown,hmod,i0,fc,fmid,w50) ! On "plotspec" special request, compute Doppler spread for a decoded signal From b9328b96c93dff44d43a78c89293bcdeba6c6d2b Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Fri, 21 Aug 2020 09:18:59 -0500 Subject: [PATCH 12/18] Tweaks to update the diagnostics that are written to fort.21. --- lib/fst4/decode240_101.f90 | 3 ++- lib/fst4/decode240_74.f90 | 3 ++- lib/fst4/get_fst4_bitmetrics.f90 | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/fst4/decode240_101.f90 b/lib/fst4/decode240_101.f90 index e924f00ec..4271a464c 100644 --- a/lib/fst4/decode240_101.f90 +++ b/lib/fst4/decode240_101.f90 @@ -140,8 +140,9 @@ subroutine decode240_101(llr,Keff,maxosd,norder,apmask,message101,cw,ntype,nhard hdec=0 where(llr .ge. 0) hdec=1 nxor=ieor(hdec,cw) + nharderror=sum(nxor) ! re-calculate nharderror based on input llrs dmin=sum(nxor*abs(llr)) - ntype=1+nosd + ntype=1+i return endif enddo diff --git a/lib/fst4/decode240_74.f90 b/lib/fst4/decode240_74.f90 index 224a2860d..be18f6e09 100644 --- a/lib/fst4/decode240_74.f90 +++ b/lib/fst4/decode240_74.f90 @@ -140,8 +140,9 @@ subroutine decode240_74(llr,Keff,maxosd,norder,apmask,message74,cw,ntype,nharder hdec=0 where(llr .ge. 0) hdec=1 nxor=ieor(hdec,cw) + nharderror=sum(nxor) ! nharderror based on input llrs dmin=sum(nxor*abs(llr)) - ntype=1+nosd + ntype=1+i return endif enddo diff --git a/lib/fst4/get_fst4_bitmetrics.f90 b/lib/fst4/get_fst4_bitmetrics.f90 index f34cb9322..e245db18c 100644 --- a/lib/fst4/get_fst4_bitmetrics.f90 +++ b/lib/fst4/get_fst4_bitmetrics.f90 @@ -1,4 +1,4 @@ -subroutine get_fst4_bitmetrics(cd,nss,hmod,nmax,nhicoh,bitmetrics,s4,badsync) +subroutine get_fst4_bitmetrics(cd,nss,hmod,nmax,nhicoh,bitmetrics,s4,nsync_qual,badsync) include 'fst4_params.f90' complex cd(0:NN*nss-1) From ecaca6af9f0f873c87ddd3421457a7ee6691e284 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Sat, 22 Aug 2020 09:42:34 -0500 Subject: [PATCH 13/18] Fix argument list in call to fet_fst4_bitmetrics.f90 --- lib/fst4_decode.f90 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/fst4_decode.f90 b/lib/fst4_decode.f90 index 8a116bbbf..444553618 100644 --- a/lib/fst4_decode.f90 +++ b/lib/fst4_decode.f90 @@ -338,7 +338,8 @@ contains cframe=c2(is0:is0+160*nss-1) bitmetrics=0 call timer('bitmetrc',0) - call get_fst4_bitmetrics(cframe,nss,hmod,nblock,nhicoh,bitmetrics,s4,badsync) + call get_fst4_bitmetrics(cframe,nss,hmod,nblock,nhicoh,bitmetrics, & + s4,nsync_qual,badsync) call timer('bitmetrc',1) if(badsync) cycle From d82b9f5b0e10e9cef76e3d823cf5b9f1244e52a0 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Mon, 24 Aug 2020 10:17:45 -0500 Subject: [PATCH 14/18] Speed up decoder by eliminating some complex multiples in sequence detection loop. Add timer calls for doppler spread calculation and sequence detection loop. --- lib/fst4/get_fst4_bitmetrics.f90 | 13 ++++++++++--- lib/fst4_decode.f90 | 2 ++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/fst4/get_fst4_bitmetrics.f90 b/lib/fst4/get_fst4_bitmetrics.f90 index e245db18c..69a649a04 100644 --- a/lib/fst4/get_fst4_bitmetrics.f90 +++ b/lib/fst4/get_fst4_bitmetrics.f90 @@ -1,5 +1,6 @@ subroutine get_fst4_bitmetrics(cd,nss,hmod,nmax,nhicoh,bitmetrics,s4,nsync_qual,badsync) + use timer_module, only: timer include 'fst4_params.f90' complex cd(0:NN*nss-1) complex cs(0:3,NN) @@ -84,6 +85,8 @@ subroutine get_fst4_bitmetrics(cd,nss,hmod,nmax,nhicoh,bitmetrics,s4,nsync_qual, return endif + + call timer('seqcorrs',0) bitmetrics=0.0 do nseq=1,nmax !Try coherent sequences of 1,2,3,4 or 1,2,4,8 symbols if(nseq.eq.1) nsym=1 @@ -100,11 +103,14 @@ subroutine get_fst4_bitmetrics(cd,nss,hmod,nmax,nhicoh,bitmetrics,s4,nsync_qual, s2=0 do i=0,nt-1 csum=0 - cterm=1 +! cterm=1 ! hmod.ne.1 + term=1 do j=0,nsym-1 ntone=mod(i/4**(nsym-1-j),4) - csum=csum+cs(graymap(ntone),ks+j)*cterm - cterm=cterm*conjg(cp(graymap(ntone))) + csum=csum+cs(graymap(ntone),ks+j)*term + term=-term +! csum=csum+cs(graymap(ntone),ks+j)*cterm ! hmod.ne.1 +! cterm=cterm*conjg(cp(graymap(ntone))) ! hmod.ne.1 enddo s2(i)=abs(csum) enddo @@ -122,6 +128,7 @@ subroutine get_fst4_bitmetrics(cd,nss,hmod,nmax,nhicoh,bitmetrics,s4,nsync_qual, enddo enddo enddo + call timer('seqcorrs',1) hbits=0 where(bitmetrics(:,1).ge.0) hbits=1 diff --git a/lib/fst4_decode.f90 b/lib/fst4_decode.f90 index 444553618..efe6a3798 100644 --- a/lib/fst4_decode.f90 +++ b/lib/fst4_decode.f90 @@ -455,10 +455,12 @@ contains endif inquire(file='plotspec',exist=ex) fmid=-999.0 + call timer('dopsprd ',0) if(ex) then call dopspread(itone,iwave,nsps,nmax,ndown,hmod, & isbest,fc_synced,fmid,w50) endif + call timer('dopsprd ',1) xsig=0 do i=1,NN xsig=xsig+s4(itone(i),i) From 5ca81a6507618adab704fbec6c16d406ef4b993f Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Fri, 28 Aug 2020 09:22:22 -0500 Subject: [PATCH 15/18] Use 3rd order polynomial fit to estimate the noise baseline. The polynomial fit is done over 400 Hz bandwidth for T/R periods longer than 15s, and over approx. 600 Hz (10 times the signal bandwidth) for T/R period of 15s. --- CMakeLists.txt | 1 + lib/fst4/fst4_baseline.f90 | 48 ++++++++++++++++++++++++++++++++++++++ lib/fst4_decode.f90 | 48 +++++++++++++++++++++++--------------- 3 files changed, 78 insertions(+), 19 deletions(-) create mode 100644 lib/fst4/fst4_baseline.f90 diff --git a/CMakeLists.txt b/CMakeLists.txt index 01ec7727e..a2a31b388 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -618,6 +618,7 @@ set (wsjt_FSRCS lib/fst4/osd240_101.f90 lib/fst4/osd240_74.f90 lib/fst4/get_crc24.f90 + lib/fst4/fst4_baseline.f90 ) # temporary workaround for a gfortran v7.3 ICE on Fedora 27 64-bit diff --git a/lib/fst4/fst4_baseline.f90 b/lib/fst4/fst4_baseline.f90 new file mode 100644 index 000000000..32776651a --- /dev/null +++ b/lib/fst4/fst4_baseline.f90 @@ -0,0 +1,48 @@ +subroutine fst4_baseline(s,np,ia,ib,npct,sbase) + +! Fit baseline to spectrum (for FST4) +! Input: s(npts) Linear scale in power +! Output: sbase(npts) Baseline + + implicit real*8 (a-h,o-z) + real*4 s(np),sw(np) + real*4 sbase(np) + real*4 base + real*8 x(1000),y(1000),a(5) + data nseg/8/ + + do i=ia,ib + sw(i)=10.0*log10(s(i)) !Convert to dB scale + enddo + + nterms=3 + nlen=(ib-ia+1)/nseg !Length of test segment + i0=(ib-ia+1)/2 !Midpoint + k=0 + do n=1,nseg !Loop over all segments + ja=ia + (n-1)*nlen + jb=ja+nlen-1 + call pctile(sw(ja),nlen,npct,base) !Find lowest npct of points + do i=ja,jb + if(sw(i).le.base) then + if (k.lt.1000) k=k+1 !Save all "lower envelope" points + x(k)=i-i0 + y(k)=sw(i) + endif + enddo + enddo + kz=k + a=0. + call polyfit(x,y,y,kz,nterms,0,a,chisqr) !Fit a low-order polynomial + sbase=0.0 + do i=ia,ib + t=i-i0 + sbase(i)=a(1)+t*(a(2)+t*(a(3))) + 0.2 +! write(51,3051) i,sw(i),sbase(i) +!3051 format(i8,2f12.3) + enddo + + sbase=10**(sbase/10.0) + + return +end subroutine fst4_baseline diff --git a/lib/fst4_decode.f90 b/lib/fst4_decode.f90 index efe6a3798..d609df115 100644 --- a/lib/fst4_decode.f90 +++ b/lib/fst4_decode.f90 @@ -49,7 +49,7 @@ contains complex, allocatable :: cframe(:) complex, allocatable :: c_bigfft(:) !Complex waveform real llr(240),llrs(240,4) - real candidates(200,4) + real candidates(200,5) real bitmetrics(320,4) real s4(0:3,NN) real minsync @@ -254,14 +254,19 @@ contains nhicoh=1 nsyncoh=8 - fa=max(100,nint(nfqso+1.5*hmod*baud-ntol)) - fb=min(4800,nint(nfqso+1.5*hmod*baud+ntol)) - minsync=1.2 + if(iwspr.eq.1) then + fa=1400.0 + fb=1600.0 + else + fa=max(100,nint(nfqso+1.5*hmod*baud-ntol)) + fb=min(4800,nint(nfqso+1.5*hmod*baud+ntol)) + endif + minsync=1.20 if(ntrperiod.eq.15) minsync=1.15 ! Get first approximation of candidate frequencies call get_candidates_fst4(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & - minsync,ncand,candidates,base) + minsync,ncand,candidates) ndecodes=0 decodes=' ' @@ -317,7 +322,7 @@ contains enddo ncand=ic xsnr=0. - +!write(*,*) 'ncand ',ncand do icand=1,ncand sync=candidates(icand,2) fc_synced=candidates(icand,3) @@ -465,6 +470,7 @@ contains do i=1,NN xsig=xsig+s4(itone(i),i) enddo + base=candidates(icand,5) arg=600.0*(xsig/base)-1.0 if(arg.gt.0.0) then xsnr=10*log10(arg)-35.5-12.5*log10(nsps/8200.0) @@ -645,14 +651,15 @@ contains end subroutine fst4_downsample subroutine get_candidates_fst4(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & - minsync,ncand,candidates,base) + minsync,ncand,candidates) complex c_bigfft(0:nfft1/2) !Full length FFT of raw data integer hmod !Modulation index (submode) integer im(1) !For maxloc - real candidates(200,4) !Candidate list + real candidates(200,5) !Candidate list real, allocatable :: s(:) !Low resolution power spectrum real, allocatable :: s2(:) !CCF of s() with 4 tones + real, allocatable :: sbase(:) !noise baseline estimate real xdb(-3:3) !Model 4-tone CCF peaks real minsync data xdb/0.25,0.50,0.75,1.0,0.75,0.50,0.25/ @@ -668,17 +675,17 @@ contains signal_bw=4*(12000.0/nsps)*hmod analysis_bw=min(4800.0,fb)-max(100.0,fa) xnoise_bw=10.0*signal_bw !Is this a good compromise? - if(analysis_bw.gt.xnoise_bw) then - ina=ia - inb=ib - else - fcenter=(fa+fb)/2.0 !If noise_bw > analysis_bw, - fl = max(100.0,fcenter-xnoise_bw/2.)/df2 !we'll search over noise_bw + if(xnoise_bw .lt. 400.0) xnoise_bw=400.0 + if(analysis_bw.gt.xnoise_bw) then !Estimate noise baseline over analysis bw + ina=0.9*ia + inb=min(int(1.1*ib),nfft1/2) + else !Estimate noise baseline over noise bw + fcenter=(fa+fb)/2.0 + fl = max(100.0,fcenter-xnoise_bw/2.)/df2 fh = min(4800.0,fcenter+xnoise_bw/2.)/df2 ina=nint(fl) inb=nint(fh) endif - nnw=nint(48000.*nsps*2./fs) allocate (s(nnw)) s=0. !Compute low-resolution power spectrum @@ -692,12 +699,16 @@ contains ina=max(ina,1+3*hmod) !Don't run off the ends inb=min(inb,nnw-3*hmod) allocate (s2(nnw)) + allocate (sbase(nnw)) s2=0. do i=ina,inb !Compute CCF of s() and 4 tones s2(i)=s(i-hmod*3) + s(i-hmod) +s(i+hmod) +s(i+hmod*3) enddo - call pctile(s2(ina+hmod*3:inb-hmod*3),inb-ina+1-hmod*6,30,base) - s2=s2/base !Normalize wrt noise level + npct=30 + call fst4_baseline(s2,nnw,ina+hmod*3,inb-hmod*3,npct,sbase) + if(any(sbase(ina:inb).le.0.0)) return + s2(ina:inb)=s2(ina:inb)/sbase(ina:inb) !Normalize wrt noise level + ncand=0 candidates=0 if(ia.lt.3) ia=3 @@ -717,12 +728,11 @@ contains s2(k)=max(0.,s2(k)-0.9*pval*xdb(i)) endif enddo -! s2(max(1,iploc-2*hmod*3):min(nnw,iploc+2*hmod*3))=0.0 ncand=ncand+1 candidates(ncand,1)=df2*iploc !Candidate frequency candidates(ncand,2)=pval !Rough estimate of SNR + candidates(ncand,5)=sbase(iploc) enddo - return end subroutine get_candidates_fst4 From f0669360438687f21b20189bc752b7675953d5fb Mon Sep 17 00:00:00 2001 From: K9AN Date: Fri, 28 Aug 2020 12:25:17 -0500 Subject: [PATCH 16/18] Remove an unused variable from fst4_decode --- lib/fst4_decode.f90 | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/fst4_decode.f90 b/lib/fst4_decode.f90 index d609df115..a3c2e2a98 100644 --- a/lib/fst4_decode.f90 +++ b/lib/fst4_decode.f90 @@ -57,7 +57,6 @@ contains integer itone(NN) integer hmod integer*1 apmask(240),cw(240) - integer*1 hbits(320) integer*1 message101(101),message74(74),message77(77) integer*1 rvec(77) integer apbits(240) From b5392486248324a2fd5d4691b61a3f7d25ca35a0 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Tue, 1 Sep 2020 17:31:44 +0100 Subject: [PATCH 17/18] Remove some diagnostic prints --- Configuration.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Configuration.cpp b/Configuration.cpp index 1f94b83e8..43c0e77de 100644 --- a/Configuration.cpp +++ b/Configuration.cpp @@ -901,7 +901,7 @@ auto Configuration::special_op_id () const -> SpecialOperatingActivity void Configuration::set_location (QString const& grid_descriptor) { // change the dynamic grid - qDebug () << "Configuration::set_location - location:" << grid_descriptor; + // qDebug () << "Configuration::set_location - location:" << grid_descriptor; m_->dynamic_grid_ = grid_descriptor.trimmed (); } @@ -2610,7 +2610,7 @@ void Configuration::impl::transceiver_frequency (Frequency f) current_offset_ = stations_.offset (f); cached_rig_state_.frequency (apply_calibration (f + current_offset_)); - qDebug () << "Configuration::impl::transceiver_frequency: n:" << transceiver_command_number_ + 1 << "f:" << f; + // qDebug () << "Configuration::impl::transceiver_frequency: n:" << transceiver_command_number_ + 1 << "f:" << f; Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_); } @@ -2636,7 +2636,7 @@ void Configuration::impl::transceiver_tx_frequency (Frequency f) cached_rig_state_.tx_frequency (apply_calibration (f + current_tx_offset_)); } - qDebug () << "Configuration::impl::transceiver_tx_frequency: n:" << transceiver_command_number_ + 1 << "f:" << f; + // qDebug () << "Configuration::impl::transceiver_tx_frequency: n:" << transceiver_command_number_ + 1 << "f:" << f; Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_); } } @@ -2645,7 +2645,7 @@ void Configuration::impl::transceiver_mode (MODE m) { cached_rig_state_.online (true); // we want the rig online cached_rig_state_.mode (m); - qDebug () << "Configuration::impl::transceiver_mode: n:" << transceiver_command_number_ + 1 << "m:" << m; + // qDebug () << "Configuration::impl::transceiver_mode: n:" << transceiver_command_number_ + 1 << "m:" << m; Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_); } @@ -2654,7 +2654,7 @@ void Configuration::impl::transceiver_ptt (bool on) cached_rig_state_.online (true); // we want the rig online set_cached_mode (); cached_rig_state_.ptt (on); - qDebug () << "Configuration::impl::transceiver_ptt: n:" << transceiver_command_number_ + 1 << "on:" << on; + // qDebug () << "Configuration::impl::transceiver_ptt: n:" << transceiver_command_number_ + 1 << "on:" << on; Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_); } From a00473fa9c234bafc0be3bee553ebcd7bbeb9650 Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Tue, 1 Sep 2020 17:32:22 +0100 Subject: [PATCH 18/18] Select band by wavelength only if a working frequency is available --- validators/LiveFrequencyValidator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/validators/LiveFrequencyValidator.cpp b/validators/LiveFrequencyValidator.cpp index 6d2205807..873224920 100644 --- a/validators/LiveFrequencyValidator.cpp +++ b/validators/LiveFrequencyValidator.cpp @@ -54,7 +54,7 @@ void LiveFrequencyValidator::fixup (QString& input) const input = input.toLower (); QVector frequencies; - for (auto const& item : frequencies_->frequency_list ()) + for (auto const& item : *frequencies_) { if (bands_->find (item.frequency_) == input) {