mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-25 05:38:46 -05:00
1. Alt+F8 arms "Call 1st" as if a CQ had been sent.
2. "Call 1st" label turns red when armed to respond to a caller. 3. Suppress some recognizable false decodes, send them to cumulative file "data_dir/false_decodes.txt". 4. Reduce sleep delay in decoder() to 10 ms. git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@7928 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
parent
ee38f44656
commit
73df0d00ef
@ -376,6 +376,7 @@ set (wsjt_FSRCS
|
||||
lib/fsk4hf/chkcrc10.f90
|
||||
lib/fsk4hf/chkcrc12.f90
|
||||
lib/fsk4hf/chkcrc12a.f90
|
||||
lib/chkcall.f90
|
||||
lib/chkhist.f90
|
||||
lib/chkmsg.f90
|
||||
lib/chkss2.f90
|
||||
@ -474,6 +475,7 @@ set (wsjt_FSRCS
|
||||
lib/iscat.f90
|
||||
lib/jplsubs.f
|
||||
lib/jt9fano.f90
|
||||
lib/jtmsg.f90
|
||||
lib/ldpcsim144.f90
|
||||
lib/fsk4hf/ldpcsim120.f90
|
||||
lib/fsk4hf/ldpcsim168.f90
|
||||
|
58
lib/chkcall.f90
Normal file
58
lib/chkcall.f90
Normal file
@ -0,0 +1,58 @@
|
||||
subroutine chkcall(w,bc,cok)
|
||||
|
||||
! Check "w" to see if it could be a valid standard callsign or a valid
|
||||
! compound callsign.
|
||||
! Return base call "bc" and a logical "cok" indicator.
|
||||
|
||||
character w*13 !A putative callsign
|
||||
character bc*6 !Base call (tentative)
|
||||
character c*1
|
||||
logical cok,isdigit,isletter
|
||||
|
||||
isdigit(c)=(ichar(c).ge.ichar('0')) .and. (ichar(c).le.ichar('9'))
|
||||
isletter(c)=(ichar(c).ge.ichar('A')) .and. (ichar(c).le.ichar('Z'))
|
||||
|
||||
cok=.true.
|
||||
bc=w(1:6)
|
||||
n1=len_trim(w)
|
||||
if(n1.gt.11) go to 100
|
||||
if(index(w,'.').ge.1) go to 100
|
||||
if(index(w,'+').ge.1) go to 100
|
||||
if(index(w,'-').ge.1) go to 100
|
||||
if(index(w,'?').ge.1) go to 100
|
||||
if(n1.gt.6 .and. index(w,'/').le.0) go to 100
|
||||
|
||||
i0=index(w,'/')
|
||||
if(max(i0-1,n1-i0).gt.6) go to 100 !Base call must be < 7 characters
|
||||
if(i0.ge.2 .and. i0.le.n1-1) then !Extract base call from compound call
|
||||
if(i0-1.le.n1-i0) bc=w(i0+1:n1)//' '
|
||||
if(i0-1.gt.n1-i0) bc=w(1:i0-1)//' '
|
||||
endif
|
||||
|
||||
nbc=len_trim(bc)
|
||||
if(nbc.gt.6) go to 100 !Base call should have no more than 6 characters
|
||||
|
||||
! One of first two characters (c1 or c2) must be a letter
|
||||
if((.not.isletter(bc(1:1))) .and. (.not.isletter(bc(2:2)))) go to 100
|
||||
if(bc(1:1).eq.'Q') go to 100 !Calls don't start with Q
|
||||
|
||||
! Must have a digit in 2nd or 3rd position
|
||||
i1=0
|
||||
if(isdigit(bc(2:2))) i1=2
|
||||
if(isdigit(bc(3:3))) i1=3
|
||||
if(i1.eq.0) go to 100
|
||||
|
||||
! Callsign must have a suffix of 1-3 letters
|
||||
if(i1.eq.nbc) go to 100
|
||||
n=0
|
||||
do i=i1+1,nbc
|
||||
j=ichar(bc(i:i))
|
||||
if(j.lt.ichar('A') .or. j.gt.ichar('Z')) go to 100
|
||||
n=n+1
|
||||
enddo
|
||||
if(n.ge.1 .and. n.le.3) go to 200
|
||||
|
||||
100 cok=.false.
|
||||
|
||||
200 return
|
||||
end subroutine chkcall
|
@ -61,7 +61,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
|
||||
if(ios.ne.0) then
|
||||
nfail=nfail+1
|
||||
if(nfail.le.3) then
|
||||
call sleep_msec(100)
|
||||
call sleep_msec(10)
|
||||
go to 10
|
||||
endif
|
||||
endif
|
||||
|
@ -252,7 +252,8 @@ subroutine ft8b(dd0,newdat,nfqso,ndepth,lsubtract,iaptype,icand,sync0,f1,xdt,
|
||||
if(any(decoded(75:75).ne.0)) cycle !Reject if any of the 3 extra bits are nonzero
|
||||
if(nharderrors.ge.0 .and. nharderrors+dmin.lt.60.0 .and. &
|
||||
.not.(sync.lt.2.0 .and. nharderrors.gt.35) .and. &
|
||||
.not.( iap .gt. 0 .and. nharderrors.gt.39) &
|
||||
.not.(iap.gt.0 .and. nharderrors.gt.39) .and. &
|
||||
.not.(iera.ge.2 .and. nharderrors.gt.30) &
|
||||
) then
|
||||
call chkcrc12a(decoded,nbadcrc)
|
||||
else
|
||||
|
@ -81,13 +81,26 @@ contains
|
||||
xdt,apsym,nharderrors,dmin,nbadcrc,iap,ipass,iera,message,xsnr)
|
||||
nsnr=nint(xsnr)
|
||||
xdt=xdt-0.5
|
||||
hd=nharderrors+dmin
|
||||
call timer('ft8b ',1)
|
||||
if(nbadcrc.eq.0 .and. associated(this%callback)) then
|
||||
if(nbadcrc.eq.0) then
|
||||
call jtmsg(message,iflag)
|
||||
if(iand(iflag,16).ne.0) message(22:22)='?'
|
||||
if(iand(iflag,15).eq.0) then
|
||||
! write(81,1004) nutc,ncand,icand,ipass,iaptype,iap,iera, &
|
||||
! iflag,nharderrors,dmin,hd,min(sync,999.0),nint(xsnr), &
|
||||
! xdt,nint(f1),message
|
||||
! flush(81)
|
||||
if(associated(this%callback)) then
|
||||
call this%callback(sync,nsnr,xdt,f1,iap,iera,message)
|
||||
write(81,3081) ncand,icand,iera,nharderrors,ipass,iap,iaptype, &
|
||||
db(sync),f1,xdt,dmin,xsnr,message
|
||||
3081 format(2i5,i2,i3,i2,i2,i2,f7.2,f7.1,3f7.2,1x,a22)
|
||||
flush(81)
|
||||
endif
|
||||
else
|
||||
write(19,1004) nutc,ncand,icand,ipass,iaptype,iap,iera, &
|
||||
iflag,nharderrors,dmin,hd,min(sync,999.0),nint(xsnr), &
|
||||
xdt,nint(f1),message
|
||||
1004 format(i6.6,2i4,4i2,2i3,3f6.1,i4,f6.2,i5,2x,a22)
|
||||
flush(19)
|
||||
endif
|
||||
endif
|
||||
enddo
|
||||
! h=default_header(12000,NMAX)
|
||||
|
@ -161,6 +161,8 @@ program jt9
|
||||
! Import FFTW wisdom, if available
|
||||
wisfile=trim(data_dir)//'/jt9_wisdom.dat'// C_NULL_CHAR
|
||||
iret=fftwf_import_wisdom_from_filename(wisfile)
|
||||
open(19,file=trim(data_dir)//'/false_decodes.txt',status='unknown', &
|
||||
position='append')
|
||||
|
||||
ntry65a=0
|
||||
ntry65b=0
|
||||
|
125
lib/jtmsg.f90
Normal file
125
lib/jtmsg.f90
Normal file
@ -0,0 +1,125 @@
|
||||
subroutine jtmsg(msg,iflag)
|
||||
|
||||
! Attempts to identify false decodes in JT-style messages.
|
||||
|
||||
! Returns iflag with sum of bits as follows:
|
||||
! ------------------------------------------
|
||||
! 1 Grid/Report invalid
|
||||
! 2 Second callsign invalid
|
||||
! 4 First callsign invalid
|
||||
! 8 Very unlikely free text
|
||||
! 16 Questionable free text
|
||||
! 0 Message is probably OK
|
||||
! ------------------------------------------
|
||||
|
||||
character*22 msg,t
|
||||
character*13 w1,w2,w3,w
|
||||
character*6 bc1,bc2
|
||||
character*1 c
|
||||
logical c1ok,c2ok,isdigit,isletter,isgrid4
|
||||
|
||||
! Statement functions
|
||||
isdigit(c)=(ichar(c).ge.ichar('0')) .and. (ichar(c).le.ichar('9'))
|
||||
isletter(c)=(ichar(c).ge.ichar('A')) .and. (ichar(c).le.ichar('Z'))
|
||||
isgrid4(w)=(len_trim(w).eq.4 .and. &
|
||||
ichar(w(1:1)).ge.ichar('A') .and. ichar(w(1:1)).le.ichar('R') .and. &
|
||||
ichar(w(2:2)).ge.ichar('A') .and. ichar(w(2:2)).le.ichar('R') .and. &
|
||||
ichar(w(3:3)).ge.ichar('0') .and. ichar(w(3:3)).le.ichar('9') .and. &
|
||||
ichar(w(4:4)).ge.ichar('0') .and. ichar(w(4:4)).le.ichar('9'))
|
||||
|
||||
t=trim(msg) !Temporary copy of msg
|
||||
nt=len_trim(t)
|
||||
|
||||
! Check for standard messages
|
||||
! Insert underscore in "CQ AA " to "CQ ZZ ", "CQ nnn " to make them one word.
|
||||
if(t(1:3).eq.'CQ ' .and. isletter(t(4:4)) .and. &
|
||||
isletter(t(5:5)) .and. t(6:6).eq.' ') t(3:3)='_'
|
||||
if(t(1:3).eq.'CQ ' .and. isdigit(t(4:4)) .and. &
|
||||
isdigit(t(5:5)) .and. isdigit(t(6:6)) .and. t(7:7).eq.' ') t(3:3)='_'
|
||||
|
||||
! Parse first three words
|
||||
w1=' '
|
||||
w2=' '
|
||||
w3=' '
|
||||
i1=index(t,' ')
|
||||
if(i1.gt.0) w1(1:i1-1)=t(1:i1-1)
|
||||
t=t(i1+1:)
|
||||
i2=index(t,' ')
|
||||
if(i2.gt.0) w2(1:i2-1)=t(1:i2-1)
|
||||
t=t(i2+1:)
|
||||
i3=index(t,' ')
|
||||
if(i3.gt.0) w3(1:i3-1)=t(1:i3-1)
|
||||
|
||||
if(w1(1:3).eq.'CQ ' .or. w1(1:3).eq.'CQ_' .or. w1(1:3).eq.'DE ' .or. &
|
||||
w1(1:4).eq.'QRZ ') then
|
||||
! CQ/DE/QRZ: Should have one good callsign in w2 and maybe a grid/rpt in w3
|
||||
call chkcall(w2,bc2,c2ok)
|
||||
iflag=0
|
||||
if(.not.c2ok) iflag=iflag+2
|
||||
if(len_trim(w3).ne.0 .and. (.not.isgrid4(w3))) iflag=iflag+1
|
||||
if(w1(1:3).eq.'DE ' .and. c2ok) iflag=0
|
||||
if(iflag.eq.0) return
|
||||
endif
|
||||
|
||||
! Check for two calls and maybe a grid, rpt, R+rpr, RRR, or 73
|
||||
iflag=0
|
||||
call chkcall(w1,bc1,c1ok)
|
||||
call chkcall(w2,bc2,c2ok)
|
||||
if(.not.c1ok) iflag=iflag+4
|
||||
if(.not.c2ok) iflag=iflag+2
|
||||
if(len_trim(w3).ne.0 .and. (.not.isgrid4(w3)) .and. &
|
||||
w3(1:1).ne.'+' .and. w3(1:1).ne.'-' .and. &
|
||||
w3(1:2).ne.'R+' .and. w3(1:2).ne.'R-' .and. &
|
||||
w3(1:3).ne.'73 ' .and. w3(1:4).ne.'RRR ') iflag=iflag+1
|
||||
if(iflag.eq.0 .or. nt.gt.13) return
|
||||
|
||||
! Check for plausible free text
|
||||
|
||||
nc=0
|
||||
np=0
|
||||
do i=1,13
|
||||
c=msg(i:i)
|
||||
if(c.ne.' ') nc=nc+1 !Number of non-blank characters
|
||||
if(c.eq.'+') np=np+1 !Number of punctuation characters
|
||||
if(c.eq.'-') np=np+1
|
||||
if(c.eq.'.') np=np+1
|
||||
if(c.eq.'/') np=np+1
|
||||
if(c.eq.'?') np=np+1
|
||||
enddo
|
||||
nb=13-nc !Number of blanks
|
||||
iflag=16 !Mark as potentially questionable
|
||||
if(nc.ge.12 .or. (nc.ge.11 .and. np.gt.0)) then
|
||||
iflag=8 !Unlikely free text, flag it
|
||||
endif
|
||||
|
||||
! Save messages containing some common words
|
||||
if(msg(1:3).eq.'CQ ') iflag=0
|
||||
if(index(msg,'DE ').gt.0) iflag=0
|
||||
if(index(msg,'TU ').gt.0) iflag=0
|
||||
if(index(msg,' TU').gt.0) iflag=0
|
||||
if(index(msg,'73 ').gt.0) iflag=0
|
||||
if(index(msg,' 73').gt.0) iflag=0
|
||||
if(index(msg,'TNX').gt.0) iflag=0
|
||||
if(index(msg,'THX').gt.0) iflag=0
|
||||
if(index(msg,'EQSL').gt.0) iflag=0
|
||||
if(index(msg,'LOTW').gt.0) iflag=0
|
||||
if(index(msg,'DECOD').gt.0) iflag=0
|
||||
if(index(msg,'CHK').gt.0) iflag=0
|
||||
if(index(msg,'CLK').gt.0) iflag=0
|
||||
if(index(msg,'CLOCK').gt.0) iflag=0
|
||||
if(index(msg,'LOG').gt.0) iflag=0
|
||||
if(index(msg,'QRM').gt.0) iflag=0
|
||||
if(index(msg,'QSY').gt.0) iflag=0
|
||||
if(index(msg,'TEST').gt.0) iflag=0
|
||||
if(index(msg,'CQDX').gt.0) iflag=0
|
||||
if(index(msg,'CALL').gt.0) iflag=0
|
||||
if(index(msg,'QRZ').gt.0) iflag=0
|
||||
if(index(msg,'AUTO').gt.0) iflag=0
|
||||
|
||||
if(c1ok .and. w1(1:6).eq.bc1) iflag=0
|
||||
if(c2ok .and. w2(1:6).eq.bc2) iflag=0
|
||||
|
||||
if(nb.ge.4) iflag=0
|
||||
|
||||
return
|
||||
end subroutine jtmsg
|
@ -1701,6 +1701,12 @@ void MainWindow::keyPressEvent (QKeyEvent * e)
|
||||
}
|
||||
on_actionOpen_next_in_directory_triggered();
|
||||
return;
|
||||
case Qt::Key_F8:
|
||||
if((e->modifiers() & Qt::AltModifier) and ui->cbFirst->isChecked()) {
|
||||
m_bCallingCQ=true;
|
||||
ui->cbFirst->setStyleSheet("QCheckBox{color:red}");
|
||||
return;
|
||||
}
|
||||
case Qt::Key_F10:
|
||||
if(e->modifiers() & Qt::ControlModifier) freqCalStep();
|
||||
break;
|
||||
@ -1708,9 +1714,12 @@ void MainWindow::keyPressEvent (QKeyEvent * e)
|
||||
n=11;
|
||||
if(e->modifiers() & Qt::ControlModifier) n+=100;
|
||||
if(e->modifiers() & Qt::ShiftModifier) {
|
||||
/*
|
||||
int f=ui->TxFreqSpinBox->value()/50;
|
||||
if((ui->TxFreqSpinBox->value() % 50) == 0) f=f-1;
|
||||
ui->TxFreqSpinBox->setValue(50*f);
|
||||
*/
|
||||
ui->TxFreqSpinBox->setValue(ui->TxFreqSpinBox->value()-60);
|
||||
} else{
|
||||
bumpFqso(n);
|
||||
}
|
||||
@ -1719,8 +1728,12 @@ void MainWindow::keyPressEvent (QKeyEvent * e)
|
||||
n=12;
|
||||
if(e->modifiers() & Qt::ControlModifier) n+=100;
|
||||
if(e->modifiers() & Qt::ShiftModifier) {
|
||||
/*
|
||||
int f=ui->TxFreqSpinBox->value()/50;
|
||||
ui->TxFreqSpinBox->setValue(50*(f+1));
|
||||
*/
|
||||
ui->TxFreqSpinBox->setValue(ui->TxFreqSpinBox->value()+60);
|
||||
|
||||
} else {
|
||||
bumpFqso(n);
|
||||
}
|
||||
@ -2730,6 +2743,7 @@ void MainWindow::readFromStdout() //readFromStdout
|
||||
m_bDoubleClicked=true;
|
||||
processMessage(decodedtext.string(),43,false);
|
||||
m_bCallingCQ=false;
|
||||
ui->cbFirst->setStyleSheet("");
|
||||
} else {
|
||||
audioFreq=decodedtext.string().mid(16,4).toInt();
|
||||
if(i1>0 or (abs(audioFreq - m_wideGraph->rxFreq()) <= 10)) bDisplayRight=true;
|
||||
@ -3082,7 +3096,15 @@ void MainWindow::guiUpdate()
|
||||
}
|
||||
|
||||
m_currentMessage = QString::fromLatin1(msgsent);
|
||||
if(m_mode=="FT8") m_bCallingCQ=m_currentMessage.mid(0,3)=="CQ ";
|
||||
if(m_mode=="FT8") {
|
||||
m_bCallingCQ=m_currentMessage.mid(0,3)=="CQ ";
|
||||
if(m_bCallingCQ) {
|
||||
ui->cbFirst->setStyleSheet("QCheckBox{color:red}");
|
||||
} else {
|
||||
ui->cbFirst->setStyleSheet("");
|
||||
}
|
||||
}
|
||||
|
||||
if (m_tune) {
|
||||
m_currentMessage = "TUNE";
|
||||
m_currentMessageType = -1;
|
||||
|
Loading…
Reference in New Issue
Block a user