mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-12-24 11:40:31 -05:00
Use 4 different Costas arrays to prevent false syncs as received frames move
through the analysis window. Add a random 77-bit vector to each message so that tone transitions occur even if the message contains a long string of 0 or 1 (like a CQ). Add alternative sync calculation as an option (sync2), for testing. Add basic framework for AP decoding.
This commit is contained in:
parent
91e3dbdf20
commit
71cb6d9f50
@ -1,17 +1,19 @@
|
||||
subroutine ft4_decode(cdatetime0,tbuf,nfa,nfb,nfqso,iwave,ndecodes,mycall, &
|
||||
subroutine ft4_decode(cdatetime0,tbuf,nfa,nfb,nQSOProgress,nfqso,iwave,ndecodes,mycall, &
|
||||
hiscall,nrx,line,data_dir)
|
||||
|
||||
use packjt77
|
||||
include 'ft4_params.f90'
|
||||
parameter (NSS=NSPS/NDOWN)
|
||||
|
||||
character message*37
|
||||
character message*37,msgsent*37
|
||||
character c77*77
|
||||
character*61 line,linex(100)
|
||||
character*37 decodes(100)
|
||||
character*512 data_dir,fname
|
||||
character*17 cdatetime0
|
||||
character*6 mycall,hiscall,hhmmss
|
||||
character*6 mycall,hiscall
|
||||
character*6 mycall0,hiscall0
|
||||
character*6 hhmmss
|
||||
|
||||
complex cd2(0:NMAX/NDOWN-1) !Complex waveform
|
||||
complex cb(0:NMAX/NDOWN-1)
|
||||
@ -29,31 +31,50 @@ subroutine ft4_decode(cdatetime0,tbuf,nfa,nfb,nfqso,iwave,ndecodes,mycall, &
|
||||
real savg(NH1),sbase(NH1)
|
||||
|
||||
integer nrxx(100)
|
||||
integer icos4(0:3)
|
||||
integer icos4a(0:3),icos4b(0:3),icos4c(0:3),icos4d(0:3)
|
||||
integer*2 iwave(NMAX) !Generated full-length waveform
|
||||
integer*1 message77(77),apmask(2*ND),cw(2*ND)
|
||||
integer*1 message77(77),rvec(77),apbits(2*ND),apmask(2*ND),cw(2*ND)
|
||||
integer*1 hbits(2*NN)
|
||||
integer graymap(0:3)
|
||||
integer ip(1)
|
||||
integer nappasses(0:5) ! # of decoding passes for QSO States 0-5
|
||||
integer naptypes(0:5,4) ! nQSOProgress, decoding pass
|
||||
integer mcq(29),mcqru(29),mcqfd(29),mcqtest(29)
|
||||
integer mrrr(19),m73(19),mrr73(19)
|
||||
integer mcall(29),hcall(29)
|
||||
|
||||
logical unpk77_success
|
||||
logical one(0:255,0:7) ! 256 4-symbol sequences, 8 bits
|
||||
logical first
|
||||
|
||||
data icos4/0,1,3,2/
|
||||
data icos4a/0,1,3,2/
|
||||
data icos4b/1,0,2,3/
|
||||
data icos4c/2,3,1,0/
|
||||
data icos4d/3,2,0,1/
|
||||
data graymap/0,1,3,2/
|
||||
data first/.true./
|
||||
save one,first,nrxx,linex
|
||||
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 mcqru/0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,0,0,1,1,0,0/
|
||||
data mcqfd/0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,1,0/
|
||||
data mcqtest/0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,0,1,0,1,1,1,1,1,1,0,0,1,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/
|
||||
save fs,dt,tt,txt,twopi,h,one,first,nrxx,linex,apbits,nappasses,naptypes,mycall0,hiscall0
|
||||
|
||||
call clockit('ft4_deco',0)
|
||||
hhmmss=cdatetime0(8:13)
|
||||
fs=12000.0/NDOWN !Sample rate after downsampling
|
||||
dt=1/fs !Sample interval after downsample (s)
|
||||
tt=NSPS*dt !Duration of "itone" symbols (s)
|
||||
txt=NZ*dt !Transmission length (s) without ramp up/down
|
||||
twopi=8.0*atan(1.0)
|
||||
h=1.0
|
||||
|
||||
if(first) then
|
||||
fs=12000.0/NDOWN !Sample rate after downsampling
|
||||
dt=1/fs !Sample interval after downsample (s)
|
||||
tt=NSPS*dt !Duration of "itone" symbols (s)
|
||||
txt=NZ*dt !Transmission length (s) without ramp up/down
|
||||
twopi=8.0*atan(1.0)
|
||||
h=1.0
|
||||
one=.false.
|
||||
do i=0,255
|
||||
do j=0,7
|
||||
@ -63,6 +84,22 @@ subroutine ft4_decode(cdatetime0,tbuf,nfa,nfb,nfqso,iwave,ndecodes,mycall, &
|
||||
first=.false.
|
||||
endif
|
||||
|
||||
if(mycall.ne.mycall0 .or. hiscall.ne.hiscall0) then
|
||||
message=trim(mycall)//' '//trim(hiscall)//' '//'RR73'
|
||||
i3=-1
|
||||
n3=-1
|
||||
call pack77(message,i3,n3,c77)
|
||||
call unpack77(c77,0,msgsent,unpk77_success)
|
||||
if(message.ne.msgsent) write(*,*) 'ERROR setting AP message'
|
||||
read(c77,"(77i1)") message77
|
||||
message77=mod(message77+rvec,2)
|
||||
call encode174_91(message77,cw)
|
||||
mcall=cw(1:29)
|
||||
hcall=cw(30:58)
|
||||
mycall0=mycall
|
||||
hiscall0=hiscall
|
||||
endif
|
||||
|
||||
candidate=0.0
|
||||
ncand=0
|
||||
syncmin=1.2
|
||||
@ -87,7 +124,7 @@ subroutine ft4_decode(cdatetime0,tbuf,nfa,nfb,nfqso,iwave,ndecodes,mycall, &
|
||||
sum2=sum(cd2*conjg(cd2))/(real(NMAX)/real(NDOWN))
|
||||
if(sum2.gt.0.0) cd2=cd2/sqrt(sum2)
|
||||
! Sample rate is now 12000/16 = 750 samples/second
|
||||
do isync=1,2
|
||||
do isync=1,1
|
||||
if(isync.eq.1) then
|
||||
idfmin=-12
|
||||
idfmax=12
|
||||
@ -116,7 +153,7 @@ subroutine ft4_decode(cdatetime0,tbuf,nfa,nfb,nfqso,iwave,ndecodes,mycall, &
|
||||
|
||||
call clockit('sync4d ',0)
|
||||
do istart=ibmin,ibmax,ibstp
|
||||
call sync4d(cd2,istart,ctwk2,1,sync) !Find sync power
|
||||
call sync4d(cd2,istart,ctwk2,1,sync,sync2) !Find sync power
|
||||
if(sync.gt.smax) then
|
||||
smax=sync
|
||||
ibest=istart
|
||||
@ -127,8 +164,10 @@ subroutine ft4_decode(cdatetime0,tbuf,nfa,nfb,nfqso,iwave,ndecodes,mycall, &
|
||||
|
||||
enddo
|
||||
enddo
|
||||
|
||||
f0=f0+real(idfbest)
|
||||
|
||||
!f0=1500
|
||||
!ibest=219
|
||||
call clockit('ft4down ',0)
|
||||
call ft4_downsample(iwave,f0,cb) !Final downsample with corrected f0
|
||||
call clockit('ft4down ',1)
|
||||
@ -152,17 +191,17 @@ subroutine ft4_decode(cdatetime0,tbuf,nfa,nfb,nfqso,iwave,ndecodes,mycall, &
|
||||
is4=0
|
||||
do k=1,4
|
||||
ip=maxloc(s4(:,k))
|
||||
if(icos4(k-1).eq.(ip(1)-1)) is1=is1+1
|
||||
if(icos4a(k-1).eq.(ip(1)-1)) is1=is1+1
|
||||
ip=maxloc(s4(:,k+33))
|
||||
if(icos4(k-1).eq.(ip(1)-1)) is2=is2+1
|
||||
if(icos4b(k-1).eq.(ip(1)-1)) is2=is2+1
|
||||
ip=maxloc(s4(:,k+66))
|
||||
if(icos4(k-1).eq.(ip(1)-1)) is3=is3+1
|
||||
if(icos4c(k-1).eq.(ip(1)-1)) is3=is3+1
|
||||
ip=maxloc(s4(:,k+99))
|
||||
if(icos4(k-1).eq.(ip(1)-1)) is4=is4+1
|
||||
if(icos4d(k-1).eq.(ip(1)-1)) is4=is4+1
|
||||
enddo
|
||||
nsync=is1+is2+is3+is4 !Number of hard sync errors, 0-16
|
||||
if(smax .lt. 0.9 .or. nsync .lt. 9) cycle
|
||||
|
||||
if(smax .lt. 0.7 .or. nsync .lt. 8) cycle
|
||||
|
||||
do nseq=1,3 !Try coherent sequences of 1, 2, and 4 symbols
|
||||
if(nseq.eq.1) nsym=1
|
||||
if(nseq.eq.2) nsym=2
|
||||
@ -217,11 +256,10 @@ subroutine ft4_decode(cdatetime0,tbuf,nfa,nfb,nfqso,iwave,ndecodes,mycall, &
|
||||
hbits=0
|
||||
where(bmeta.ge.0) hbits=1
|
||||
ns1=count(hbits( 1: 8).eq.(/0,0,0,1,1,0,1,1/))
|
||||
ns2=count(hbits( 67: 74).eq.(/0,0,0,1,1,0,1,1/))
|
||||
ns3=count(hbits(133:140).eq.(/0,0,0,1,1,0,1,1/))
|
||||
ns4=count(hbits(199:206).eq.(/0,0,0,1,1,0,1,1/))
|
||||
ns2=count(hbits( 67: 74).eq.(/0,1,0,0,1,1,1,0/))
|
||||
ns3=count(hbits(133:140).eq.(/1,1,1,0,0,1,0,0/))
|
||||
ns4=count(hbits(199:206).eq.(/1,0,1,1,0,0,0,1/))
|
||||
nsync_qual=ns1+ns2+ns3+ns4
|
||||
|
||||
if(nsync_qual.lt. 20) cycle
|
||||
|
||||
scalefac=2.83
|
||||
@ -242,7 +280,9 @@ subroutine ft4_decode(cdatetime0,tbuf,nfa,nfb,nfqso,iwave,ndecodes,mycall, &
|
||||
if(isd.eq.1) llr=llra
|
||||
if(isd.eq.2) llr=llrb
|
||||
if(isd.eq.3) llr=llrc
|
||||
!llr(1:59)=1.5*scalefac*(2*apbits(1:59)-1)
|
||||
apmask=0
|
||||
!apmask(1:91)=1
|
||||
max_iterations=40
|
||||
do ibias=0,0
|
||||
llr2=llr
|
||||
@ -256,6 +296,7 @@ subroutine ft4_decode(cdatetime0,tbuf,nfa,nfb,nfqso,iwave,ndecodes,mycall, &
|
||||
enddo
|
||||
if(sum(message77).eq.0) cycle
|
||||
if( nharderror.ge.0 ) then
|
||||
message77=mod(message77+rvec,2)
|
||||
write(c77,'(77i1)') message77(1:77)
|
||||
call unpack77(c77,1,message,unpk77_success)
|
||||
idupe=0
|
||||
@ -310,8 +351,9 @@ subroutine ft4_decode(cdatetime0,tbuf,nfa,nfb,nfqso,iwave,ndecodes,mycall, &
|
||||
enddo !Sequence estimation
|
||||
enddo !Candidate list
|
||||
call clockit('ft4_deco',1)
|
||||
call clockit2(data_dir)
|
||||
call clockit('ft4_deco',101)
|
||||
! clockit data directory does not get set properly on the Mac.
|
||||
! call clockit2(data_dir)
|
||||
! call clockit('ft4_deco',101)
|
||||
return
|
||||
|
||||
entry get_ft4msg(idecode,nrx,line)
|
||||
|
@ -44,6 +44,7 @@ program ft4d
|
||||
endif
|
||||
nfa=200
|
||||
nfb=3000
|
||||
nQSOProgress=0
|
||||
|
||||
do ifile=iarg,nargs
|
||||
call getarg(ifile,infile)
|
||||
@ -55,7 +56,7 @@ program ft4d
|
||||
cdatetime=' '//datetime
|
||||
close(10)
|
||||
|
||||
call ft4_decode(cdatetime,0.0,nfa,nfb,nfqso,iwave,ndecodes,mycall, &
|
||||
call ft4_decode(cdatetime,0.0,nfa,nfb,nQSOProgress,nfqso,iwave,ndecodes,mycall, &
|
||||
hiscall,nrx,line,data_dir)
|
||||
|
||||
do idecode=1,ndecodes
|
||||
|
@ -23,11 +23,16 @@ subroutine genft4(msg0,ichk,msgsent,i4tone)
|
||||
character*77 c77
|
||||
integer*4 i4tone(NN),itmp(ND)
|
||||
integer*1 codeword(2*ND)
|
||||
integer*1 msgbits(77)
|
||||
integer icos4(4)
|
||||
integer*1 msgbits(77),rvec(77)
|
||||
integer icos4a(4),icos4b(4),icos4c(4),icos4d(4)
|
||||
logical unpk77_success
|
||||
data icos4/0,1,3,2/
|
||||
|
||||
data icos4a/0,1,3,2/
|
||||
data icos4b/1,0,2,3/
|
||||
data icos4c/2,3,1,0/
|
||||
data icos4d/3,2,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/
|
||||
message=msg0
|
||||
|
||||
do i=1, 37
|
||||
@ -48,6 +53,7 @@ subroutine genft4(msg0,ichk,msgsent,i4tone)
|
||||
|
||||
if(ichk.eq.1) go to 999
|
||||
read(c77,"(77i1)") msgbits
|
||||
msgbits=mod(msgbits+rvec,2)
|
||||
call encode174_91(msgbits,codeword)
|
||||
|
||||
! Grayscale mapping:
|
||||
@ -64,13 +70,13 @@ subroutine genft4(msg0,ichk,msgsent,i4tone)
|
||||
if(is.eq.3) itmp(i)=2
|
||||
enddo
|
||||
|
||||
i4tone(1:4)=icos4
|
||||
i4tone(1:4)=icos4a
|
||||
i4tone(5:33)=itmp(1:29)
|
||||
i4tone(34:37)=icos4
|
||||
i4tone(34:37)=icos4b
|
||||
i4tone(38:66)=itmp(30:58)
|
||||
i4tone(67:70)=icos4
|
||||
i4tone(67:70)=icos4c
|
||||
i4tone(71:99)=itmp(59:87)
|
||||
i4tone(100:103)=icos4
|
||||
i4tone(100:103)=icos4d
|
||||
|
||||
999 return
|
||||
end subroutine genft4
|
||||
|
@ -1,31 +1,47 @@
|
||||
subroutine sync4d(cd0,i0,ctwk,itwk,sync)
|
||||
subroutine sync4d(cd0,i0,ctwk,itwk,sync,sync2)
|
||||
|
||||
! Compute sync power for a complex, downsampled FT4 signal.
|
||||
|
||||
include 'ft4_params.f90'
|
||||
parameter(NP=NMAX/NDOWN,NSS=NSPS/NDOWN)
|
||||
complex cd0(0:NP-1)
|
||||
complex csync(4*NSS)
|
||||
complex csynca(4*NSS),csyncb(4*NSS),csyncc(4*NSS),csyncd(4*NSS)
|
||||
complex csync2(4*NSS)
|
||||
complex ctwk(4*NSS)
|
||||
complex z1,z2,z3,z4
|
||||
complex zz1,zz2,zz3,zz4
|
||||
logical first
|
||||
integer icos4(0:3)
|
||||
data icos4/0,1,3,2/
|
||||
integer icos4a(0:3),icos4b(0:3),icos4c(0:3),icos4d(0:3)
|
||||
data icos4a/0,1,3,2/
|
||||
data icos4b/1,0,2,3/
|
||||
data icos4c/2,3,1,0/
|
||||
data icos4d/3,2,0,1/
|
||||
data first/.true./
|
||||
save first,twopi,csync,fac
|
||||
save first,twopi,csynca,csyncb,csyncc,csyncd,fac
|
||||
|
||||
p(z1)=real(z1*fac)**2 + aimag(z1*fac)**2 !Statement function for power
|
||||
|
||||
if( first ) then
|
||||
twopi=8.0*atan(1.0)
|
||||
k=1
|
||||
phi=0.0
|
||||
phia=0.0
|
||||
phib=0.0
|
||||
phic=0.0
|
||||
phid=0.0
|
||||
do i=0,3
|
||||
dphi=twopi*icos4(i)/real(NSS)
|
||||
dphia=twopi*icos4a(i)/real(NSS)
|
||||
dphib=twopi*icos4b(i)/real(NSS)
|
||||
dphic=twopi*icos4c(i)/real(NSS)
|
||||
dphid=twopi*icos4d(i)/real(NSS)
|
||||
do j=1,NSS
|
||||
csync(k)=cmplx(cos(phi),sin(phi))
|
||||
phi=mod(phi+dphi,twopi)
|
||||
csynca(k)=cmplx(cos(phia),sin(phia))
|
||||
csyncb(k)=cmplx(cos(phib),sin(phib))
|
||||
csyncc(k)=cmplx(cos(phic),sin(phic))
|
||||
csyncd(k)=cmplx(cos(phid),sin(phid))
|
||||
phia=mod(phia+dphia,twopi)
|
||||
phib=mod(phib+dphib,twopi)
|
||||
phic=mod(phic+dphic,twopi)
|
||||
phid=mod(phid+dphid,twopi)
|
||||
k=k+1
|
||||
enddo
|
||||
enddo
|
||||
@ -33,18 +49,45 @@ subroutine sync4d(cd0,i0,ctwk,itwk,sync)
|
||||
fac=1.0/(4.0*NSS)
|
||||
endif
|
||||
|
||||
sync=0
|
||||
i1=i0 !four Costas arrays
|
||||
i2=i0+33*NSS
|
||||
i3=i0+66*NSS
|
||||
i4=i0+99*NSS
|
||||
csync2=csync
|
||||
if(itwk.eq.1) csync2=ctwk*csync2 !Tweak the frequency
|
||||
|
||||
z1=0.
|
||||
z2=0.
|
||||
z3=0.
|
||||
z4=0.
|
||||
|
||||
if(itwk.eq.1) csync2=ctwk*csynca !Tweak the frequency
|
||||
if(i1.ge.0 .and. i1+4*NSS-1.le.NP-1) z1=sum(cd0(i1:i1+4*NSS-1)*conjg(csync2))
|
||||
|
||||
if(itwk.eq.1) csync2=ctwk*csyncb !Tweak the frequency
|
||||
if(i2.ge.0 .and. i2+4*NSS-1.le.NP-1) z2=sum(cd0(i2:i2+4*NSS-1)*conjg(csync2))
|
||||
|
||||
if(itwk.eq.1) csync2=ctwk*csyncc !Tweak the frequency
|
||||
if(i3.ge.0 .and. i3+4*NSS-1.le.NP-1) z3=sum(cd0(i3:i3+4*NSS-1)*conjg(csync2))
|
||||
|
||||
if(itwk.eq.1) csync2=ctwk*csyncd !Tweak the frequency
|
||||
if(i4.ge.0 .and. i4+4*NSS-1.le.NP-1) z4=sum(cd0(i4:i4+4*NSS-1)*conjg(csync2))
|
||||
sync = sync + p(z1) + p(z2) + p(z3) + p(z4)
|
||||
|
||||
sync = p(z1) + p(z2) + p(z3) + p(z4)
|
||||
|
||||
sync2=0.0
|
||||
do i=1,4
|
||||
i1=i0+(i-1)*33*NSS
|
||||
if(i.eq.1) csync2=ctwk*csynca
|
||||
if(i.eq.2) csync2=ctwk*csyncb
|
||||
if(i.eq.3) csync2=ctwk*csyncc
|
||||
if(i.eq.4) csync2=ctwk*csyncd
|
||||
z1=sum(cd0(i1 :i1+ NSS-1)*conjg(csync2( 1: NSS)))
|
||||
z2=sum(cd0(i1+ NSS:i1+2*NSS-1)*conjg(csync2( NSS+1:2*NSS)))
|
||||
z3=sum(cd0(i1+2*NSS:i1+3*NSS-1)*conjg(csync2(2*NSS+1:3*NSS)))
|
||||
z4=sum(cd0(i1+3*NSS:i1+4*NSS-1)*conjg(csync2(3*NSS+1:4*NSS)))
|
||||
sync2=sync2 + abs(z1)**2+abs(z2)**2+abs(z3)**2+abs(z4)**2+&
|
||||
2*abs(z1*conjg(z2)+z2*conjg(z3)+z3*conjg(z4))
|
||||
enddo
|
||||
sync2=sync2*(fac**2)
|
||||
|
||||
return
|
||||
end subroutine sync4d
|
||||
|
@ -163,10 +163,10 @@ extern "C" {
|
||||
|
||||
void chkcall_(char* w, char* basc_call, bool cok, int len1, int len2);
|
||||
|
||||
void ft4_decode_(char* cdatetime, float* tbuf, int* nfa, int* nfb, int* nfqso,
|
||||
short int id[], int* ndecodes, char* mycall6, char* hiscall6,
|
||||
int* nrx, char* line, char* ddir, int len1, int len2, int len3,
|
||||
int len4, int len5);
|
||||
void ft4_decode_(char* cdatetime, float* tbuf, int* nfa, int* nfb, int* nQSOProgress,
|
||||
int* nfqso, short int id[], int* ndecodes, char* mycall6,
|
||||
char* hiscall6, int* nrx, char* line, char* ddir, int len1, int len2,
|
||||
int len3, int len4, int len5);
|
||||
|
||||
void get_ft4msg_(int* idecode, int* nrx, char* line, int len);
|
||||
|
||||
@ -8659,11 +8659,12 @@ void MainWindow::ft4Data(int k)
|
||||
int nrx=-1;
|
||||
int nfa=m_wideGraph->nStartFreq();
|
||||
int nfb=m_wideGraph->Fmax();
|
||||
int nQSOProgress=m_QSOProgress;
|
||||
QString dataDir;
|
||||
dataDir = m_config.writeable_data_dir ().absolutePath ();
|
||||
char ddir[512];
|
||||
strncpy(ddir,dataDir.toLatin1(), sizeof (ddir) - 1);
|
||||
ft4_decode_(cdatetime,&tbuf,&nfa,&nfb,&nfqso,id,&ndecodes,mycall6,hiscall6,
|
||||
ft4_decode_(cdatetime,&tbuf,&nfa,&nfb,&nQSOProgress,&nfqso,id,&ndecodes,mycall6,hiscall6,
|
||||
&nrx,&line[0],&ddir[0],17,6,6,61,512);
|
||||
line[60]=0;
|
||||
// if(ndecodes>0) {
|
||||
|
Loading…
Reference in New Issue
Block a user