From 630ef640ac2bf801fee078b07c476416d6af2d45 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Tue, 30 Jun 2020 15:06:18 -0500 Subject: [PATCH 1/4] First cut at joint QSO/WSPR type decoding for FST240. --- lib/fst240_decode.f90 | 1319 +++++++++++++++++++++-------------------- 1 file changed, 671 insertions(+), 648 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index f899f544c..c82c18e14 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -1,99 +1,100 @@ module fst240_decode - type :: fst240_decoder - procedure(fst240_decode_callback), pointer :: callback + type :: fst240_decoder + procedure(fst240_decode_callback), pointer :: callback contains - procedure :: decode - end type fst240_decoder + procedure :: decode + end type fst240_decoder - abstract interface - subroutine fst240_decode_callback (this,nutc,sync,nsnr,dt,freq, & - decoded,nap,qual,ntrperiod,lwspr) - import fst240_decoder - implicit none - class(fst240_decoder), intent(inout) :: this - integer, intent(in) :: nutc - real, intent(in) :: sync - integer, intent(in) :: nsnr - real, intent(in) :: dt - real, intent(in) :: freq - character(len=37), intent(in) :: decoded - integer, intent(in) :: nap - real, intent(in) :: qual - integer, intent(in) :: ntrperiod - logical, intent(in) :: lwspr - end subroutine fst240_decode_callback - end interface + abstract interface + subroutine fst240_decode_callback (this,nutc,sync,nsnr,dt,freq, & + decoded,nap,qual,ntrperiod,lwspr) + import fst240_decoder + implicit none + class(fst240_decoder), intent(inout) :: this + integer, intent(in) :: nutc + real, intent(in) :: sync + integer, intent(in) :: nsnr + real, intent(in) :: dt + real, intent(in) :: freq + character(len=37), intent(in) :: decoded + integer, intent(in) :: nap + real, intent(in) :: qual + integer, intent(in) :: ntrperiod + logical, intent(in) :: lwspr + end subroutine fst240_decode_callback + end interface contains - subroutine decode(this,callback,iwave,nutc,nQSOProgress,nfqso, & + subroutine decode(this,callback,iwave,nutc,nQSOProgress,nfqso, & nfa,nfb,nsubmode,ndeep,ntrperiod,nexp_decode,ntol,nzhsym, & emedelay,lapcqonly,napwid,mycall,hiscall,nfsplit,iwspr) - use timer_module, only: timer - use packjt77 - include 'fst240/fst240_params.f90' - parameter (MAXCAND=100) - class(fst240_decoder), intent(inout) :: this - procedure(fst240_decode_callback) :: callback - character*37 decodes(100) - character*37 msg,msgsent - character*77 c77 - character*12 mycall,hiscall - character*12 mycall0,hiscall0 - complex, allocatable :: c2(:) - complex, allocatable :: cframe(:) - complex, allocatable :: c_bigfft(:) !Complex waveform - real, allocatable :: r_data(:) - real llr(240),llra(240),llrb(240),llrc(240),llrd(240) - real candidates(100,4) - real bitmetrics(320,4) - real s4(0:3,NN) - logical lapcqonly - integer itone(NN) - integer hmod - integer*1 apmask(240),cw(240) - integer*1 hbits(320) - integer*1 message101(101),message74(74),message77(77) - integer*1 rvec(77) - integer apbits(240) - integer nappasses(0:5) ! # of decoding passes for QSO states 0-5 - integer naptypes(0:5,4) ! (nQSOProgress,decoding pass) - integer mcq(29),mrrr(19),m73(19),mrr73(19) + use timer_module, only: timer + use packjt77 + include 'fst240/fst240_params.f90' + parameter (MAXCAND=100) + class(fst240_decoder), intent(inout) :: this + procedure(fst240_decode_callback) :: callback + character*37 decodes(100) + character*37 msg,msgsent + character*77 c77 + character*12 mycall,hiscall + character*12 mycall0,hiscall0 + complex, allocatable :: c2(:) + complex, allocatable :: cframe(:) + complex, allocatable :: c_bigfft(:) !Complex waveform + real, allocatable :: r_data(:) + real llr(240),llra(240),llrb(240),llrc(240),llrd(240) + real candidates(100,4) + real bitmetrics(320,4) + real s4(0:3,NN) + real minsync + logical lapcqonly + integer itone(NN) + integer hmod + integer*1 apmask(240),cw(240) + integer*1 hbits(320) + integer*1 message101(101),message74(74),message77(77) + integer*1 rvec(77) + integer apbits(240) + integer nappasses(0:5) ! # of decoding passes for QSO states 0-5 + integer naptypes(0:5,4) ! (nQSOProgress,decoding pass) + integer mcq(29),mrrr(19),m73(19),mrr73(19) - logical badsync,unpk77_success,single_decode - logical first,nohiscall,lwspr + logical badsync,unpk77_success,single_decode + logical first,nohiscall,lwspr - integer*2 iwave(300*12000) + integer*2 iwave(300*12000) - data mcq/0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0/ - data mrrr/0,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,1/ - data m73/0,1,1,1,1,1,1,0,1,0,0,1,0,1,0,0,0,0,1/ - data mrr73/0,1,1,1,1,1,1,0,0,1,1,1,0,1,0,1,0,0,1/ - data rvec/0,1,0,0,1,0,1,0,0,1,0,1,1,1,1,0,1,0,0,0,1,0,0,1,1,0,1,1,0, & - 1,0,0,1,0,1,1,0,0,0,0,1,0,0,0,1,0,1,0,0,1,1,1,1,0,0,1,0,1, & - 0,1,0,1,0,1,1,0,1,1,1,1,1,0,0,0,1,0,1/ - data first/.true./ - save first,apbits,nappasses,naptypes,mycall0,hiscall0 + data mcq/0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0/ + data mrrr/0,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,1/ + data m73/0,1,1,1,1,1,1,0,1,0,0,1,0,1,0,0,0,0,1/ + data mrr73/0,1,1,1,1,1,1,0,0,1,1,1,0,1,0,1,0,0,1/ + data rvec/0,1,0,0,1,0,1,0,0,1,0,1,1,1,1,0,1,0,0,0,1,0,0,1,1,0,1,1,0, & + 1,0,0,1,0,1,1,0,0,0,0,1,0,0,0,1,0,1,0,0,1,1,1,1,0,0,1,0,1, & + 0,1,0,1,0,1,1,0,1,1,1,1,1,0,0,0,1,0,1/ + data first/.true./ + save first,apbits,nappasses,naptypes,mycall0,hiscall0 - this%callback => callback + this%callback => callback - dxcall13=hiscall ! initialize for use in packjt77 - mycall13=mycall + dxcall13=hiscall ! initialize for use in packjt77 + mycall13=mycall - if(first) then - mcq=2*mod(mcq+rvec(1:29),2)-1 - mrrr=2*mod(mrrr+rvec(59:77),2)-1 - m73=2*mod(m73+rvec(59:77),2)-1 - mrr73=2*mod(mrr73+rvec(59:77),2)-1 + if(first) then + mcq=2*mod(mcq+rvec(1:29),2)-1 + mrrr=2*mod(mrrr+rvec(59:77),2)-1 + m73=2*mod(m73+rvec(59:77),2)-1 + mrr73=2*mod(mrr73+rvec(59:77),2)-1 - nappasses(0)=2 - nappasses(1)=2 - nappasses(2)=2 - nappasses(3)=2 - nappasses(4)=2 - nappasses(5)=3 + nappasses(0)=2 + nappasses(1)=2 + nappasses(2)=2 + nappasses(3)=2 + nappasses(4)=2 + nappasses(5)=3 ! iaptype !------------------------ @@ -105,632 +106,654 @@ contains ! 6 MyCall DxCall RR73 (77 ap bits) !******** - naptypes(0,1:4)=(/1,2,0,0/) ! Tx6 selected (CQ) - naptypes(1,1:4)=(/2,3,0,0/) ! Tx1 - naptypes(2,1:4)=(/2,3,0,0/) ! Tx2 - naptypes(3,1:4)=(/3,6,0,0/) ! Tx3 - naptypes(4,1:4)=(/3,6,0,0/) ! Tx4 - naptypes(5,1:4)=(/3,1,2,0/) ! Tx5 + naptypes(0,1:4)=(/1,2,0,0/) ! Tx6 selected (CQ) + naptypes(1,1:4)=(/2,3,0,0/) ! Tx1 + naptypes(2,1:4)=(/2,3,0,0/) ! Tx2 + naptypes(3,1:4)=(/3,6,0,0/) ! Tx3 + naptypes(4,1:4)=(/3,6,0,0/) ! Tx4 + naptypes(5,1:4)=(/3,1,2,0/) ! Tx5 - mycall0='' - hiscall0='' - first=.false. - endif - - l1=index(mycall,char(0)) - if(l1.ne.0) mycall(l1:)=" " - l1=index(hiscall,char(0)) - if(l1.ne.0) hiscall(l1:)=" " - if(mycall.ne.mycall0 .or. hiscall.ne.hiscall0) then - apbits=0 - apbits(1)=99 - apbits(30)=99 - - if(len(trim(mycall)) .lt. 3) go to 10 - - nohiscall=.false. - hiscall0=hiscall - if(len(trim(hiscall0)).lt.3) then - hiscall0=mycall ! use mycall for dummy hiscall - mycall won't be hashed. - nohiscall=.true. + mycall0='' + hiscall0='' + first=.false. endif - msg=trim(mycall)//' '//trim(hiscall0)//' RR73' - i3=-1 - n3=-1 - call pack77(msg,i3,n3,c77) - call unpack77(c77,1,msgsent,unpk77_success) - if(i3.ne.1 .or. (msg.ne.msgsent) .or. .not.unpk77_success) go to 10 - read(c77,'(77i1)') message77 - message77=mod(message77+rvec,2) - call encode174_91(message77,cw) - apbits=2*cw-1 - if(nohiscall) apbits(30)=99 -10 continue - mycall0=mycall - hiscall0=hiscall - endif + l1=index(mycall,char(0)) + if(l1.ne.0) mycall(l1:)=" " + l1=index(hiscall,char(0)) + if(l1.ne.0) hiscall(l1:)=" " + if(mycall.ne.mycall0 .or. hiscall.ne.hiscall0) then + apbits=0 + apbits(1)=99 + apbits(30)=99 + + if(len(trim(mycall)) .lt. 3) go to 10 + + nohiscall=.false. + hiscall0=hiscall + if(len(trim(hiscall0)).lt.3) then + hiscall0=mycall ! use mycall for dummy hiscall - mycall won't be hashed. + nohiscall=.true. + endif + msg=trim(mycall)//' '//trim(hiscall0)//' RR73' + i3=-1 + n3=-1 + call pack77(msg,i3,n3,c77) + call unpack77(c77,1,msgsent,unpk77_success) + if(i3.ne.1 .or. (msg.ne.msgsent) .or. .not.unpk77_success) go to 10 + read(c77,'(77i1)') message77 + message77=mod(message77+rvec,2) + call encode174_91(message77,cw) + apbits=2*cw-1 + if(nohiscall) apbits(30)=99 + +10 continue + mycall0=mycall + hiscall0=hiscall + endif !************************************ - hmod=2**nsubmode - if(nfqso+nqsoprogress.eq.-999) return - Keff=91 - iwspr=1 - nmax=15*12000 - single_decode=iand(nexp_decode,32).eq.32 - if(ntrperiod.eq.15) then - nsps=720 + hmod=2**nsubmode + if(nfqso+nqsoprogress.eq.-999) return + Keff=91 + iwspr=1 nmax=15*12000 - ndown=18/hmod !nss=40,80,160,400 - if(hmod.eq.4) ndown=4 - if(hmod.eq.8) ndown=2 - nfft1=int(nmax/ndown)*ndown - else if(ntrperiod.eq.30) then - nsps=1680 - nmax=30*12000 - ndown=42/hmod !nss=40,80,168,336 - nfft1=359856 - if(hmod.eq.4) then - ndown=10 - nfft1=nmax + single_decode=iand(nexp_decode,32).eq.32 + if(ntrperiod.eq.15) then + nsps=720 + nmax=15*12000 + ndown=18/hmod !nss=40,80,160,400 + if(hmod.eq.4) ndown=4 + if(hmod.eq.8) ndown=2 + nfft1=int(nmax/ndown)*ndown + else if(ntrperiod.eq.30) then + nsps=1680 + nmax=30*12000 + ndown=42/hmod !nss=40,80,168,336 + nfft1=359856 + if(hmod.eq.4) then + ndown=10 + nfft1=nmax + endif + if(hmod.eq.8) then + ndown=5 + nfft1=nmax + endif + else if(ntrperiod.eq.60) then + nsps=3888 + nmax=60*12000 + ndown=96/hmod !nss=36,81,162,324 + if(hmod.eq.1) ndown=108 + nfft1=int(719808/ndown)*ndown + else if(ntrperiod.eq.120) then + nsps=8200 + nmax=120*12000 + ndown=200/hmod !nss=40,82,164,328 + if(hmod.eq.1) ndown=205 + nfft1=int(nmax/ndown)*ndown + else if(ntrperiod.eq.300) then + nsps=21504 + nmax=300*12000 + ndown=512/hmod !nss=42,84,168,336 + nfft1=int((nmax-200)/ndown)*ndown + end if + nss=nsps/ndown + fs=12000.0 !Sample rate + fs2=fs/ndown + nspsec=nint(fs2) + dt=1.0/fs !Sample interval (s) + dt2=1.0/fs2 + tt=nsps*dt !Duration of "itone" symbols (s) + baud=1.0/tt + sigbw=4.0*hmod*baud + nfft2=nfft1/ndown !make sure that nfft1 is exactly nfft2*ndown + nfft1=nfft2*ndown + nh1=nfft1/2 + + allocate( r_data(1:nfft1+2) ) + allocate( c_bigfft(0:nfft1/2) ) + + allocate( c2(0:nfft2-1) ) + allocate( cframe(0:160*nss-1) ) + + + if(ndeep.eq.3) then + nblock=1 + if(hmod.eq.1) nblock=4 ! number of block sizes to try + jittermax=2 + norder=3 + elseif(ndeep.eq.2) then + nblock=1 + if(hmod.eq.1) nblock=3 + jittermax=0 + norder=3 + elseif(ndeep.eq.1) then + nblock=1 + jittermax=0 + norder=3 endif - if(hmod.eq.8) then - ndown=5 - nfft1=nmax - endif - else if(ntrperiod.eq.60) then - nsps=3888 - nmax=60*12000 - ndown=96/hmod !nss=36,81,162,324 - if(hmod.eq.1) ndown=108 - nfft1=int(719808/ndown)*ndown - else if(ntrperiod.eq.120) then - nsps=8200 - nmax=120*12000 - ndown=200/hmod !nss=40,82,164,328 - if(hmod.eq.1) ndown=205 - nfft1=int(nmax/ndown)*ndown - else if(ntrperiod.eq.300) then - nsps=21504 - nmax=300*12000 - ndown=512/hmod !nss=42,84,168,336 - nfft1=int((nmax-200)/ndown)*ndown - end if - nss=nsps/ndown - fs=12000.0 !Sample rate - fs2=fs/ndown - nspsec=nint(fs2) - dt=1.0/fs !Sample interval (s) - dt2=1.0/fs2 - tt=nsps*dt !Duration of "itone" symbols (s) - baud=1.0/tt - sigbw=4.0*hmod*baud - nfft2=nfft1/ndown !make sure that nfft1 is exactly nfft2*ndown - nfft1=nfft2*ndown - nh1=nfft1/2 - allocate( r_data(1:nfft1+2) ) - allocate( c_bigfft(0:nfft1/2) ) - - allocate( c2(0:nfft2-1) ) - allocate( cframe(0:160*nss-1) ) - - if(single_decode) then - fa=max(100,nint(nfqso+1.5*hmod*baud-ntol)) - fb=min(4800,nint(nfqso+1.5*hmod*baud+ntol)) - else - fa=max(100,nfa) - fb=min(4800,nfb) - endif - - if(ndeep.eq.3) then - nblock=1 - if(hmod.eq.1) nblock=4 ! number of block sizes to try - jittermax=2 - norder=3 - elseif(ndeep.eq.2) then - nblock=1 - if(hmod.eq.1) nblock=3 - jittermax=0 - norder=3 - elseif(ndeep.eq.1) then - nblock=1 - jittermax=0 - norder=3 - endif - -! The big fft is done once and is used for calculating the smoothed spectrum +! The big fft is done once and is used for calculating the smoothed spectrum ! and also for downconverting/downsampling each candidate. - r_data(1:nfft1)=iwave(1:nfft1) - r_data(nfft1+1:nfft1+2)=0.0 - call four2a(r_data,nfft1,1,-1,0) - c_bigfft=cmplx(r_data(1:nfft1+2:2),r_data(2:nfft1+2:2)) + r_data(1:nfft1)=iwave(1:nfft1) + r_data(nfft1+1:nfft1+2)=0.0 + call four2a(r_data,nfft1,1,-1,0) + c_bigfft=cmplx(r_data(1:nfft1+2:2),r_data(2:nfft1+2:2)) + + if(iwspr.eq.0) then + itype1=1 + itype2=1 + elseif( iwspr.eq.1 ) then + itype1=2 + itype2=2 + elseif( iwspr.eq.2 ) then + itype1=1 + itype2=2 + endif + + do iqorw=itype1,itype2 ! iqorw=1 for QSO mode and iqorw=2 for wspr-type messages + if( iwspr.lt.2 ) then + if( single_decode ) then + fa=max(100,nint(nfqso+1.5*hmod*baud-ntol)) + fb=min(4800,nint(nfqso+1.5*hmod*baud+ntol)) + else + fa=max(100,nfa) + fb=min(4800,nfb) + endif + elseif( iwspr.eq.2 .and. iqorw.eq.1 ) then + fa=max(100,nfa) + fb=nfsplit + elseif( iwspr.eq.2 .and. iqorw.eq.2 ) then + fa=nfsplit + fb=min(4800,nfb) + endif + + minsync=1.25 + if(iqorw.eq.2) then + minsync=1.2 + endif ! Get first approximation of candidate frequencies - call get_candidates_fst240(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & - ncand,candidates,base) + call get_candidates_fst240(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & + minsync,ncand,candidates,base) - ndecodes=0 - decodes=' ' + ndecodes=0 + decodes=' ' - isbest1=0 - isbest8=0 - fc21=0. - fc28=0. - do icand=1,ncand - fc0=candidates(icand,1) - detmet=candidates(icand,2) + isbest1=0 + isbest8=0 + fc21=0. + fc28=0. + do icand=1,ncand + fc0=candidates(icand,1) + detmet=candidates(icand,2) ! Downconvert and downsample a slice of the spectrum centered on the ! rough estimate of the candidates frequency. ! Output array c2 is complex baseband sampled at 12000/ndown Sa/sec. ! The size of the downsampled c2 array is nfft2=nfft1/ndown - call fst240_downsample(c_bigfft,nfft1,ndown,fc0,sigbw,c2) + call fst240_downsample(c_bigfft,nfft1,ndown,fc0,sigbw,c2) - call timer('sync240 ',0) - do isync=0,1 - if(isync.eq.0) then - fc1=0.0 - if(emedelay.lt.0.1) then ! search offsets from 0 s to 2 s - is0=1.5*nspsec - ishw=1.5*nspsec - else ! search plus or minus 1.5 s centered on emedelay - is0=nint(emedelay*nspsec) - ishw=1.5*nspsec - endif - isst=4*hmod - ifhw=12 - df=.1*baud - else if(isync.eq.1) then - fc1=fc21 - if(hmod.eq.1) fc1=fc28 - is0=isbest1 - if(hmod.eq.1) is0=isbest8 - ishw=4*hmod - isst=1*hmod - ifhw=7 - df=.02*baud - endif - - smax1=0.0 - smax8=0.0 - do if=-ifhw,ifhw - fc=fc1+df*if - do istart=max(1,is0-ishw),is0+ishw,isst - call sync_fst240(c2,istart,fc,hmod,1,nfft2,nss,fs2,sync1) - call sync_fst240(c2,istart,fc,hmod,8,nfft2,nss,fs2,sync8) - if(sync8.gt.smax8) then - fc28=fc - isbest8=istart - smax8=sync8 + call timer('sync240 ',0) + do isync=0,1 + if(isync.eq.0) then + fc1=0.0 + if(emedelay.lt.0.1) then ! search offsets from 0 s to 2 s + is0=1.5*nspsec + ishw=1.5*nspsec + else ! search plus or minus 1.5 s centered on emedelay + is0=nint(emedelay*nspsec) + ishw=1.5*nspsec + endif + isst=4*hmod + ifhw=12 + df=.1*baud + else if(isync.eq.1) then + fc1=fc21 + if(hmod.eq.1) fc1=fc28 + is0=isbest1 + if(hmod.eq.1) is0=isbest8 + ishw=4*hmod + isst=1*hmod + ifhw=7 + df=.02*baud endif - if(sync1.gt.smax1) then - fc21=fc - isbest1=istart - smax1=sync1 + + smax1=0.0 + smax8=0.0 + do if=-ifhw,ifhw + fc=fc1+df*if + do istart=max(1,is0-ishw),is0+ishw,isst + call sync_fst240(c2,istart,fc,hmod,1,nfft2,nss,fs2,sync1) + call sync_fst240(c2,istart,fc,hmod,8,nfft2,nss,fs2,sync8) + if(sync8.gt.smax8) then + fc28=fc + isbest8=istart + smax8=sync8 + endif + if(sync1.gt.smax1) then + fc21=fc + isbest1=istart + smax1=sync1 + endif + enddo + enddo + enddo + call timer('sync240 ',1) + + if(smax8/smax1 .lt. 0.65 ) then + fc2=fc21 + isbest=isbest1 + njitter=2 + else + fc2=fc28 + isbest=isbest8 + njitter=2 + endif + fc_synced = fc0 + fc2 + dt_synced = (isbest-fs2)*dt2 !nominal dt is 1 second so frame starts at sample fs2 + candidates(icand,3)=fc_synced + candidates(icand,4)=isbest + enddo + +! remove duplicate candidates + do icand=1,ncand + fc=candidates(icand,3) + isbest=nint(candidates(icand,4)) + do ic2=1,ncand + fc2=candidates(ic2,3) + isbest2=nint(candidates(ic2,4)) + if(ic2.ne.icand .and. fc2.gt.0.0) then + if(abs(fc2-fc).lt.0.10*baud) then ! same frequency + if(abs(isbest2-isbest).le.2) then + candidates(ic2,3)=-1 + endif + endif endif enddo enddo - enddo - call timer('sync240 ',1) - if(smax8/smax1 .lt. 0.65 ) then - fc2=fc21 - isbest=isbest1 - njitter=2 - else - fc2=fc28 - isbest=isbest8 - njitter=2 - endif - fc_synced = fc0 + fc2 - dt_synced = (isbest-fs2)*dt2 !nominal dt is 1 second so frame starts at sample fs2 - candidates(icand,3)=fc_synced - candidates(icand,4)=isbest - enddo - -! remove duplicate candidates - do icand=1,ncand - fc=candidates(icand,3) - isbest=nint(candidates(icand,4)) - do ic2=1,ncand - fc2=candidates(ic2,3) - isbest2=nint(candidates(ic2,4)) - if(ic2.ne.icand .and. fc2.gt.0.0) then - if(abs(fc2-fc).lt.0.10*baud) then ! same frequency - if(abs(isbest2-isbest).le.2) then - candidates(ic2,3)=-1 - endif + ic=0 + do icand=1,ncand + if(candidates(icand,3).gt.0) then + ic=ic+1 + candidates(ic,:)=candidates(icand,:) endif - endif - enddo - enddo + enddo + ncand=ic + xsnr=0. - ic=0 - do icand=1,ncand - if(candidates(icand,3).gt.0) then - ic=ic+1 - candidates(ic,:)=candidates(icand,:) - endif - enddo - ncand=ic - xsnr=0. + do icand=1,ncand + sync=candidates(icand,2) + fc_synced=candidates(icand,3) + isbest=nint(candidates(icand,4)) + xdt=(isbest-nspsec)/fs2 + if(ntrperiod.eq.15) xdt=(isbest-real(nspsec)/2.0)/fs2 + call fst240_downsample(c_bigfft,nfft1,ndown,fc_synced,sigbw,c2) - do icand=1,ncand - sync=candidates(icand,2) - fc_synced=candidates(icand,3) - isbest=nint(candidates(icand,4)) - xdt=(isbest-nspsec)/fs2 - if(ntrperiod.eq.15) xdt=(isbest-real(nspsec)/2.0)/fs2 - call fst240_downsample(c_bigfft,nfft1,ndown,fc_synced,sigbw,c2) + do ijitter=0,jittermax + if(ijitter.eq.0) ioffset=0 + if(ijitter.eq.1) ioffset=1 + if(ijitter.eq.2) ioffset=-1 + is0=isbest+ioffset + if(is0.lt.0) cycle + cframe=c2(is0:is0+160*nss-1) + bitmetrics=0 + call get_fst240_bitmetrics(cframe,nss,hmod,nblock,bitmetrics,s4,badsync) + if(badsync) cycle - do ijitter=0,jittermax - if(ijitter.eq.0) ioffset=0 - if(ijitter.eq.1) ioffset=1 - if(ijitter.eq.2) ioffset=-1 - is0=isbest+ioffset - if(is0.lt.0) cycle - cframe=c2(is0:is0+160*nss-1) - bitmetrics=0 - call get_fst240_bitmetrics(cframe,nss,hmod,nblock,bitmetrics,s4,badsync) - if(badsync) cycle + hbits=0 + where(bitmetrics(:,1).ge.0) hbits=1 + ns1=count(hbits( 1: 16).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) + ns2=count(hbits( 77: 92).eq.(/1,1,1,0,0,1,0,0,1,0,1,1,0,0,0,1/)) + ns3=count(hbits(153:168).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) + ns4=count(hbits(229:244).eq.(/1,1,1,0,0,1,0,0,1,0,1,1,0,0,0,1/)) + ns5=count(hbits(305:320).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) + nsync_qual=ns1+ns2+ns3+ns4+ns5 + if(nsync_qual.lt. 44) cycle !### Value ?? ### - hbits=0 - where(bitmetrics(:,1).ge.0) hbits=1 - ns1=count(hbits( 1: 16).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) - ns2=count(hbits( 77: 92).eq.(/1,1,1,0,0,1,0,0,1,0,1,1,0,0,0,1/)) - ns3=count(hbits(153:168).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) - ns4=count(hbits(229:244).eq.(/1,1,1,0,0,1,0,0,1,0,1,1,0,0,0,1/)) - ns5=count(hbits(305:320).eq.(/0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0/)) - nsync_qual=ns1+ns2+ns3+ns4+ns5 - if(nsync_qual.lt. 44) cycle !### Value ?? ### + scalefac=2.83 + llra( 1: 60)=bitmetrics( 17: 76, 1) + llra( 61:120)=bitmetrics( 93:152, 1) + llra(121:180)=bitmetrics(169:228, 1) + llra(181:240)=bitmetrics(245:304, 1) + llra=scalefac*llra + llrb( 1: 60)=bitmetrics( 17: 76, 2) + llrb( 61:120)=bitmetrics( 93:152, 2) + llrb(121:180)=bitmetrics(169:228, 2) + llrb(181:240)=bitmetrics(245:304, 2) + llrb=scalefac*llrb + llrc( 1: 60)=bitmetrics( 17: 76, 3) + llrc( 61:120)=bitmetrics( 93:152, 3) + llrc(121:180)=bitmetrics(169:228, 3) + llrc(181:240)=bitmetrics(245:304, 3) + llrc=scalefac*llrc + llrd( 1: 60)=bitmetrics( 17: 76, 4) + llrd( 61:120)=bitmetrics( 93:152, 4) + llrd(121:180)=bitmetrics(169:228, 4) + llrd(181:240)=bitmetrics(245:304, 4) + llrd=scalefac*llrd - scalefac=2.83 - llra( 1: 60)=bitmetrics( 17: 76, 1) - llra( 61:120)=bitmetrics( 93:152, 1) - llra(121:180)=bitmetrics(169:228, 1) - llra(181:240)=bitmetrics(245:304, 1) - llra=scalefac*llra - llrb( 1: 60)=bitmetrics( 17: 76, 2) - llrb( 61:120)=bitmetrics( 93:152, 2) - llrb(121:180)=bitmetrics(169:228, 2) - llrb(181:240)=bitmetrics(245:304, 2) - llrb=scalefac*llrb - llrc( 1: 60)=bitmetrics( 17: 76, 3) - llrc( 61:120)=bitmetrics( 93:152, 3) - llrc(121:180)=bitmetrics(169:228, 3) - llrc(181:240)=bitmetrics(245:304, 3) - llrc=scalefac*llrc - llrd( 1: 60)=bitmetrics( 17: 76, 4) - llrd( 61:120)=bitmetrics( 93:152, 4) - llrd(121:180)=bitmetrics(169:228, 4) - llrd(181:240)=bitmetrics(245:304, 4) - llrd=scalefac*llrd - - apmag=maxval(abs(llra))*1.1 - ntmax=nblock+nappasses(nQSOProgress) - if(lapcqonly) ntmax=nblock+1 - if(ndepth.eq.1) ntmax=nblock - apmask=0 - - if(iwspr.eq.1) then - nblock=4 - ntmax=nblock - endif - - do itry=1,ntmax - if(itry.eq.1) llr=llra - if(itry.eq.2.and.itry.le.nblock) llr=llrb - if(itry.eq.3.and.itry.le.nblock) llr=llrc - if(itry.eq.4.and.itry.le.nblock) llr=llrd - if(itry.le.nblock) then + apmag=maxval(abs(llra))*1.1 + ntmax=nblock+nappasses(nQSOProgress) + if(lapcqonly) ntmax=nblock+1 + if(ndepth.eq.1) ntmax=nblock apmask=0 - iaptype=0 - endif - napwid=1.2*(4.0*baud*hmod) - - if(itry.gt.nblock) then - if(nblock.eq.1) llr=llra - if(nblock.gt.1) llr=llrc - iaptype=naptypes(nQSOProgress,itry-nblock) - if(lapcqonly) iaptype=1 - if(iaptype.ge.2 .and. apbits(1).gt.1) cycle ! No, or nonstandard, mycall - if(iaptype.ge.3 .and. apbits(30).gt.1) cycle ! No, or nonstandard, dxcall - if(iaptype.eq.1) then ! CQ - apmask=0 - apmask(1:29)=1 - llr(1:29)=apmag*mcq(1:29) - endif - - if(iaptype.eq.2) then ! MyCall ??? ??? - apmask=0 - apmask(1:29)=1 - llr(1:29)=apmag*apbits(1:29) - endif - - if(iaptype.eq.3) then ! MyCall DxCall ??? - apmask=0 - apmask(1:58)=1 - llr(1:58)=apmag*apbits(1:58) + + if(iqorw.eq.2) then ! 50-bit msgs, no ap decoding + nblock=4 + ntmax=nblock endif - if(iaptype.eq.4 .or. iaptype.eq.5 .or. iaptype .eq.6) then - apmask=0 - apmask(1:77)=1 - llr(1:58)=apmag*apbits(1:58) - if(iaptype.eq.4) llr(59:77)=apmag*mrrr(1:19) - if(iaptype.eq.5) llr(59:77)=apmag*m73(1:19) - if(iaptype.eq.6) llr(59:77)=apmag*mrr73(1:19) - endif - endif - - dmin=0.0 - nharderrors=-1 - unpk77_success=.false. - if(iwspr.eq.0) then - maxosd=2 - call timer('d240_101',0) - call decode240_101(llr,Keff,maxosd,norder,apmask,message101, & - cw,ntype,nharderrors,dmin) - call timer('d240_101',1) - else - maxosd=2 - call timer('d240_74 ',0) - Keff=64 - norder=4 - call decode240_74(llr,Keff,maxosd,norder,apmask,message74,cw, & - ntype,nharderrors,dmin) - call timer('d240_74 ',1) - endif - if(nharderrors .ge.0) then - if(iwspr.eq.0) then - write(c77,'(77i1)') mod(message101(1:77)+rvec,2) - call unpack77(c77,0,msg,unpk77_success) - else - write(c77,'(50i1)') message74(1:50) - c77(51:77)='000000000000000000000110000' - call unpack77(c77,0,msg,unpk77_success) - endif - if(unpk77_success) then - idupe=0 - do i=1,ndecodes - if(decodes(i).eq.msg) idupe=1 - enddo - if(idupe.eq.1) exit - ndecodes=ndecodes+1 - decodes(ndecodes)=msg - if(iwspr.eq.0) then - call get_fst240_tones_from_bits(message101,itone,iwspr) - xsig=0 - do i=1,NN - xsig=xsig+s4(itone(i),i)**2 - enddo - arg=400.0*(xsig/base)-1.0 - if(arg.gt.0.0) then - xsnr=10*log10(arg)-21.0-11.7*log10(nsps/800.0) - else - xsnr=-99.9 + do itry=1,ntmax + if(itry.eq.1) llr=llra + if(itry.eq.2.and.itry.le.nblock) llr=llrb + if(itry.eq.3.and.itry.le.nblock) llr=llrc + if(itry.eq.4.and.itry.le.nblock) llr=llrd + if(itry.le.nblock) then + apmask=0 + iaptype=0 + endif + napwid=1.2*(4.0*baud*hmod) + + if(itry.gt.nblock) then + if(nblock.eq.1) llr=llra + if(nblock.gt.1) llr=llrc + iaptype=naptypes(nQSOProgress,itry-nblock) + if(lapcqonly) iaptype=1 + if(iaptype.ge.2 .and. apbits(1).gt.1) cycle ! No, or nonstandard, mycall + if(iaptype.ge.3 .and. apbits(30).gt.1) cycle ! No, or nonstandard, dxcall + if(iaptype.eq.1) then ! CQ + apmask=0 + apmask(1:29)=1 + llr(1:29)=apmag*mcq(1:29) + endif + + if(iaptype.eq.2) then ! MyCall ??? ??? + apmask=0 + apmask(1:29)=1 + llr(1:29)=apmag*apbits(1:29) + endif + + if(iaptype.eq.3) then ! MyCall DxCall ??? + apmask=0 + apmask(1:58)=1 + llr(1:58)=apmag*apbits(1:58) + endif + + if(iaptype.eq.4 .or. iaptype.eq.5 .or. iaptype .eq.6) then + apmask=0 + apmask(1:77)=1 + llr(1:58)=apmag*apbits(1:58) + if(iaptype.eq.4) llr(59:77)=apmag*mrrr(1:19) + if(iaptype.eq.5) llr(59:77)=apmag*m73(1:19) + if(iaptype.eq.6) llr(59:77)=apmag*mrr73(1:19) endif endif - nsnr=nint(xsnr) - qual=0. - fsig=fc_synced - 1.5*hmod*baud + + dmin=0.0 + nharderrors=-1 + unpk77_success=.false. + if(iqorw.eq.1) then + maxosd=2 + norder=3 + call timer('d240_101',0) + call decode240_101(llr,Keff,maxosd,norder,apmask,message101, & + cw,ntype,nharderrors,dmin) + call timer('d240_101',1) + elseif(iqorw.eq.2) then + maxosd=2 + call timer('d240_74 ',0) + Keff=64 + norder=4 + call decode240_74(llr,Keff,maxosd,norder,apmask,message74,cw, & + ntype,nharderrors,dmin) + call timer('d240_74 ',1) + endif + if(nharderrors .ge.0) then + if(iqor2.eq.1) then + write(c77,'(77i1)') mod(message101(1:77)+rvec,2) + call unpack77(c77,0,msg,unpk77_success) + else + write(c77,'(50i1)') message74(1:50) + c77(51:77)='000000000000000000000110000' + call unpack77(c77,0,msg,unpk77_success) + endif + if(unpk77_success) then + idupe=0 + do i=1,ndecodes + if(decodes(i).eq.msg) idupe=1 + enddo + if(idupe.eq.1) exit + ndecodes=ndecodes+1 + decodes(ndecodes)=msg + + call get_fst240_tones_from_bits(message101,itone,iwspr) + xsig=0 + do i=1,NN + xsig=xsig+s4(itone(i),i)**2 + enddo + arg=400.0*(xsig/base)-1.0 + if(arg.gt.0.0) then + xsnr=10*log10(arg)-21.0-11.7*log10(nsps/800.0) + else + xsnr=-99.9 + endif + endif + nsnr=nint(xsnr) + qual=0. + fsig=fc_synced - 1.5*hmod*baud !write(21,'(i6,7i6,f7.1,f9.2,3f7.1,1x,a37)') & ! nutc,icand,itry,iaptype,ijitter,ntype,nsync_qual,nharderrors,dmin,sync,xsnr,x!dt,fsig,msg - call this%callback(nutc,smax1,nsnr,xdt,fsig,msg, & - iaptype,qual,ntrperiod,lwspr) - goto 2002 - else - cycle - endif - endif - enddo ! metrics - enddo ! istart jitter -2002 continue - enddo !candidate list!ws + call this%callback(nutc,smax1,nsnr,xdt,fsig,msg, & + iaptype,qual,ntrperiod,lwspr) + goto 2002 + endif + enddo ! metrics + enddo ! istart jitter +2002 continue + enddo !candidate list + enddo ! iqorw - return - end subroutine decode + return + end subroutine decode - subroutine sync_fst240(cd0,i0,f0,hmod,ncoh,np,nss,fs,sync) + subroutine sync_fst240(cd0,i0,f0,hmod,ncoh,np,nss,fs,sync) ! Compute sync power for a complex, downsampled FST240 signal. - include 'fst240/fst240_params.f90' - complex cd0(0:np-1) - complex, allocatable, save :: csync1(:),csync2(:) - complex, allocatable, save :: csynct1(:),csynct2(:) - complex ctwk(8*nss) - complex z1,z2,z3,z4,z5 - logical first - integer hmod,isyncword1(0:7),isyncword2(0:7) - real f0save - data isyncword1/0,1,3,2,1,0,2,3/ - data isyncword2/2,3,1,0,3,2,0,1/ - data first/.true./,f0save/-99.9/,nss0/-1/ - save first,twopi,dt,fac,f0save,nss0 - p(z1)=(real(z1*fac)**2 + aimag(z1*fac)**2)**0.5 !Compute power + include 'fst240/fst240_params.f90' + complex cd0(0:np-1) + complex, allocatable, save :: csync1(:),csync2(:) + complex, allocatable, save :: csynct1(:),csynct2(:) + complex ctwk(8*nss) + complex z1,z2,z3,z4,z5 + logical first + integer hmod,isyncword1(0:7),isyncword2(0:7) + real f0save + data isyncword1/0,1,3,2,1,0,2,3/ + data isyncword2/2,3,1,0,3,2,0,1/ + data first/.true./,f0save/-99.9/,nss0/-1/ + save first,twopi,dt,fac,f0save,nss0 + p(z1)=(real(z1*fac)**2 + aimag(z1*fac)**2)**0.5 !Compute power - if(nss.ne.nss0 .and. allocated(csync1)) deallocate(csync1,csync2,csynct1,csynct2) - if(first .or. nss.ne.nss0) then - allocate( csync1(8*nss), csync2(8*nss) ) - allocate( csynct1(8*nss), csynct2(8*nss) ) - twopi=8.0*atan(1.0) - dt=1/fs - k=1 - phi1=0.0 - phi2=0.0 - do i=0,7 - dphi1=twopi*hmod*(isyncword1(i)-1.5)/real(nss) - dphi2=twopi*hmod*(isyncword2(i)-1.5)/real(nss) - do j=1,nss - csync1(k)=cmplx(cos(phi1),sin(phi1)) - csync2(k)=cmplx(cos(phi2),sin(phi2)) - phi1=mod(phi1+dphi1,twopi) - phi2=mod(phi2+dphi2,twopi) - k=k+1 + if(nss.ne.nss0 .and. allocated(csync1)) deallocate(csync1,csync2,csynct1,csynct2) + if(first .or. nss.ne.nss0) then + allocate( csync1(8*nss), csync2(8*nss) ) + allocate( csynct1(8*nss), csynct2(8*nss) ) + twopi=8.0*atan(1.0) + dt=1/fs + k=1 + phi1=0.0 + phi2=0.0 + do i=0,7 + dphi1=twopi*hmod*(isyncword1(i)-1.5)/real(nss) + dphi2=twopi*hmod*(isyncword2(i)-1.5)/real(nss) + do j=1,nss + csync1(k)=cmplx(cos(phi1),sin(phi1)) + csync2(k)=cmplx(cos(phi2),sin(phi2)) + phi1=mod(phi1+dphi1,twopi) + phi2=mod(phi2+dphi2,twopi) + k=k+1 + enddo enddo - enddo - first=.false. - nss0=nss - fac=1.0/(8.0*nss) - endif - - if(f0.ne.f0save) then - dphi=twopi*f0*dt - phi=0.0 - do i=1,8*nss - ctwk(i)=cmplx(cos(phi),sin(phi)) - phi=mod(phi+dphi,twopi) - enddo - csynct1=ctwk*csync1 - csynct2=ctwk*csync2 - f0save=f0 - endif - - i1=i0 !Costas arrays - i2=i0+38*nss - i3=i0+76*nss - i4=i0+114*nss - i5=i0+152*nss - - s1=0.0 - s2=0.0 - s3=0.0 - s4=0.0 - s5=0.0 - - nsec=8/ncoh - do i=1,nsec - is=(i-1)*ncoh*nss - z1=0 - if(i1+is.ge.1) then - z1=sum(cd0(i1+is:i1+is+ncoh*nss-1)*conjg(csynct1(is+1:is+ncoh*nss))) + first=.false. + nss0=nss + fac=1.0/(8.0*nss) endif - z2=sum(cd0(i2+is:i2+is+ncoh*nss-1)*conjg(csynct2(is+1:is+ncoh*nss))) - z3=sum(cd0(i3+is:i3+is+ncoh*nss-1)*conjg(csynct1(is+1:is+ncoh*nss))) - z4=sum(cd0(i4+is:i4+is+ncoh*nss-1)*conjg(csynct2(is+1:is+ncoh*nss))) - z5=0 - if(i5+is+ncoh*nss-1.le.np) then - z5=sum(cd0(i5+is:i5+is+ncoh*nss-1)*conjg(csynct1(is+1:is+ncoh*nss))) + + if(f0.ne.f0save) then + dphi=twopi*f0*dt + phi=0.0 + do i=1,8*nss + ctwk(i)=cmplx(cos(phi),sin(phi)) + phi=mod(phi+dphi,twopi) + enddo + csynct1=ctwk*csync1 + csynct2=ctwk*csync2 + f0save=f0 endif - s1=s1+abs(z1)/(8*nss) - s2=s2+abs(z2)/(8*nss) - s3=s3+abs(z3)/(8*nss) - s4=s4+abs(z4)/(8*nss) - s5=s5+abs(z5)/(8*nss) - enddo - sync = s1+s2+s3+s4+s5 - return - end subroutine sync_fst240 + i1=i0 !Costas arrays + i2=i0+38*nss + i3=i0+76*nss + i4=i0+114*nss + i5=i0+152*nss - subroutine fst240_downsample(c_bigfft,nfft1,ndown,f0,sigbw,c1) + s1=0.0 + s2=0.0 + s3=0.0 + s4=0.0 + s5=0.0 + + nsec=8/ncoh + do i=1,nsec + is=(i-1)*ncoh*nss + z1=0 + if(i1+is.ge.1) then + z1=sum(cd0(i1+is:i1+is+ncoh*nss-1)*conjg(csynct1(is+1:is+ncoh*nss))) + endif + z2=sum(cd0(i2+is:i2+is+ncoh*nss-1)*conjg(csynct2(is+1:is+ncoh*nss))) + z3=sum(cd0(i3+is:i3+is+ncoh*nss-1)*conjg(csynct1(is+1:is+ncoh*nss))) + z4=sum(cd0(i4+is:i4+is+ncoh*nss-1)*conjg(csynct2(is+1:is+ncoh*nss))) + z5=0 + if(i5+is+ncoh*nss-1.le.np) then + z5=sum(cd0(i5+is:i5+is+ncoh*nss-1)*conjg(csynct1(is+1:is+ncoh*nss))) + endif + s1=s1+abs(z1)/(8*nss) + s2=s2+abs(z2)/(8*nss) + s3=s3+abs(z3)/(8*nss) + s4=s4+abs(z4)/(8*nss) + s5=s5+abs(z5)/(8*nss) + enddo + sync = s1+s2+s3+s4+s5 + + return + end subroutine sync_fst240 + + subroutine fst240_downsample(c_bigfft,nfft1,ndown,f0,sigbw,c1) ! Output: Complex data in c(), sampled at 12000/ndown Hz - complex c_bigfft(0:nfft1/2) - complex c1(0:nfft1/ndown-1) + complex c_bigfft(0:nfft1/2) + complex c1(0:nfft1/ndown-1) - df=12000.0/nfft1 - i0=nint(f0/df) - ih=nint( ( f0 + 1.3*sigbw/2.0 )/df) - nbw=ih-i0+1 - c1=0. - c1(0)=c_bigfft(i0) - nfft2=nfft1/ndown - do i=1,nbw - if(i0+i.le.nfft1/2) c1(i)=c_bigfft(i0+i) - if(i0-i.ge.0) c1(nfft2-i)=c_bigfft(i0-i) - enddo - c1=c1/nfft2 - call four2a(c1,nfft2,1,1,1) !c2c FFT back to time domain - return - - end subroutine fst240_downsample - - subroutine get_candidates_fst240(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & - ncand,candidates,base) - - complex c_bigfft(0:nfft1/2) !Full length FFT of raw data - integer hmod !Modulation index (submode) - integer im(1) !For maxloc - real candidates(100,4) !Candidate list - real s(18000) !Low resolution power spectrum - real s2(18000) !CCF of s() with 4 tones - real xdb(-3:3) !Model 4-tone CCF peaks - data xdb/0.25,0.50,0.75,1.0,0.75,0.50,0.25/ - data nfft1z/-1/ - save nfft1z - - nh1=nfft1/2 - df1=fs/nfft1 - baud=fs/nsps !Keying rate - df2=baud/2.0 - nd=df2/df1 !s() sums this many bins of big FFT - ndh=nd/2 - ia=nint(max(100.0,fa)/df2) !Low frequency search limit - ib=nint(min(4800.0,fb)/df2) !High frequency limit - signal_bw=4*(12000.0/nsps)*hmod - analysis_bw=min(4800.0,fb)-max(100.0,fa) - noise_bw=10.0*signal_bw !Is this a good compromise? - if(analysis_bw.gt.noise_bw) then - ina=ia - inb=ib - else - fcenter=(fa+fb)/2.0 !If noise_bw > analysis_bw, - fl = max(100.0,fcenter-noise_bw/2.)/df2 !we'll search over noise_bw - fh = min(4800.0,fcenter+noise_bw/2.)/df2 - ina=nint(fl) - inb=nint(fh) - endif - - s=0. !Compute low-resloution power spectrum - do i=ina,inb ! noise analysis window includes signal analysis window - j0=nint(i*df2/df1) - do j=j0-ndh,j0+ndh - s(i)=s(i) + real(c_bigfft(j))**2 + aimag(c_bigfft(j))**2 + df=12000.0/nfft1 + i0=nint(f0/df) + ih=nint( ( f0 + 1.3*sigbw/2.0 )/df) + nbw=ih-i0+1 + c1=0. + c1(0)=c_bigfft(i0) + nfft2=nfft1/ndown + do i=1,nbw + if(i0+i.le.nfft1/2) c1(i)=c_bigfft(i0+i) + if(i0-i.ge.0) c1(nfft2-i)=c_bigfft(i0-i) enddo - enddo - - ina=max(ina,1+3*hmod) !Don't run off the ends - inb=min(inb,18000-3*hmod) - s2=0. - do i=ina,inb !Compute CCF of s() and 4 tones - s2(i)=s(i-hmod*3) + s(i-hmod) +s(i+hmod) +s(i+hmod*3) - enddo - call pctile(s2(ina+hmod*3:inb-hmod*3),inb-ina+1-hmod*6,30,base) - s2=s2/base !Normalize wrt noise level -! thresh=1.25 - thresh=1.15 !First candidate threshold + c1=c1/nfft2 + call four2a(c1,nfft2,1,1,1) !c2c FFT back to time domain + return - ncand=0 - candidates=0 - if(ia.lt.3) ia=3 - if(ib.gt.18000-2) ib=18000-2 + end subroutine fst240_downsample + + subroutine get_candidates_fst240(c_bigfft,nfft1,nsps,hmod,fs,fa,fb, & + minsync,ncand,candidates,base) + + complex c_bigfft(0:nfft1/2) !Full length FFT of raw data + integer hmod !Modulation index (submode) + integer im(1) !For maxloc + real candidates(100,4) !Candidate list + real s(18000) !Low resolution power spectrum + real s2(18000) !CCF of s() with 4 tones + real xdb(-3:3) !Model 4-tone CCF peaks + real minsync + data xdb/0.25,0.50,0.75,1.0,0.75,0.50,0.25/ + + nh1=nfft1/2 + df1=fs/nfft1 + baud=fs/nsps !Keying rate + df2=baud/2.0 + nd=df2/df1 !s() sums this many bins of big FFT + ndh=nd/2 + ia=nint(max(100.0,fa)/df2) !Low frequency search limit + ib=nint(min(4800.0,fb)/df2) !High frequency limit + signal_bw=4*(12000.0/nsps)*hmod + analysis_bw=min(4800.0,fb)-max(100.0,fa) + noise_bw=10.0*signal_bw !Is this a good compromise? + if(analysis_bw.gt.noise_bw) then + ina=ia + inb=ib + else + fcenter=(fa+fb)/2.0 !If noise_bw > analysis_bw, + fl = max(100.0,fcenter-noise_bw/2.)/df2 !we'll search over noise_bw + fh = min(4800.0,fcenter+noise_bw/2.)/df2 + ina=nint(fl) + inb=nint(fh) + endif + + s=0. !Compute low-resloution power spectrum + do i=ina,inb ! noise analysis window includes signal analysis window + j0=nint(i*df2/df1) + do j=j0-ndh,j0+ndh + s(i)=s(i) + real(c_bigfft(j))**2 + aimag(c_bigfft(j))**2 + enddo + enddo + + ina=max(ina,1+3*hmod) !Don't run off the ends + inb=min(inb,18000-3*hmod) + s2=0. + do i=ina,inb !Compute CCF of s() and 4 tones + s2(i)=s(i-hmod*3) + s(i-hmod) +s(i+hmod) +s(i+hmod*3) + enddo + call pctile(s2(ina+hmod*3:inb-hmod*3),inb-ina+1-hmod*6,30,base) + s2=s2/base !Normalize wrt noise level + + ncand=0 + candidates=0 + if(ia.lt.3) ia=3 + if(ib.gt.18000-2) ib=18000-2 ! Find candidates, using the CLEAN algorithm to remove a model of each one -! from s2() after it has been found. - pval=99.99 - do while(ncand.lt.100 .and. pval.gt.thresh) - im=maxloc(s2(ia:ib)) - iploc=ia+im(1)-1 !Index of CCF peak - pval=s2(iploc) !Peak value - if(s2(iploc).gt.thresh) then !Is this a possible candidate? - do i=-3,+3 !Remove 0.9 of a model CCF at - k=iploc+2*hmod*i !this frequency from s2() - if(k.ge.ia .and. k.le.ib) then - s2(k)=max(0.,s2(k)-0.9*pval*xdb(i)) - endif - enddo - ncand=ncand+1 - candidates(ncand,1)=df2*iploc !Candidate frequency - candidates(ncand,2)=pval !Rough estimate of SNR - endif - enddo +! from s2() after it has been found. + pval=99.99 + do while(ncand.lt.100 .and. pval.gt.minsync) + im=maxloc(s2(ia:ib)) + iploc=ia+im(1)-1 !Index of CCF peak + pval=s2(iploc) !Peak value + if(s2(iploc).gt.thresh) then !Is this a possible candidate? + do i=-3,+3 !Remove 0.9 of a model CCF at + k=iploc+2*hmod*i !this frequency from s2() + if(k.ge.ia .and. k.le.ib) then + s2(k)=max(0.,s2(k)-0.9*pval*xdb(i)) + endif + enddo + ncand=ncand+1 + candidates(ncand,1)=df2*iploc !Candidate frequency + candidates(ncand,2)=pval !Rough estimate of SNR + endif + enddo - return - end subroutine get_candidates_fst240 + return + end subroutine get_candidates_fst240 end module fst240_decode From 7345e1366154bb25b6bfe41c0ff79bd48b62c8c5 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Tue, 30 Jun 2020 15:50:50 -0500 Subject: [PATCH 2/4] Fix a bug --- lib/fst240_decode.f90 | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index c82c18e14..257f517aa 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -155,8 +155,6 @@ contains hmod=2**nsubmode if(nfqso+nqsoprogress.eq.-999) return - Keff=91 - iwspr=1 nmax=15*12000 single_decode=iand(nexp_decode,32).eq.32 if(ntrperiod.eq.15) then @@ -240,6 +238,8 @@ contains call four2a(r_data,nfft1,1,-1,0) c_bigfft=cmplx(r_data(1:nfft1+2:2),r_data(2:nfft1+2:2)) +if(iwspr.ne.0.and.iwspr.ne.1.and.iwspr.ne.2) iwspr=1 ! TEMPORARY + if(iwspr.eq.0) then itype1=1 itype2=1 @@ -497,6 +497,7 @@ contains unpk77_success=.false. if(iqorw.eq.1) then maxosd=2 + Keff=91 norder=3 call timer('d240_101',0) call decode240_101(llr,Keff,maxosd,norder,apmask,message101, & @@ -511,8 +512,9 @@ contains ntype,nharderrors,dmin) call timer('d240_74 ',1) endif + if(nharderrors .ge.0) then - if(iqor2.eq.1) then + if(iqorw.eq.1) then write(c77,'(77i1)') mod(message101(1:77)+rvec,2) call unpack77(c77,0,msg,unpk77_success) else @@ -552,8 +554,7 @@ contains endif enddo ! metrics enddo ! istart jitter -2002 continue - enddo !candidate list +2002 enddo !candidate list enddo ! iqorw return From a8b87f1f3a98badfc4dba8e5ad55a39046c91580 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Tue, 30 Jun 2020 16:05:52 -0500 Subject: [PATCH 3/4] Fix wspr-mode SNR. --- lib/.fst240_decode.f90.swp | Bin 45056 -> 0 bytes lib/fst240_decode.f90 | 8 ++++++-- 2 files changed, 6 insertions(+), 2 deletions(-) delete mode 100644 lib/.fst240_decode.f90.swp diff --git a/lib/.fst240_decode.f90.swp b/lib/.fst240_decode.f90.swp deleted file mode 100644 index 80719f14301320e718670170abe1f21b1c9edddd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45056 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 Date: Tue, 30 Jun 2020 16:06:53 -0500 Subject: [PATCH 4/4] Remove temporary stuff. --- lib/fst240_decode.f90 | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/fst240_decode.f90 b/lib/fst240_decode.f90 index 7099ebc5a..6dfa3643d 100644 --- a/lib/fst240_decode.f90 +++ b/lib/fst240_decode.f90 @@ -238,8 +238,6 @@ contains call four2a(r_data,nfft1,1,-1,0) c_bigfft=cmplx(r_data(1:nfft1+2:2),r_data(2:nfft1+2:2)) -if(iwspr.ne.0.and.iwspr.ne.1.and.iwspr.ne.2) iwspr=1 ! TEMPORARY -iwspr=1 if(iwspr.eq.0) then itype1=1 itype2=1