mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-22 12:23:37 -05:00
151 lines
4.2 KiB
FortranFixed
151 lines
4.2 KiB
FortranFixed
|
subroutine mtdecode(dat,jz,s2,nchan,nz,MinSigdB,MinWidth,
|
||
|
+ NQRN,DFTolerance,istart,pick,MouseButton,NSaveCum,
|
||
|
+ cfile6,ps0)
|
||
|
|
||
|
C Decode Multi-Tone FSK441 mesages.
|
||
|
|
||
|
real dat(jz) !Raw audio data
|
||
|
real s2(nchan,nz) !2d spectrum of data
|
||
|
integer NQRN
|
||
|
integer DFTolerance
|
||
|
logical pick
|
||
|
character*6 cfile6,cf*1
|
||
|
|
||
|
real sigdb(3100) !Detected signal in dB, sampled at 20 ms
|
||
|
real work(3100)
|
||
|
integer indx(3100)
|
||
|
real pingdat(3,100)
|
||
|
real ps(128)
|
||
|
real ps0(128)
|
||
|
character msg*40,msg3*3
|
||
|
character*90 line
|
||
|
common/ccom/nline,tping(100),line(100)
|
||
|
|
||
|
! slim=10.0*log10(10.0**(0.1*MinSigdB)+1.0)
|
||
|
slim=MinSigdB
|
||
|
wmin=0.001*MinWidth * (19.95/20.0)
|
||
|
nf1=-DFTolerance
|
||
|
nf2=DFTolerance
|
||
|
msg3=' '
|
||
|
nq=64
|
||
|
dt=1.0/11025.0
|
||
|
df=11025.0/256.0
|
||
|
|
||
|
C Find signal power at suitable intervals to search for pings.
|
||
|
istep=221
|
||
|
dtbuf=istep/11025.
|
||
|
do n=1,nz
|
||
|
s=0.
|
||
|
ib=n*istep
|
||
|
ia=ib-istep+1
|
||
|
do i=ia,ib
|
||
|
s=s+dat(i)**2
|
||
|
enddo
|
||
|
sigdb(n)=s/istep
|
||
|
enddo
|
||
|
|
||
|
!#####################################################################
|
||
|
if(.not.pick) then
|
||
|
! Remove initial transient from sigdb
|
||
|
call indexx(nz,sigdb,indx)
|
||
|
imax=0
|
||
|
do i=1,50
|
||
|
if(indx(i).gt.50) go to 10
|
||
|
imax=max(imax,indx(i))
|
||
|
enddo
|
||
|
10 do i=1,50
|
||
|
if(indx(nz+1-i).gt.50) go to 20
|
||
|
imax=max(imax,indx(nz+1-i))
|
||
|
enddo
|
||
|
20 imax=imax+6 !Safety margin
|
||
|
base1=sigdb(indx(nz/2))
|
||
|
do i=1,imax
|
||
|
sigdb(i)=base1
|
||
|
enddo
|
||
|
endif
|
||
|
!##################################################################
|
||
|
|
||
|
call smooth(sigdb,nz)
|
||
|
|
||
|
C Remove baseline and one dB for good measure.
|
||
|
call pctile (sigdb,work,nz,50,base1)
|
||
|
do i=1,nz
|
||
|
sigdb(i)=dB(sigdb(i)/base1) - 1.0
|
||
|
enddo
|
||
|
|
||
|
call ping(sigdb,nz,dtbuf,slim,wmin,pingdat,nping)
|
||
|
|
||
|
C If this is a "mouse pick", force a psuedo-ping at the center of
|
||
|
C the data.
|
||
|
if(pick) then
|
||
|
if(nping.le.99) nping=nping+1
|
||
|
pingdat(1,nping)=0.5*jz*dt
|
||
|
pingdat(2,nping)=0.16
|
||
|
pingdat(3,nping)=1.0
|
||
|
endif
|
||
|
|
||
|
bigpeak=0.
|
||
|
do iping=1,nping
|
||
|
C Find starting place and length of data to be analyzed:
|
||
|
tstart=pingdat(1,iping)
|
||
|
width=pingdat(2,iping)
|
||
|
peak=pingdat(3,iping)
|
||
|
mswidth=10*nint(100.0*width)
|
||
|
jj=(tstart-0.02)/dt
|
||
|
if(jj.lt.1) jj=1
|
||
|
jjz=nint((width+0.02)/dt)+1
|
||
|
jjz=min(jjz,jz+1-jj)
|
||
|
|
||
|
C Compute average spectrum of this ping.
|
||
|
call spec441(dat(jj),jjz,ps,f0)
|
||
|
|
||
|
C Decode the message.
|
||
|
msg=' '
|
||
|
call longx(dat(jj),jjz,ps,DFTolerance,noffset,msg,
|
||
|
+ msglen,bauderr,MouseButton)
|
||
|
qrnlimit=4.4*1.5**(5.0-NQRN)
|
||
|
if(NQRN.eq.0) qrnlimit=99.
|
||
|
if(msglen.eq.0) go to 100
|
||
|
|
||
|
C Assemble a signal report:
|
||
|
nwidth=0
|
||
|
if(width.ge.0.04) nwidth=1 !These might depend on NSPD
|
||
|
if(width.ge.0.12) nwidth=2
|
||
|
if(width.gt.1.00) nwidth=3
|
||
|
nstrength=6
|
||
|
if(peak.ge.11.0) nstrength=7
|
||
|
if(peak.ge.17.0) nstrength=8
|
||
|
if(peak.ge.23.0) nstrength=9
|
||
|
|
||
|
! if(peak.gt.5.0 .and.mswidth.ge.100) then
|
||
|
! call specsq(dat(jj),jjz,DFTolerance,0,noffset2)
|
||
|
! noffset=noffset2
|
||
|
! endif
|
||
|
|
||
|
C Discard this ping if DF outside tolerance limits or bauderr too big.
|
||
|
C (However, if the ping was mouse-picked, proceed anyway.)
|
||
|
|
||
|
if(.not.pick .and. ((noffset.lt.nf1 .or. noffset.gt.nf2) .or.
|
||
|
+ (abs(bauderr).gt.qrnlimit))) goto 100
|
||
|
|
||
|
C If it's the best ping yet, save the spectrum:
|
||
|
if(peak.gt.bigpeak) then
|
||
|
bigpeak=peak
|
||
|
do i=1,128
|
||
|
ps0(i)=ps(i)
|
||
|
enddo
|
||
|
endif
|
||
|
|
||
|
tstart=tstart + dt*(istart-1)
|
||
|
cf=' '
|
||
|
if(nline.le.99) nline=nline+1
|
||
|
tping(nline)=tstart
|
||
|
snr=10.0*log10(10.0**(0.1*peak)-1.0)
|
||
|
write(line(nline),1050) cfile6,tstart,mswidth,int(peak),
|
||
|
+ nwidth,nstrength,noffset,msg3,msg,cf
|
||
|
1050 format(a6,f5.1,i5,i3,1x,2i1,i5,1x,a3,1x,a40,1x,a1)
|
||
|
100 enddo
|
||
|
|
||
|
return
|
||
|
end
|