diff --git a/Versions.cmake b/Versions.cmake index f74a2fa43..4c319dae9 100644 --- a/Versions.cmake +++ b/Versions.cmake @@ -2,5 +2,5 @@ set (WSJTX_VERSION_MAJOR 2) set (WSJTX_VERSION_MINOR 0) set (WSJTX_VERSION_PATCH 0) -set (WSJTX_RC 1) # release candidate number, comment out or zero for development versions +set (WSJTX_RC 2) # release candidate number, comment out or zero for development versions set (WSJTX_VERSION_IS_RELEASE 0) # set to 1 for final release build diff --git a/displaytext.cpp b/displaytext.cpp index 394fe658d..b17421a74 100644 --- a/displaytext.cpp +++ b/displaytext.cpp @@ -178,13 +178,12 @@ QString DisplayText::appendWorkedB4(QString message, QString const& callsign, QS if(call.length()<3) return message; if(!call.contains(QRegExp("[0-9]|[A-Z]"))) return message; + logBook.match(/*in*/call,grid,/*out*/countryName,callWorkedBefore,countryWorkedBefore,gridB4); + logBook.match(/*in*/call,grid,/*out*/countryName,callB4onBand,countryB4onBand,gridB4onBand, + /*in*/ currentBand); if(grid=="") { gridB4=true; gridB4onBand=true; - } else { - logBook.match(/*in*/call,grid,/*out*/countryName,callWorkedBefore,countryWorkedBefore,gridB4); - logBook.match(/*in*/call,grid,/*out*/countryName,callB4onBand,countryB4onBand,gridB4onBand, - /*in*/ currentBand); } message = message.trimmed (); diff --git a/lib/77bit/encode77.f90 b/lib/77bit/encode77.f90 index 3c81e07f2..987efc4f6 100644 --- a/lib/77bit/encode77.f90 +++ b/lib/77bit/encode77.f90 @@ -6,6 +6,7 @@ program encode77 character msg*37,cerr*1 character*77 c77 character*80 infile + logical unpk77_success nargs=iargc() if(nargs.ne.1 .and.nargs.ne.2) then @@ -33,7 +34,7 @@ program encode77 i3=-1 n3=-1 call pack77(msg0(1:37),i3,n3,c77) - call unpack77(c77,msg) + call unpack77(c77,msg,unpk77_success) cerr=' ' if(msg.ne.msg0(1:37)) cerr='*' if(i3.eq.0) write(*,1004) i3,n3,cerr,msg0(1:37),msg diff --git a/lib/77bit/g5 b/lib/77bit/g5 deleted file mode 100644 index 70cffcefa..000000000 --- a/lib/77bit/g5 +++ /dev/null @@ -1,4 +0,0 @@ -gfortran -c -O2 ../packjt.f90 -gfortran -o t5 -O2 t5.f90 ../deg2grid.f90 ../grid2deg.f90 \ - ../fix_contest_msg.f90 ../to_contest_msg.f90 ../fmtmsg.f90 \ - ../azdist.f90 ../geodist.f90 packjt.o diff --git a/lib/77bit/packjt77.f90 b/lib/77bit/packjt77.f90 index 553f1a01b..24d41ec04 100644 --- a/lib/77bit/packjt77.f90 +++ b/lib/77bit/packjt77.f90 @@ -1,10 +1,11 @@ module packjt77 -! These variables are accessible from outside via "use packjt": - parameter (MAXHASH=100) +! These variables are accessible from outside via "use packjt77": + parameter (MAXHASH=1000,MAXRECENT=10) character*13 callsign(MAXHASH) integer ihash10(MAXHASH),ihash12(MAXHASH),ihash22(MAXHASH) integer n28a,n28b,nzhash + character*13 recent_calls(MAXRECENT) contains @@ -92,8 +93,9 @@ subroutine save_hash_call(c13,n10,n12,n22) character*13 c13 logical first + data first/.true./ save first - + if(first) then ihash10=-1 ihash12=-1 @@ -102,6 +104,8 @@ subroutine save_hash_call(c13,n10,n12,n22) nzhash=0 first=.false. endif + + if(c13(1:1).eq.' ' .or. c13(1:5).eq.'<...>') return n10=ihashcall(c13,10) n12=ihashcall(c13,12) @@ -155,9 +159,10 @@ subroutine pack77(msg0,i3,n3,c77) ! Check 0.3 and 0.4 (ARRL Field Day exchange) call pack77_03(nwords,w,i3,n3,c77) if(i3.ge.0) go to 900 + if(nwords.ge.2) go to 100 -! Check 0.5 (telemetry) -5 i0=index(msg,' ') + ! Check 0.5 (telemetry) +5 i0=index(msg,' ') c18=msg(1:i0-1)//' ' c18=adjustr(c18) ntel=-99 @@ -211,7 +216,7 @@ subroutine unpack77(c77,msg,unpk77_success) character*4 grid4,cserial character*3 csec(NSEC) character*38 c - logical unpk77_success + logical unpk28_success,unpk77_success data c/' 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ/'/ data csec/ & @@ -260,8 +265,10 @@ subroutine unpack77(c77,msg,unpk77_success) write(crpt,1012) irpt 1012 format(i3.2) if(irpt.ge.0) crpt(1:1)='+' - call unpack28(n28a,call_1) - call unpack28(n28b,call_2) + call unpack28(n28a,call_1,unpk28_success) + if(.not.unpk28_success .or. n28a.le.2) unpk77_success=.false. + call unpack28(n28b,call_2,unpk28_success) + if(.not.unpk28_success .or. n28b.le.2) unpk77_success=.false. call hash10(n10,call_3) if(call_3(1:1).eq.'<') then msg=trim(call_1)//' RR73; '//trim(call_2)//' '//trim(call_3)// & @@ -274,7 +281,8 @@ subroutine unpack77(c77,msg,unpk77_success) ! 0.2 PA3XYZ/P R 590003 IO91NP 28 1 1 3 12 25 70 EU VHF contest read(c77,1020) n28a,ip,ir,irpt,iserial,igrid6 1020 format(b28,2b1,b3,b12,b25) - call unpack28(n28a,call_1) + call unpack28(n28a,call_1,unpk28_success) + if(.not.unpk28_success .or. n28a.le.2) unpk77_success=.false. nrs=52+irpt if(ip.eq.1) call_1=trim(call_1)//'/P'//' ' write(cexch,1022) nrs,iserial @@ -304,11 +312,14 @@ subroutine unpack77(c77,msg,unpk77_success) ! 0.4 WA9XYZ KA1ABC R 32A EMA 28 28 1 4 3 7 71 ARRL Field Day read(c77,1030) n28a,n28b,ir,intx,nclass,isec 1030 format(2b28,b1,b4,b3,b7) - if(isec.gt.NSEC .or. isec.lt.1) unpk77_success=.false. - if(isec.gt.NSEC) isec=NSEC !### Check range for other params? ### - if(isec.lt.1) isec=1 !### Flag these so they aren't printed? ### - call unpack28(n28a,call_1) - call unpack28(n28b,call_2) + if(isec.gt.NSEC .or. isec.lt.1) then + unpk77_success=.false. + isec=1 + endif + call unpack28(n28a,call_1,unpk28_success) + if(.not.unpk28_success .or. n28a.le.2) unpk77_success=.false. + call unpack28(n28b,call_2,unpk28_success) + if(.not.unpk28_success .or. n28b.le.2) unpk77_success=.false. ntx=intx+1 if(n3.eq.4) ntx=ntx+16 write(cntx(1:2),1032) ntx @@ -339,16 +350,23 @@ subroutine unpack77(c77,msg,unpk77_success) ! Type 1 (standard message) or Type 2 ("/P" form for EU VHF contest) read(c77,1000) n28a,ipa,n28b,ipb,ir,igrid4,i3 1000 format(2(b28,b1),b1,b15,b3) - call unpack28(n28a,call_1) - call unpack28(n28b,call_2) + call unpack28(n28a,call_1,unpk28_success) + if(.not.unpk28_success) unpk77_success=.false. + call unpack28(n28b,call_2,unpk28_success) + if(.not.unpk28_success) unpk77_success=.false. if(call_1(1:3).eq.'CQ_') call_1(3:3)=' ' - i=index(call_1,' ') - if(i.ge.4 .and. ipa.eq.1 .and. i3.eq.1) call_1(i:i+1)='/R' - if(i.ge.4 .and. ipa.eq.1 .and. i3.eq.2) call_1(i:i+1)='/P' - i=index(call_2,' ') - if(i.ge.4 .and. ipb.eq.1 .and. i3.eq.1) call_2(i:i+1)='/R' - if(i.ge.4 .and. ipb.eq.1 .and. i3.eq.2) call_2(i:i+1)='/P' - + if(index(call_1,'<').le.0) then + i=index(call_1,' ') + if(i.ge.4 .and. ipa.eq.1 .and. i3.eq.1) call_1(i:i+1)='/R' + if(i.ge.4 .and. ipa.eq.1 .and. i3.eq.2) call_1(i:i+1)='/P' + if(i.ge.4) call add_call_to_recent_calls(call_1) + endif + if(index(call_2,'<').le.0) then + i=index(call_2,' ') + if(i.ge.4 .and. ipb.eq.1 .and. i3.eq.1) call_2(i:i+1)='/R' + if(i.ge.4 .and. ipb.eq.1 .and. i3.eq.2) call_2(i:i+1)='/P' + if(i.ge.4) call add_call_to_recent_calls(call_2) + endif if(igrid4.le.MAXGRID4) then n=igrid4 j1=n/(18*10*10) @@ -389,8 +407,10 @@ subroutine unpack77(c77,msg,unpk77_success) imult=nexch-8000 nserial=-1 endif - call unpack28(n28a,call_1) - call unpack28(n28b,call_2) + call unpack28(n28a,call_1,unpk28_success) + if(.not.unpk28_success) unpk77_success=.false. + call unpack28(n28b,call_2,unpk28_success) + if(.not.unpk28_success) unpk77_success=.false. imult=0 nserial=0 if(nexch.gt.8000) imult=nexch-8000 @@ -441,6 +461,7 @@ subroutine unpack77(c77,msg,unpk77_success) msg='CQ '//trim(call_2) endif endif + if(msg(1:4).eq.'CQ <') unpk77_success=.false. return end subroutine unpack77 @@ -451,7 +472,6 @@ subroutine pack28(c13,n28) ! integer. parameter (NTOKENS=2063592,MAX22=4194304) - integer nc(6) logical is_digit,is_letter character*13 c13 character*6 callsign @@ -465,7 +485,6 @@ subroutine pack28(c13,n28) data a2/'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'/ data a3/'0123456789'/ data a4/' ABCDEFGHIJKLMNOPQRSTUVWXYZ'/ - data nc/37,36,19,27,27,27/ is_digit(c)=c.ge.'0' .and. c.le.'9' is_letter(c)=c.ge.'A' .and. c.le.'Z' @@ -523,6 +542,7 @@ subroutine pack28(c13,n28) endif endif endif + ! Check for <...> callsign if(c13(1:1).eq.'<')then call save_hash_call(c13,n10,n12,n22) !Save callsign in hash table @@ -557,6 +577,7 @@ subroutine pack28(c13,n28) n=len(trim(c13)) ! This is a standard callsign + call save_hash_call(c13,n10,n12,n22) !Save callsign in hash table if(iarea.eq.2) callsign=' '//c13(1:5) if(iarea.eq.3) callsign=c13(1:6) i1=index(a1,callsign(1:1))-1 @@ -569,15 +590,15 @@ subroutine pack28(c13,n28) 27*i5 + i6 n28=n28 + NTOKENS + MAX22 -900 n28=iand(n28,2**28-1) +900 n28=iand(n28,ishft(1,28)-1) return end subroutine pack28 -subroutine unpack28(n28_0,c13) +subroutine unpack28(n28_0,c13,success) parameter (NTOKENS=2063592,MAX22=4194304) - integer nc(6) + logical success character*13 c13 character*37 c1 character*36 c2 @@ -587,8 +608,8 @@ subroutine unpack28(n28_0,c13) data c2/'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'/ data c3/'0123456789'/ data c4/' ABCDEFGHIJKLMNOPQRSTUVWXYZ'/ - data nc/37,36,19,27,27,27/ + success=.true. n28=n28_0 if(n28.lt.NTOKENS) then ! Special tokens DE, QRZ, CQ, CQ_nnn, CQ_aaaa @@ -641,7 +662,10 @@ subroutine unpack28(n28_0,c13) c13=adjustl(c13) 900 i0=index(c13,' ') - if(i0.lt.len(trim(c13))) c13='QU1RK' + if(i0.lt.len(trim(c13))) then + c13='QU1RK' + success=.false. + endif return end subroutine unpack28 @@ -811,7 +835,7 @@ subroutine pack77_03(nwords,w,i3,n3,c77) if(.not.ok1 .or. .not.ok2) return isec=-1 do i=1,NSEC - if(csec(i).eq.w(nwords)) then + if(csec(i).eq.w(nwords)(1:3)) then isec=i exit endif @@ -1087,56 +1111,114 @@ end subroutine pack77_4 subroutine packtext77(c13,c71) - real*16 q character*13 c13,w character*71 c71 character*42 c + character*1 qa(10),qb(10) data c/' 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+-./?'/ - q=0.q0 + call mp_short_init + qa=char(0) w=adjustr(c13) do i=1,13 j=index(c,w(i:i))-1 if(j.lt.0) j=0 - q=42.q0*q + j + call mp_short_mult(qb,qa(2:10),9,42) !qb(1:9)=42*qa(2:9) + call mp_short_add(qa,qb(2:10),9,j) !qa(1:9)=qb(2:9)+j enddo - do i=71,1,-1 - c71(i:i)='0' - n=mod(q,2.q0) - q=q/2.q0 - if(n.eq.1) then - c71(i:i)='1' - q=q-0.q5 - endif - enddo + write(c71,1010) qa(2:10) +1010 format(b7.7,8b8.8) return end subroutine packtext77 - subroutine unpacktext77(c71,c13) - real*16 q,q1 - integer*8 n1,n2 + integer*1 ia(10) + character*1 qa(10),qb(10) character*13 c13 character*71 c71 character*42 c + equivalence (qa,ia),(qb,ib) data c/' 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+-./?'/ - read(c71,1001) n1,n2 -1001 format(b63,b8) - q=n1*256.q0 + n2 + qa(1)=char(0) + read(c71,1010) qa(2:10) +1010 format(b7.7,8b8.8) do i=13,1,-1 - q1=mod(q,42.q0) - j=q1+1.q0 - c13(i:i)=c(j:j) - q=(q-q1)/42.q0 + call mp_short_div(qb,qa(2:10),9,42,ir) + c13(i:i)=c(ir+1:ir+1) + qa(2:10)=qb(1:9) enddo return end subroutine unpacktext77 +subroutine mp_short_ops(w,u) + character*1 w(*),u(*) + integer i,ireg,j,n,ir,iv,ii1,ii2 + character*1 creg(4) + save ii1,ii2 + equivalence (ireg,creg) + + entry mp_short_init + ireg=256*ichar('2')+ichar('1') + do j=1,4 + if (creg(j).eq.'1') ii1=j + if (creg(j).eq.'2') ii2=j + enddo + return + + entry mp_short_add(w,u,n,iv) + ireg=256*iv + do j=n,1,-1 + ireg=ichar(u(j))+ichar(creg(ii2)) + w(j+1)=creg(ii1) + enddo + w(1)=creg(ii2) + return + + entry mp_short_mult(w,u,n,iv) + ireg=0 + do j=n,1,-1 + ireg=ichar(u(j))*iv+ichar(creg(ii2)) + w(j+1)=creg(ii1) + enddo + w(1)=creg(ii2) + return + + entry mp_short_div(w,u,n,iv,ir) + ir=0 + do j=1,n + i=256*ir+ichar(u(j)) + w(j)=char(i/iv) + ir=mod(i,iv) + enddo + return + + return +end subroutine mp_short_ops + +subroutine add_call_to_recent_calls(callsign) + + character*13 callsign + logical ladd +! only add if the callsign is not already on the list + ladd=.true. + do i=1,MAXRECENT-1 ! if callsign is at the end of the list add it again + if(recent_calls(i).eq.callsign) ladd=.false. + enddo + + if(ladd) then + do i=MAXRECENT,2,-1 + recent_calls(i)=recent_calls(i-1) + enddo + recent_calls(1)=callsign + endif + + return +end subroutine add_call_to_recent_calls end module packjt77 diff --git a/lib/77bit/parse77.f90 b/lib/77bit/parse77.f90 index 62c3cc785..a0a8b8618 100644 --- a/lib/77bit/parse77.f90 +++ b/lib/77bit/parse77.f90 @@ -2,6 +2,9 @@ subroutine parse77(msg,i3,n3) use packjt77 character msg*37,c77*77 + + i3=-1 + n3=-1 call pack77(msg,i3,n3,c77) return diff --git a/lib/ft8/ft8b_2.f90 b/lib/ft8/ft8b_2.f90 index 5db727168..3bfee314f 100644 --- a/lib/ft8/ft8b_2.f90 +++ b/lib/ft8/ft8b_2.f90 @@ -335,13 +335,13 @@ subroutine ft8b_2(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, & ios=mod(itone(i)+4,7) xnoi=xnoi+s8(ios,i)**2 enddo - xsnr=0.001 if(xnoi.gt.0 .and. xnoi.lt.xsig) xsnr=xsig/xnoi-1.0 xsnr=10.0*log10(xsnr)-27.0 -! need to reconcile signal normalization between this routine and the old ft8b_1 so -! that SNRs come out the same. - xsnr2=db(xsig/xbase - 1.0) - 32.0 + xbase=10**(xbase/10.0) +! factor=xnoi/xbase + factor=3.6e6 + xsnr2=10*log10(xsig/xbase/factor-1.0)-27.0 ! if(.not.nagain) xsnr=xsnr2 if(xsnr .lt. -24.0) xsnr=-24.0 diff --git a/lib/ft8/ft8sim2.f90 b/lib/ft8/ft8sim2.f90 index d45d9167d..b06a5ff75 100644 --- a/lib/ft8/ft8sim2.f90 +++ b/lib/ft8/ft8sim2.f90 @@ -62,7 +62,9 @@ program ft8sim2 if(snrdb.gt.90.0) sig=1.0 txt=NN*NSPS/12000.0 -! Source-encode, then get itone() + ! Source-encode, then get itone() + i3=-1 + n3=-1 call pack77(msg37,i3,n3,c77) call genft8_174_91(msg37,i3,n3,msgsent37,msgbits,itone) diff --git a/lib/ft8/genft8_174_91.f90 b/lib/ft8/genft8_174_91.f90 index d56187d6c..c9b2a7cd7 100644 --- a/lib/ft8/genft8_174_91.f90 +++ b/lib/ft8/genft8_174_91.f90 @@ -14,8 +14,10 @@ subroutine genft8_174_91(msg,i3,n3,msgsent,msgbits,itone) data icos7/3,1,4,0,6,5,2/ !Costas 7x7 tone pattern data graymap/0,1,3,2,5,6,4,7/ + i3=-1 + n3=-1 call pack77(msg,i3,n3,c77) - call unpack77(c77,msgsent,unpk77_success) + call unpack77(c77,msgsent,unpk77_success) read(c77,'(77i1)',err=1) msgbits go to 2 diff --git a/lib/ft8/sync8.f90 b/lib/ft8/sync8.f90 index f7510758f..c4d3d3efa 100644 --- a/lib/ft8/sync8.f90 +++ b/lib/ft8/sync8.f90 @@ -39,11 +39,6 @@ subroutine sync8(dd,nfa,nfb,syncmin,nfqso,ldecode77,maxcand,s,candidate,ncand,sb savg=savg + s(1:NH1,j) !Average spectrum enddo call baseline(savg,nfa,nfb,sbase) -! savg=savg/NHSYM -! do i=1,NH1 -! write(51,3051) i*df,savg(i),db(savg(i)) -!3051 format(f10.3,e12.3,f12.3) -! enddo ia=max(1,nint(nfa/df)) ib=nint(nfb/df) diff --git a/lib/genmsk40.f90 b/lib/genmsk40.f90 index 3310b1066..80411819f 100644 --- a/lib/genmsk40.f90 +++ b/lib/genmsk40.f90 @@ -1,7 +1,7 @@ subroutine genmsk40(msg,msgsent,ichk,itone,itype) use hashing - character*22 msg,msgsent,hashmsg + character*37 msg,msgsent,hashmsg character*4 crpt,rpt(0:15) logical first integer*4 itone(144) diff --git a/lib/genmsk_128_90.f90 b/lib/genmsk_128_90.f90 index f1e82f683..7ced79f29 100644 --- a/lib/genmsk_128_90.f90 +++ b/lib/genmsk_128_90.f90 @@ -46,6 +46,7 @@ subroutine genmsk_128_90(msg0,ichk,msgsent,i4tone,itype) enddo endif + itype=1 if(msg0(1:1).eq.'@') then !Generate a fixed tone read(msg0(2:5),*,end=1,err=1) nfreq !at specified frequency go to 2 @@ -72,7 +73,9 @@ subroutine genmsk_128_90(msg0,ichk,msgsent,i4tone,itype) go to 999 endif - call pack77(message,i3,n3,c77) + i3=-1 + n3=-1 + call pack77(message,i3,n3,c77) call unpack77(c77,msgsent,unpk77_success) !Unpack to get msgsent if(ichk.eq.1) go to 999 read(c77,"(77i1)") msgbits diff --git a/lib/msk144decodeframe.f90 b/lib/msk144decodeframe.f90 index 4fcb2cfe9..de039aadc 100644 --- a/lib/msk144decodeframe.f90 +++ b/lib/msk144decodeframe.f90 @@ -1,9 +1,8 @@ -subroutine msk144decodeframe(c,softbits,msgreceived,nsuccess,recent_calls,nrecent) +subroutine msk144decodeframe(c,softbits,msgreceived,nsuccess) ! use timer_module, only: timer use packjt77 parameter (NSPM=864) character*37 msgreceived - character*12 recent_calls(nrecent) character*77 c77 complex cb(42) complex cfac,cca,ccb @@ -101,7 +100,13 @@ subroutine msk144decodeframe(c,softbits,msgreceived,nsuccess,recent_calls,nrecen if( nharderror .ge. 0 .and. nharderror .lt. 18 ) then nsuccess=1 write(c77,'(77i1)') decoded77 - call unpack77(c77,msgreceived,unpk77_success) + 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 + call unpack77(c77,msgreceived,unpk77_success) + if(.not.unpk77_success) nsuccess=0 + endif endif return diff --git a/lib/msk144sim.f90 b/lib/msk144sim.f90 index 32da98f72..fe2959cea 100644 --- a/lib/msk144sim.f90 +++ b/lib/msk144sim.f90 @@ -38,8 +38,13 @@ program msk144sim ichk=0 itype=1 call genmsk_128_90(msg,ichk,msgsent,itone,itype) - twopi=8.d0*atan(1.d0) + write(*,*) 'Requested message: ',msg + write(*,*) 'Message sent : ',msgsent + write(*,*) 'Tones: ' + write(*,'(1x,72i1)') itone(1:72) + write(*,'(1x,72i1)') itone(73:144) + twopi=8.d0*atan(1.d0) nsym=144 nsps=6*nslow if( itone(41) .lt. 0 ) nsym=40 @@ -49,7 +54,7 @@ program msk144sim phi=0.0 k=0 nreps=NMAX/(nsym*nsps) - print*,nsym,nslow,nsps,baud,freq + do jrep=1,nreps do i=1,nsym if( itone(i) .eq. 0 ) then diff --git a/lib/msk144spd.f90 b/lib/msk144spd.f90 index 92ed56162..2bc6dcfef 100644 --- a/lib/msk144spd.f90 +++ b/lib/msk144spd.f90 @@ -1,13 +1,13 @@ subroutine msk144spd(cbig,n,ntol,nsuccess,msgreceived,fc,fret,tret,navg,ct, & - softbits,recent_calls,nrecent) + softbits) ! MSK144 short-ping-decoder + use packjt77 use timer_module, only: timer parameter (NSPM=864, MAXSTEPS=100, NFFT=NSPM, MAXCAND=5, NPATTERNS=6) character*37 msgreceived - character*12 recent_calls(nrecent) complex cbig(n) complex cdat(3*NSPM) !Analytic signal complex c(NSPM) @@ -179,8 +179,7 @@ subroutine msk144spd(cbig,n,ntol,nsuccess,msgreceived,fc,fret,tret,navg,ct, & if( is.eq.2) ic0=max(1,ic0-1) if( is.eq.3) ic0=min(NSPM,ic0+1) ct=cshift(c,ic0-1) - call msk144decodeframe(ct,softbits,msgreceived,ndecodesuccess, & - recent_calls,nrecent) + call msk144decodeframe(ct,softbits,msgreceived,ndecodesuccess) if( ndecodesuccess .gt. 0 ) then tret=(nstart(icand)+NSPM/2)/fs fret=fest diff --git a/lib/msk40decodeframe.f90 b/lib/msk40decodeframe.f90 index ae75ddf95..51c9346a8 100644 --- a/lib/msk40decodeframe.f90 +++ b/lib/msk40decodeframe.f90 @@ -1,19 +1,19 @@ subroutine msk40decodeframe(c,mycall,hiscall,xsnr,bswl,nhasharray, & - recent_calls,nrecent,msgreceived,nsuccess) + msgreceived,nsuccess) ! use timer_module, only: timer + use packjt77 parameter (NSPM=240) character*4 rpt(0:15) character*6 mycall,hiscall,mycall0,hiscall0 character*22 hashmsg,msgreceived - character*12 recent_calls(nrecent) complex cb(42) complex cfac,cca complex c(NSPM) integer*1 cw(32) integer*1 decoded(16) integer s8r(8),hardbits(40) - integer nhasharray(nrecent,nrecent) + integer nhasharray(MAXRECENT,MAXRECENT) real*8 dt, fs, pi, twopi real cbi(42),cbq(42) real pp(12) @@ -115,7 +115,6 @@ subroutine msk40decodeframe(c,mycall,hiscall,xsnr,bswl,nhasharray, & max_iterations=5 call bpdecode40(llr,max_iterations,decoded,niterations) - if( niterations .ge. 0.0 ) then call encode_msk40(decoded,cw) nhammd=0 @@ -133,33 +132,28 @@ subroutine msk40decodeframe(c,mycall,hiscall,xsnr,bswl,nhasharray, & enddo nrxrpt=iand(imsg,15) nrxhash=(imsg-nrxrpt)/16 - if(nhammd.le.4 .and. cord .lt. 0.65 .and. & nrxhash.eq.ihash .and. nrxrpt.ge.7) then -!write(*,*) 'decodeframe 1',nbadsync,nhammd,cord,nrxhash,nrxrpt,ihash,xsnr,sigma nsuccess=1 write(msgreceived,'(a1,a,1x,a,a1,1x,a4)') "<",trim(mycall), & trim(hiscall),">",rpt(nrxrpt) return elseif(bswl .and. nhammd.le.4 .and. cord.lt.0.65 .and. nrxrpt.ge.7 ) then - do i=1,nrecent - do j=i+1,nrecent + do i=1,MAXRECENT + do j=i+1,MAXRECENT if( nrxhash .eq. nhasharray(i,j) ) then nsuccess=2 write(msgreceived,'(a1,a,1x,a,a1,1x,a4)') "<",trim(recent_calls(i)), & trim(recent_calls(j)),">",rpt(nrxrpt) -!write(*,*) 'decodeframe 2',nbadsync,nhammd,cord,nrxhash,nrxrpt,ihash,xsnr,sigma elseif( nrxhash .eq. nhasharray(j,i) ) then nsuccess=2 write(msgreceived,'(a1,a,1x,a,a1,1x,a4)') "<",trim(recent_calls(j)), & trim(recent_calls(i)),">",rpt(nrxrpt) -!write(*,*) 'decodeframe 3',nbadsync,nhammd,cord,nrxhash,nrxrpt,ihash,xsnr,sigma endif enddo enddo if(nsuccess.eq.0) then nsuccess=3 -!write(*,*) 'decodeframe 4',bswl,nbadsync,nhammd,cord,nrxhash,nrxrpt,ihash,xsnr,sigma,nsuccess write(msgreceived,'(a1,i4.4,a1,1x,a4)') "<",nrxhash,">",rpt(nrxrpt) endif endif diff --git a/lib/msk40spd.f90 b/lib/msk40spd.f90 index c8af1a49e..337bc8cc8 100644 --- a/lib/msk40spd.f90 +++ b/lib/msk40spd.f90 @@ -1,13 +1,13 @@ -subroutine msk40spd(cbig,n,ntol,mycall,hiscall,bswl,nhasharray,recent_calls, & - nrecent,nsuccess,msgreceived,fc,fret,tret,navg) +subroutine msk40spd(cbig,n,ntol,mycall,hiscall,bswl,nhasharray, & + nsuccess,msgreceived,fc,fret,tret,navg) ! msk40 short-ping-decoder + use packjt77 use timer_module, only: timer parameter (NSPM=240, MAXSTEPS=150, NFFT=NSPM, MAXCAND=5, NPATTERNS=6) character*6 mycall,hiscall character*22 msgreceived - character*12 recent_calls(nrecent) complex cbig(n) complex cdat(3*NSPM) !Analytic signal complex c(NSPM) @@ -19,7 +19,6 @@ subroutine msk40spd(cbig,n,ntol,mycall,hiscall,bswl,nhasharray,recent_calls, & integer navpatterns(3,NPATTERNS) integer navmask(3) integer nstart(MAXCAND) - integer nhasharray(nrecent,nrecent) logical ismask(NFFT) logical*1 bswl real detmet(-2:MAXSTEPS+3) @@ -181,7 +180,7 @@ subroutine msk40spd(cbig,n,ntol,mycall,hiscall,bswl,nhasharray,recent_calls, & if( is.eq.3) ic0=min(NSPM,ic0+1) ct=cshift(c,ic0-1) call msk40decodeframe(ct,mycall,hiscall,xsnr,bswl,nhasharray, & - recent_calls,nrecent,msgreceived,ndecodesuccess) + msgreceived,ndecodesuccess) if( ndecodesuccess .gt. 0 ) then !write(*,*) icand, iav, ipk, is, tret, fret, msgreceived tret=(nstart(icand)+NSPM/2)/fs diff --git a/lib/mskrtd.f90 b/lib/mskrtd.f90 index b249b8883..ccb1f2406 100644 --- a/lib/mskrtd.f90 +++ b/lib/mskrtd.f90 @@ -5,21 +5,22 @@ subroutine mskrtd(id2,nutc0,tsec,ntol,nrxfreq,ndepth,mycall,mygrid,hiscall, & ! Analysis block size = NZ = 7168 samples, t_block = 0.597333 s ! Called from hspec() at half-block increments, about 0.3 s + use packjt77 + parameter (NZ=7168) !Block size parameter (NSPM=864) !Number of samples per message frame parameter (NFFT1=8192) !FFT size for making analytic signal parameter (NPATTERNS=4) !Number of frame averaging patterns to try - parameter (NRECENT=10) !Number of recent calls to remember parameter (NSHMEM=50) !Number of recent SWL messages to remember character*4 decsym !"&" for mskspd or "^" for long averages character*37 msgreceived !Decoded message + character*22 msgrx22 !Sh messages are returned as 22chars character*37 msglast,msglastswl !Used for dupechecking character*80 line !Formatted line with UTC dB T Freq Msg character*12 mycall,hiscall character*6 mygrid - character*12 recent_calls(NRECENT) - character*22 recent_shmsgs(NSHMEM) + character*37 recent_shmsgs(NSHMEM) character*512 datadir complex cdat(NFFT1) !Analytic signal @@ -30,7 +31,7 @@ subroutine mskrtd(id2,nutc0,tsec,ntol,nrxfreq,ndepth,mycall,mygrid,hiscall, & integer iavmask(8) integer iavpatterns(8,NPATTERNS) integer npkloc(10) - integer nhasharray(NRECENT,NRECENT) + integer nhasharray(MAXRECENT,MAXRECENT) integer nsnrlast,nsnrlastswl real d(NFFT1) @@ -54,20 +55,20 @@ subroutine mskrtd(id2,nutc0,tsec,ntol,nrxfreq,ndepth,mycall,mygrid,hiscall, & 1,1,1,1,1,1,1,0/ data xmc/2.0,4.5,2.5,3.5/ !Used to set time at center of averaging mask save first,tsec0,nutc00,pnoise,cdat,msglast,msglastswl, & - nsnrlast,nsnrlastswl,recent_calls,nhasharray,recent_shmsgs + nsnrlast,nsnrlastswl,nhasharray,recent_shmsgs if(first) then tsec0=tsec nutc00=nutc0 pnoise=-1.0 - do i=1,nrecent - recent_calls(i)(1:12)=' ' + do i=1,MAXRECENT + recent_calls(i)(1:13)=' ' enddo do i=1,nshmem - recent_shmsgs(i)(1:22)=' ' + recent_shmsgs(i)(1:37)=' ' enddo - msglast=' ' - msglastswl=' ' + msglast=' ' + msglastswl=' ' nsnrlast=-99 nsnrlastswl=-99 first=.false. @@ -77,8 +78,8 @@ subroutine mskrtd(id2,nutc0,tsec,ntol,nrxfreq,ndepth,mycall,mygrid,hiscall, & ! Dupe checking setup if(nutc00.ne.nutc0 .or. tsec.lt.tsec0) then ! reset dupe checker - msglast=' ' - msglastswl=' ' + msglast=' ' + msglastswl=' ' nsnrlast=-99 nsnrlastswl=-99 nutc00=nutc0 @@ -86,7 +87,7 @@ subroutine mskrtd(id2,nutc0,tsec,ntol,nrxfreq,ndepth,mycall,mygrid,hiscall, & tframe=float(NSPM)/12000.0 line=char(0) - msgreceived=' ' + msgreceived=' ' max_iterations=10 niterations=0 d(1:NZ)=id2 @@ -116,10 +117,11 @@ subroutine mskrtd(id2,nutc0,tsec,ntol,nrxfreq,ndepth,mycall,mygrid,hiscall, & ! 3 frames along with 2- and 3-frame averages. np=8*NSPM call msk144spd(cdat,np,ntol,ndecodesuccess,msgreceived,fc,fest,tdec,navg,ct, & - softbits,recent_calls,nrecent) + softbits) if(ndecodesuccess.eq.0 .and. (bshmsg.or.bswl)) then call msk40spd(cdat,np,ntol,mycall(1:6),hiscall(1:6),bswl,nhasharray, & - recent_calls,nrecent,ndecodesuccess,msgreceived,fc,fest,tdec,navg) + ndecodesuccess,msgrx22,fc,fest,tdec,navg) + if( ndecodesuccess .ge. 1 ) msgreceived(1:22)=msgrx22 endif if( ndecodesuccess .ge. 1 ) then tdec=tsec+tdec @@ -150,8 +152,7 @@ subroutine mskrtd(id2,nutc0,tsec,ntol,nrxfreq,ndepth,mycall,mygrid,hiscall, & if(is.eq.2) ic0=max(1,ic0-1) if(is.eq.3) ic0=min(NSPM,ic0+1) ct=cshift(c,ic0-1) - call msk144decodeframe(ct,softbits,msgreceived,ndecodesuccess, & - recent_calls,nrecent) + call msk144decodeframe(ct,softbits,msgreceived,ndecodesuccess) if(ndecodesuccess .gt. 0) then tdec=tsec+xmc(iavg)*tframe goto 900 @@ -192,7 +193,7 @@ subroutine mskrtd(id2,nutc0,tsec,ntol,nrxfreq,ndepth,mycall,mygrid,hiscall, & decsym=' & ' if( btrain ) decsym=' ^ ' - if( msgreceived(1:1).eq.'<') then + if( bshdecode ) then ncorrected=0 eyeopening=0.0 endif @@ -207,11 +208,17 @@ subroutine mskrtd(id2,nutc0,tsec,ntol,nrxfreq,ndepth,mycall,mygrid,hiscall, & msglast=msgreceived nsnrlast=nsnr if(.not. bshdecode) then - call update_hasharray(recent_calls,nrecent,nhasharray) + call update_hasharray(nhasharray) + endif + if( .not.bshdecode ) then + write(line,1020) nutc0,nsnr,tdec,nint(fest),decsym,msgreceived(1:22), & + navg,ncorrected,eyeopening,char(0) +1020 format(i6.6,i4,f5.1,i5,a4,a22,i2,i3,f5.1,a1) + else + write(line,1022) nutc0,nsnr,tdec,nint(fest),decsym,msgreceived(1:22), & + navg,char(0) +1022 format(i6.6,i4,f5.1,i5,a4,a22,i2,a1) endif - write(line,1020) nutc0,nsnr,tdec,nint(fest),decsym,msgreceived, & - navg,ncorrected,eyeopening,char(0) -1020 format(i6.6,i4,f5.1,i5,a4,a22,i2,i3,f5.1,a1) elseif(bswl .and. ndecodesuccess.ge.2) then seenb4=.false. do i=1,nshmem @@ -226,8 +233,8 @@ subroutine mskrtd(id2,nutc0,tsec,ntol,nrxfreq,ndepth,mycall,mygrid,hiscall, & if(bflag) then msglastswl=msgreceived nsnrlastswl=nsnr - write(line,1020) nutc0,nsnr,tdec,nint(fest),decsym,msgreceived, & - navg,ncorrected,eyeopening,char(0) + write(line,1022) nutc0,nsnr,tdec,nint(fest),decsym,msgreceived, & + navg,char(0) endif endif 999 tsec0=tsec @@ -236,8 +243,8 @@ subroutine mskrtd(id2,nutc0,tsec,ntol,nrxfreq,ndepth,mycall,mygrid,hiscall, & end subroutine mskrtd subroutine update_recent_shmsgs(message,msgs,nsize) - character*22 msgs(nsize) - character*22 message + character*37 msgs(nsize) + character*37 message logical*1 seen seen=.false. diff --git a/lib/stdmsg.f90 b/lib/stdmsg.f90 index f61935622..cc50f5804 100644 --- a/lib/stdmsg.f90 +++ b/lib/stdmsg.f90 @@ -2,15 +2,6 @@ function stdmsg(msg0) ! Returns .true. if msg0 a standard "JT-style" message - ! itype - ! 1 Standard 72-bit structured message - ! 2 Type 1 prefix - ! 3 Type 1 suffix - ! 4 Type 2 prefix - ! 5 Type 2 suffix - ! 6 Free text - ! 7 Hashed calls (MSK144 short format) - ! i3.n3 ! 0.0 Free text ! 0.1 DXpeditiion mode @@ -27,23 +18,26 @@ function stdmsg(msg0) use iso_c_binding, only: c_bool use packjt - character*37 msg0,msg1,msg - integer dat(12) + use packjt77 + + character*37 msg0,msg1 + character*77 c77 logical(c_bool) :: stdmsg msg1=msg0 - i0=index(msg1,' OOO ') - if(i0.gt.10) msg1=msg0(1:i0) - call packmsg(msg0,dat,itype) - call unpackmsg(dat,msg) - msg(23:37)=' ' - stdmsg=(msg(1:22).eq.msg1(1:22)) .and. (itype.ge.0) .and. (itype.ne.6) - if(.not.stdmsg) then - i0=index(msg1,' ') - msg1(i0:)=' ' - call parse77(msg1,i3,n3) - if(i3.gt.0 .or. n3.gt.0) stdmsg=.true. - endif + i3=-1 + n3=-1 + call pack77(msg1,i3,n3,c77) + stdmsg=(i3.gt.0 .or. n3.gt.0) +!### +! rewind 82 +! do i=1,nzhash +! write(82,3082) i,nzhash,callsign(i),ihash10(i),ihash12(i),ihash22(i) +!3082 format(2i5,2x,a13,3i10) +! enddo +! flush(82) +!### + return end function stdmsg diff --git a/lib/update_hasharray.f90 b/lib/update_hasharray.f90 index 0f9c872e8..4ccbba51c 100644 --- a/lib/update_hasharray.f90 +++ b/lib/update_hasharray.f90 @@ -1,12 +1,12 @@ -subroutine update_hasharray(recent_calls,nrecent,nhasharray) - - character*12 recent_calls(nrecent) +subroutine update_hasharray(nhasharray) + + use packjt77 character*22 hashmsg - integer nhasharray(nrecent,nrecent) + integer nhasharray(MAXRECENT,MAXRECENT) nhasharray=-1 - do i=1,nrecent - do j=i+1,nrecent + do i=1,MAXRECENT + do j=i+1,MAXRECENT if( recent_calls(i)(1:1) .ne. ' ' .and. recent_calls(j)(1:1) .ne. ' ' ) then hashmsg=trim(recent_calls(i))//' '//trim(recent_calls(j)) call fmtmsg(hashmsg,iz) diff --git a/mainwindow.cpp b/mainwindow.cpp index 2bc7e0878..022f90af4 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -88,7 +88,7 @@ extern "C" { void gen9_(char* msg, int* ichk, char* msgsent, int itone[], int* itext, fortran_charlen_t, fortran_charlen_t); - void genmsk_128_90_(char* msg, int* ichk, char* msgsent, int itone[], int* itext, + void genmsk_128_90_(char* msg, int* ichk, char* msgsent, int itone[], int* itype, fortran_charlen_t, fortran_charlen_t); void gen65_(char* msg, int* ichk, char* msgsent, int itone[], @@ -3616,6 +3616,8 @@ void MainWindow::guiUpdate() if (msg_parts.size () > 2) { // clean up short code forms msg_parts[0].remove (QChar {'<'}); + msg_parts[0].remove (QChar {'>'}); + msg_parts[1].remove (QChar {'<'}); msg_parts[1].remove (QChar {'>'}); } auto is_73 = m_QSOProgress >= ROGER_REPORT @@ -4640,12 +4642,20 @@ bool MainWindow::stdCall(QString w) 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; + 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") or (c>="0" and c<="9") or c=="/"; - if(!b) return false; + if(i1==99 and (c>="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; }