subroutine fast9(id2,narg,line) ! Decoder for "fast9" modes, JT9E to JT9H. parameter (NMAX=30*12000,NSAVE=500) integer*2 id2(0:NMAX) integer narg(0:14) integer*1 i1SoftSymbols(207) integer*1 i1save(207,NSAVE) integer indx(NSAVE) integer*8 count0,count1,clkfreq real s1(720000) !To reserve space. Logically s1(nq,jz) real s2(240,340) !Symbol spectra at quarter-symbol steps real ss2(0:8,85) !Folded symbol spectra real ss3(0:7,69) !Folded spectra without sync symbols real s(1500) real ccfsave(NSAVE) real t0save(NSAVE) real t1save(NSAVE) real freqSave(NSAVE) real t(6) character*22 msg !Decoded message character*80 line(100) data nsubmode0/-1/,ntot/0/ save s1,nsubmode0,ntot ! Parameters from GUI are in narg(): nutc=narg(0) !UTC npts=min(narg(1),NMAX) !Number of samples in id2 (12000 Hz) nsubmode=narg(2) !0=A 1=B 2=C 3=D 4=E 5=F 6=G 7=H if(nsubmode.lt.4) go to 900 newdat=narg(3) !1==> new data, compute symbol spectra minsync=narg(4) !Lower sync limit npick=narg(5) t0=0.001*narg(6) t1=0.001*narg(7) maxlines=narg(8) !Max # of decodes to return to caller nmode=narg(9) nrxfreq=narg(10) !Targer Rx audio frequency (Hz) ntol=narg(11) !Search range, +/- ntol (Hz) tmid=npts*0.5/12000.0 line(1:100)(1:1)=char(0) s=0 s2=0 nsps=60 * 2**(7-nsubmode) !Samples per sysbol nfft=2*nsps !FFT size nh=nfft/2 nq=nfft/4 istep=nsps/4 !Symbol spectra at quarter-symbol steps jz=npts/istep df=12000.0/nfft !FFT bin width db1=db(2500.0/df) nfa=max(200,nrxfreq-ntol) !Lower frequency limit nfb=min(nrxfreq+ntol,2500) !Upper frequency limit nline=0 t=0. if(newdat.eq.1 .or. nsubmode.ne.nsubmode0) then call system_clock(count0,clkfreq) call spec9f(id2,npts,nsps,s1,jz,nq) !Compute symbol spectra, s1 call system_clock(count1,clkfreq) t(1)=t(1)+float(count1-count0)/float(clkfreq) endif nsubmode0=nsubmode tmsg=nsps*85.0/12000.0 limit=2000 nlen0=0 i1=0 i2=0 ccfsave=0. do ilength=1,14 nlen=1.4142136**(ilength-1) if(nlen.gt.jz/340) nlen=jz/340 if(nlen.eq.nlen0) cycle nlen0=nlen db0=db(float(nlen)) jlen=nlen*340 jstep=jlen/4 !### Is this about right? ### if(nsubmode.ge.6) jstep=jlen/2 do ja=1,jz-jlen,jstep jb=ja+jlen-1 call system_clock(count0,clkfreq) call foldspec9f(s1,nq,jz,ja,jb,s2) !Fold symbol spectra into s2 call system_clock(count1,clkfreq) t(2)=t(2)+float(count1-count0)/float(clkfreq) ! Find sync; put sync'ed symbol spectra into ss2 and ss3 ! Might want to do a peakup in DT and DF, then re-compute symbol spectra. call system_clock(count0,clkfreq) call sync9f(s2,nq,nfa,nfb,ss2,ss3,lagpk,ipk,ccfbest) call system_clock(count1,clkfreq) t(3)=t(3)+float(count1-count0)/float(clkfreq) i1=i1+1 if(ccfbest.lt.30.0) cycle call system_clock(count0,clkfreq) call softsym9f(ss2,ss3,i1SoftSymbols) !Compute soft symbols call system_clock(count1,clkfreq) t(4)=t(4)+float(count1-count0)/float(clkfreq) i2=i2+1 ccfsave(i2)=ccfbest i1save(1:207,i2)=i1SoftSymbols t0=(ja-1)*istep/12000.0 t1=(jb-1)*istep/12000.0 t0save(i2)=t0 t1save(i2)=t1 freq=ipk*df freqSave(i2)=freq enddo enddo nsaved=i2 ccfsave(1:nsaved)=-ccfsave(1:nsaved) call system_clock(count0,clkfreq) indx=0 call indexx(ccfsave,nsaved,indx) call system_clock(count1,clkfreq) t(5)=t(5)+float(count1-count0)/float(clkfreq) ccfsave(1:nsaved)=-ccfsave(1:nsaved) do iter=1,2 ! do isave=1,nsaved do isave=1,50 i2=indx(isave) if(i2.lt.1 .or. i2.gt.nsaved) cycle !### Why needed? ### t0=t0save(i2) t1=t1save(i2) if(iter.eq.1 .and. t1.lt.tmid) cycle if(iter.eq.2 .and. t1.ge.tmid) cycle ccfbest=ccfsave(i2) i1SoftSymbols=i1save(1:207,i2) freq=freqSave(i2) call system_clock(count0,clkfreq) call jt9fano(i1SoftSymbols,limit,nlim,msg) !Invoke Fano decoder call system_clock(count1,clkfreq) t(6)=t(6)+float(count1-count0)/float(clkfreq) i=t0*12000.0 kz=(t1-t0)/0.02 smax=0. do k=1,kz sq=0. do n=1,240 i=i+1 x=id2(i) sq=sq+x*x enddo s(k)=sq/240. smax=max(s(k),smax) enddo call pctile(s,kz,35,base) snr=smax/(1.1*base) - 1.0 nsnr=-20 if(snr.gt.0.0) nsnr=nint(db(snr)) ! write(72,3002) nutc,iter,isave,nlen,tmid,t0,t1,ccfbest, & ! nint(freq),nlim,msg !3002 format(i6.6,i1,i4,i3,4f6.1,i5,i7,1x,a22) if(msg.ne.' ') then ! Display multiple decodes only if they differ: do n=1,nline if(index(line(n),msg).gt.1) go to 100 enddo !### Might want to use decoded message to get a complete estimate of S/N. nline=nline+1 write(line(nline),1000) nutc,nsnr,t0,nint(freq),msg,char(0) 1000 format(i6.6,i4,f5.1,i5,1x,'@ ',1x,a22,a1) ntot=ntot+1 ! write(70,5001) nsaved,isave,nline,maxlines,ntot,nutc,msg !5001 format(5i5,i7.6,1x,a22) if(nline.ge.maxlines) go to 900 endif 100 continue enddo enddo 900 continue ! write(*,6001) t,t(6)/sum(t) !6001 format(7f10.3) return end subroutine fast9