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
This commit is contained in:
Joe Taylor 2014-10-19 00:56:41 +00:00
parent 5add0aeb97
commit 0e96882d8b
10 changed files with 139 additions and 105 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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<int *> (itone)
, &itext
, &itype
, len1
, len1);
if(m_modeTx=="JT65") gen65_(message
, &ichk
, msgsent
, const_cast<int *> (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<int *> (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);

View File

@ -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;