diff --git a/Configuration.ui b/Configuration.ui index 03e3c4c3d..dfcb6b110 100644 --- a/Configuration.ui +++ b/Configuration.ui @@ -6,7 +6,7 @@ 0 0 - 521 + 536 507 @@ -188,6 +188,12 @@ Qt::Horizontal + + + 0 + 0 + + @@ -237,6 +243,12 @@ Qt::Vertical + + + 0 + 0 + + @@ -301,6 +313,12 @@ Qt::Horizontal + + + 0 + 0 + + @@ -390,6 +408,12 @@ quiet period when decoding is done. Qt::Horizontal + + + 0 + 0 + + @@ -1882,6 +1906,12 @@ for assessing propagation and system performance. Qt::Horizontal + + + 0 + 0 + + @@ -2178,6 +2208,12 @@ Right click for insert and delete options. Qt::Horizontal + + + 0 + 0 + + @@ -2198,6 +2234,12 @@ Right click for insert and delete options. Qt::Horizontal + + + 0 + 0 + + @@ -2300,7 +2342,7 @@ Right click for insert and delete options. <html><head/><body><p>Exchange 4-character grid locators instead of reports. See User Guide for details.</p></body></html> - MSK144 Contest Mode + FT8 and MSK144 Contest Mode @@ -2595,9 +2637,9 @@ soundcard changes - - + + diff --git a/lib/decoder.f90 b/lib/decoder.f90 index e6995961b..f3a6d43e8 100644 --- a/lib/decoder.f90 +++ b/lib/decoder.f90 @@ -70,11 +70,11 @@ subroutine multimode_decoder(ss,id2,params,nfsample) ! We're in FT8 mode call timer('decft8 ',0) newdat=params%newdat - call my_ft8%decode(ft8_decoded,id2,params%nQSOProgress,params%nfqso, & - params%nftx,newdat,params%nutc,params%nfa, & - params%nfb,logical(params%nagain), & - params%ndepth,logical(params%lapon),params%napwid,params%nsubmode, & - params%mycall,params%hiscall,params%hisgrid) + call my_ft8%decode(ft8_decoded,id2,params%nQSOProgress,params%nfqso, & + params%nftx,newdat,params%nutc,params%nfa,params%nfb, & + params%nexp_decode,params%ndepth,logical(params%lapon), & + params%napwid,params%mycall,params%mygrid,params%hiscall, & + params%hisgrid) call timer('decft8 ',1) go to 800 endif diff --git a/lib/fsk4hf/ft8apset.f90 b/lib/fsk4hf/ft8apset.f90 index 4c89d72b0..8f34aae2f 100644 --- a/lib/fsk4hf/ft8apset.f90 +++ b/lib/fsk4hf/ft8apset.f90 @@ -1,10 +1,11 @@ -subroutine ft8apset(mycall12,hiscall12,hisgrid6,apsym,iaptype) +subroutine ft8apset(mycall12,mygrid6,hiscall12,hisgrid6,bcontest,apsym,iaptype) parameter(NAPM=4,KK=87) character*12 mycall12,hiscall12 character*22 msg,msgsent character*6 mycall,hiscall - character*6 hisgrid6 + character*6 mygrid6,hisgrid6 character*4 hisgrid + logical bcontest integer apsym(KK) integer*1 msgbits(KK) integer itone(KK) @@ -22,7 +23,8 @@ subroutine ft8apset(mycall12,hiscall12,hisgrid6,apsym,iaptype) ! if(len_trim(hisgrid).eq.0) hisgrid="EN50" if(index(hisgrid," ").eq.0) hisgrid="EN50" msg=mycall//' '//hiscall//' '//hisgrid - call genft8(msg,msgsent,msgbits,itone) - apsym=2*msgbits-1 + call genft8(msg,mygrid6,bcontest,msgsent,msgbits,itone) + apsym=2*msgbits-1 + return - end subroutine ft8apset +end subroutine ft8apset diff --git a/lib/fsk4hf/ft8b.f90 b/lib/fsk4hf/ft8b.f90 index f73f9d27f..3e871cf01 100644 --- a/lib/fsk4hf/ft8b.f90 +++ b/lib/fsk4hf/ft8b.f90 @@ -1,12 +1,14 @@ -subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,napwid, & - lsubtract,iaptype,icand,sync0,f1,xdt,apsym,nharderrors,dmin, & - nbadcrc,ipass,iera,message,xsnr) +subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,napwid, & + lsubtract,iaptype,mygrid6,bcontest,sync0,f1,xdt,apsym,nharderrors,dmin, & + nbadcrc,ipass,iera,message,xsnr) use timer_module, only: timer include 'ft8_params.f90' parameter(NRECENT=10,NP2=2812) character message*22,msgsent*22 character*12 recent_calls(NRECENT) + character*6 mygrid6 + logical bcontest real a(5) real s1(0:7,ND),s2(0:7,NN) real ps(0:7) @@ -336,7 +338,7 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,napwid, & endif if(nbadcrc.eq.0) then call extractmessage174(decoded,message,ncrcflag,recent_calls,nrecent) - call genft8(message,msgsent,msgbits,itone) + call genft8(message,mygrid6,bcontest,msgsent,msgbits,itone) if(lsubtract) call subtractft8(dd0,itone,f1,xdt2) xsig=0.0 xnoi=0.0 diff --git a/lib/fsk4hf/ft8sim.f90 b/lib/fsk4hf/ft8sim.f90 index 07041acab..2801717d4 100644 --- a/lib/fsk4hf/ft8sim.f90 +++ b/lib/fsk4hf/ft8sim.f90 @@ -8,19 +8,23 @@ program ft8sim type(hdr) h !Header for .wav file character arg*12,fname*17,sorm*1 character msg*22,msgsent*22 + character*6 mygrid6 + logical bcontest complex c0(0:NMAX-1) complex c(0:NMAX-1) integer itone(NN) integer*1 msgbits(KK) - integer*2 iwave(NMAX) !Generated full-length waveform + integer*2 iwave(NMAX) !Generated full-length waveform + data mygrid6/'EM48 '/ ! Get command-line argument(s) nargs=iargc() if(nargs.ne.8) then - print*,'Usage: ft8sim "message" sorm f0 DT fdop del nfiles snr' + print*,'Usage: ft8sim "message" s|m f0 DT fdop del nfiles snr' print*,'Example: ft8sim "K1ABC W9XYZ EN37" m 1500.0 0.0 0.1 1.0 10 -18' - print*,'sorm: "s" for single signal at 1500 Hz, "m" for 25 signals' + print*,'s|m: "s" for single signal at 1500 Hz, "m" for 25 signals' print*,'f0 is ignored when sorm = m' + print*,'Make nfiles negative to invoke 72-bit contest mode.' go to 999 endif call getarg(1,msg) !Message to be transmitted @@ -48,6 +52,8 @@ program ft8sim call getarg(8,arg) read(arg,*) snrdb !SNR_2500 + bcontest=nfiles.lt.0 + nfiles=abs(nfiles) twopi=8.0*atan(1.0) fs=12000.0 !Sample rate (Hz) dt=1.0/fs !Sample interval (s) @@ -60,7 +66,8 @@ program ft8sim if(snrdb.gt.90.0) sig=1.0 txt=NN*NSPS/12000.0 - call genft8(msg,msgsent,msgbits,itone) !Source-encode, then get itone() +! Source-encode, then get itone() + call genft8(msg,mygrid6,bcontest,msgsent,msgbits,itone) write(*,1000) f0,xdt,txt,snrdb,bw,msgsent 1000 format('f0:',f9.3,' DT:',f6.2,' TxT:',f6.1,' SNR:',f6.1, & ' BW:',f4.1,2x,a22) diff --git a/lib/fsk4hf/genft8.f90 b/lib/fsk4hf/genft8.f90 index c5306cc8e..5916fc2b2 100644 --- a/lib/fsk4hf/genft8.f90 +++ b/lib/fsk4hf/genft8.f90 @@ -1,4 +1,4 @@ -subroutine genft8(msg,msgsent,msgbits,itone) +subroutine genft8(msg,mygrid,bcontest,msgsent,msgbits,itone) ! Encode an FT8 message, producing array itone(). @@ -6,8 +6,10 @@ subroutine genft8(msg,msgsent,msgbits,itone) use packjt include 'ft8_params.f90' character*22 msg,msgsent + character*6 mygrid,g1,g2 character*87 cbits -! logical checksumok + logical*1 bcontest + logical isgrid integer*4 i4Msg6BitWords(12) !72-bit message as 6-bit words integer*1 msgbits(KK),codeword(3*ND) integer*1, target:: i1Msg8BitBytes(11) @@ -15,6 +17,23 @@ subroutine genft8(msg,msgsent,msgbits,itone) integer icos7(0:6) data icos7/2,5,6,0,4,1,3/ !Costas 7x7 tone pattern + isgrid(g1)=g1(1:1).ge.'A' .and. g1(1:1).le.'R' .and. g1(2:2).ge.'A' .and. & + g1(2:2).le.'R' .and. g1(3:3).ge.'0' .and. g1(3:3).le.'9' .and. & + g1(4:4).ge.'0' .and. g1(4:4).le.'9' .and. g1(1:4).ne.'RR73' + + if(bcontest) then + i0=index(msg,' R ') + 3 !Check for ' R ' in message + g1=msg(i0:i0+3)//' ' + if(isgrid(g1)) then !Check for ' R grid' + call grid2deg(g1,dlong,dlat) + dlong=dlong+180.0 + if(dlong.gt.180.0) dlong=dlong-360.0 + dlat=-dlat + call deg2grid(dlong,dlat,g2) !g2=antipodes grid + msg=msg(1:i0-3)//g2(1:4) !Send message with g2 + endif + endif + call packmsg(msg,i4Msg6BitWords,itype) !Pack into 12 6-bit bytes call unpackmsg(i4Msg6BitWords,msgsent) !Unpack to get msgsent i3bit=0 !### temporary ### diff --git a/lib/ft8_decode.f90 b/lib/ft8_decode.f90 index b80ab60e9..8a4f2b9b5 100644 --- a/lib/ft8_decode.f90 +++ b/lib/ft8_decode.f90 @@ -23,8 +23,9 @@ module ft8_decode contains - subroutine decode(this,callback,iwave,nQSOProgress,nfqso,nftx,newdat,nutc, & - nfa,nfb,nagain,ndepth,lapon,napwid,nsubmode,mycall12,hiscall12,hisgrid6) + subroutine decode(this,callback,iwave,nQSOProgress,nfqso,nftx,newdat, & + nutc,nfa,nfb,nexp_decode,ndepth,lapon,napwid,mycall12,mygrid6, & + hiscall12,hisgrid6) ! use wavhdr use timer_module, only: timer include 'fsk4hf/ft8_params.f90' @@ -35,10 +36,10 @@ contains real s(NH1,NHSYM) real candidate(3,200) real dd(15*12000) - logical, intent(in) :: nagain,lapon - logical newdat,lsubtract,ldupe + logical, intent(in) :: lapon + logical newdat,lsubtract,ldupe,bcontest character*12 mycall12, hiscall12 - character*6 hisgrid6 + character*6 mygrid6,hisgrid6 integer*2 iwave(15*12000) integer apsym(KK) character datetime*13,message*22 @@ -46,11 +47,12 @@ contains integer allsnrs(100) save s,dd + bcontest=iand(nexp_decode,128).ne.0 this%callback => callback write(datetime,1001) nutc !### TEMPORARY ### 1001 format("000000_",i6.6) - call ft8apset(mycall12,hiscall12,hisgrid6,apsym,iaptype) + call ft8apset(mycall12,mygrid6,hiscall12,hisgrid6,bcontest,apsym,iaptype) dd=iwave @@ -84,14 +86,15 @@ contains nsnr0=min(99,nint(10.0*log10(sync) - 25.5)) !### empirical ### call timer('ft8b ',0) call ft8b(dd,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,napwid, & - lsubtract,iaptype,icand,sync,f1,xdt,apsym,nharderrors,dmin, & - nbadcrc,iappass,iera,message,xsnr) + lsubtract,iaptype,mygrid6,bcontest,sync,f1,xdt,apsym, & + nharderrors,dmin,nbadcrc,iappass,iera,message,xsnr) nsnr=nint(xsnr) xdt=xdt-0.5 hd=nharderrors+dmin call timer('ft8b ',1) if(nbadcrc.eq.0) then call jtmsg(message,iflag) + if(bcontest) call fix_contest_msg(mygrid6,message) if(iand(iflag,16).ne.0) message(22:22)='?' if(iand(iflag,15).eq.0) then ldupe=.false. diff --git a/lib/genmsk144.f90 b/lib/genmsk144.f90 index cbd2285b4..7d4d200e7 100644 --- a/lib/genmsk144.f90 +++ b/lib/genmsk144.f90 @@ -41,17 +41,17 @@ subroutine genmsk144(msg0,mygrid,ichk,bcontest,msgsent,i4tone,itype) data first/.true./ save - isgrid(g1)=g1(1:1).ge.'A' .and. g1(1:1).le.'R' .and. g1(2:2).ge.'A' .and. & + isgrid(g1)=g1(1:1).ge.'A' .and. g1(1:1).le.'R' .and. g1(2:2).ge.'A' .and. & g1(2:2).le.'R' .and. g1(3:3).ge.'0' .and. g1(3:3).le.'9' .and. & g1(4:4).ge.'0' .and. g1(4:4).le.'9' .and. g1(1:4).ne.'RR73' - if( first ) then + if(first) then first=.false. nsym=128 - pi=4.*atan(1.0) + pi=4.0*atan(1.0) twopi=8.*atan(1.0) do i=1,12 - pp(i)=sin( (i-1)*pi/12 ) + pp(i)=sin((i-1)*pi/12) enddo endif diff --git a/mainwindow.cpp b/mainwindow.cpp index bb953c0a4..493c899fc 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -75,7 +75,8 @@ extern "C" { int len1, int len2, int len3, int len4, int len5); // float s[], int* jh, char line[], char mygrid[], - void genft8_(char* msg, char* msgsent, char ft8msgbits[], int itone[], int len1, int len2); + void genft8_(char* msg, char* MyGrid, bool* bcontest, char* msgsent, + char ft8msgbits[], int itone[], int len1, int len2); void gen4_(char* msg, int* ichk, char* msgsent, int itone[], int* itext, int len1, int len2); @@ -2490,7 +2491,7 @@ void MainWindow::decode() //decode() dec_data.params.nexp_decode=0; if(m_config.single_decode()) dec_data.params.nexp_decode += 32; if(m_config.enable_VHF_features()) dec_data.params.nexp_decode += 64; - + if(m_config.contestMode()) dec_data.params.nexp_decode += 128; strncpy(dec_data.params.datetime, m_dateTime.toLatin1(), 20); strncpy(dec_data.params.mycall, (m_config.my_callsign()+" ").toLatin1(),12); @@ -3103,18 +3104,22 @@ void MainWindow::guiUpdate() len1, len1); if(m_modeTx=="WSPR-LF") genwspr_fsk8_(message, msgsent, const_cast (itone), len1, len1); - if(m_modeTx=="FT8") genft8_(message, msgsent, const_cast (ft8msgbits), - const_cast (itone), len1, len1); - if(m_modeTx=="MSK144") { + if(m_modeTx=="MSK144" or m_modeTx=="FT8") { bool bcontest=m_config.contestMode(); char MyGrid[6]; strncpy(MyGrid, (m_config.my_grid()+" ").toLatin1(),6); - genmsk144_(message, MyGrid, &ichk, &bcontest, msgsent, const_cast (itone), - &m_currentMessageType, len1, 6, len1); - if(m_restart) { - int nsym=144; - if(itone[40]==-40) nsym=40; - m_modulator->set_nsym(nsym); + if(m_modeTx=="MSK144") { + genmsk144_(message, MyGrid, &ichk, &bcontest, msgsent, const_cast (itone), + &m_currentMessageType, len1, 6, len1); + if(m_restart) { + int nsym=144; + if(itone[40]==-40) nsym=40; + m_modulator->set_nsym(nsym); + } + } + if(m_modeTx=="FT8") { + genft8_(message, MyGrid, &bcontest, msgsent, const_cast (ft8msgbits), + const_cast (itone), len1, len1); } } msgsent[22]=0;