mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-12-24 11:40:31 -05:00
Merge branch 'feat-fst280' into develop
This commit is contained in:
commit
a1150cca61
@ -1,50 +1,78 @@
|
||||
Mode: Q65-30A
|
||||
Data: 30A_K1JT_6m_Ionoscatter (62 files, DT 0.1 to 0.4)
|
||||
Data: 30A_K1JT_6m_Ionoscatter (62 files, 6m ionoscatter DT 0.1 to 0.4)
|
||||
Message: "K1JT K9AN R-16"
|
||||
RxFreq: 1000/10
|
||||
|
||||
Commit No_AP MyCall BothCalls
|
||||
-----------------------------------
|
||||
ef4787: 3 10 6 14 30 33
|
||||
ada5a6: 3 6 6 10 29 36
|
||||
Commit No_AP MyCall BothCalls
|
||||
-----------------------------------------------
|
||||
ef4787: 3 10 6 14 30 33
|
||||
ada5a6: 3 6 6 10 29 36
|
||||
10f574: 2 7 97.6 6 10 95.4 21 33 80.7
|
||||
b8ea4c: 2 7 100.5 6 10 96.9 21 33 81.0
|
||||
|
||||
Mode: Q65-30A
|
||||
Data: 30A_N0AN_6m_Ionoscatter (69 files, DT=0 to 0.1)
|
||||
Data: 30A_N0AN_6m_Ionoscatter (69 files, 6m ionoscatter)
|
||||
Message: "N0AN K1JT -19"
|
||||
RxFreq: 1500/10
|
||||
|
||||
Commit No_AP MyCall BothCalls
|
||||
-----------------------------------
|
||||
ef4787: 7 14 16 22 38 40
|
||||
70a348: 38 43
|
||||
ada5a6: 10 17 11 23 40 46
|
||||
Commit No_AP MyCall BothCalls
|
||||
------------------------------------------------
|
||||
ef4787: 7 14 16 22 38 40
|
||||
70a348: 38 43
|
||||
ada5a6: 10 17 11 23 40 46
|
||||
10f574: 8 16 99.4 15 24 91.8 34 44 68.8
|
||||
b8ea4c: 8 16 96.0 15 23 92.4 34 44 68.8
|
||||
|
||||
Mode: Q65-60B
|
||||
Data: 60B_1296_Troposcatter (75 files)
|
||||
Message: "VK7MO VK7PD QE38"
|
||||
RxFreq: 1000/10
|
||||
|
||||
Commit No_AP MyCall BothCalls
|
||||
-----------------------------------
|
||||
ef4787: 1 2 11 23 64 67
|
||||
ada5a6: 1 5 14 28 64 67
|
||||
Commit No_AP MyCall BothCalls
|
||||
--------------------------------------------------
|
||||
ef4787: 1 2 11 23 64 67
|
||||
ada5a6: 1 5 14 28 64 67
|
||||
10f574: 1 5 142.7 11 27 129.8 65 67 36.8
|
||||
b8ea4c: 1 5 144.3 11 27 132.2 65 67 39.3
|
||||
|
||||
Mode: Q65-60D
|
||||
Data: MsgAvg (22 files, simulated fDop = 50 Hz)
|
||||
Message: "K1ABC W9XYZ EN37"
|
||||
RxFreq: 1000/10
|
||||
|
||||
Commit No_AP MyCall BothCalls
|
||||
-----------------------------------
|
||||
ef4787: 0 10 21 21 22 22
|
||||
ada5a6 0 11 21 21 22 22
|
||||
Commit No_AP MyCall BothCalls
|
||||
------------------------------------------------
|
||||
ef4787: 0 10 21 21 22 22
|
||||
ada5a6 0 11 21 21 22 22
|
||||
10f574: 0 11 47.7 21 21 33.9 22 22 11.6
|
||||
b8ea4c: 0 11 46.4 21 21 33.8 22 22 11.9
|
||||
|
||||
Mode: Q65-60D
|
||||
Data: Nil Average (40 files, simulated fDop = 0? Hz )
|
||||
Data: 60D_2 (21 files, 1296 troposcatter)
|
||||
Message: "VK7MO VK3WE QF32"
|
||||
RxFreq: 1200/20
|
||||
Requires nsmo=1 ###
|
||||
RxFreq: 1000/20
|
||||
|
||||
Commit No_AP MyCall BothCalls
|
||||
-----------------------------------
|
||||
ef4787: 1 16 24 28 39 39
|
||||
Commit No_AP MyCall BothCalls
|
||||
----------------------------------------------
|
||||
10f574: 5 5 33.6 7 8 31.8 12 14 25.1
|
||||
b8ea4v: 5 5 39.1 7 8 38.0 13 14 30.8
|
||||
|
||||
Mode: Q65-120D
|
||||
Data: 120D (14 files, 10 GHz troposcatter)
|
||||
Message: "VK7MO VK3WE QF32"
|
||||
RxFreq: 1000/20
|
||||
|
||||
Commit No_AP MyCall BothCalls
|
||||
----------------------------------------------
|
||||
10f574: 0 0 24.9 0 0 25.0 1 4 25.0
|
||||
b8ea4v: 0 0 39.1 0 0 25.4 1 5 40.1
|
||||
|
||||
Mode: Q65-60D
|
||||
Data: 60D_10_GHz_EME (14 files)
|
||||
Message: "VK7MO K6QPV DM12", "VK7MO K6QPV -15"
|
||||
RxFreq: 1000/50
|
||||
|
||||
Commit No_AP MyCall BothCalls
|
||||
----------------------------------------------
|
||||
10f574: 9 10 13.6 10 11 12.7 14 14 7.1
|
||||
b8ea4v: 9 10 13.7 10 11 12.6 14 14 7.5
|
||||
|
@ -1,16 +1,16 @@
|
||||
subroutine ana64(dd,npts,c0)
|
||||
subroutine ana64(iwave,npts,c0)
|
||||
|
||||
use timer_module, only: timer
|
||||
|
||||
real dd(npts) !Raw data at 12000 Hz
|
||||
integer*2 iwave(npts) !Raw data at 12000 Hz
|
||||
complex c0(0:npts-1) !Complex data at 6000 Hz
|
||||
save
|
||||
|
||||
nfft1=npts
|
||||
nfft2=nfft1/2
|
||||
df1=12000.0/nfft1
|
||||
fac=2.0/nfft1
|
||||
c0(0:npts-1)=fac*dd(1:npts)
|
||||
fac=2.0/(32767.0*nfft1)
|
||||
c0(0:npts-1)=fac*iwave(1:npts)
|
||||
call four2a(c0,nfft1,1,-1,1) !Forward c2c FFT
|
||||
c0(nfft2/2+1:nfft2-1)=0.
|
||||
c0(0)=0.5*c0(0)
|
||||
|
@ -205,11 +205,12 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
|
||||
open(17,file=trim(temp_dir)//'/red.dat',status='unknown')
|
||||
open(14,file=trim(temp_dir)//'/avemsg.txt',status='unknown')
|
||||
call timer('dec_q65 ',0)
|
||||
call my_q65%decode(q65_decoded,id2,params%nutc,params%ntr, &
|
||||
params%nsubmode,params%nfqso,params%ntol,params%ndepth, &
|
||||
params%nfa,params%nfb,logical(params%nclearave), &
|
||||
params%emedelay,mycall,hiscall,hisgrid,params%nQSOProgress, &
|
||||
ncontest,logical(params%lapcqonly),navg0)
|
||||
call my_q65%decode(q65_decoded,id2,params%nutc,params%ntr, &
|
||||
params%nsubmode,params%nfqso,params%ntol,params%ndepth, &
|
||||
params%nfa,params%nfb,logical(params%nclearave), &
|
||||
single_decode,logical(params%nagain), &
|
||||
logical(params%newdat),params%emedelay,mycall,hiscall,hisgrid, &
|
||||
params%nQSOProgress,ncontest,logical(params%lapcqonly),navg0)
|
||||
call timer('dec_q65 ',1)
|
||||
close(17)
|
||||
go to 800
|
||||
|
@ -26,9 +26,9 @@ module q65_decode
|
||||
|
||||
contains
|
||||
|
||||
subroutine decode(this,callback,iwave,nutc,ntrperiod,nsubmode,nfqso, &
|
||||
ntol,ndepth,nfa0,nfb0,lclearave,emedelay,mycall,hiscall,hisgrid, &
|
||||
nQSOprogress,ncontest,lapcqonly,navg0)
|
||||
subroutine decode(this,callback,iwave,nutc,ntrperiod,nsubmode,nfqso, &
|
||||
ntol,ndepth,nfa0,nfb0,lclearave,single_decode,lagain,lnewdat0, &
|
||||
emedelay,mycall,hiscall,hisgrid,nQSOprogress,ncontest,lapcqonly,navg0)
|
||||
|
||||
! Top-level routine that organizes the decoding of Q65 signals
|
||||
! Input: iwave Raw data, i*2
|
||||
@ -49,6 +49,7 @@ contains
|
||||
use packjt77
|
||||
use, intrinsic :: iso_c_binding
|
||||
use q65 !Shared variables
|
||||
use prog_args
|
||||
|
||||
parameter (NMAX=300*12000) !Max TRperiod is 300 s
|
||||
class(q65_decoder), intent(inout) :: this
|
||||
@ -59,18 +60,26 @@ contains
|
||||
character*77 c77
|
||||
character*78 c78
|
||||
character*6 cutc
|
||||
character c6*6,c4*4,cmode*4
|
||||
character*80 fmt
|
||||
integer*2 iwave(NMAX) !Raw data
|
||||
real, allocatable :: dd(:) !Raw data
|
||||
integer dat4(13) !Decoded message as 12 6-bit integers
|
||||
integer dgen(13)
|
||||
logical lclearave,lapcqonly,unpk77_success
|
||||
logical lclearave,lnewdat0,lapcqonly,unpk77_success
|
||||
logical single_decode,lagain
|
||||
complex, allocatable :: c00(:) !Analytic signal, 6000 Sa/s
|
||||
complex, allocatable :: c0(:) !Analytic signal, 6000 Sa/s
|
||||
|
||||
! Start by setting some parameters and allocating storage for large arrays
|
||||
call sec0(0,tdecode)
|
||||
nfa=nfa0
|
||||
nfb=nfb0
|
||||
lnewdat=lnewdat0
|
||||
idec=-1
|
||||
idf=0
|
||||
idt=0
|
||||
irc=0
|
||||
mode_q65=2**nsubmode
|
||||
npts=ntrperiod*12000
|
||||
nfft1=ntrperiod*12000
|
||||
@ -106,9 +115,12 @@ contains
|
||||
baud=12000.0/nsps
|
||||
this%callback => callback
|
||||
nFadingModel=1
|
||||
ibwa=max(1,int(1.8*log(baud*mode_q65)) + 2)
|
||||
ibwb=min(10,ibwa+4)
|
||||
if(iand(ndepth,3).eq.3) then
|
||||
ibwa=max(1,int(1.8*log(baud*mode_q65)) + 1)
|
||||
ibwb=min(10,ibwa+3)
|
||||
if(iand(ndepth,3).ge.2) then
|
||||
ibwa=max(1,int(1.8*log(baud*mode_q65)) + 2)
|
||||
ibwb=min(10,ibwa+5)
|
||||
else if(iand(ndepth,3).eq.3) then
|
||||
ibwa=max(1,ibwa-1)
|
||||
ibwb=min(10,ibwb+1)
|
||||
endif
|
||||
@ -128,24 +140,16 @@ contains
|
||||
call timer('q65_dec0',1)
|
||||
|
||||
if(idec.ge.0) then
|
||||
dtdec=xdt !We have a list-decode result
|
||||
dtdec=xdt !We have a list-decode result at nfqso
|
||||
f0dec=f0
|
||||
go to 100
|
||||
endif
|
||||
|
||||
if(snr1.lt.2.8) then
|
||||
dtdec=0. !No reliable sync, abandon decoding attempt
|
||||
f0dec=0.
|
||||
go to 100
|
||||
endif
|
||||
|
||||
! Prepare for a single-period decode woth iaptype = 0, 1, or 2 (also 4?)
|
||||
! Prepare for a single-period decode with iaptype = 0, 1, 2, or 4
|
||||
jpk0=(xdt+1.0)*6000 !Index of nominal start of signal
|
||||
if(ntrperiod.le.30) jpk0=(xdt+0.5)*6000 !For shortest sequences
|
||||
if(jpk0.lt.0) jpk0=0
|
||||
fac=1.0/32767.0
|
||||
dd=fac*iwave(1:npts)
|
||||
call ana64(dd,npts,c00) !Convert to complex c00() at 6000 Sa/s
|
||||
call ana64(iwave,npts,c00) !Convert to complex c00() at 6000 Sa/s
|
||||
call ft8apset(mycall,hiscall,ncontest,apsym0,aph10) ! Generate ap symbols
|
||||
where(apsym0.eq.-1) apsym0=0
|
||||
|
||||
@ -196,7 +200,7 @@ contains
|
||||
go to 100
|
||||
endif
|
||||
|
||||
! There was no 'q3n' decode. Try for a 'q[012]n' decode.
|
||||
! There was no 'q3n' decode. Try for a 'q[0124]n' decode.
|
||||
! Call top-level routine in q65 module: establish sync and try for a q[012]n
|
||||
! decode, this time using the cumulative 's1a' symbol spectra.
|
||||
|
||||
@ -229,17 +233,109 @@ contains
|
||||
call this%callback(nutc,snr1,nsnr,dtdec,f0dec,decoded, &
|
||||
idec,nused,ntrperiod)
|
||||
if(iand(ndepth,128).ne.0) call q65_clravg !AutoClrAvg after decode
|
||||
call sec0(1,tdecode)
|
||||
open(22,file=trim(data_dir)//'/q65_decodes.dat',status='unknown', &
|
||||
position='append',iostat=ios)
|
||||
if(ios.eq.0) then
|
||||
! Save decoding parameters to q65_decoded.dat, for later analysis.
|
||||
write(cmode,'(i3)') ntrperiod
|
||||
cmode(4:4)=char(ichar('A')+nsubmode)
|
||||
c6=hiscall(1:6)
|
||||
if(c6.eq.' ') c6='<b> '
|
||||
c4=hisgrid(1:4)
|
||||
if(c4.eq.' ') c4='<b> '
|
||||
fmt='(i6.4,1x,a4,5i2,3i3,f6.2,f7.1,f7.2,f6.1,f6.2,'// &
|
||||
'1x,a6,1x,a6,1x,a4,1x,a)'
|
||||
if(ntrperiod.le.30) fmt(5:5)='6'
|
||||
write(22,fmt) nutc,cmode,nQSOprogress,idec,idf,idt,ibw,nused, &
|
||||
icand,ncand,xdt,f0,snr1,snr2,tdecode,mycall(1:6),c6,c4, &
|
||||
trim(decoded)
|
||||
close(22)
|
||||
endif
|
||||
else
|
||||
! Report snr1, even if no decode.
|
||||
nsnr=db(snr1) - 35.0
|
||||
if(nsnr.lt.-35) nsnr=-35
|
||||
idec=-1
|
||||
call this%callback(nutc,snr1,nsnr,xdt,f0,decoded, &
|
||||
call this%callback(nutc,snr1,nsnr,xdt,f0,decoded, &
|
||||
idec,0,ntrperiod)
|
||||
endif
|
||||
navg0=1000*navg(0) + navg(1)
|
||||
if(single_decode .or. lagain) go to 900
|
||||
|
||||
return
|
||||
do icand=1,ncand
|
||||
! Prepare for single-period candidate decodes with iaptype = 0, 1, 2, or 4
|
||||
snr1=candidates(icand,1)
|
||||
xdt= candidates(icand,2)
|
||||
f0 = candidates(icand,3)
|
||||
jpk0=(xdt+1.0)*6000 !Index of nominal start of signal
|
||||
if(ntrperiod.le.30) jpk0=(xdt+0.5)*6000 !For shortest sequences
|
||||
if(jpk0.lt.0) jpk0=0
|
||||
call ana64(iwave,npts,c00) !Convert to complex c00() at 6000 Sa/s
|
||||
call ft8apset(mycall,hiscall,ncontest,apsym0,aph10) ! Generate ap symbols
|
||||
where(apsym0.eq.-1) apsym0=0
|
||||
|
||||
npasses=2
|
||||
if(nQSOprogress.eq.5) npasses=3
|
||||
if(lapcqonly) npasses=1
|
||||
iaptype=0
|
||||
do ipass=0,npasses !Loop over AP passes
|
||||
apmask=0 !Try first with no AP information
|
||||
apsymbols=0
|
||||
if(ipass.ge.1) then
|
||||
! Subsequent passes use AP information appropiate for nQSOprogress
|
||||
call q65_ap(nQSOprogress,ipass,ncontest,lapcqonly,iaptype, &
|
||||
apsym0,apmask1,apsymbols1)
|
||||
write(c78,1050) apmask1
|
||||
read(c78,1060) apmask
|
||||
write(c78,1050) apsymbols1
|
||||
read(c78,1060) apsymbols
|
||||
endif
|
||||
|
||||
call timer('q65loops',0)
|
||||
call q65_loops(c00,npts/2,nsps/2,nsubmode,ndepth,jpk0, &
|
||||
xdt,f0,iaptype,xdt1,f1,snr2,dat4,idec)
|
||||
! idec=-1 !### TEMPORARY ###
|
||||
call timer('q65loops',1)
|
||||
if(idec.ge.0) then
|
||||
dtdec=xdt1
|
||||
f0dec=f1
|
||||
go to 200 !Successful decode, we're done
|
||||
endif
|
||||
enddo ! ipass
|
||||
|
||||
200 decoded=' '
|
||||
if(idec.ge.0) then
|
||||
! Unpack decoded message for display to user
|
||||
write(c77,1000) dat4(1:12),dat4(13)/2
|
||||
call unpack77(c77,0,decoded,unpk77_success) !Unpack to get msgsent
|
||||
nsnr=nint(snr2)
|
||||
call this%callback(nutc,snr1,nsnr,dtdec,f0dec,decoded, &
|
||||
idec,nused,ntrperiod)
|
||||
if(iand(ndepth,128).ne.0) call q65_clravg !AutoClrAvg after decode
|
||||
call sec0(1,tdecode)
|
||||
open(22,file=trim(data_dir)//'/q65_decodes.dat',status='unknown', &
|
||||
position='append',iostat=ios)
|
||||
if(ios.eq.0) then
|
||||
! Save decoding parameters to q65_decoded.dat, for later analysis.
|
||||
write(cmode,'(i3)') ntrperiod
|
||||
cmode(4:4)=char(ichar('A')+nsubmode)
|
||||
c6=hiscall(1:6)
|
||||
if(c6.eq.' ') c6='<b> '
|
||||
c4=hisgrid(1:4)
|
||||
if(c4.eq.' ') c4='<b> '
|
||||
fmt='(i6.4,1x,a4,5i2,3i3,f6.2,f7.1,f7.2,f6.1,f6.2,'// &
|
||||
'1x,a6,1x,a6,1x,a4,1x,a)'
|
||||
if(ntrperiod.le.30) fmt(5:5)='6'
|
||||
write(22,fmt) nutc,cmode,nQSOprogress,idec,idf,idt,ibw,nused, &
|
||||
icand,ncand,xdt,f0,snr1,snr2,tdecode,mycall(1:6),c6,c4, &
|
||||
trim(decoded)
|
||||
close(22)
|
||||
endif
|
||||
endif
|
||||
enddo
|
||||
|
||||
900 return
|
||||
end subroutine decode
|
||||
|
||||
end module q65_decode
|
||||
|
@ -11,12 +11,15 @@ module q65
|
||||
38,46,50,55,60,62,66,69,74,76,85/)
|
||||
integer codewords(63,206)
|
||||
integer ibwa,ibwb,ncw,nsps,mode_q65,nfa,nfb
|
||||
integer istep,nsmo,lag1,lag2,npasses,nused,iseq
|
||||
integer idf,idt,ibw
|
||||
integer istep,nsmo,lag1,lag2,npasses,nused,iseq,ncand
|
||||
integer i0,j0
|
||||
integer navg(0:1)
|
||||
logical lnewdat
|
||||
real candidates(20,3) !snr, xdt, and f0 of top candidates
|
||||
real,allocatable,save :: s1a(:,:,:) !Cumulative symbol spectra
|
||||
real sync(85) !sync vector
|
||||
real df,dtstep,dtdec,f0dec
|
||||
real df,dtstep,dtdec,f0dec,ftol
|
||||
|
||||
contains
|
||||
|
||||
@ -59,9 +62,8 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
logical first,lclearave
|
||||
real, allocatable :: s1(:,:) !Symbol spectra, 1/8-symbol steps
|
||||
real, allocatable :: s3(:,:) !Data-symbol energies s3(LL,63)
|
||||
real, allocatable :: ccf(:,:) !CCF(freq,lag)
|
||||
real, allocatable :: ccf1(:) !CCF(freq) at best lag
|
||||
real, allocatable :: ccf2(:) !CCF(freq) at any lag
|
||||
real, allocatable :: ccf1(:) !CCF(freq) at fixed lag (red)
|
||||
real, allocatable :: ccf2(:) !Max CCF(freq) at any lag (orange)
|
||||
data first/.true./
|
||||
save first
|
||||
|
||||
@ -80,6 +82,7 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
txt=85.0*nsps/12000.0
|
||||
jz=(txt+1.0)*12000.0/istep !Number of symbol/NSTEP bins
|
||||
if(nsps.ge.6912) jz=(txt+2.0)*12000.0/istep !For TR 60 s and higher
|
||||
ftol=ntol
|
||||
ia=ntol/df
|
||||
ia2=max(ia,10*mode_q65,nint(100.0/df))
|
||||
nsmo=int(0.7*mode_q65*mode_q65)
|
||||
@ -93,9 +96,8 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
|
||||
allocate(s1(iz,jz))
|
||||
allocate(s3(-64:LL-65,63))
|
||||
allocate(ccf(-ia2:ia2,-53:214))
|
||||
allocate(ccf1(-ia2:ia2))
|
||||
allocate(ccf2(-ia2:ia2))
|
||||
allocate(ccf2(iz))
|
||||
if(LL.ne.LL0 .or. iz.ne.iz0 .or. jz.ne.jz0 .or. lclearave) then
|
||||
if(allocated(s1a)) deallocate(s1a)
|
||||
allocate(s1a(iz,jz,0:1))
|
||||
@ -140,59 +142,36 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
! Try list decoding via "Deep Likelihood".
|
||||
call timer('ccf_85 ',0)
|
||||
! Try to synchronize using all 85 symbols
|
||||
call q65_ccf_85(s1,iz,jz,nfqso,ia,ia2,ipk,jpk,f0,xdt,imsg_best,ccf,ccf1)
|
||||
call q65_ccf_85(s1,iz,jz,nfqso,ia,ia2,ipk,jpk,f0,xdt,imsg_best,ccf1)
|
||||
call timer('ccf_85 ',1)
|
||||
|
||||
call timer('list_dec',0)
|
||||
call q65_dec_q3(s1,iz,jz,s3,LL,ipk,jpk,snr2,dat4,idec,decoded)
|
||||
call timer('list_dec',1)
|
||||
if(idec.ne.0) then
|
||||
ic=ia2/4;
|
||||
base=(sum(ccf1(-ia2:-ia2+ic)) + sum(ccf1(ia2-ic:ia2)))/(2.0+2.0*ic);
|
||||
ccf1=ccf1-base
|
||||
smax=maxval(ccf1)
|
||||
if(smax.gt.10.0) ccf1=10.0*ccf1/smax
|
||||
base=(sum(ccf2(-ia2:-ia2+ic)) + sum(ccf2(ia2-ic:ia2)))/(2.0+2.0*ic);
|
||||
ccf2=ccf2-base
|
||||
smax=maxval(ccf2)
|
||||
if(smax.gt.10.0) ccf2=10.0*ccf2/smax
|
||||
endif
|
||||
endif
|
||||
|
||||
! Get 2d CCF and ccf2 using sync symbols only
|
||||
call q65_ccf_22(s1,iz,jz,nfqso,ia,ia2,ipk,jpk,f0a,xdta,ccf,ccf2)
|
||||
call q65_ccf_22(s1,iz,jz,nfqso,ipk,jpk,f0a,xdta,ccf2)
|
||||
if(idec.lt.0) then
|
||||
f0=f0a
|
||||
xdt=xdta
|
||||
endif
|
||||
|
||||
! Estimate rms on ccf baseline
|
||||
sq=0.
|
||||
nsq=0
|
||||
jd=(lag2-lag1)/4
|
||||
do i=-ia2,ia2
|
||||
do j=lag1,lag2
|
||||
if(abs(j-jpk).gt.jd .and. abs(i-ipk).gt.ia/2) then
|
||||
sq=sq + ccf(i,j)**2
|
||||
nsq=nsq+1
|
||||
endif
|
||||
enddo
|
||||
enddo
|
||||
rms=sqrt(sq/nsq)
|
||||
smax=ccf(ipk,jpk)
|
||||
snr1=smax/rms
|
||||
ccf2=ccf2/rms
|
||||
if(snr1.gt.10.0) ccf2=(10.0/snr1)*ccf2
|
||||
! Estimate rms on ccf2 baseline
|
||||
call q65_sync_curve(ccf2,1,iz,rms2)
|
||||
smax=maxval(ccf2)
|
||||
snr1=0.
|
||||
if(rms2.gt.0) snr1=smax/rms2
|
||||
|
||||
if(idec.le.0) then
|
||||
! The q3 decode attempt failed. Copy synchronied symbol spectra from s1
|
||||
! The q3 decode attempt failed. Copy synchronized symbol energies from s1
|
||||
! into s3 and prepare to try a more general decode.
|
||||
ccf1=ccf(:,jpk)/rms
|
||||
if(snr1.gt.10.0) ccf1=(10.0/snr1)*ccf1
|
||||
call q65_s1_to_s3(s1,iz,jz,ipk,jpk,LL,mode_q65,sync,s3)
|
||||
endif
|
||||
|
||||
smax=maxval(ccf1)
|
||||
|
||||
! Estimate frequenct spread
|
||||
i1=-9999
|
||||
i2=-9999
|
||||
do i=-ia,ia
|
||||
@ -201,16 +180,8 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
enddo
|
||||
width=df*(i2-i1)
|
||||
|
||||
! Write data for the red and orange sync curves.
|
||||
do i=-ia2,ia2
|
||||
freq=nfqso + i*df
|
||||
if(freq.ge.float(nfa) .and. freq.le.float(nfb)) then
|
||||
write(17,1100) freq,ccf1(i),xdt,ccf2(i)
|
||||
1100 format(4f10.3)
|
||||
endif
|
||||
enddo
|
||||
rewind 17
|
||||
|
||||
if(ncw.eq.0) ccf1=0.
|
||||
call q65_write_red(iz,ia2,xdt,ccf1,ccf2)
|
||||
|
||||
if(iavg.eq.2) then
|
||||
call q65_dec_q012(s3,LL,snr2,dat4,idec,decoded)
|
||||
@ -261,43 +232,31 @@ subroutine q65_symspec(iwave,nmax,iz,jz,s1)
|
||||
call smo121(s1(1:iz,j),iz)
|
||||
enddo
|
||||
enddo
|
||||
s1a(:,:,iseq)=s1a(:,:,iseq) + s1
|
||||
navg(iseq)=navg(iseq) + 1
|
||||
if(lnewdat) then
|
||||
s1a(:,:,iseq)=s1a(:,:,iseq) + s1
|
||||
navg(iseq)=navg(iseq) + 1
|
||||
endif
|
||||
|
||||
return
|
||||
end subroutine q65_symspec
|
||||
|
||||
subroutine q65_dec_q3(s1,iz,jz,s3,LL,ipk,jpk,snr2,dat4,idec,decoded)
|
||||
|
||||
! Copy synchronized symbol spectra from s1 into s3, then attempt a q3 decode.
|
||||
! Copy synchronized symbol energies from s1 into s3, then attempt a q3 decode.
|
||||
|
||||
character*37 decoded
|
||||
integer dat4(13)
|
||||
real s1(iz,jz)
|
||||
real s3(-64:LL-65,63)
|
||||
|
||||
i1=i0+ipk-64
|
||||
i2=i1+LL-1
|
||||
j=j0+jpk-7
|
||||
n=0
|
||||
do k=1,85
|
||||
j=j+8
|
||||
if(sync(k).gt.0.0) then
|
||||
cycle
|
||||
endif
|
||||
n=n+1
|
||||
if(j.ge.1 .and. j.le.jz) then
|
||||
do i=0,LL-1
|
||||
s3(i-64,n)=s1(i+i1,j) !Copy from s1 into s3
|
||||
enddo
|
||||
endif
|
||||
enddo
|
||||
call q65_s1_to_s3(s1,iz,jz,ipk,jpk,LL,mode_q65,sync,s3)
|
||||
|
||||
nsubmode=0
|
||||
if(mode_q65.eq.2) nsubmode=1
|
||||
if(mode_q65.eq.4) nsubmode=2
|
||||
if(mode_q65.eq.8) nsubmode=3
|
||||
if(mode_q65.eq.16) nsubmode=4
|
||||
if(mode_q65.eq.32) nsubmode=5
|
||||
baud=12000.0/nsps
|
||||
|
||||
do ibw=ibwa,ibwb
|
||||
@ -366,17 +325,18 @@ subroutine q65_dec_q012(s3,LL,snr2,dat4,idec,decoded)
|
||||
100 return
|
||||
end subroutine q65_dec_q012
|
||||
|
||||
subroutine q65_ccf_85(s1,iz,jz,nfqso,ia,ia2,ipk,jpk,f0,xdt,imsg_best,ccf,ccf1)
|
||||
subroutine q65_ccf_85(s1,iz,jz,nfqso,ia,ia2,ipk,jpk,f0,xdt,imsg_best,ccf1)
|
||||
|
||||
! Attempt synchronization using all 85 symbols, in advance of an
|
||||
! attempt at q3 decoding. Return ccf1 for the "red sync curve".
|
||||
|
||||
real s1(iz,jz)
|
||||
real ccf(-ia2:ia2,-53:214)
|
||||
real, allocatable :: ccf(:,:) !CCF(freq,lag)
|
||||
real ccf1(-ia2:ia2)
|
||||
integer ijpk(2)
|
||||
integer itone(85)
|
||||
|
||||
|
||||
allocate(ccf(-ia2:ia2,-53:214))
|
||||
ipk=0
|
||||
jpk=0
|
||||
ccf_best=0.
|
||||
@ -387,10 +347,10 @@ subroutine q65_ccf_85(s1,iz,jz,nfqso,ia,ia2,ipk,jpk,f0,xdt,imsg_best,ccf,ccf1)
|
||||
do j=1,85
|
||||
if(j.eq.isync(i)) then
|
||||
i=i+1
|
||||
itone(j)=-1
|
||||
itone(j)=0
|
||||
else
|
||||
k=k+1
|
||||
itone(j)=codewords(k,imsg)
|
||||
itone(j)=codewords(k,imsg) + 1
|
||||
endif
|
||||
enddo
|
||||
|
||||
@ -416,48 +376,90 @@ subroutine q65_ccf_85(s1,iz,jz,nfqso,ia,ia2,ipk,jpk,f0,xdt,imsg_best,ccf,ccf1)
|
||||
ijpk=maxloc(ccf(-ia:ia,:))
|
||||
ipk=ijpk(1)-ia-1
|
||||
jpk=ijpk(2)-53-1
|
||||
f0=nfqso + (ipk-mode_q65)*df
|
||||
f0=nfqso + ipk*df
|
||||
xdt=jpk*dtstep
|
||||
imsg_best=imsg
|
||||
ccf1=ccf(:,jpk)
|
||||
endif
|
||||
enddo ! imsg
|
||||
deallocate(ccf)
|
||||
|
||||
return
|
||||
end subroutine q65_ccf_85
|
||||
|
||||
subroutine q65_ccf_22(s1,iz,jz,nfqso,ia,ia2,ipk,jpk,f0,xdt,ccf,ccf2)
|
||||
subroutine q65_ccf_22(s1,iz,jz,nfqso,ipk,jpk,f0,xdt,ccf2)
|
||||
|
||||
! Attempt synchronization using only the 22 sync symbols. Return ccf2
|
||||
! for the "orange sync curve".
|
||||
|
||||
real s1(iz,jz)
|
||||
real ccf(-ia2:ia2,-53:214)
|
||||
real ccf2(-ia2:ia2)
|
||||
integer ijpk(2)
|
||||
|
||||
ccf=0.
|
||||
do lag=lag1,lag2
|
||||
do k=1,85
|
||||
n=NSTEP*(k-1) + 1
|
||||
j=n+lag+j0
|
||||
if(j.ge.1 .and. j.le.jz) then
|
||||
do i=-ia2,ia2
|
||||
if(i0+i.lt.1 .or. i0+i.gt.iz) cycle
|
||||
ccf(i,lag)=ccf(i,lag) + sync(k)*s1(i0+i,j)
|
||||
enddo
|
||||
real s1(iz,jz)
|
||||
real ccf2(iz) !Orange sync curve
|
||||
real, allocatable :: xdt2(:)
|
||||
integer, allocatable :: indx(:)
|
||||
|
||||
allocate(xdt2(iz))
|
||||
allocate(indx(iz))
|
||||
|
||||
ccfbest=0.
|
||||
ibest=0
|
||||
lagpk=0
|
||||
lagbest=0
|
||||
do i=1,iz
|
||||
ccfmax=0.
|
||||
do lag=lag1,lag2
|
||||
ccft=0.
|
||||
do k=1,85
|
||||
n=NSTEP*(k-1) + 1
|
||||
j=n+lag+j0
|
||||
if(j.ge.1 .and. j.le.jz) then
|
||||
ccft=ccft + sync(k)*s1(i,j)
|
||||
endif
|
||||
enddo
|
||||
if(ccft.gt.ccfmax) then
|
||||
ccfmax=ccft
|
||||
lagpk=lag
|
||||
endif
|
||||
enddo
|
||||
ccf2(i)=ccfmax
|
||||
xdt2(i)=lagpk*dtstep
|
||||
if(ccfmax.gt.ccfbest .and. abs(i*df-nfqso).le.ftol) then
|
||||
ccfbest=ccfmax
|
||||
ibest=i
|
||||
lagbest=lagpk
|
||||
endif
|
||||
enddo
|
||||
do i=-ia2,ia2
|
||||
ccf2(i)=maxval(ccf(i,:))
|
||||
enddo
|
||||
ijpk=maxloc(ccf(-ia:ia,:))
|
||||
ipk=ijpk(1)-ia-1
|
||||
jpk=ijpk(2)-53-1
|
||||
|
||||
! Parameters for the top candidate:
|
||||
ipk=ibest - i0
|
||||
jpk=lagbest
|
||||
f0=nfqso + ipk*df
|
||||
xdt=jpk*dtstep
|
||||
|
||||
! Save parameters for best candidates
|
||||
i1=max(nfa,100)/df
|
||||
i2=min(nfb,4900)/df
|
||||
jzz=i2-i1+1
|
||||
call pctile(ccf2(i1:i2),jzz,40,base)
|
||||
ccf2=ccf2/base
|
||||
call indexx(ccf2(i1:i2),jzz,indx)
|
||||
ncand=0
|
||||
maxcand=20
|
||||
do j=1,20
|
||||
i=indx(jzz-j+1)+i1-1
|
||||
if(ccf2(i).lt.3.4) exit !Candidate limit
|
||||
f=i*df
|
||||
if(f.ge.(nfqso-ftol) .and. f.le.(nfqso+ftol)) cycle
|
||||
i3=max(1,i-67*mode_q65)
|
||||
i4=min(iz,i+3*mode_q65)
|
||||
biggest=maxval(ccf2(i3:i4))
|
||||
if(ccf2(i).ne.biggest) cycle
|
||||
ncand=ncand+1
|
||||
candidates(ncand,1)=ccf2(i)
|
||||
candidates(ncand,2)=xdt2(i)
|
||||
candidates(ncand,3)=f
|
||||
if(ncand.ge.maxcand) exit
|
||||
enddo
|
||||
|
||||
return
|
||||
end subroutine q65_ccf_22
|
||||
|
||||
@ -539,4 +541,52 @@ subroutine q65_s1_to_s3(s1,iz,jz,ipk,jpk,LL,mode_q65,sync,s3)
|
||||
return
|
||||
end subroutine q65_s1_to_s3
|
||||
|
||||
subroutine q65_write_red(iz,ia2,xdt,ccf1,ccf2)
|
||||
|
||||
! Write data for the red and orange sync curves to LU 17.
|
||||
|
||||
real ccf1(-ia2:ia2)
|
||||
real ccf2(iz)
|
||||
|
||||
call q65_sync_curve(ccf1,-ia2,ia2,rms1)
|
||||
call q65_sync_curve(ccf2,1,iz,rms2)
|
||||
|
||||
rewind 17
|
||||
write(17,1000) xdt
|
||||
do i=1,iz
|
||||
freq=i*df
|
||||
ii=i-i0
|
||||
if(freq.ge.float(nfa) .and. freq.le.float(nfb)) then
|
||||
ccf1a=-99.0
|
||||
if(ii.ge.-ia2 .and. ii.le.ia2) ccf1a=ccf1(ii)
|
||||
write(17,1000) freq,ccf1a,ccf2(i)
|
||||
1000 format(3f10.3)
|
||||
endif
|
||||
enddo
|
||||
|
||||
return
|
||||
end subroutine q65_write_red
|
||||
|
||||
subroutine q65_sync_curve(ccf1,ia,ib,rms1)
|
||||
|
||||
! Condition the red or orange sync curve for plotting.
|
||||
|
||||
real ccf1(ia:ib)
|
||||
|
||||
ic=(ib-ia)/8;
|
||||
nsum=2*(ic+1)
|
||||
|
||||
base1=(sum(ccf1(ia:ia+ic)) + sum(ccf1(ib-ic:ib)))/nsum
|
||||
ccf1=ccf1-base1
|
||||
sq=dot_product(ccf1(ia:ia+ic),ccf1(ia:ia+ic)) + &
|
||||
dot_product(ccf1(ib-ic:ib),ccf1(ib-ic:ib))
|
||||
rms1=0.
|
||||
if(nsum.gt.0) rms1=sqrt(sq/nsum)
|
||||
if(rms1.gt.0.0) ccf1=2.0*ccf1/rms1
|
||||
smax1=maxval(ccf1)
|
||||
if(smax1.gt.10.0) ccf1=10.0*ccf1/smax1
|
||||
|
||||
return
|
||||
end subroutine q65_sync_curve
|
||||
|
||||
end module q65
|
||||
|
@ -6,7 +6,7 @@ subroutine q65_loops(c00,npts2,nsps2,nsubmode,ndepth,jpk0, &
|
||||
use q65
|
||||
|
||||
parameter (NN=63)
|
||||
parameter (LN=1152*63) !LN=LL*NN; LL=64*(mode_q65+2), NN=63
|
||||
parameter (LN=2176*63) !LN=LL*NN; LL=64*(mode_q65+2), NN=63
|
||||
complex c00(0:npts2-1) !Analytic representation of dd(), 6000 Hz
|
||||
complex ,allocatable :: c0(:) !Ditto, with freq shift
|
||||
character decoded*37
|
||||
@ -51,7 +51,7 @@ subroutine q65_loops(c00,npts2,nsps2,nsubmode,ndepth,jpk0, &
|
||||
jpk=jpk0 + nsps2*ndt/16 !tsym/16
|
||||
if(jpk.lt.0) jpk=0
|
||||
call timer('spec64 ',0)
|
||||
call spec64(c0,nsps2,65,mode_q65,jpk,s3,LL,NN)
|
||||
call spec64(c0,nsps2,mode_q65,jpk,s3,LL,NN)
|
||||
call timer('spec64 ',1)
|
||||
call pctile(s3,LL*NN,40,base)
|
||||
s3=s3/base
|
||||
@ -75,9 +75,6 @@ subroutine q65_loops(c00,npts2,nsps2,nsubmode,ndepth,jpk0, &
|
||||
enddo ! idf (f0 loop)
|
||||
|
||||
100 if(irc.ge.0) then
|
||||
! write(55,3055) ndepth,iaptype,idf,idt,ibw,ndist,irc,sum(s3(1:LL*NN)), &
|
||||
! trim(decoded)
|
||||
!3055 format(7i4,f10.1,1x,a)
|
||||
idec=iaptype
|
||||
snr2=esnodb - db(2500.0/baud)
|
||||
xdt1=xdt0 + nsps2*ndt/(16.0*6000.0)
|
||||
|
128
lib/qra64a.f90
128
lib/qra64a.f90
@ -1,128 +0,0 @@
|
||||
subroutine qra64a(dd,npts,nf1,nf2,nfqso,ntol,mode64,minsync,ndepth, &
|
||||
emedelay,mycall_12,hiscall_12,hisgrid_6,sync,nsnr,dtx,nfreq,decoded,nft)
|
||||
|
||||
use packjt
|
||||
use timer_module, only: timer
|
||||
|
||||
parameter (NMAX=60*12000,LN=1152*63)
|
||||
character decoded*22
|
||||
character*12 mycall_12,hiscall_12
|
||||
character*6 mycall,hiscall,hisgrid_6
|
||||
character*4 hisgrid
|
||||
logical ltext
|
||||
complex c00(0:720000) !Analytic signal for dd()
|
||||
real dd(NMAX) !Raw data sampled at 12000 Hz
|
||||
integer dat4(12) !Decoded message (as 12 integers)
|
||||
data nc1z/-1/,nc2z/-1/,ng2z/-1/,maxaptypez/-1/
|
||||
save
|
||||
|
||||
call timer('qra64a ',0)
|
||||
irc=-1
|
||||
decoded=' '
|
||||
nft=99
|
||||
if(nfqso.lt.nf1 .or. nfqso.gt.nf2) go to 900
|
||||
|
||||
mycall=mycall_12(1:6) !### May need fixing? ###
|
||||
hiscall=hiscall_12(1:6)
|
||||
hisgrid=hisgrid_6(1:4)
|
||||
call packcall(mycall,nc1,ltext)
|
||||
call packcall(hiscall,nc2,ltext)
|
||||
call packgrid(hisgrid,ng2,ltext)
|
||||
nSubmode=0
|
||||
if(mode64.eq.2) nSubmode=1
|
||||
if(mode64.eq.4) nSubmode=2
|
||||
if(mode64.eq.8) nSubmode=3
|
||||
if(mode64.eq.16) nSubmode=4
|
||||
b90=1.0
|
||||
nFadingModel=1
|
||||
maxaptype=4
|
||||
if(iand(ndepth,64).ne.0) maxaptype=5
|
||||
call qra_params(ndepth,maxaptype,idfmax,idtmax,ibwmin,ibwmax,maxdist)
|
||||
if(nc1.ne.nc1z .or. nc2.ne.nc2z .or. ng2.ne.ng2z .or. &
|
||||
maxaptype.ne.maxaptypez) then
|
||||
do naptype=0,maxaptype
|
||||
if(naptype.eq.2 .and. maxaptype.eq.4) cycle
|
||||
call qra64_dec(s3dummy,nc1,nc2,ng2,naptype,1,nSubmode,b90, &
|
||||
nFadingModel,dat4,snr2,irc)
|
||||
enddo
|
||||
nc1z=nc1
|
||||
nc2z=nc2
|
||||
ng2z=ng2
|
||||
maxaptypez=maxaptype
|
||||
endif
|
||||
naptype=maxaptype
|
||||
|
||||
call ana64(dd,npts,c00)
|
||||
|
||||
call timer('sync64 ',0)
|
||||
call sync64(c00,nf1,nf2,nfqso,ntol,minsync,mode64,emedelay,dtx,f0, &
|
||||
jpk0,sync,sync2,width)
|
||||
call timer('sync64 ',1)
|
||||
nfreq=nint(f0)
|
||||
if(mode64.eq.1 .and. minsync.ne.-1 .and. (sync-7.0).lt.minsync) go to 900
|
||||
|
||||
nsps=6912
|
||||
call timer('qraloops',0)
|
||||
call qra_loops(c00,npts/2,nsps,64,mode64,nsubmode,nFadingModel, &
|
||||
ndepth,nc1,nc2,ng2,naptype,jpk0,dtx,f0,width,snr2,irc,dat4)
|
||||
call timer('qraloops',1)
|
||||
|
||||
decoded=' '
|
||||
if(irc.ge.0) then
|
||||
call unpackmsg(dat4,decoded) !Unpack the user message
|
||||
call fmtmsg(decoded,iz)
|
||||
if(index(decoded,"000AAA ").ge.1) then
|
||||
! Suppress a certain type of garbage decode.
|
||||
decoded=' '
|
||||
irc=-1
|
||||
endif
|
||||
nft=100 + irc
|
||||
nsnr=nint(snr2)
|
||||
else
|
||||
snr2=0.
|
||||
endif
|
||||
nfreq=nint(f0)
|
||||
|
||||
900 if(irc.lt.0) then
|
||||
sy=max(1.0,sync)
|
||||
if(nSubmode.eq.0) nsnr=nint(10.0*log10(sy)-35.0) !A
|
||||
if(nSubmode.eq.1) nsnr=nint(10.0*log10(sy)-34.0) !B
|
||||
if(nSubmode.eq.2) nsnr=nint(10.0*log10(sy)-29.0) !C
|
||||
if(nSubmode.eq.3) nsnr=nint(10.0*log10(sy)-29.0) !D
|
||||
if(nSubmode.eq.4) nsnr=nint(10.0*log10(sy)-24.0) !E
|
||||
endif
|
||||
call timer('qra64a ',1)
|
||||
|
||||
return
|
||||
end subroutine qra64a
|
||||
|
||||
subroutine qra_params(ndepth,maxaptype,idf0max,idt0max,ibwmin,ibwmax,maxdist)
|
||||
|
||||
! If file qra_params is present in CWD, read decoding params from it.
|
||||
|
||||
integer iparam(7)
|
||||
logical first,ex
|
||||
! data iparam/3,5,11,11,0,11,60/ !Maximum effort
|
||||
data iparam/3,5,7,7,0,4,15/ !Default values
|
||||
data first/.true./
|
||||
save first,iparam
|
||||
|
||||
if(first) then
|
||||
inquire(file='qra_params',exist=ex)
|
||||
if(ex) then
|
||||
open(29,file='qra_params',status='old')
|
||||
read(29,*) iparam
|
||||
close(29)
|
||||
endif
|
||||
first=.false.
|
||||
endif
|
||||
ndepth=iparam(1)
|
||||
maxaptype=iparam(2)
|
||||
idf0max=iparam(3)
|
||||
idt0max=iparam(4)
|
||||
ibwmin=iparam(5)
|
||||
ibwmax=iparam(6)
|
||||
maxdist=iparam(7)
|
||||
|
||||
return
|
||||
end subroutine qra_params
|
@ -1,4 +1,4 @@
|
||||
subroutine spec64(c0,nsps,mode,mode64,jpk,s3,LL,NN)
|
||||
subroutine spec64(c0,nsps,mode_q65,jpk,s3,LL,NN)
|
||||
|
||||
parameter (MAXFFT=20736)
|
||||
!### Fix this:
|
||||
@ -11,41 +11,24 @@ subroutine spec64(c0,nsps,mode,mode64,jpk,s3,LL,NN)
|
||||
data isync/1,9,12,13,15,22,23,26,27,33,35,38,46,50,55,60,62,66,69,74,76,85/
|
||||
|
||||
nfft=nsps
|
||||
|
||||
if(mode.eq.64) then
|
||||
do j=1,NN
|
||||
jj=j+7 !Skip first Costas array
|
||||
if(j.ge.33) jj=j+14 !Skip middle Costas array
|
||||
ja=jpk + (jj-1)*nfft
|
||||
jb=ja+nfft-1
|
||||
cs(0:nfft-1)=c0(ja:jb)
|
||||
call four2a(cs,nfft,1,-1,1)
|
||||
do ii=1,LL
|
||||
i=ii-65
|
||||
if(i.lt.0) i=i+nfft
|
||||
s3(ii,j)=real(cs(i))**2 + aimag(cs(i))**2
|
||||
enddo
|
||||
j=0
|
||||
n=1
|
||||
do k=1,84
|
||||
if(k.eq.isync(n)) then
|
||||
n=n+1
|
||||
cycle
|
||||
endif
|
||||
j=j+1
|
||||
ja=(k-1)*nsps + jpk
|
||||
jb=ja+nsps-1
|
||||
cs(0:nfft-1)=c0(ja:jb)
|
||||
call four2a(cs,nsps,1,-1,1) !c2c FFT to frequency
|
||||
do ii=1,LL
|
||||
i=ii-65+mode_q65 !mode_q65 = 1 2 4 8 16 for Q65 A B C D E
|
||||
if(i.lt.0) i=i+nsps
|
||||
s3(ii,j)=real(cs(i))**2 + aimag(cs(i))**2
|
||||
enddo
|
||||
else
|
||||
j=0
|
||||
n=1
|
||||
do k=1,84
|
||||
if(k.eq.isync(n)) then
|
||||
n=n+1
|
||||
cycle
|
||||
endif
|
||||
j=j+1
|
||||
ja=(k-1)*nsps + jpk
|
||||
jb=ja+nsps-1
|
||||
cs(0:nfft-1)=c0(ja:jb)
|
||||
call four2a(cs,nsps,1,-1,1) !c2c FFT to frequency
|
||||
do ii=1,LL
|
||||
i=ii-65+mode64 !mode64 = 1 2 4 8 16 for Q65 A B C D E
|
||||
if(i.lt.0) i=i+nsps
|
||||
s3(ii,j)=real(cs(i))**2 + aimag(cs(i))**2
|
||||
enddo
|
||||
enddo
|
||||
endif
|
||||
enddo
|
||||
|
||||
df=6000.0/nfft
|
||||
do i=1,LL
|
||||
|
@ -73,7 +73,7 @@ program test_q65
|
||||
! 1 2 3 4 5 6 7
|
||||
! 123456789012345678901234567890123456789012345678901234567890123456789012345'
|
||||
cmd1='q65sim "K1ABC W9XYZ EN37 " A 1500 5.0 0.0 0.0 1 60 100 -10.0 > junk0'
|
||||
cmd2='jt9 -3 -p 15 -L 300 -H 3000 -d 3 -b A -Q 3 -f 1500 *.wav > junk'
|
||||
cmd2='jt9 -3 -p 15 -L 300 -H 3000 -d 3 -b A -Q 3 -f 1500 *.wav > junk'
|
||||
|
||||
write(cmd1(10:33),'(a)') '"'//msg//'"'
|
||||
cmd1(35:35)=csubmode
|
||||
@ -86,10 +86,10 @@ program test_q65
|
||||
write(cmd1(62:66),'(i5)') nfiles
|
||||
|
||||
write(cmd2(11:13),'(i3)') ntrperiod
|
||||
write(cmd2(33:34),'(i2)') ndepth
|
||||
write(cmd2(44:44),'(i1)') nQSOprogress
|
||||
write(cmd2(49:52),'(i4)') nf0
|
||||
cmd2(39:39)=csubmode
|
||||
write(cmd2(33:35),'(i3)') ndepth
|
||||
write(cmd2(45:45),'(i1)') nQSOprogress
|
||||
write(cmd2(50:53),'(i4)') nf0
|
||||
cmd2(40:40)=csubmode
|
||||
|
||||
call system('rm -f *.wav')
|
||||
|
||||
@ -142,13 +142,14 @@ program test_q65
|
||||
if(line(i0:i0).ne.' ') then
|
||||
i1=index(line,'q')
|
||||
idec=-1
|
||||
read(line(i1+1:),*) idec
|
||||
endif
|
||||
if(idec.lt.0) cycle
|
||||
if(idec.ge.12) then
|
||||
iavg=idec-10
|
||||
idec=1
|
||||
read(line(i1+1:i1+1),*) idec
|
||||
if(line(i1+2:i1+2).eq.'*') then
|
||||
iavg=10
|
||||
else
|
||||
read(line(i1+2:i1+2),*,end=100) iavg
|
||||
endif
|
||||
endif
|
||||
100 if(idec.lt.0) cycle
|
||||
if(decok) then
|
||||
ndecn=ndecn + 1
|
||||
if(iavg.le.1) ndec1=ndec1 + 1
|
||||
|
Binary file not shown.
@ -3054,6 +3054,7 @@ void MainWindow::on_ClrAvgButton_clicked()
|
||||
if(m_msgAvgWidget != NULL) {
|
||||
if(m_msgAvgWidget->isVisible()) m_msgAvgWidget->displayAvg("");
|
||||
}
|
||||
if(m_mode=="Q65") ndecodes_label.setText("0 0");
|
||||
}
|
||||
|
||||
void MainWindow::msgAvgDecode2()
|
||||
|
@ -141,7 +141,7 @@ void CPlotter::draw(float swide[], bool bScroll, bool bRed)
|
||||
//move current data down one line (must do this before attaching a QPainter object)
|
||||
if(bScroll and !m_bReplot) m_WaterfallPixmap.scroll(0,1,0,0,m_w,m_h1);
|
||||
QPainter painter1(&m_WaterfallPixmap);
|
||||
if(m_bFirst or bRed or (!m_bQ65_Sync and !m_bQ65_MultiSync) or m_mode!=m_mode0
|
||||
if(m_bFirst or bRed or !m_bQ65_Sync or m_mode!=m_mode0
|
||||
or m_bResized or m_rxFreq!=m_rxFreq0) {
|
||||
m_2DPixmap = m_OverlayPixmap.copy(0,0,m_w,m_h2);
|
||||
m_bFirst=false;
|
||||
@ -165,6 +165,7 @@ void CPlotter::draw(float swide[], bool bScroll, bool bRed)
|
||||
}
|
||||
static QPoint LineBuf[MAX_SCREENSIZE];
|
||||
static QPoint LineBuf2[MAX_SCREENSIZE];
|
||||
static QPoint LineBuf3[MAX_SCREENSIZE];
|
||||
j=0;
|
||||
j0=int(m_startFreq/m_fftBinWidth + 0.5);
|
||||
int iz=XfromFreq(5000.0);
|
||||
@ -229,7 +230,7 @@ void CPlotter::draw(float swide[], bool bScroll, bool bRed)
|
||||
|
||||
}
|
||||
|
||||
if(i==iz-1 and !m_bQ65_Sync and !m_bQ65_MultiSync) {
|
||||
if(i==iz-1 and !m_bQ65_Sync) {
|
||||
painter2D.drawPolyline(LineBuf,j);
|
||||
}
|
||||
LineBuf[j].setX(i);
|
||||
@ -273,28 +274,37 @@ void CPlotter::draw(float swide[], bool bScroll, bool bRed)
|
||||
painter2D.drawText(x1-4,y,"73");
|
||||
}
|
||||
|
||||
if(bRed and (m_bQ65_Sync or m_bQ65_MultiSync)) { //Plot the Q65 red or orange sync curve
|
||||
if(bRed and m_bQ65_Sync) { //Plot the Q65 red or orange sync curve
|
||||
int k=0;
|
||||
int k2=0;
|
||||
std::ifstream f;
|
||||
f.open(m_redFile.toLatin1());
|
||||
if(f) {
|
||||
int x,y;
|
||||
float freq,sync,xdt,sync2;
|
||||
float freq,xdt,sync,sync2;
|
||||
f >> xdt;
|
||||
for(int i=0; i<99999; i++) {
|
||||
f >> freq >> sync >> xdt >> sync2;
|
||||
f >> freq >> sync >> sync2;
|
||||
if(f.eof()) break;
|
||||
x=XfromFreq(freq);
|
||||
if(m_bQ65_MultiSync) sync=sync2;
|
||||
y=m_h2*(0.9 - 0.09*gain2d*sync) - m_plot2dZero;
|
||||
LineBuf2[k].setX(x);
|
||||
LineBuf2[k].setY(y);
|
||||
if(sync > -99.0 and sync != 0.0) {
|
||||
y=m_h2*(0.9 - 0.09*gain2d*sync) - m_plot2dZero - 10;
|
||||
LineBuf2[k2].setX(x); //Red sync curve
|
||||
LineBuf2[k2].setY(y);
|
||||
k2++;
|
||||
}
|
||||
y=m_h2*(0.9 - 0.09*gain2d*sync2) - m_plot2dZero;
|
||||
LineBuf3[k].setX(x); //Orange sync curve
|
||||
LineBuf3[k].setY(y);
|
||||
k++;
|
||||
}
|
||||
f.close();
|
||||
QPen pen0(Qt::red,2);
|
||||
if(m_bQ65_MultiSync) pen0.setColor("orange");
|
||||
painter2D.setPen(pen0);
|
||||
painter2D.drawPolyline(LineBuf2,k);
|
||||
painter2D.drawPolyline(LineBuf2,k2);
|
||||
pen0.setColor("orange");
|
||||
painter2D.setPen(pen0);
|
||||
painter2D.drawPolyline(LineBuf3,k);
|
||||
if(m_bQ65_Sync) {
|
||||
QString t;
|
||||
t = t.asprintf("DT = %6.2f",xdt);
|
||||
|
@ -82,8 +82,7 @@ public:
|
||||
bool Reference() const {return m_bReference;}
|
||||
void setQ65_Sync(bool b) {m_bQ65_Sync = b;}
|
||||
bool Q65_Sync() const {return m_bQ65_Sync;}
|
||||
void setQ65_MultiSync(bool b) {m_bQ65_MultiSync = b;}
|
||||
bool Q65_MultiSync() const {return m_bQ65_MultiSync;} void drawRed(int ia, int ib, float swide[]);
|
||||
void drawRed(int ia, int ib, float swide[]);
|
||||
void setVHF(bool bVHF);
|
||||
void setRedFile(QString fRed);
|
||||
void setFST4_FreqRange(int fLow,int fHigh);
|
||||
@ -117,7 +116,6 @@ private:
|
||||
bool m_bReference;
|
||||
bool m_bReference0;
|
||||
bool m_bQ65_Sync;
|
||||
bool m_bQ65_MultiSync;
|
||||
bool m_bVHF;
|
||||
bool m_bSingleDecode;
|
||||
bool m_bFirst=true;
|
||||
|
@ -71,13 +71,11 @@ WideGraph::WideGraph(QSettings * settings, QWidget *parent) :
|
||||
ui->widePlot->setLinearAvg(m_settings->value("LinearAvg",false).toBool());
|
||||
ui->widePlot->setReference(m_settings->value("Reference",false).toBool());
|
||||
ui->widePlot->setQ65_Sync(m_settings->value("Q65_Sync",false).toBool());
|
||||
ui->widePlot->setQ65_MultiSync(m_settings->value("Q65_MultiSync",false).toBool());
|
||||
if(ui->widePlot->current()) ui->spec2dComboBox->setCurrentIndex(0);
|
||||
if(ui->widePlot->cumulative()) ui->spec2dComboBox->setCurrentIndex(1);
|
||||
if(ui->widePlot->linearAvg()) ui->spec2dComboBox->setCurrentIndex(2);
|
||||
if(ui->widePlot->Reference()) ui->spec2dComboBox->setCurrentIndex(3);
|
||||
if(ui->widePlot->Q65_Sync()) ui->spec2dComboBox->setCurrentIndex(4);
|
||||
if(ui->widePlot->Q65_MultiSync()) ui->spec2dComboBox->setCurrentIndex(5);
|
||||
int nbpp=m_settings->value("BinsPerPixel",2).toInt();
|
||||
ui->widePlot->setBinsPerPixel(nbpp);
|
||||
ui->sbPercent2dPlot->setValue(m_Percent2DScreen);
|
||||
@ -135,7 +133,6 @@ void WideGraph::saveSettings() //saveS
|
||||
m_settings->setValue ("LinearAvg", ui->widePlot->linearAvg());
|
||||
m_settings->setValue ("Reference", ui->widePlot->Reference());
|
||||
m_settings->setValue ("Q65_Sync", ui->widePlot->Q65_Sync());
|
||||
m_settings->setValue ("Q65_MultiSync", ui->widePlot->Q65_MultiSync());
|
||||
m_settings->setValue ("BinsPerPixel", ui->widePlot->binsPerPixel ());
|
||||
m_settings->setValue ("StartFreq", ui->widePlot->startFreq ());
|
||||
m_settings->setValue ("WaterfallPalette", m_waterfallPalette);
|
||||
@ -323,7 +320,6 @@ void WideGraph::on_spec2dComboBox_currentIndexChanged(int index)
|
||||
ui->widePlot->setLinearAvg(false);
|
||||
ui->widePlot->setReference(false);
|
||||
ui->widePlot->setQ65_Sync(false);
|
||||
ui->widePlot->setQ65_MultiSync(false);
|
||||
ui->smoSpinBox->setEnabled(false);
|
||||
switch (index)
|
||||
{
|
||||
@ -343,9 +339,6 @@ void WideGraph::on_spec2dComboBox_currentIndexChanged(int index)
|
||||
case 4:
|
||||
ui->widePlot->setQ65_Sync(true);
|
||||
break;
|
||||
case 5:
|
||||
ui->widePlot->setQ65_MultiSync(true);
|
||||
break;
|
||||
}
|
||||
replot();
|
||||
}
|
||||
|
@ -340,11 +340,6 @@
|
||||
<string>Q65_Sync</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Q65_MultiSync</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
|
Loading…
Reference in New Issue
Block a user