2015-12-15 16:24:22 -05:00
|
|
|
subroutine exp_decode65(s3,mrs,mrs2,mrsym,mr2sym,mrprob,mode65,flip, &
|
2015-12-16 16:16:23 -05:00
|
|
|
mycall,hiscall0,hisgrid0,nexp_decode,qual,decoded)
|
2015-11-24 14:49:04 -05:00
|
|
|
|
|
|
|
use packjt
|
|
|
|
use prog_args
|
|
|
|
parameter (NMAX=10000)
|
2015-12-09 16:02:37 -05:00
|
|
|
real s3(64,63)
|
2015-12-15 16:24:22 -05:00
|
|
|
real pp(NMAX),bb(NMAX)
|
2015-11-24 14:49:04 -05:00
|
|
|
integer*1 sym1(0:62,NMAX)
|
2015-12-09 16:02:37 -05:00
|
|
|
integer*1 sym2(0:62,NMAX)
|
|
|
|
integer mrs(63),mrs2(63)
|
2015-12-15 16:24:22 -05:00
|
|
|
integer mrsym(0:62),mr2sym(0:62),mrprob(0:62)
|
2015-11-24 14:49:04 -05:00
|
|
|
integer dgen(12),sym(0:62),sym_rev(0:62)
|
2015-12-15 16:24:22 -05:00
|
|
|
integer test(0:62)
|
2015-12-16 16:16:23 -05:00
|
|
|
character*6 mycall,hiscall0,hisgrid0,hiscall(NMAX)
|
2015-11-24 14:49:04 -05:00
|
|
|
character*4 hisgrid(NMAX)
|
|
|
|
character callsign*12,grid*4
|
|
|
|
character*180 line
|
|
|
|
character ceme*3,msg*22
|
2015-12-09 16:02:37 -05:00
|
|
|
character*22 msg0(1000),decoded
|
2015-11-24 14:49:04 -05:00
|
|
|
logical*1 eme(NMAX)
|
|
|
|
logical first
|
2015-12-15 16:24:22 -05:00
|
|
|
data first/.true./,nn/0/
|
|
|
|
save first,sym1,nused,msg0,sym2,nn
|
2015-11-24 14:49:04 -05:00
|
|
|
|
2015-12-16 16:16:23 -05:00
|
|
|
! print*,mycall,hiscall0,hisgrid0,nexp_decode
|
|
|
|
|
2015-11-24 14:49:04 -05:00
|
|
|
if(first) then
|
|
|
|
neme=1
|
|
|
|
open(23,file=trim(data_dir)//'/CALL3.TXT',status='unknown')
|
|
|
|
icall=0
|
|
|
|
j=0
|
|
|
|
do i=1,NMAX
|
|
|
|
read(23,1002,end=10) line
|
|
|
|
1002 format(a80)
|
|
|
|
if(line(1:4).eq.'ZZZZ') cycle
|
|
|
|
if(line(1:2).eq.'//') cycle
|
|
|
|
i1=index(line,',')
|
|
|
|
if(i1.lt.4) cycle
|
|
|
|
i2=index(line(i1+1:),',')
|
|
|
|
if(i2.lt.5) cycle
|
|
|
|
i2=i2+i1
|
|
|
|
i3=index(line(i2+1:),',')
|
|
|
|
if(i3.lt.1) i3=index(line(i2+1:),' ')
|
|
|
|
i3=i2+i3
|
|
|
|
callsign=line(1:i1-1)
|
|
|
|
grid=line(i1+1:i2-1)
|
|
|
|
ceme=line(i2+1:i3-1)
|
|
|
|
eme(i)=ceme.eq.'EME'
|
|
|
|
if(neme.eq.1 .and. (.not.eme(i))) cycle
|
|
|
|
j=j+1
|
|
|
|
hiscall(j)=callsign(1:6) !### Fix for compound callsigns!
|
|
|
|
hisgrid(j)=grid
|
|
|
|
enddo
|
|
|
|
10 ncalls=j
|
|
|
|
close(23)
|
|
|
|
|
|
|
|
j=0
|
|
|
|
do i=1,ncalls
|
|
|
|
if(neme.eq.1 .and. (.not.eme(i))) cycle
|
2015-12-09 16:02:37 -05:00
|
|
|
|
|
|
|
!### Special for tests ###
|
|
|
|
do isnr=-20,-30,-1
|
|
|
|
j=j+1
|
|
|
|
msg=mycall//' '//hiscall(i)//' '//hisgrid(i)
|
2015-12-15 16:24:22 -05:00
|
|
|
if(isnr.ne.-20) write(msg(14:18),"(i3,' ')") isnr
|
2015-12-09 16:02:37 -05:00
|
|
|
call fmtmsg(msg,iz)
|
|
|
|
call packmsg(msg,dgen,itype) !Pack message into 72 bits
|
|
|
|
call rs_encode(dgen,sym_rev) !RS encode
|
|
|
|
sym(0:62)=sym_rev(62:0:-1)
|
|
|
|
sym1(0:62,j)=sym
|
|
|
|
|
|
|
|
call interleave63(sym_rev,1) !Interleave channel symbols
|
|
|
|
call graycode(sym_rev,63,1,sym_rev) !Apply Gray code
|
|
|
|
sym2(0:62,j)=sym_rev(0:62)
|
|
|
|
msg0(j)=msg
|
|
|
|
enddo
|
|
|
|
|
2015-11-24 14:49:04 -05:00
|
|
|
enddo
|
|
|
|
nused=j
|
|
|
|
first=.false.
|
|
|
|
endif
|
|
|
|
|
2015-12-09 16:02:37 -05:00
|
|
|
ref0=0.
|
|
|
|
do j=1,63
|
|
|
|
ref0=ref0 + s3(mrs(j)+1,j)
|
|
|
|
enddo
|
2015-11-24 14:49:04 -05:00
|
|
|
|
2015-12-09 16:02:37 -05:00
|
|
|
p1=-1.e30
|
|
|
|
p2=-1.e30
|
2015-12-15 16:24:22 -05:00
|
|
|
bb1=1.e30
|
|
|
|
bb2=1.e30
|
|
|
|
|
|
|
|
! Find p1 and p2 (best and second-best) codeword from a list, using
|
|
|
|
! matched filters
|
2015-12-09 16:02:37 -05:00
|
|
|
ip1=1 !Silence compiler warning
|
2015-12-15 16:24:22 -05:00
|
|
|
ip2=1
|
2015-12-09 16:02:37 -05:00
|
|
|
do k=1,nused
|
|
|
|
pp(k)=0.
|
|
|
|
if(k.ge.2 .and. k.le.64 .and. flip.lt.0.0) cycle
|
|
|
|
! Test all messages if flip=+1; skip the CQ messages if flip=-1.
|
|
|
|
if(flip.gt.0.0 .or. msg0(k)(1:3).ne.'CQ ') then
|
2015-12-15 16:24:22 -05:00
|
|
|
psum=0.
|
2015-12-09 16:02:37 -05:00
|
|
|
ref=ref0
|
|
|
|
do j=1,63
|
|
|
|
! i=ncode(j,k)+1
|
|
|
|
i=sym2(j-1,k)+1
|
2015-12-15 16:24:22 -05:00
|
|
|
psum=psum + s3(i,j)
|
2015-12-09 16:02:37 -05:00
|
|
|
if(i.eq.mrs(j)+1) ref=ref - s3(i,j) + s3(mrs2(j)+1,j)
|
|
|
|
enddo
|
2015-12-15 16:24:22 -05:00
|
|
|
p=psum/ref
|
2015-12-09 16:02:37 -05:00
|
|
|
pp(k)=p
|
|
|
|
if(p.gt.p1) then
|
|
|
|
p1=p
|
|
|
|
ip1=k
|
|
|
|
endif
|
2015-11-24 14:49:04 -05:00
|
|
|
endif
|
2015-12-15 16:24:22 -05:00
|
|
|
|
|
|
|
! Find best and second-best codeword using the FT-defined soft distance
|
|
|
|
test=sym1(0:62,k)
|
|
|
|
nh=0
|
|
|
|
ns=0
|
|
|
|
do i=0,62
|
|
|
|
j=62-i
|
|
|
|
if(mrsym(j).ne.test(i)) then
|
|
|
|
nh=nh+1
|
|
|
|
if(mr2sym(j).ne.test(i)) ns=ns+mrprob(j)
|
|
|
|
endif
|
|
|
|
enddo
|
|
|
|
ds=ns*63.0/sum(mrprob)
|
|
|
|
bb(k)=nh+ds
|
|
|
|
|
|
|
|
if(nh+ds.lt.bb1) then
|
|
|
|
nhard=nh
|
|
|
|
dsoft=ds
|
|
|
|
bb1=nh+ds
|
|
|
|
ncandidates=0
|
|
|
|
ntry=0
|
|
|
|
ip2=k
|
|
|
|
endif
|
2015-12-09 16:02:37 -05:00
|
|
|
enddo
|
|
|
|
|
|
|
|
do i=1,nused
|
|
|
|
if(pp(i).gt.p2 .and. pp(i).ne.p1) p2=pp(i)
|
2015-12-15 16:24:22 -05:00
|
|
|
if(bb(i).lt.bb2 .and. bb(i).ne.bb1) bb2=bb(i)
|
2015-11-24 14:49:04 -05:00
|
|
|
enddo
|
|
|
|
|
2015-12-09 16:02:37 -05:00
|
|
|
! ### DO NOT REMOVE ###
|
2015-12-18 15:00:59 -05:00
|
|
|
rewind 77
|
|
|
|
write(77,*) p1,p2
|
|
|
|
call flush(77)
|
|
|
|
! ### Works OK without these three lines (in both Windows and Linux)
|
|
|
|
! ### if compiled without optimization.
|
2015-12-09 16:02:37 -05:00
|
|
|
|
|
|
|
bias=max(1.12*p2,0.335)
|
|
|
|
if(mode65.eq.2) bias=max(1.08*p2,0.405)
|
|
|
|
if(mode65.ge.4) bias=max(1.04*p2,0.505)
|
|
|
|
|
|
|
|
if(p2.eq.p1 .and. p1.ne.-1.e30) stop 'Error in deep65'
|
|
|
|
qual=100.0*(p1-bias)
|
|
|
|
decoded=' '
|
2015-12-15 16:24:22 -05:00
|
|
|
if(bb1.le.110.0) decoded=msg0(ip2)
|
|
|
|
nn=nn+1
|
|
|
|
qual2=110.0-bb1 + 1.0
|
2015-12-09 16:02:37 -05:00
|
|
|
|
2015-11-24 14:49:04 -05:00
|
|
|
return
|
|
|
|
end subroutine exp_decode65
|