Many changes to the JT65 decode chain. This is development code! It

includes an initial implementation of the FTRSD decoder with a "qual"
parameter for evaluation of candidate codewords.  Also includes hinted
decoding.  Further testing is needed.


git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@6278 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
Joe Taylor 2015-12-15 21:24:22 +00:00
parent 295ceef27d
commit a7c6f42ba4
9 changed files with 173 additions and 139 deletions

View File

@ -27,7 +27,7 @@ CFLAGS = -I. -fbounds-check -fPIE
%.o: %.F90 %.o: %.F90
${FC} ${FFLAGS} -c $< ${FC} ${FFLAGS} -c $<
all: libjt9.a jt65 jt65sim all: libjt9.a jt65 jt65sim t3
OBJS1 = astrosub.o astro0.o astro.o sun.o coord.o tmoonsub.o \ OBJS1 = astrosub.o astro0.o astro.o sun.o coord.o tmoonsub.o \
fmtmsg.o deg2grid.o\ fmtmsg.o deg2grid.o\
@ -61,6 +61,14 @@ jt65sim: $(OBJS2) libjt9.a
$(FC) -o jt65sim $(OBJS2) -L. -L/opt/local/lib -ljt9 -lfftw3f $(FC) -o jt65sim $(OBJS2) -L. -L/opt/local/lib -ljt9 -lfftw3f
$(CP) jt65sim $(EXE_DIR) $(CP) jt65sim $(EXE_DIR)
OBJS3 = t3.o
t3: $(OBJS3) libjt9.a
$(FC) -o t3 $(OBJS3) -L. -L/opt/local/lib -ljt9
OBJS6 = jt65code.o
jt65code: $(OBJS6) libjt9.a
$(FC) -o jt65code $(OBJS6) libjt9.a
init_rs.o: init_rs.c init_rs.o: init_rs.c
$(CC) -c -DBIGSYM=1 -o init_rs.o init_rs.c $(CC) -c -DBIGSYM=1 -o init_rs.o init_rs.c

View File

@ -23,8 +23,8 @@ subroutine decode65b(s2,nflip,mode65,ntrials,naggressive,ndepth,nexp_decode, &
enddo enddo
nadd=mode65 nadd=mode65
call extract(s3,nadd,nqd,ntrials,naggressive,ndepth, & call extract(s3,nadd,ntrials,naggressive,ndepth,ncount,nhist,decoded, &
ncount,nhist,decoded,ltext,nft,qual) !Extract the message ltext,nft,qual) !Extract the message
! Suppress "birdie messages" and other garbage decodes: ! Suppress "birdie messages" and other garbage decodes:
if(decoded(1:7).eq.'000AAA ') ncount=-1 if(decoded(1:7).eq.'000AAA ') ncount=-1

View File

@ -1,14 +1,17 @@
subroutine exp_decode65(s3,mrs,mrs2,mode65,flip,mycall,qual,decoded) subroutine exp_decode65(s3,mrs,mrs2,mrsym,mr2sym,mrprob,mode65,flip, &
mycall,qual,decoded)
use packjt use packjt
use prog_args use prog_args
parameter (NMAX=10000) parameter (NMAX=10000)
real s3(64,63) real s3(64,63)
real pp(NMAX) real pp(NMAX),bb(NMAX)
integer*1 sym1(0:62,NMAX) integer*1 sym1(0:62,NMAX)
integer*1 sym2(0:62,NMAX) integer*1 sym2(0:62,NMAX)
integer mrs(63),mrs2(63) integer mrs(63),mrs2(63)
integer mrsym(0:62),mr2sym(0:62),mrprob(0:62)
integer dgen(12),sym(0:62),sym_rev(0:62) integer dgen(12),sym(0:62),sym_rev(0:62)
integer test(0:62)
character*6 mycall,hiscall(NMAX) character*6 mycall,hiscall(NMAX)
character*4 hisgrid(NMAX) character*4 hisgrid(NMAX)
character callsign*12,grid*4 character callsign*12,grid*4
@ -17,8 +20,8 @@ subroutine exp_decode65(s3,mrs,mrs2,mode65,flip,mycall,qual,decoded)
character*22 msg0(1000),decoded character*22 msg0(1000),decoded
logical*1 eme(NMAX) logical*1 eme(NMAX)
logical first logical first
data first/.true./ data first/.true./,nn/0/
save first,sym1,nused,msg0,sym2 save first,sym1,nused,msg0,sym2,nn
if(first) then if(first) then
neme=1 neme=1
@ -58,7 +61,7 @@ subroutine exp_decode65(s3,mrs,mrs2,mode65,flip,mycall,qual,decoded)
do isnr=-20,-30,-1 do isnr=-20,-30,-1
j=j+1 j=j+1
msg=mycall//' '//hiscall(i)//' '//hisgrid(i) msg=mycall//' '//hiscall(i)//' '//hisgrid(i)
write(msg(14:18),"(i3,' ')") isnr if(isnr.ne.-20) write(msg(14:18),"(i3,' ')") isnr
call fmtmsg(msg,iz) call fmtmsg(msg,iz)
call packmsg(msg,dgen,itype) !Pack message into 72 bits call packmsg(msg,dgen,itype) !Pack message into 72 bits
call rs_encode(dgen,sym_rev) !RS encode call rs_encode(dgen,sym_rev) !RS encode
@ -83,40 +86,68 @@ subroutine exp_decode65(s3,mrs,mrs2,mode65,flip,mycall,qual,decoded)
p1=-1.e30 p1=-1.e30
p2=-1.e30 p2=-1.e30
bb1=1.e30
bb2=1.e30
! Find p1 and p2 (best and second-best) codeword from a list, using
! matched filters
ip1=1 !Silence compiler warning ip1=1 !Silence compiler warning
ip2=1
do k=1,nused do k=1,nused
pp(k)=0. pp(k)=0.
if(k.ge.2 .and. k.le.64 .and. flip.lt.0.0) cycle 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. ! 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 if(flip.gt.0.0 .or. msg0(k)(1:3).ne.'CQ ') then
sum=0. psum=0.
ref=ref0 ref=ref0
do j=1,63 do j=1,63
! i=ncode(j,k)+1 ! i=ncode(j,k)+1
i=sym2(j-1,k)+1 i=sym2(j-1,k)+1
sum=sum + s3(i,j) psum=psum + s3(i,j)
if(i.eq.mrs(j)+1) ref=ref - s3(i,j) + s3(mrs2(j)+1,j) if(i.eq.mrs(j)+1) ref=ref - s3(i,j) + s3(mrs2(j)+1,j)
enddo enddo
p=sum/ref p=psum/ref
pp(k)=p pp(k)=p
if(p.gt.p1) then if(p.gt.p1) then
p1=p p1=p
ip1=k ip1=k
endif endif
endif endif
! write(*,3001) k,p,msg0(k)
!3001 format(i5,f10.3,2x,a22) ! 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
enddo enddo
do i=1,nused do i=1,nused
if(pp(i).gt.p2 .and. pp(i).ne.p1) p2=pp(i) if(pp(i).gt.p2 .and. pp(i).ne.p1) p2=pp(i)
if(bb(i).lt.bb2 .and. bb(i).ne.bb1) bb2=bb(i)
enddo enddo
! ### DO NOT REMOVE ### ! ### DO NOT REMOVE ###
! call cs_lock('deep65') ! call cs_lock('deep65')
rewind 77 ! rewind 77
write(77,*) p1,p2 ! write(77,*) p1,p2
call flush(77) ! call flush(77)
! call cs_unlock ! call cs_unlock
! ### Works OK without it (in both Windows and Linux) if compiled ! ### Works OK without it (in both Windows and Linux) if compiled
! ### without optimization. However, in Windows this is a colossal ! ### without optimization. However, in Windows this is a colossal
@ -128,9 +159,10 @@ subroutine exp_decode65(s3,mrs,mrs2,mode65,flip,mycall,qual,decoded)
if(p2.eq.p1 .and. p1.ne.-1.e30) stop 'Error in deep65' if(p2.eq.p1 .and. p1.ne.-1.e30) stop 'Error in deep65'
qual=100.0*(p1-bias) qual=100.0*(p1-bias)
if(qual.lt.0.0) qual=0.0
decoded=' ' decoded=' '
if(qual.ge.1.0) decoded=msg0(ip1) if(bb1.le.110.0) decoded=msg0(ip2)
nn=nn+1
qual2=110.0-bb1 + 1.0
return return
end subroutine exp_decode65 end subroutine exp_decode65

View File

@ -1,5 +1,5 @@
subroutine extract(s3,nadd,nqd,ntrials,naggressive,ndepth, & subroutine extract(s3,nadd,ntrials,naggressive,ndepth,ncount,nhist, &
ncount,nhist,decoded,ltext,nft,qual) decoded,ltext,nft,qual)
! Input: ! Input:
! s3 64-point spectra for each of 63 data symbols ! s3 64-point spectra for each of 63 data symbols
@ -21,15 +21,12 @@ subroutine extract(s3,nadd,nqd,ntrials,naggressive,ndepth, &
character*6 mycall character*6 mycall
integer dat4(12) integer dat4(12)
integer mrsym(63),mr2sym(63),mrprob(63),mr2prob(63) integer mrsym(63),mr2sym(63),mrprob(63),mr2prob(63)
integer mrs(63),mrs2(63)
integer correct(63),tmp(63) integer correct(63),tmp(63)
integer param(0:7) integer param(0:8)
integer indx(0:62) logical ltext
real*8 tt
logical nokv,ltext
common/chansyms65/correct common/chansyms65/correct
common/test000/param !### TEST ONLY ### common/test000/param !### TEST ONLY ###
data nokv/.false./,nsec1/0/ common/test001/s3a(64,63),mrs(63),mrs2(63) !### TEST ONLY ###
save save
qual=0. qual=0.
@ -41,6 +38,8 @@ subroutine extract(s3,nadd,nqd,ntrials,naggressive,ndepth, &
decoded=' ' decoded=' '
call pctile(s3,4032,npct,base) call pctile(s3,4032,npct,base)
s3=s3/base s3=s3/base
s3a=s3 !###
! Get most reliable and second-most-reliable symbol values, and their ! Get most reliable and second-most-reliable symbol values, and their
! probabilities ! probabilities
1 call demod64a(s3,nadd,afac1,mrsym,mrprob,mr2sym,mr2prob,ntest,nlow) 1 call demod64a(s3,nadd,afac1,mrsym,mrprob,mr2sym,mr2prob,ntest,nlow)
@ -70,10 +69,9 @@ subroutine extract(s3,nadd,nqd,ntrials,naggressive,ndepth, &
call interleave63(mr2prob,-1) call interleave63(mr2prob,-1)
ntry=0 ntry=0
nverbose=0
call timer('ftrsd ',0) call timer('ftrsd ',0)
call ftrsd2(mrsym,mrprob,mr2sym,mr2prob,ntrials,nverbose,correct, & param=0
param,indx,tt,ntry) call ftrsd2(mrsym,mrprob,mr2sym,mr2prob,ntrials,correct,param,ntry)
call timer('ftrsd ',1) call timer('ftrsd ',1)
ncandidates=param(0) ncandidates=param(0)
nhard=param(1) nhard=param(1)
@ -81,20 +79,18 @@ subroutine extract(s3,nadd,nqd,ntrials,naggressive,ndepth, &
nerased=param(3) nerased=param(3)
nsofter=param(4) nsofter=param(4)
ntotal=param(5) ntotal=param(5)
qual=0.001*param(7)
qmin=11-naggressive
if(qual.ge.qmin) nft=1
nhard_max=44
nd_a=72 + naggressive
if(nhard.le.nhard_max .and. ntotal.le.nd_a) nft=1
! print*,'AAA',ndepth
if(nft.eq.0 .and. ndepth.ge.5) then if(nft.eq.0 .and. ndepth.ge.5) then
! print*,'BBB',ndepth
call timer('exp_deco',0) call timer('exp_deco',0)
mode65=1 mode65=1
flip=1.0 flip=1.0
mycall='K1ABC' !### TEMPORARY ### mycall='K1ABC' !### TEMPORARY ###
call exp_decode65(s3,mrs,mrs2,mode65,flip,mycall,qual,decoded) call exp_decode65(s3,mrs,mrs2,mrsym,mr2sym,mrprob,mode65,flip, &
if(qual.ge.1.0) then mycall,qual,decoded)
if(qual.ge.qmin) then
nft=2 nft=2
else else
param=0 param=0
@ -108,8 +104,8 @@ subroutine extract(s3,nadd,nqd,ntrials,naggressive,ndepth, &
decoded=' ' decoded=' '
ltext=.false. ltext=.false.
if(nft.gt.0) then if(nft.gt.0) then
!turn the corrected symbol array into channel symbols for subtraction ! Turn the corrected symbol array into channel symbols for subtraction;
!pass it back to jt65a via common block "chansyms65" ! pass it back to jt65a via common block "chansyms65".
do i=1,12 do i=1,12
dat4(i)=correct(13-i) dat4(i)=correct(13-i)
enddo enddo
@ -125,8 +121,34 @@ subroutine extract(s3,nadd,nqd,ntrials,naggressive,ndepth, &
endif endif
900 continue 900 continue
if(nft.eq.1 .and. nhard.lt.0) decoded=' ' if(nft.eq.1 .and. nhard.lt.0) decoded=' '
! write(*,3300) nft,nhard,ntotal,int(qual),decoded
!3300 format(4i5,2x,a22) ! write(71,3300) nft,nhard,ntotal,int(qual),ncount,decoded
!3300 format(5i5,2x,a22)
return return
end subroutine extract end subroutine extract
subroutine getpp(workdat,p)
integer workdat(63)
integer a(63)
common/test001/s3a(64,63),mrs(63),mrs2(63)
a(1:63)=workdat(63:1:-1)
call interleave63(a,1)
call graycode(a,63,1,a)
psum=0.
ref=0.
do j=1,63
i=a(j)+1
x=s3a(i,j)
s3a(i,j)=0.
psum=psum + x
ref=ref + maxval(s3a(1:64,j))
s3a(i,j)=x
enddo
p=psum/ref
return
end subroutine getpp

View File

@ -26,8 +26,8 @@ subroutine fillcom(nutc0,ndepth0,nrxfreq,mode,tx9,flow,fsplit,fhigh)
minsync=-1 !### TEST ONLY minsync=-1 !### TEST ONLY
n2pass=1 n2pass=1
nranera=10 !ntrials=100000 nranera=8 !ntrials=10000
naggressive=3 naggressive=0
nrobust=0 nrobust=0
if (tx9) then if (tx9) then

View File

@ -22,83 +22,36 @@
#include "rs2.h" #include "rs2.h"
static void *rs; static void *rs;
void getpp_(int workdat[], float *pp);
void ftrsd2_(int mrsym[], int mrprob[], int mr2sym[], int mr2prob[], void ftrsd2_(int mrsym[], int mrprob[], int mr2sym[], int mr2prob[],
int* ntrials0, int* verbose0, int correct[], int param[], int* ntrials0, int correct[], int param[], int ntry[])
int indexes[], double tt[], int ntry[])
{ {
int rxdat[63], rxprob[63], rxdat2[63], rxprob2[63]; int rxdat[63], rxprob[63], rxdat2[63], rxprob2[63];
int workdat[63]; int workdat[63];
int indexes[63];
int era_pos[51]; int era_pos[51];
int i, j, numera, nerr, nn=63; int i, j, numera, nerr, nn=63;
FILE *logfile = NULL; FILE *logfile = NULL;
int ntrials = *ntrials0; int ntrials = *ntrials0;
int verbose = *verbose0; int verbose = 0;
int nhard=0,nhard_min=32768,nsoft=0,nsoft_min=32768; int nhard=0,nhard_min=32768,nsoft=0,nsoft_min=32768;
int nsofter=0,nsofter_min=32768,ntotal=0,ntotal_min=32768,ncandidates; int nsofter=0,nsofter_min=32768,ntotal=0,ntotal_min=32768,ncandidates;
int nera_best=0; int nera_best=0;
clock_t t0=0,t1=0; float pp,pp1,pp2,bias;
float qual=0.0;
static unsigned int nseed; static unsigned int nseed;
/* For JT exp(x) symbol metrics - gaussian noise, no fading // Power-percentage symbol metrics - composite gnnf/hf
int perr[8][8] = { int perr[8][8] = {
{12, 31, 44, 52, 60, 57, 50, 50}, { 4, 9, 11, 13, 14, 14, 15, 15},
{28, 38, 49, 58, 65, 69, 64, 80}, { 2, 20, 20, 30, 40, 50, 50, 50},
{40, 41, 53, 62, 66, 73, 76, 81}, { 7, 24, 27, 40, 50, 50, 50, 50},
{50, 53, 53, 64, 70, 76, 77, 81},
{50, 50, 52, 60, 71, 72, 77, 84},
{50, 50, 56, 62, 67, 73, 81, 85},
{50, 50, 71, 62, 70, 77, 80, 85},
{50, 50, 62, 64, 71, 75, 82, 87}};
*/
/* For JT exp(x) symbol metrics - hf conditions
int perr[8][8] = {
{10, 10, 10, 12, 13, 15, 15, 9},
{28, 30, 43, 50, 61, 58, 50, 34},
{40, 40, 50, 53, 70, 65, 58, 45},
{50, 50, 53, 74, 71, 68, 66, 52},
{50, 50, 52, 45, 67, 70, 70, 60},
{50, 50, 56, 73, 55, 74, 69, 67},
{50, 50, 70, 81, 81, 69, 76, 75},
{50, 50, 62, 57, 77, 81, 73, 78}};
*/
// For SF power-percentage symbol metrics - composite gnnf/hf
int perr[8][8] = {
{4, 9, 11, 13, 14, 14, 15, 15},
{2, 20, 20, 30, 40, 50, 50, 50},
{7, 24, 27, 40, 50, 50, 50, 50},
{13, 25, 35, 46, 52, 70, 50, 50}, {13, 25, 35, 46, 52, 70, 50, 50},
{17, 30, 42, 54, 55, 64, 71, 70}, {17, 30, 42, 54, 55, 64, 71, 70},
{25, 39, 48, 57, 64, 66, 77, 77}, {25, 39, 48, 57, 64, 66, 77, 77},
{32, 45, 54, 63, 66, 75, 78, 83}, {32, 45, 54, 63, 66, 75, 78, 83},
{51, 58, 57, 66, 72, 77, 82, 86}}; {51, 58, 57, 66, 72, 77, 82, 86}};
//
/* For SF power-percentage symbol metrics - gaussian noise, no fading
int perr[8][8] = {
{1, 10, 10, 20, 30, 50, 50, 50},
{2, 20, 20, 30, 40, 50, 50, 50},
{7, 24, 27, 40, 50, 50, 50, 50},
{13, 25, 35, 46, 52, 70, 50, 50},
{17, 30, 42, 54, 55, 64, 71, 70},
{25, 39, 48, 57, 64, 66, 77, 77},
{32, 45, 54, 63, 66, 75, 78, 83},
{51, 58, 57, 66, 72, 77, 82, 86}};
*/
/* For SF power-percentage symbol metrics - hf
int perr[8][8] = {
{4, 9, 11, 13, 14, 14, 15, 15},
{9, 12, 14, 25, 28, 30, 50, 50},
{18, 22, 22, 28, 32, 35, 50, 50},
{30, 35, 38, 38, 57, 50, 50, 50},
{43, 46, 45, 53, 50, 64, 70, 50},
{56, 58, 58, 57, 67, 66, 80, 77},
{65, 72, 73, 72, 67, 75, 80, 83},
{70, 74, 73, 70, 75, 77, 80, 86}};
*/
if(verbose) { if(verbose) {
logfile=fopen("/tmp/ftrsd.log","a"); logfile=fopen("/tmp/ftrsd.log","a");
@ -112,7 +65,7 @@ void ftrsd2_(int mrsym[], int mrprob[], int mr2sym[], int mr2prob[],
unsigned int symsize=6, gfpoly=0x43, fcr=3, prim=1, nroots=51; unsigned int symsize=6, gfpoly=0x43, fcr=3, prim=1, nroots=51;
rs=init_rs_int(symsize, gfpoly, fcr, prim, nroots, 0); rs=init_rs_int(symsize, gfpoly, fcr, prim, nroots, 0);
// Reverse the received symbol vector for BM decoder // Reverse the received symbol vectors for BM decoder
for (i=0; i<63; i++) { for (i=0; i<63; i++) {
rxdat[i]=mrsym[62-i]; rxdat[i]=mrsym[62-i];
rxprob[i]=mrprob[62-i]; rxprob[i]=mrprob[62-i];
@ -120,7 +73,7 @@ void ftrsd2_(int mrsym[], int mrprob[], int mr2sym[], int mr2prob[],
rxprob2[i]=mr2prob[62-i]; rxprob2[i]=mr2prob[62-i];
} }
// Sort the mrsym probabilities to find the least reliable symbols // Sort rxprob to find indexes of the least reliable symbols
int k, pass, tmp, nsym=63; int k, pass, tmp, nsym=63;
int probs[63]; int probs[63];
for (i=0; i<63; i++) { for (i=0; i<63; i++) {
@ -146,33 +99,33 @@ void ftrsd2_(int mrsym[], int mrprob[], int mr2sym[], int mr2prob[],
memcpy(workdat,rxdat,sizeof(rxdat)); memcpy(workdat,rxdat,sizeof(rxdat));
nerr=decode_rs_int(rs,workdat,era_pos,numera,1); nerr=decode_rs_int(rs,workdat,era_pos,numera,1);
if( nerr >= 0 ) { if( nerr >= 0 ) {
// Hard-decision decoding succeeded. Save codeword and some parameters.
nhard=0; nhard=0;
for (i=0; i<63; i++) { for (i=0; i<63; i++) {
if( workdat[i] != rxdat[i] ) nhard=nhard+1; if( workdat[i] != rxdat[i] ) nhard=nhard+1;
} }
if(logfile) {
fprintf(logfile,"BM decode nerrors= %3d : \n",nerr);
fclose(logfile);
}
memcpy(correct,workdat,63*sizeof(int)); memcpy(correct,workdat,63*sizeof(int));
param[0]=0; param[0]=0;
param[1]=nhard; param[1]=nhard;
param[2]=0; param[2]=0;
param[3]=0; param[3]=0;
param[4]=0; param[4]=0;
param[5]=0;
param[7]=1000*1000;
ntry[0]=0; ntry[0]=0;
return; return;
} }
/* /*
Hard-decision decoding failed. Try the FT soft-decision method.
Generate random erasure-locator vectors and see if any of them Generate random erasure-locator vectors and see if any of them
decode. This will generate a list of potential codewords. The decode. This will generate a list of "candidate" codewords. The
"soft" distance between each codeword and the received word is soft distance between each candidate codeword and the received
used to decide which codeword is "best". word (or a quality estimator "qual") is used to decide which
candidate codeword is "best".
*/ */
nseed=1; //Seed for random numbers nseed=1; //Seed for random numbers
float ratio; float ratio;
int thresh, nsum; int thresh, nsum;
int thresh0[63]; int thresh0[63];
@ -187,8 +140,10 @@ used to decide which codeword is "best".
jj = (62-i)/8; jj = (62-i)/8;
thresh0[i] = 1.3*perr[ii][jj]; thresh0[i] = 1.3*perr[ii][jj];
} }
if(nsum==0) return; if(nsum<=0) return;
pp1=0.0;
pp2=0.0;
for (k=1; k<=ntrials; k++) { for (k=1; k<=ntrials; k++) {
memset(era_pos,0,51*sizeof(int)); memset(era_pos,0,51*sizeof(int));
memcpy(workdat,rxdat,sizeof(rxdat)); memcpy(workdat,rxdat,sizeof(rxdat));
@ -215,12 +170,11 @@ NB: j is the symbol-vector index of the symbol with rank i.
} }
} }
t0=clock();
nerr=decode_rs_int(rs,workdat,era_pos,numera,0); nerr=decode_rs_int(rs,workdat,era_pos,numera,0);
t1=clock();
tt[0]+=(double)(t1-t0)/CLOCKS_PER_SEC;
if( nerr >= 0 ) { if( nerr >= 0 ) {
// We have a candidate coderowd. Find its hard and soft distance from
// the received word. Also find its quality estimate "qual" from the
// full s3(64,63) array of synchronized symbol spectra.
ncandidates=ncandidates+1; ncandidates=ncandidates+1;
nhard=0; nhard=0;
nsoft=0; nsoft=0;
@ -239,7 +193,11 @@ NB: j is the symbol-vector index of the symbol with rank i.
nsoft=63*nsoft/nsum; nsoft=63*nsoft/nsum;
nsofter=63*nsofter/nsum; nsofter=63*nsofter/nsum;
ntotal=nsoft+nhard; ntotal=nsoft+nhard;
if( ntotal<ntotal_min ) {
getpp_(workdat,&pp);
if(pp>pp1) {
pp2=pp1;
pp1=pp;
nsoft_min=nsoft; nsoft_min=nsoft;
nhard_min=nhard; nhard_min=nhard;
nsofter_min=nsofter; nsofter_min=nsofter;
@ -247,15 +205,19 @@ NB: j is the symbol-vector index of the symbol with rank i.
memcpy(correct,workdat,63*sizeof(int)); memcpy(correct,workdat,63*sizeof(int));
nera_best=numera; nera_best=numera;
ntry[0]=k; ntry[0]=k;
} bias=1.12*pp2;
// if(ntotal_min<72 && nhard_min<42) break; if(bias<0.570) bias=0.570;
if(ntotal_min<76 && nhard_min<44) break; // if(bias<0.335) bias=0.335;
} // if(mode65.eq.2) bias=max(1.08*p2,0.405)
if(k == ntrials) ntry[0]=k; // if(mode65.ge.4) bias=max(1.04*p2,0.505)
qual=100.0*(pp1-bias);
} else {
if(pp>pp2 && pp!=pp1) pp2=pp;
} }
if( ntotal_min>=76 || nhard_min>=44 ) { if(qual>10.0 && ncandidates>=100) break;
nhard_min=-1; }
if(k == ntrials) ntry[0]=k;
} }
if(logfile) { if(logfile) {
@ -269,6 +231,9 @@ NB: j is the symbol-vector index of the symbol with rank i.
param[2]=nsoft_min; param[2]=nsoft_min;
param[3]=nera_best; param[3]=nera_best;
param[4]=nsofter_min; param[4]=nsofter_min;
param[5]=ntotal_min;
param[6]=ntry[0];
param[7]=1000.0*qual;
if(param[0]==0) param[2]=-1; if(param[0]==0) param[2]=-1;
return; return;
} }

View File

@ -28,7 +28,7 @@ subroutine jt65a(dd0,npts,newdat,nutc,nf1,nf2,nfqso,ntol,nsubmode, &
common/decstats/ntry65a,ntry65b,n65a,n65b,num9,numfano common/decstats/ntry65a,ntry65b,n65a,n65b,num9,numfano
common/steve/thresh0 common/steve/thresh0
common/test000/ncandidates,nhard_min,nsoft_min,nera_best,nsofter_min, & common/test000/ncandidates,nhard_min,nsoft_min,nera_best,nsofter_min, &
ntotal_min,ntry !### TEST ONLY ### ntotal_min,ntry,nq1000,ntot !### TEST ONLY ###
save save
dd=dd0 dd=dd0
@ -84,6 +84,7 @@ subroutine jt65a(dd0,npts,newdat,nutc,nf1,nf2,nfqso,ntol,nsubmode, &
nflip=1 !### temporary ### nflip=1 !### temporary ###
nqd=0 nqd=0
decoded0="" decoded0=""
freq0=0.
do icand=1,ncand do icand=1,ncand
freq=ca(icand)%freq freq=ca(icand)%freq
@ -95,7 +96,8 @@ subroutine jt65a(dd0,npts,newdat,nutc,nf1,nf2,nfqso,ntol,nsubmode, &
call decode65a(dd,npts,newdat,nqd,freq,nflip,mode65,nvec, & call decode65a(dd,npts,newdat,nqd,freq,nflip,mode65,nvec, &
naggressive,ndepth,nexp_decode,sync2,a,dtx,nft,qual,nhist,decoded) naggressive,ndepth,nexp_decode,sync2,a,dtx,nft,qual,nhist,decoded)
call timer('decod65a',1) call timer('decod65a',1)
if(decoded.eq.decoded0 .and. minsync.ge.0) cycle !Don't display dupes if(decoded.eq.decoded0 .and. abs(freq-freq0).lt. 3.0 .and. &
minsync.ge.0) cycle !Don't display dupes
if(decoded.ne.' ' .or. minsync.lt.0) then if(decoded.ne.' ' .or. minsync.lt.0) then
if( nsubtract .eq. 1 ) then if( nsubtract .eq. 1 ) then
call timer('subtr65 ',0) call timer('subtr65 ',0)
@ -127,7 +129,7 @@ subroutine jt65a(dd0,npts,newdat,nutc,nf1,nf2,nfqso,ntol,nsubmode, &
dec(ndecoded)%sync=sync2 dec(ndecoded)%sync=sync2
dec(ndecoded)%decoded=decoded dec(ndecoded)%decoded=decoded
nqual=qual nqual=qual
if(nqual.gt.10) nqual=10 ! if(nqual.gt.10) nqual=10
write(*,1010) nutc,nsnr,dtx-1.0,nfreq,decoded write(*,1010) nutc,nsnr,dtx-1.0,nfreq,decoded
1010 format(i4.4,i4,f5.1,i5,1x,'#',1x,a22) 1010 format(i4.4,i4,f5.1,i5,1x,'#',1x,a22)
write(13,1012) nutc,nint(sync1),nsnr,dtx-1.0,float(nfreq),ndrift, & write(13,1012) nutc,nint(sync1),nsnr,dtx-1.0,float(nfreq),ndrift, &
@ -135,12 +137,14 @@ subroutine jt65a(dd0,npts,newdat,nutc,nf1,nf2,nfqso,ntol,nsubmode, &
1012 format(i4.4,i4,i5,f6.1,f8.0,i4,3x,a22,' JT65',i4) 1012 format(i4.4,i4,i5,f6.1,f8.0,i4,3x,a22,' JT65',i4)
call flush(6) call flush(6)
call flush(13) call flush(13)
write(79,3001) nutc,nint(sync1),nsnr,dtx-1.0,nfreq,ncandidates, & ! write(79,3001) nutc,nint(sync1),nsnr,dtx-1.0,nfreq,ncandidates, &
nhard_min,ntotal_min,ntry,naggressive,nft,nqual,decoded ! nhard_min,ntotal_min,ntry,naggressive,nft,nqual,ntry0, &
3001 format(i4.4,i3,i4,f6.2,i5,i6,i3,i4,i8,i3,i2,i3,1x,a22) ! ntot,decoded(1:16)
flush(79) !3001 format(i4.4,i3,i4,f6.2,i5,i7,i3,i4,i8,i3,i2,i5,i5,i4,1x,a16)
! flush(79)
endif endif
decoded0=decoded decoded0=decoded
freq0=freq
if(decoded0.eq.' ') decoded0='*' if(decoded0.eq.' ') decoded0='*'
!$omp end critical(decode_results) !$omp end critical(decode_results)
endif endif

View File

@ -140,13 +140,16 @@ program jt65sim
if(csubmode.eq.'B' .and. snrdb.eq.0.0) xsnr=-21 - isig if(csubmode.eq.'B' .and. snrdb.eq.0.0) xsnr=-21 - isig
if(csubmode.eq.'C' .and. snrdb.eq.0.0) xsnr=-21 - isig if(csubmode.eq.'C' .and. snrdb.eq.0.0) xsnr=-21 - isig
call1="K1ABC" !###
ic3=65+mod(isig-1,26) ! call1="K1ABC"
ic2=65+mod((isig-1)/26,26) ! ic3=65+mod(isig-1,26)
ic1=65 ! ic2=65+mod((isig-1)/26,26)
call2="W9"//char(ic1)//char(ic2)//char(ic3) ! ic1=65
write(msg,1010) call1,call2,nint(xsnr) ! call2="W9"//char(ic1)//char(ic2)//char(ic3)
1010 format(a5,1x,a5,1x,i3.2) ! write(msg,1010) call1,call2,nint(xsnr)
!1010 format(a5,1x,a5,1x,i3.2)
msg="K1ABC W9XYZ EN37"
!###
call packmsg(msg,dgen,itype) !Pack message into 12 six-bit bytes call packmsg(msg,dgen,itype) !Pack message into 12 six-bit bytes
call rs_encode(dgen,sent) !Encode using RS(63,12) call rs_encode(dgen,sent) !Encode using RS(63,12)

View File

@ -46,9 +46,9 @@ subroutine sync65(ss,nfa,nfb,nhsym,ca,ncand,nrobust)
itry=1 itry=1
ncand=ncand+1 ncand=ncand+1
endif endif
! write(79,1010) i,freq,ccfred(i),itry,ncand ! write(76,1010) i,freq,ccfred(i),itry,ncand
!1010 format(i6,2f10.2,i5,i6) !1010 format(i6,2f10.2,i5,i6)
! flush(79) ! flush(76)
if(itry.ne.0) then if(itry.ne.0) then
call xcor(ss,i,nhsym,nsym,lag1,lag2,ccfblue,ccf0,lagpk,flip,fdot,nrobust) call xcor(ss,i,nhsym,nsym,lag1,lag2,ccfblue,ccf0,lagpk,flip,fdot,nrobust)
call slope(ccfblue(lag1),lag2-lag1+1,lagpk-lag1+1.0) call slope(ccfblue(lag1),lag2-lag1+1,lagpk-lag1+1.0)