From 7348bc323e063da9b358e6aad95262b7db7edb59 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 5 Dec 2023 15:11:57 -0500 Subject: [PATCH] Work in progress: Q65-30B candidate selection now basically working. --- qmap/libqmap/getcand2.f90 | 64 +++++++++++++++++++++++++++++++-------- qmap/libqmap/q65_sync.f90 | 26 ++++++++++++---- qmap/libqmap/qmapa.f90 | 1 + qmap/libqmap/symspec.f90 | 19 ++++++------ 4 files changed, 81 insertions(+), 29 deletions(-) diff --git a/qmap/libqmap/getcand2.f90 b/qmap/libqmap/getcand2.f90 index 6b2d08f37..db548c75d 100644 --- a/qmap/libqmap/getcand2.f90 +++ b/qmap/libqmap/getcand2.f90 @@ -6,6 +6,7 @@ subroutine getcand2(ss,savg0,nts_q65,nagain,ntol,f0_selected,cand,ncand) real :: snr !Relative S/N of sync detection real :: f !Freq of sync tone, 0 to 96000 Hz real :: xdt !DT of matching sync pattern, -1.0 to +4.0 s + integer :: ntrperiod !60 for Q65-60x, 30 for Q65-30x end type candidate parameter (NFFT=32768) !FFTs done in symspec() @@ -48,20 +49,57 @@ subroutine getcand2(ss,savg0,nts_q65,nagain,ntol,f0_selected,cand,ncand) i0=ipk1(1) + i - 1 !Index of local peak in savg() fpk=0.001*i0*df !Frequency of peak (kHz) ! Check to see if sync tone is present. - call q65_sync(ss,i0,nts_q65,sync_ok,snr_sync,xdt) - if(.not.sync_ok) cycle - + ntrperiod=60 + iseq=0 + call q65_sync(ss,i0,nts_q65,ntrperiod,iseq,sync_ok,snr_sync,xdt) + if(sync_ok) then ! Sync tone is present, we have a candidate for decoding - j=j+1 - cand(j)%f=fpk - cand(j)%xdt=xdt - cand(j)%snr=snr_sync - ia=max(1,min(i,i0-nguard)) - ib=min(i0+nbw+nguard,32768) - savg(ia:ib)=0. - write(*,3301) j,fpk+80-48,xdt,snr_sync -3301 format(i3,f8.1,f8.2,f8.1) - if(j.ge.MAX_CANDIDATES) exit + j=j+1 + cand(j)%f=fpk + cand(j)%xdt=xdt + cand(j)%snr=snr_sync + cand(j)%ntrperiod=ntrperiod + ia=max(1,min(i,i0-nguard)) + ib=min(i0+nbw+nguard,32768) + savg(ia:ib)=0. +! write(*,3301) j,fpk+80-48,xdt,snr_sync,ntrperiod,iseq +3301 format(i3,f8.1,f8.2,f8.1,2i5) + if(j.ge.MAX_CANDIDATES) exit + endif + + ntrperiod=30 +! if(ntrperiod.eq.30) cycle + + call q65_sync(ss,i0,nts_q65,ntrperiod,iseq,sync_ok,snr_sync,xdt) + if(sync_ok) then +! Sync tone is present, we have a candidate for decoding + j=j+1 + cand(j)%f=fpk + cand(j)%xdt=xdt + cand(j)%snr=snr_sync + cand(j)%ntrperiod=ntrperiod + ia=max(1,min(i,i0-nguard)) + ib=min(i0+nbw+nguard,32768) + savg(ia:ib)=0. +! write(*,3301) j,fpk+80-48,xdt,snr_sync,ntrperiod,iseq + if(j.ge.MAX_CANDIDATES) exit + endif + + iseq=1 + call q65_sync(ss,i0,nts_q65,ntrperiod,iseq,sync_ok,snr_sync,xdt) + if(sync_ok) then +! Sync tone is present, we have a candidate for decoding + j=j+1 + cand(j)%f=fpk + cand(j)%xdt=xdt + cand(j)%snr=snr_sync + cand(j)%ntrperiod=ntrperiod + ia=max(1,min(i,i0-nguard)) + ib=min(i0+nbw+nguard,32768) + savg(ia:ib)=0. +! write(*,3301) j,fpk+80-48,xdt,snr_sync,ntrperiod,iseq + if(j.ge.MAX_CANDIDATES) exit + endif enddo ncand=j !Total number of candidates found diff --git a/qmap/libqmap/q65_sync.f90 b/qmap/libqmap/q65_sync.f90 index 0a8f43b12..a09c9c209 100644 --- a/qmap/libqmap/q65_sync.f90 +++ b/qmap/libqmap/q65_sync.f90 @@ -1,4 +1,4 @@ -subroutine q65_sync(ss,i0,nts_q65,sync_ok,snr,xdt) +subroutine q65_sync(ss,i0,nts_q65,ntrperiod,iseq,sync_ok,snr,xdt) ! Test for presence of Q65 sync tone @@ -7,26 +7,36 @@ subroutine q65_sync(ss,i0,nts_q65,sync_ok,snr,xdt) real ss(373,NFFT) !Symbol spectra real ccf(0:LAGMAX) !The WSJT "blue curve", peak at DT logical sync_ok - logical first integer isync0(22),isync(22),ipk(1) ! Q65 sync symbols data isync0/1,9,12,13,15,22,23,26,27,33,35,38,46,50,55,60,62,66,69,74,76,85/ + sync_ok=.false. +! if(ntrperiod.ne.60) return + tstep=0.15 !0.5*tsym_Q65-30x, 0.25*tsys_Q65-60x + nfac=4 + if(ntrperiod.eq.30) nfac=2 do i=1,22 !Expand sync stride for Q65-60x - isync(i)=4*(isync0(i)-1) + 1 + isync(i)=nfac*(isync0(i)-1) + 1 enddo m=nts_q65/2 + if(ntrperiod.eq.30) m=nts_q65/4 i1=max(1,i0-m) i2=min(NFFT,i0+m) ccf=0. do lag=0,LAGMAX !Search over range of DT do j=1,22 !Test for Q65 sync - k=isync(j) + lag - ccf(lag)=ccf(lag) + sum(ss(k,i1:i2)) + sum(ss(k+1,i1:i2)) & - + sum(ss(k+2,i1:i2)) + sum(ss(k+3,i1:i2)) + k=isync(j) + lag + iseq*200 + if(ntrperiod.eq.60) then + ccf(lag)=ccf(lag) + sum(ss(k,i1:i2)) + sum(ss(k+1,i1:i2)) & + + sum(ss(k+2,i1:i2)) + sum(ss(k+3,i1:i2)) + else + if(k.ge.372) cycle + ccf(lag)=ccf(lag) + sum(ss(k,i1:i2)) + sum(ss(k+1,i1:i2)) + endif ! Q: Should we use weighted sums, perhaps a Lorentzian peak? enddo enddo @@ -34,16 +44,20 @@ subroutine q65_sync(ss,i0,nts_q65,sync_ok,snr,xdt) ipk=maxloc(ccf) lagbest=ipk(1)-1 xdt=lagbest*tstep - 1.0 + if(ntrperiod.eq.30) xd=xdt+0.6 !Why ??? xsum=0. sq=0. nsum=0 + fpk=0.001*i0*96000.0/32768.0 + 32.0 do i=0,lagmax !Compute ave and rms of "blue curve" if(abs(i-lagbest).gt.2) then xsum=xsum+ccf(i) sq=sq+ccf(i)**2 nsum=nsum+1 endif + write(40,3040) i,i*tstep-1.0,ccf(i),fpk +3040 format(i5,3f8.2) enddo ave=xsum/nsum rms=sqrt(sq/nsum - ave*ave) diff --git a/qmap/libqmap/qmapa.f90 b/qmap/libqmap/qmapa.f90 index 5c38513e7..13e1f9928 100644 --- a/qmap/libqmap/qmapa.f90 +++ b/qmap/libqmap/qmapa.f90 @@ -10,6 +10,7 @@ subroutine qmapa(dd,ss,savg,newdat,nutc,fcenter,ntol,nfa,nfb, & real :: snr !Relative S/N of sync detection real :: f !Freq of sync tone, 0 to 96000 Hz real :: xdt !DT of matching sync pattern, -1.0 to +4.0 s + integer :: ntrperiod !60 for Q65-60x, 30 for Q65-30x end type candidate parameter (NFFT=32768) !Size of FFTs done in symspec() diff --git a/qmap/libqmap/symspec.f90 b/qmap/libqmap/symspec.f90 index 0ef92d759..2794d90b0 100644 --- a/qmap/libqmap/symspec.f90 +++ b/qmap/libqmap/symspec.f90 @@ -26,20 +26,21 @@ subroutine symspec(k,ndiskdat,nb,nbslider,nfsample, & data rms/999.0/,k0/99999999/,nadjx/0/,nadjy/0/ save + hsym=0.15d0*96000.d0 !Samples per Q65-30x half-symbol + npts=2*hsym !Full Q65-30x symbol if(k.gt.5751000) go to 999 - if(k.lt.NFFT) then + if(k.lt.npts) then ihsym=0 go to 999 !Wait for enough samples to start endif if(k0.eq.99999999) then - pi=4.0*atan(1.0) - do i=1,NFFT - w(i)=(sin(i*pi/NFFT))**2 !Window - enddo +! pi=4.0*atan(1.0) +! do i=1,NFFT +! w(i)=(sin(i*pi/NFFT))**2 !Window +! enddo + w=0.7 !Flat window endif - hsym=0.15d0*96000.d0 !Samples per Q65-30x half-symbol - if(k.lt.k0) then ts=1.d0 - hsym savg=0. @@ -76,12 +77,9 @@ subroutine symspec(k,ndiskdat,nb,nbslider,nfsample, & k1=k1+kstep enddo - npts=NFFT !Samples used in each half-symbol FFT - ts=ts+hsym ja=ts !Index of first sample jb=ja+npts-1 !Last sample - i=0 fac=0.0002 do j=ja,jb !Copy data into cx @@ -90,6 +88,7 @@ subroutine symspec(k,ndiskdat,nb,nbslider,nfsample, & i=i+1 cx(i)=fac*cmplx(x1,x2) enddo + cx(npts+1:)=0. if(nzap/178.lt.50 .and. (ndiskdat.eq.0 .or. ihsym.lt.280)) then nsum=nblks*kstep - nzap