mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-28 23:28:49 -05:00
New method for measuring SNR of decoded Q65 signals.
This commit is contained in:
parent
23eb287449
commit
b156ecd3a1
@ -225,6 +225,7 @@ contains
|
|||||||
write(c77,1000) dat4(1:12),dat4(13)/2
|
write(c77,1000) dat4(1:12),dat4(13)/2
|
||||||
1000 format(12b6.6,b5.5)
|
1000 format(12b6.6,b5.5)
|
||||||
call unpack77(c77,0,decoded,unpk77_success) !Unpack to get msgsent
|
call unpack77(c77,0,decoded,unpk77_success) !Unpack to get msgsent
|
||||||
|
call q65_snr(dat4,dtdec,f0dec,mode_q65,snr2)
|
||||||
nsnr=nint(snr2)
|
nsnr=nint(snr2)
|
||||||
call this%callback(nutc,snr1,nsnr,dtdec,f0dec,decoded, &
|
call this%callback(nutc,snr1,nsnr,dtdec,f0dec,decoded, &
|
||||||
idec,nused,ntrperiod)
|
idec,nused,ntrperiod)
|
||||||
@ -306,6 +307,7 @@ contains
|
|||||||
! Unpack decoded message for display to user
|
! Unpack decoded message for display to user
|
||||||
write(c77,1000) dat4(1:12),dat4(13)/2
|
write(c77,1000) dat4(1:12),dat4(13)/2
|
||||||
call unpack77(c77,0,decoded,unpk77_success) !Unpack to get msgsent
|
call unpack77(c77,0,decoded,unpk77_success) !Unpack to get msgsent
|
||||||
|
call q65_snr(dat4,dtdec,f0dec,mode_q65,snr2)
|
||||||
nsnr=nint(snr2)
|
nsnr=nint(snr2)
|
||||||
call this%callback(nutc,snr1,nsnr,dtdec,f0dec,decoded, &
|
call this%callback(nutc,snr1,nsnr,dtdec,f0dec,decoded, &
|
||||||
idec,nused,ntrperiod)
|
idec,nused,ntrperiod)
|
||||||
|
@ -17,7 +17,9 @@ module q65
|
|||||||
integer navg(0:1)
|
integer navg(0:1)
|
||||||
logical lnewdat
|
logical lnewdat
|
||||||
real candidates(20,3) !snr, xdt, and f0 of top candidates
|
real candidates(20,3) !snr, xdt, and f0 of top candidates
|
||||||
real,allocatable,save :: s1a(:,:,:) !Cumulative symbol spectra
|
real, allocatable :: s1raw(:,:) !Symbol spectra, 1/8-symbol steps
|
||||||
|
real, allocatable :: s1(:,:) !Symbol spectra w/suppressed peaks
|
||||||
|
real, allocatable,save :: s1a(:,:,:) !Cumulative symbol spectra
|
||||||
real sync(85) !sync vector
|
real sync(85) !sync vector
|
||||||
real df,dtstep,dtdec,f0dec,ftol
|
real df,dtstep,dtdec,f0dec,ftol
|
||||||
|
|
||||||
@ -60,7 +62,6 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
|||||||
integer dat4(13)
|
integer dat4(13)
|
||||||
character*37 decoded
|
character*37 decoded
|
||||||
logical first,lclearave
|
logical first,lclearave
|
||||||
real, allocatable :: s1(:,:) !Symbol spectra, 1/8-symbol steps
|
|
||||||
real, allocatable :: s3(:,:) !Data-symbol energies s3(LL,63)
|
real, allocatable :: s3(:,:) !Data-symbol energies s3(LL,63)
|
||||||
real, allocatable :: ccf1(:) !CCF(freq) at fixed lag (red)
|
real, allocatable :: ccf1(:) !CCF(freq) at fixed lag (red)
|
||||||
real, allocatable :: ccf2(:) !Max CCF(freq) at any lag (orange)
|
real, allocatable :: ccf2(:) !Max CCF(freq) at any lag (orange)
|
||||||
@ -95,13 +96,17 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
|||||||
enddo
|
enddo
|
||||||
endif
|
endif
|
||||||
|
|
||||||
allocate(s1(iz,jz))
|
|
||||||
allocate(s3(-64:LL-65,63))
|
allocate(s3(-64:LL-65,63))
|
||||||
allocate(ccf1(-ia2:ia2))
|
allocate(ccf1(-ia2:ia2))
|
||||||
allocate(ccf2(iz))
|
allocate(ccf2(iz))
|
||||||
if(LL.ne.LL0 .or. iz.ne.iz0 .or. jz.ne.jz0 .or. lclearave) then
|
if(LL.ne.LL0 .or. iz.ne.iz0 .or. jz.ne.jz0 .or. lclearave) then
|
||||||
|
if(allocated(s1raw)) deallocate(s1raw)
|
||||||
|
allocate(s1raw(iz,jz))
|
||||||
|
if(allocated(s1)) deallocate(s1)
|
||||||
|
allocate(s1(iz,jz))
|
||||||
if(allocated(s1a)) deallocate(s1a)
|
if(allocated(s1a)) deallocate(s1a)
|
||||||
allocate(s1a(iz,jz,0:1))
|
allocate(s1a(iz,jz,0:1))
|
||||||
|
s1=0.
|
||||||
s1a=0.
|
s1a=0.
|
||||||
navg=0
|
navg=0
|
||||||
LL0=LL
|
LL0=LL
|
||||||
@ -130,6 +135,7 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
|||||||
if(i0-64.lt.1 .or. i0-65+LL.gt.iz) go to 900 !Frequency out of range
|
if(i0-64.lt.1 .or. i0-65+LL.gt.iz) go to 900 !Frequency out of range
|
||||||
call pctile(s1(i0-64:i0-65+LL,1:jz),LL*jz,45,base)
|
call pctile(s1(i0-64:i0-65+LL,1:jz),LL*jz,45,base)
|
||||||
s1=s1/base
|
s1=s1/base
|
||||||
|
s1raw=s1
|
||||||
|
|
||||||
! Apply fast AGC to the symbol spectra
|
! Apply fast AGC to the symbol spectra
|
||||||
s1max=20.0 !Empirical choice
|
s1max=20.0 !Empirical choice
|
||||||
@ -620,4 +626,64 @@ subroutine q65_bzap(s3,LL)
|
|||||||
return
|
return
|
||||||
end subroutine q65_bzap
|
end subroutine q65_bzap
|
||||||
|
|
||||||
|
subroutine q65_snr(dat4,dtdec,f0dec,mode_q65,snr2)
|
||||||
|
|
||||||
|
! Estimate SNR of a decoded transmission by aligning the spectra of
|
||||||
|
! all 85 symbols.
|
||||||
|
|
||||||
|
integer dat4(13)
|
||||||
|
integer codeword(63)
|
||||||
|
integer itone(85)
|
||||||
|
real, allocatable :: spec(:)
|
||||||
|
|
||||||
|
! write(70) mode_q65,df,dtdec,f0dec,iz0,jz0,s1raw
|
||||||
|
|
||||||
|
allocate(spec(iz0))
|
||||||
|
call q65_enc(dat4,codeword)
|
||||||
|
i=1
|
||||||
|
k=0
|
||||||
|
do j=1,85
|
||||||
|
if(j.eq.isync(i)) then
|
||||||
|
i=i+1
|
||||||
|
itone(j)=0
|
||||||
|
else
|
||||||
|
k=k+1
|
||||||
|
itone(j)=codeword(k) + 1
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
|
||||||
|
spec=0.
|
||||||
|
lagpk=nint(dtdec/dtstep)
|
||||||
|
do k=1,85
|
||||||
|
j=j0 + NSTEP*(k-1) + 1 + lagpk
|
||||||
|
if(j.ge.1 .and. j.le.jz0) then
|
||||||
|
do i=1,iz0
|
||||||
|
ii=i+mode_q65*itone(k)
|
||||||
|
if(ii.ge.1 .and. ii.le.iz0) spec(i)=spec(i) + s1raw(ii,j)
|
||||||
|
enddo
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
|
||||||
|
i0=nint(f0dec/df)
|
||||||
|
nsum=max(10*mode_q65,nint(50.0/df))
|
||||||
|
ia=i0 - 2*nsum
|
||||||
|
ib=i0 + 2*nsum
|
||||||
|
sum1=sum(spec(ia:ia+nsum-1))
|
||||||
|
sum2=sum(spec(ib-nsum+1:ib))
|
||||||
|
avg=(sum1+sum2)/(2.0*nsum)
|
||||||
|
spec=spec/avg !Baseline level is now 1.0
|
||||||
|
smax=maxval(spec(ia:ib))
|
||||||
|
sig_area=sum(spec(ia+nsum:ib-nsum)-1.0)
|
||||||
|
w_equiv=sig_area/(smax-1.0)
|
||||||
|
snr2=db(max(1.0,sig_area)) - db(2500.0/df)
|
||||||
|
|
||||||
|
! do i=ia,ib
|
||||||
|
! write(71,3071) i*df,spec(i),db(spec(i))
|
||||||
|
!3071 format(3f10.3)
|
||||||
|
! enddo
|
||||||
|
! flush(71)
|
||||||
|
|
||||||
|
return
|
||||||
|
end subroutine q65_snr
|
||||||
|
|
||||||
end module q65
|
end module q65
|
||||||
|
@ -103,7 +103,7 @@ program test_q65
|
|||||||
dterr=tsym/4.0
|
dterr=tsym/4.0
|
||||||
nferr=max(1,nint(0.5*baud),nint(fdop/3.0))
|
nferr=max(1,nint(0.5*baud),nint(fdop/3.0))
|
||||||
ndec1z=nfiles
|
ndec1z=nfiles
|
||||||
|
|
||||||
do nsnr=ia,ib,-1
|
do nsnr=ia,ib,-1
|
||||||
snr1=nsnr
|
snr1=nsnr
|
||||||
if(ia.eq.99) snr1=snr
|
if(ia.eq.99) snr1=snr
|
||||||
|
Loading…
Reference in New Issue
Block a user