From e4927efd62a96cceb1aa65985edf4948771baa2c Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Sun, 19 Oct 2014 00:56:41 +0000 Subject: [PATCH] Improve the way messages with compound calls are automatically generated. Routine packmsg now tries the shortlist (Type 1 prefix or suffix) first. Then it tries to to make a valid message using a Type 2 prefix or suffix. If both fail, it packs the first 13 characters as a free-text message. The GUI now generates the most useful messages with compound callsigns of all valid types. git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@4533 ab8295b8-cf94-4d9e-aec4-7959e3be5d79 --- CMakeLists.txt | 1 + lib/gen65.f90 | 6 ++-- lib/genjt9.f90 | 6 ++-- lib/getpfx1.f90 | 9 ++++-- lib/jt65code.f90 | 58 +++++++++++++++++++++++------------- lib/jt9code.f90 | 38 ++++++++++++++++-------- lib/packmsg.f90 | 77 ++++++++++++++++++++++++++---------------------- lib/stdmsg.f90 | 5 ++-- mainwindow.cpp | 26 +++++++++------- mainwindow.h | 18 +++++------ 10 files changed, 139 insertions(+), 105 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5fac99356..45a08024c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -235,6 +235,7 @@ set (wsjt_FSRCS lib/flat3.f90 lib/flat65.f90 lib/four2a.f90 + lib/fmtmsg.f90 lib/gen65.f90 lib/genjt9.f90 lib/geodist.f90 diff --git a/lib/gen65.f90 b/lib/gen65.f90 index 85802384b..869d43287 100644 --- a/lib/gen65.f90 +++ b/lib/gen65.f90 @@ -1,4 +1,4 @@ -subroutine gen65(msg0,ichk,msgsent,itone,itext) +subroutine gen65(msg0,ichk,msgsent,itone,itype) ! Encodes a JT65 message to yieild itone(1:126) ! Temporarily, does not implement EME shorthands @@ -37,9 +37,7 @@ subroutine gen65(msg0,ichk,msgsent,itone,itext) nspecial=0 ! call chkmsg(message,cok,nspecial,flip) if(nspecial.eq.0) then - call packmsg(message,dgen,text) !Pack message into 72 bits - itext=0 - if(text) itext=1 + call packmsg(message,dgen,itype) !Pack message into 72 bits call unpackmsg(dgen,msgsent) !Unpack to get message sent if(ichk.ne.0) go to 999 !Return if checking only diff --git a/lib/genjt9.f90 b/lib/genjt9.f90 index 90427e1ce..ea1ad5993 100644 --- a/lib/genjt9.f90 +++ b/lib/genjt9.f90 @@ -1,4 +1,4 @@ -subroutine genjt9(msg0,ichk,msgsent,i4tone,itext) +subroutine genjt9(msg0,ichk,msgsent,i4tone,itype) ! Encodes a JT9 message and returns msgsent, the message as it will ! be decoded, and an integer array i4tone(85) of 9-FSK tone values @@ -31,9 +31,7 @@ subroutine genjt9(msg0,ichk,msgsent,i4tone,itext) message=message(i+1:) enddo - call packmsg(message,i4Msg6BitWords,text) !Pack message into 12 6-bit bytes - itext=0 - if(text) itext=1 + call packmsg(message,i4Msg6BitWords,itype) !Pack into 12 6-bit bytes call unpackmsg(i4Msg6BitWords,msgsent) !Unpack to get msgsent if(ichk.ne.0) go to 999 call entail(i4Msg6BitWords,i1Msg8BitBytes) !Add tail, convert to 8-bit bytes diff --git a/lib/getpfx1.f90 b/lib/getpfx1.f90 index 2d4603bd9..332278eb7 100644 --- a/lib/getpfx1.f90 +++ b/lib/getpfx1.f90 @@ -8,7 +8,7 @@ subroutine getpfx1(callsign,k,nv2) include 'pfx.f90' callsign0=callsign - nv2=0 + nv2=1 iz=index(callsign,' ') - 1 if(iz.lt.0) iz=12 islash=index(callsign(1:iz),'/') @@ -22,11 +22,13 @@ subroutine getpfx1(callsign,k,nv2) do i=1,NZ if(pfx(i)(1:4).eq.c) then k=i + nv2=2 go to 10 endif enddo if(addpfx.eq.c) then k=449 + nv2=2 go to 10 endif @@ -37,6 +39,7 @@ subroutine getpfx1(callsign,k,nv2) do i=1,NZ2 if(sfx(i).eq.c(1:1)) then k=400+i + nv2=3 go to 10 endif enddo @@ -75,7 +78,7 @@ subroutine getpfx1(callsign,k,nv2) k=37*k + nchar(tpfx(2:2)) k=37*k + nchar(tpfx(3:3)) k=37*k + nchar(tpfx(4:4)) - nv2=1 + nv2=4 i=index(callsign0,'/') callsign=callsign0(:i-1) callsign=callsign0(i+1:) @@ -85,7 +88,7 @@ subroutine getpfx1(callsign,k,nv2) k=nchar(tsfx(1:1)) k=37*k + nchar(tsfx(2:2)) k=37*k + nchar(tsfx(3:3)) - nv2=2 + nv2=5 i=index(callsign0,'/') callsign=callsign0(:i-1) endif diff --git a/lib/jt65code.f90 b/lib/jt65code.f90 index 52faf7fe2..62a539040 100644 --- a/lib/jt65code.f90 +++ b/lib/jt65code.f90 @@ -4,9 +4,8 @@ program JT65code ! Reed Solomon encoding, and other necessary details of the JT65 ! protocol. - character*22 msg0,msg,decoded,cok*3 + character*22 msg,msg0,msg1,decoded,cok*3,bad*1,msgtype*10 integer dgen(12),sent(63),recd(12),era(51) - logical text nargs=iargc() if(nargs.ne.1) then @@ -14,36 +13,53 @@ program JT65code go to 999 endif - call getarg(1,msg0) !Get message from command line - msg=msg0 - - call chkmsg(msg,cok,nspecial,flip) !See if it includes "OOO" report + call getarg(1,msg) !Get message from command line + call fmtmsg(msg,iz) !To upper, collapse mult blanks + msg0=msg !Input message + call chkmsg(msg,cok,nspecial,flip) !See if it includes "OOO" report + msg1=msg !Message without "OOO" if(nspecial.gt.0) then !or is a shorthand message - write(*,1010) -1010 format('Shorthand message.') - go to 999 + if(nspecial.eq.2) decoded="RO" + if(nspecial.eq.3) decoded="RRR" + if(nspecial.eq.4) decoded="73" + itype=-1 + msgtype="Shorthand" + go to 10 endif - call packmsg(msg,dgen,text) !Pack message into 12 six-bit bytes - write(*,1020) msg0 -1020 format('Message: ',a22) !Echo input message - if(iand(dgen(10),8).ne.0) write(*,1030) !Is plain text bit set? -1030 format('Plain text.') - write(*,1040) dgen -1040 format('Packed message, 6-bit symbols: ',12i3) !Display packed symbols + call packmsg(msg1,dgen,itype) !Pack message into 12 six-bit bytes + msgtype="" + if(itype.eq.1) msgtype="Std Msg" + if(itype.eq.2) msgtype="Type 1 pfx" + if(itype.eq.3) msgtype="Type 1 sfx" + if(itype.eq.4) msgtype="Type 2 pfx" + if(itype.eq.5) msgtype="Type 2 sfx" + if(itype.eq.6) msgtype="Free text" call rs_encode(dgen,sent) !RS encode call interleave63(sent,1) !Interleave channel symbols call graycode(sent,63,1,sent) !Apply Gray code - write(*,1050) sent -1050 format('Information-carrying channel symbols:'/(i5,20i3)) - call graycode(sent,63,-1,sent) call interleave63(sent,-1) call rs_decode(sent,era,0,recd,nerr) call unpackmsg(recd,decoded) !Unpack the user message - write(*,1060) decoded,cok -1060 format('Decoded message: ',a22,2x,a3) + if(cok.eq."OOO") decoded(20:22)=cok + call fmtmsg(decoded,iz) + +10 write(*,1010) +1010 format("Message Decoded Err"/ & + "-----------------------------------------------------------------") + bad=" " + if(decoded.ne.msg0) bad="*" + write(*,1020) msg0,decoded,bad,itype,msgtype +1020 format(a22,2x,a22,3x,a1,i3,": ",a10) + + if(nspecial.gt.0) go to 999 + write(*,1030) dgen +1030 format(/'Packed message, 6-bit symbols ',12i3) !Display packed symbols + + write(*,1040) sent +1040 format(/'Information-carrying channel symbols'/(i5,20i3)) 999 end program JT65code diff --git a/lib/jt9code.f90 b/lib/jt9code.f90 index a4f0d3e79..7480a9b04 100644 --- a/lib/jt9code.f90 +++ b/lib/jt9code.f90 @@ -2,7 +2,7 @@ program jt9code ! Generate simulated data for testing of WSJT-X - character msg*22,msg0*22,decoded*22 + character msg*22,msg0*22,decoded*22,bad*1,msgtype*10 integer*4 i4tone(85) !Channel symbols (values 0-8) include 'jt9sync.f90' @@ -12,18 +12,30 @@ program jt9code go to 999 endif - call getarg(1,msg0) - write(*,1000) msg0 -1000 format('Message:',3x,a22) - msg=msg0 + call getarg(1,msg) + call fmtmsg(msg,iz) !To upper, collapse mult blanks + msg0=msg !Input message + ichk=0 - itext=0 - call genjt9(msg,ichk,decoded,i4tone,itext) !Encode message into tone #s - write(*,1002) i4tone -1002 format('Channel symbols:'/(30i2)) - if(itext.eq.0) write(*,1004) decoded -1004 format('Decoded message:',1x,a22) - if(itext.ne.0) write(*,1005) decoded -1005 format('Decoded message:',1x,a22,3x,'(free text)') + call genjt9(msg,ichk,decoded,i4tone,itype) !Encode message into tone #s + + msgtype="" + if(itype.eq.1) msgtype="Std Msg" + if(itype.eq.2) msgtype="Type 1 pfx" + if(itype.eq.3) msgtype="Type 1 sfx" + if(itype.eq.4) msgtype="Type 2 pfx" + if(itype.eq.5) msgtype="Type 2 sfx" + if(itype.eq.6) msgtype="Free text" + + write(*,1010) +1010 format("Message Decoded Err"/ & + "-----------------------------------------------------------------") + bad=" " + if(decoded.ne.msg0) bad="*" + write(*,1020) msg0,decoded,bad,itype,msgtype +1020 format(a22,2x,a22,3x,a1,i3,": ",a10) + + write(*,1030) i4tone +1030 format(/'Channel symbols'/(30i2)) 999 end program jt9code diff --git a/lib/packmsg.f90 b/lib/packmsg.f90 index 74c357b0f..004850872 100644 --- a/lib/packmsg.f90 +++ b/lib/packmsg.f90 @@ -1,4 +1,16 @@ -subroutine packmsg(msg,dat,text) +subroutine packmsg(msg,dat,itype) + +! Packs a JT4/JT9/JT65 message into twelve 6-bit symbols + +! itype Message Type +!-------------------- +! 1 Standardd message +! 2 Type 1 prefix +! 3 Type 1 suffix +! 4 Type 2 prefix +! 5 Type 2 suffix +! 6 Free text +! -1 Does not decode correctly parameter (NBASE=37*36*10*27*27*27) parameter (NBASE2=262178562) @@ -7,24 +19,12 @@ subroutine packmsg(msg,dat,text) character*12 c1,c2 character*4 c3 character*6 grid6 - logical text1,text2,text3,text + logical text1,text2,text3 - text=.false. -! Convert all letters to upper case - iz=22 - do i=1,22 - if(msg(i:i).ge.'a' .and. msg(i:i).le.'z') & - msg(i:i)= char(ichar(msg(i:i))+ichar('A')-ichar('a')) - if(msg(i:i).ne.' ') iz=i - enddo - do iter=1,5 !Collapse multiple blanks into one - ib2=index(msg(1:iz),' ') - if(ib2.lt.1) go to 5 - msg=msg(1:ib2)//msg(ib2+2:) - iz=iz-1 - enddo + itype=1 + call fmtmsg(msg,iz) -5 if(msg(1:6).eq.'CQ DX ') msg(3:3)='9' + if(msg(1:6).eq.'CQ DX ') msg(3:3)='9' ! See if it's a CQ message if(msg(1:3).eq.'CQ ') then @@ -60,12 +60,14 @@ subroutine packmsg(msg,dat,text) c3=' ' if(ic.ge.ib+1) c3=msg(ib+1:ic) if(c3.eq.'OOO ') c3=' ' !Strip out the OOO flag - call getpfx1(c1,k1,kk) - if(kk.ne.0) go to 10 !Tnx to DL9RDZ for reminding me! + call getpfx1(c1,k1,nv2a) + if(nv2a.ge.4) go to 10 call packcall(c1,nc1,text1) - call getpfx1(c2,k2,nv2) + if(text1) go to 10 + call getpfx1(c2,k2,nv2b) call packcall(c2,nc2,text2) - if(nv2.eq.0) then + if(text2) go to 10 + if(nv2a.eq.2 .or. nv2a.eq.3 .or. nv2b.eq.2 .or. nv2b.eq.3) then if(k1.lt.0 .or. k2.lt.0 .or. k1*k2.ne.0) go to 10 if(k2.gt.0) k2=k2+450 k=max(k1,k2) @@ -75,29 +77,31 @@ subroutine packmsg(msg,dat,text) endif endif call packgrid(c3,ng,text3) - if(nv2.eq.0 .and. (.not.text1) .and. (.not.text2) .and. & + + if(nv2a.lt.4 .and. nv2b.lt.4 .and. (.not.text1) .and. (.not.text2) .and. & (.not.text3)) go to 20 - if(nv2.gt.0) then - if(nv2.eq.1) then - if(c1(1:3).eq.'CQ ') nc1=262178563 + k2 - if(c1(1:4).eq.'QRZ ') nc1=264002072 + k2 - if(c1(1:3).eq.'DE ') nc1=265825581 + k2 - endif - if(nv2.eq.2) then - if(c1(1:3).eq.'CQ ') nc1=267649090 + k2 - if(c1(1:4).eq.'QRZ ') nc1=267698375 + k2 - if(c1(1:3).eq.'DE ') nc1=267747660 + k2 - endif - go to 20 + + nc1=0 + if(nv2b.eq.4) then + if(c1(1:3).eq.'CQ ') nc1=262178563 + k2 + if(c1(1:4).eq.'QRZ ') nc1=264002072 + k2 + if(c1(1:3).eq.'DE ') nc1=265825581 + k2 + else if(nv2b.eq.5) then + if(c1(1:3).eq.'CQ ') nc1=267649090 + k2 + if(c1(1:4).eq.'QRZ ') nc1=267698375 + k2 + if(c1(1:3).eq.'DE ') nc1=267747660 + k2 endif + if(nc1.ne.0) go to 20 ! The message will be treated as plain text. -10 text=.true. +10 itype=6 call packtext(msg,nc1,nc2,ng) ng=ng+32768 ! Encode data into 6-bit words -20 dat(1)=iand(ishft(nc1,-22),63) !6 bits +20 continue + if(itype.ne.6) itype=max(nv2a,nv2b) + dat(1)=iand(ishft(nc1,-22),63) !6 bits dat(2)=iand(ishft(nc1,-16),63) !6 bits dat(3)=iand(ishft(nc1,-10),63) !6 bits dat(4)=iand(ishft(nc1, -4),63) !6 bits @@ -112,3 +116,4 @@ subroutine packmsg(msg,dat,text) return end subroutine packmsg + diff --git a/lib/stdmsg.f90 b/lib/stdmsg.f90 index bc8d489ac..7670ff0f0 100644 --- a/lib/stdmsg.f90 +++ b/lib/stdmsg.f90 @@ -2,11 +2,10 @@ logical*1 function stdmsg(msg0) character*22 msg0,msg integer dat(12) - logical text - call packmsg(msg0,dat,text) + call packmsg(msg0,dat,itype) call unpackmsg(dat,msg) - stdmsg=msg.eq.msg0 .and. (.not.text) + stdmsg=(msg.eq.msg0) .and. (itype.ge.0) return end function stdmsg diff --git a/mainwindow.cpp b/mainwindow.cpp index 81423c798..cf23db3e4 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1508,19 +1508,19 @@ void MainWindow::guiUpdate() ba2msg(ba,message); // ba2msg(ba,msgsent); int len1=22; - int ichk=0,itext=0; + int ichk=0,itype=0; if(m_modeTx=="JT9") genjt9_(message , &ichk , msgsent , const_cast (itone) - , &itext + , &itype , len1 , len1); if(m_modeTx=="JT65") gen65_(message , &ichk , msgsent , const_cast (itone) - , &itext + , &itype , len1 , len1); msgsent[22]=0; @@ -1545,7 +1545,7 @@ void MainWindow::guiUpdate() t=""; if(w.length()==3) t=w[2]; icw[0]=0; - m_sent73=(t=="73" or itext!=0); + m_sent73=(t=="73" or itype==6); if(m_sent73) { if(m_config.id_after_73 ()) icw[0]=m_ncw; if(m_config.prompt_to_log () && !m_tune) logQSOTimer->start(200); @@ -1560,7 +1560,7 @@ void MainWindow::guiUpdate() } QString t2=QDateTime::currentDateTimeUtc().toString("hhmm"); - if(itext==0 and w.length()>=3 and w[1]==m_config.my_callsign ()) { + if(itype<6 and w.length()>=3 and w[1]==m_config.my_callsign ()) { int i1; bool ok; i1=t.toInt(&ok); @@ -1577,7 +1577,7 @@ void MainWindow::guiUpdate() } } } - if(itext==1 or (w.length()==3 and w[2]=="73")) m_qsoStop=t2; + if(itype==6 or (w.length()==3 and w[2]=="73")) m_qsoStop=t2; m_restart=false; } @@ -2027,9 +2027,10 @@ void MainWindow::genStdMsgs(QString rpt) //genStdMsgs() t="CQ " + m_config.my_callsign () + " " + m_config.my_grid ().mid(0,4); msgtype(t, ui->tx6); - if(m_config.my_callsign ()!=myBase) { if(shortList(m_config.my_callsign ())) { + t=hisCall + " " + m_config.my_callsign (); + msgtype(t, ui->tx1); t="CQ " + m_config.my_callsign (); msgtype(t, ui->tx6); } else { @@ -2044,7 +2045,10 @@ void MainWindow::genStdMsgs(QString rpt) //genStdMsgs() if(hisCall!=hisBase) { if(shortList(hisCall)) { t=hisCall + " " + m_config.my_callsign (); - msgtype(t, ui->tx2); + msgtype(t, ui->tx1); + } else { + t=hisCall + " 73"; + msgtype(t, ui->tx5->lineEdit()); } } } @@ -2196,17 +2200,17 @@ void MainWindow::msgtype(QString t, QLineEdit* tx) //msgtype() t=t.toUpper(); QByteArray s=t.toUpper().toLocal8Bit(); ba2msg(s,message); - int ichk=1,itext=0; + int ichk=1,itype=0; genjt9_(message , &ichk , msgsent , const_cast (itone) - , &itext + , &itype , len1 , len1); msgsent[22]=0; bool text=false; - if(itext!=0) text=true; + if(itype==6) text=true; QString t1; t1.fromLatin1(msgsent); if(text) t1=t1.mid(0,13); diff --git a/mainwindow.h b/mainwindow.h index 04a1a0d5a..7166d34f9 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -216,13 +216,19 @@ private: Frequency m_dialFreq; + Detector m_detector; + SoundInput m_soundInput; + Modulator m_modulator; + SoundOutput m_soundOutput; + QThread * m_audioThread; + qint64 m_msErase; qint64 m_secBandChanged; qint32 m_waterfallAvg; qint32 m_ntx; qint32 m_timeout; - int m_XIT; + qint32 m_XIT; qint32 m_setftx; qint32 m_ndepth; qint32 m_sec0; @@ -230,14 +236,6 @@ private: qint32 m_nutc0; qint32 m_nrx; qint32 m_hsym; - - Detector m_detector; - SoundInput m_soundInput; - - Modulator m_modulator; - SoundOutput m_soundOutput; - QThread * m_audioThread; - qint32 m_TRperiod; qint32 m_nsps; qint32 m_hsymStop; @@ -246,7 +244,6 @@ private: qint32 m_nsave; qint32 m_ncw; qint32 m_secID; - QString m_band; qint32 m_repeatMsg; qint32 m_watchdogLimit; qint32 m_astroFont; @@ -339,6 +336,7 @@ private: QString m_cmnd; QString m_msgSent0; QString m_fileToSave; + QString m_band; QStringList m_prefix; QStringList m_suffix;