Fixed a problem in the synchronization code that caused issues with failed decodes on signals that should be able to be decoded

This commit is contained in:
Jordan Sherer 2020-05-01 10:16:12 -04:00
parent 59ce3b1118
commit ff21c67e09
9 changed files with 79 additions and 63 deletions

View File

@ -10,7 +10,7 @@ subroutine js8_downsample(dd,newdat,f0,c1)
complex c1(0:NDFFT2-1)
complex cx(0:NDFFT1/2)
real dd(NMAX),x(NDFFT1),taper(0:NDD)
real*4 dd(NMAX),x(NDFFT1),taper(0:NDD)
equivalence (x,cx)
data first/.true./
save cx,first,taper

View File

@ -33,7 +33,7 @@ subroutine js8dec(dd0,icos,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly
integer naptypes(0:5,4) ! (nQSOProgress, decoding pass) maximum of 4 passes for now
integer*1, target:: i1hiscall(12)
complex cd0(0:NP-1)
complex ctwk(7*NSPS/NDOWN)
complex ctwk(NDOWNSPS)
complex csymb(NDOWNSPS)
complex cs(0:7, NN)
logical first,newdat,lsubtract,lapon,lapcqonly,nagain
@ -143,13 +143,22 @@ subroutine js8dec(dd0,icos,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly
smax=0.0
do ifr=-5,5 !Search over +/- 2.5 Hz
! compute the ctwk samples at the delta frequency to by used in syncjs8d
! to detect peaks at frequencies +/- 2.5 Hz so we can align the decoder
! for the best possible chance at decoding.
!
! NOTE: this does not need to compute the entire set of samples for the
! costas arrays...it only needs to do it for the delta frequency
! whose conjugate is multiplied against each csync array in syncjs8d
delf=ifr*0.5
dphi=twopi*delf*dt2
phi=0.0
do i=1,7*NSPS/NDOWN
do i=1,NDOWNSPS
ctwk(i)=cmplx(cos(phi),sin(phi))
phi=mod(phi+dphi,twopi)
enddo
call syncjs8d(cd0,icos,i0,ctwk,1,sync)
if(NWRITELOG.eq.1) then
write(*,*) '<DecodeDebug> ', 'df', delf, 'sync', sync
@ -166,13 +175,18 @@ subroutine js8dec(dd0,icos,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly
xdt=xdt2
f1=f1+delfbest !Improved estimate of DF
if(NWRITELOG.eq.0) then
if(NWRITELOG.eq.1) then
write(*,*) '<DecodeDebug> twk', xdt, f1, smax
flush(6)
endif
call syncjs8d(cd0,icos,i0,ctwk,0,sync)
if(NWRITELOG.eq.1) then
write(*,*) '<DecodeDebug> ibest', ibest
flush(6)
endif
j=0
do k=1,NN
i1=ibest+(k-1)*NDOWNSPS
@ -208,7 +222,7 @@ subroutine js8dec(dd0,icos,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly
call timer('badnsync', 0)
nbadcrc=1
call timer('badnsync', 1)
if(NWRITELOG.eq.0) then
if(NWRITELOG.eq.1) then
write(*,*) '<DecodeDebug> bad sync', nsync
flush(6)
endif
@ -276,43 +290,43 @@ subroutine js8dec(dd0,icos,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly
! r2=log(b2+b3+b6+b7)-log(b0+b1+b4+b5)
! r4=log(b4+b5+b6+b7)-log(b0+b1+b2+b3)
! if(nQSOProgress .eq. 0 .or. nQSOProgress .eq. 5) then
! ! When bits 88:115 are set as ap bits, bit 115 lives in symbol 39 along
! ! with no-ap bits 116 and 117. Take care of metrics for bits 116 and 117.
! if(j.eq.39) then ! take care of bits that live in symbol 39
! if(apsym(28).lt.0) then
! bmetap(i2)=max(ps(2),ps(3))-max(ps(0),ps(1))
! bmetap(i1)=max(ps(1),ps(3))-max(ps(0),ps(2))
! else
! bmetap(i2)=max(ps(6),ps(7))-max(ps(4),ps(5))
! bmetap(i1)=max(ps(5),ps(7))-max(ps(4),ps(6))
! endif
! endif
! endif
if(nQSOProgress .eq. 0 .or. nQSOProgress .eq. 5) then
! When bits 88:115 are set as ap bits, bit 115 lives in symbol 39 along
! with no-ap bits 116 and 117. Take care of metrics for bits 116 and 117.
if(j.eq.39) then ! take care of bits that live in symbol 39
if(apsym(28).lt.0) then
bmetap(i2)=max(ps(2),ps(3))-max(ps(0),ps(1))
bmetap(i1)=max(ps(1),ps(3))-max(ps(0),ps(2))
else
bmetap(i2)=max(ps(6),ps(7))-max(ps(4),ps(5))
bmetap(i1)=max(ps(5),ps(7))-max(ps(4),ps(6))
endif
endif
endif
! ! When bits 116:143 are set as ap bits, bit 115 lives in symbol 39 along
! ! with ap bits 116 and 117. Take care of metric for bit 115.
! if(j.eq.39) then ! take care of bit 115
! iii=2*(apsym(29)+1)/2 + (apsym(30)+1)/2 ! known values of bits 116 & 117
! if(iii.eq.0) bmetap(i4)=ps(4)-ps(0)
! if(iii.eq.1) bmetap(i4)=ps(5)-ps(1)
! if(iii.eq.2) bmetap(i4)=ps(6)-ps(2)
! if(iii.eq.3) bmetap(i4)=ps(7)-ps(3)
! endif
! When bits 116:143 are set as ap bits, bit 115 lives in symbol 39 along
! with ap bits 116 and 117. Take care of metric for bit 115.
if(j.eq.39) then ! take care of bit 115
iii=2*(apsym(29)+1)/2 + (apsym(30)+1)/2 ! known values of bits 116 & 117
if(iii.eq.0) bmetap(i4)=ps(4)-ps(0)
if(iii.eq.1) bmetap(i4)=ps(5)-ps(1)
if(iii.eq.2) bmetap(i4)=ps(6)-ps(2)
if(iii.eq.3) bmetap(i4)=ps(7)-ps(3)
endif
! ! bit 144 lives in symbol 48 and will be 1 if it is set as an ap bit.
! ! take care of metrics for bits 142 and 143
! if(j.eq.48) then ! bit 144 is always 1
! bmetap(i4)=max(ps(5),ps(7))-max(ps(1),ps(3))
! bmetap(i2)=max(ps(3),ps(7))-max(ps(1),ps(5))
! endif
! bit 144 lives in symbol 48 and will be 1 if it is set as an ap bit.
! take care of metrics for bits 142 and 143
if(j.eq.48) then ! bit 144 is always 1
bmetap(i4)=max(ps(5),ps(7))-max(ps(1),ps(3))
bmetap(i2)=max(ps(3),ps(7))-max(ps(1),ps(5))
endif
! ! bit 154 lives in symbol 52 and will be 0 if it is set as an ap bit
! ! take care of metrics for bits 155 and 156
! if(j.eq.52) then ! bit 154 will be 0 if it is set as an ap bit.
! bmetap(i2)=max(ps(2),ps(3))-max(ps(0),ps(1))
! bmetap(i1)=max(ps(1),ps(3))-max(ps(0),ps(2))
! endif
! bit 154 lives in symbol 52 and will be 0 if it is set as an ap bit
! take care of metrics for bits 155 and 156
if(j.eq.52) then ! bit 154 will be 0 if it is set as an ap bit.
bmetap(i2)=max(ps(2),ps(3))-max(ps(0),ps(1))
bmetap(i1)=max(ps(1),ps(3))-max(ps(0),ps(2))
endif
enddo
@ -413,7 +427,7 @@ subroutine js8dec(dd0,icos,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly
niterations)
call timer('bpd174 ',1)
if(NWRITELOG.eq.0) then
if(NWRITELOG.eq.1) then
write(*,*) '<DecodeDebug> bpd174', ipass, nharderrors, dmin
flush(6)
endif

View File

@ -149,7 +149,7 @@ subroutine syncjs8(dd,icos,nfa,nfb,syncmin,nfqso,s,candidate,ncand,sbase)
if(k.ge.200) exit
n=ia + indx(iz+1-i) - 1
if(red(n).lt.syncmin.or.isnan(red(n))) exit
if(NWRITELOG.eq.0) then
if(NWRITELOG.eq.1) then
write(*,*) '<DecodeDebug> red candidate', red(n), n*df, (jpeak(n)-1)*tstep
flush(6)
endif

View File

@ -2,12 +2,11 @@ subroutine syncjs8d(cd0,icos,i0,ctwk,itwk,sync)
! Compute sync power for a complex, downsampled JS8 signal.
!include 'js8_params.f90'
parameter(NP=NMAX/NDOWN, NP2=NN*NDOWNSPS)
complex cd0(0:NP-1)
complex csynca(7*NDOWNSPS),csyncb(7*NDOWNSPS),csyncc(7*NDOWNSPS)
complex csync2(7*NDOWNSPS)
complex ctwk(7*NDOWNSPS)
complex csynca(0:6,NDOWNSPS),csyncb(0:6,NDOWNSPS),csyncc(0:6,NDOWNSPS)
complex csync2(NDOWNSPS)
complex ctwk(NDOWNSPS)
complex z1,z2,z3
logical first
integer icos
@ -42,20 +41,18 @@ subroutine syncjs8d(cd0,icos,i0,ctwk,itwk,sync)
taus=NDOWNSPS*dt2 !Symbol duration
baud=1.0/taus !Keying rate
phia=0.0
phib=0.0
phic=0.0
do i=0,6
phia=0.0
phib=0.0
phic=0.0
dphia=twopi*icos7a(i)*baud*dt2
dphib=twopi*icos7b(i)*baud*dt2
dphic=twopi*icos7c(i)*baud*dt2
do j=1,NDOWNSPS
k=i*NDOWNSPS+j
csynca(k)=cmplx(cos(phia),sin(phia)) !Waveform for Beginning 7x7 Costas array
csyncb(k)=cmplx(cos(phib),sin(phib)) !Waveform for Middle 7x7 Costas array
csyncc(k)=cmplx(cos(phic),sin(phic)) !Waveform for End 7x7 Costas array
csynca(i,j)=cmplx(cos(phia),sin(phia)) !Waveform for Beginning 7x7 Costas array
csyncb(i,j)=cmplx(cos(phib),sin(phib)) !Waveform for Middle 7x7 Costas array
csyncc(i,j)=cmplx(cos(phic),sin(phic)) !Waveform for End 7x7 Costas array
phia=mod(phia+dphia,twopi)
phib=mod(phib+dphib,twopi)
phic=mod(phia+dphic,twopi)
@ -81,17 +78,17 @@ subroutine syncjs8d(cd0,icos,i0,ctwk,itwk,sync)
z2=0.
z3=0.
csync2=csynca
if(itwk.eq.1) csync2=ctwk*csynca
if(i1.ge.0 .and. i1+NDOWNSPS-1.le.NP2-1) z1=sum(cd0(i1:i1+7*NDOWNSPS-1)*conjg(csync2))
csync2=csynca(i,1:NDOWNSPS)
if(itwk.eq.1) csync2=ctwk*csync2
if(i1.ge.0 .and. i1+NDOWNSPS-1.le.NP2-1) z1=sum(cd0(i1:i1+NDOWNSPS-1)*conjg(csync2))
csync2=csyncb
if(itwk.eq.1) csync2=ctwk*csyncb
if(i2.ge.0 .and. i2+NDOWNSPS-1.le.NP2-1) z2=sum(cd0(i2:i2+7*NDOWNSPS-1)*conjg(csync2))
csync2=csyncb(i,1:NDOWNSPS)
if(itwk.eq.1) csync2=ctwk*csync2
if(i2.ge.0 .and. i2+NDOWNSPS-1.le.NP2-1) z2=sum(cd0(i2:i2+NDOWNSPS-1)*conjg(csync2))
csync2=csyncc
if(itwk.eq.1) csync2=ctwk*csyncc
if(i3.ge.0 .and. i3+NDOWNSPS-1.le.NP2-1) z3=sum(cd0(i3:i3+7*NDOWNSPS-1)*conjg(csync2))
csync2=csyncc(i,1:NDOWNSPS)
if(itwk.eq.1) csync2=ctwk*csync2
if(i3.ge.0 .and. i3+NDOWNSPS-1.le.NP2-1) z3=sum(cd0(i3:i3+NDOWNSPS-1)*conjg(csync2))
sync = sync + p(z1) + p(z2) + p(z3)

View File

@ -101,7 +101,7 @@ contains
xdt=candidate(2,icand)
xbase=10.0**(0.1*(sbase(nint(f1/(12000.0/NFFT1)))-40.0)) ! 3.125Hz
if(NWRITELOG.eq.0) then
if(NWRITELOG.eq.1) then
write(*,*) '<DecodeDebug> candidate', icand, 'f1', f1, 'sync', sync, 'xdt', xdt, 'xbase', xbase
flush(6)
endif

Binary file not shown.

BIN
media/tests/A_1_4.wav Normal file

Binary file not shown.

BIN
media/tests/A_2_5.wav Normal file

Binary file not shown.

5
media/tests/README Normal file
View File

@ -0,0 +1,5 @@
These are rudimentary test wav files to be run directly in the decoder.
They are named as: {MODE}_{DEPTH}_{EXPECTED_DECODES}.wav
And can be run directly from the ./js8 decoder