mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-25 21:58:38 -05:00
Remove some test code.
git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@8245 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
parent
d69564242e
commit
2620401b4b
@ -336,7 +336,6 @@ set (wsjt_FSRCS
|
|||||||
# put module sources first in the hope that they get rebuilt before use
|
# put module sources first in the hope that they get rebuilt before use
|
||||||
lib/crc.f90
|
lib/crc.f90
|
||||||
lib/fftw3mod.f90
|
lib/fftw3mod.f90
|
||||||
lib/fsk4hf/gf64math.f90
|
|
||||||
lib/hashing.f90
|
lib/hashing.f90
|
||||||
lib/iso_c_utilities.f90
|
lib/iso_c_utilities.f90
|
||||||
lib/jt4.f90
|
lib/jt4.f90
|
||||||
@ -412,7 +411,7 @@ set (wsjt_FSRCS
|
|||||||
lib/fsk4hf/encode300.f90
|
lib/fsk4hf/encode300.f90
|
||||||
lib/entail.f90
|
lib/entail.f90
|
||||||
lib/ephem.f90
|
lib/ephem.f90
|
||||||
lib/fsk4hf/extract_ap.f90
|
lib/extract.f90
|
||||||
lib/extract4.f90
|
lib/extract4.f90
|
||||||
lib/extractmessage144.f90
|
lib/extractmessage144.f90
|
||||||
lib/fsk4hf/extractmessage168.f90
|
lib/fsk4hf/extractmessage168.f90
|
||||||
@ -516,7 +515,6 @@ set (wsjt_FSRCS
|
|||||||
lib/mskrtd.f90
|
lib/mskrtd.f90
|
||||||
lib/fsk4hf/msksoftsym.f90
|
lib/fsk4hf/msksoftsym.f90
|
||||||
lib/fsk4hf/msksoftsymw.f90
|
lib/fsk4hf/msksoftsymw.f90
|
||||||
lib/fsk4hf/gf64_osd.f90
|
|
||||||
lib/ft8/osd174.f90
|
lib/ft8/osd174.f90
|
||||||
lib/fsk4hf/osd300.f90
|
lib/fsk4hf/osd300.f90
|
||||||
lib/pctile.f90
|
lib/pctile.f90
|
||||||
@ -607,7 +605,7 @@ set (qra_CSRCS
|
|||||||
|
|
||||||
set (wsjt_CSRCS
|
set (wsjt_CSRCS
|
||||||
${ka9q_CSRCS}
|
${ka9q_CSRCS}
|
||||||
lib/fsk4hf/ftrsdap.c
|
lib/ftrsd/ftrsd2.c
|
||||||
lib/sgran.c
|
lib/sgran.c
|
||||||
lib/golay24_table.c
|
lib/golay24_table.c
|
||||||
lib/gran.c
|
lib/gran.c
|
||||||
@ -1161,9 +1159,6 @@ target_link_libraries (wsjt_qtmm Qt5::Multimedia)
|
|||||||
add_executable (jt4sim lib/jt4sim.f90 wsjtx.rc)
|
add_executable (jt4sim lib/jt4sim.f90 wsjtx.rc)
|
||||||
target_link_libraries (jt4sim wsjt_fort wsjt_cxx)
|
target_link_libraries (jt4sim wsjt_fort wsjt_cxx)
|
||||||
|
|
||||||
add_executable (jt65osdtest lib/fsk4hf/jt65osdtest.f90 wsjtx.rc)
|
|
||||||
target_link_libraries (jt65osdtest wsjt_fort wsjt_cxx)
|
|
||||||
|
|
||||||
add_executable (jt65sim lib/jt65sim.f90 wsjtx.rc)
|
add_executable (jt65sim lib/jt65sim.f90 wsjtx.rc)
|
||||||
target_link_libraries (jt65sim wsjt_fort wsjt_cxx)
|
target_link_libraries (jt65sim wsjt_fort wsjt_cxx)
|
||||||
|
|
||||||
|
@ -21,9 +21,7 @@ subroutine decode65b(s2,nflip,nadd,mode65,ntrials,naggressive,ndepth, &
|
|||||||
enddo
|
enddo
|
||||||
|
|
||||||
call extract(s3,nadd,mode65,ntrials,naggressive,ndepth,nflip,mycall, &
|
call extract(s3,nadd,mode65,ntrials,naggressive,ndepth,nflip,mycall, &
|
||||||
hiscall,hisgrid,nQSOProgress,ljt65apon,nexp_decode,ncount, &
|
hiscall,hisgrid,nexp_decode,ncount,nhist,decoded,ltext,nft,qual)
|
||||||
nhist,decoded, &
|
|
||||||
ltext,nft,qual)
|
|
||||||
|
|
||||||
! 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
|
||||||
|
@ -1,188 +0,0 @@
|
|||||||
subroutine extract(s3,nadd,mode65,ntrials,naggressive,ndepth,nflip, &
|
|
||||||
mycall_12,hiscall_12,hisgrid,nQSOProgress,ljt65apon, &
|
|
||||||
nexp_decode,ncount, &
|
|
||||||
nhist,decoded,ltext,nft,qual)
|
|
||||||
|
|
||||||
! Input:
|
|
||||||
! s3 64-point spectra for each of 63 data symbols
|
|
||||||
! nadd number of spectra summed into s3
|
|
||||||
! nqd 0/1 to indicate decode attempt at QSO frequency
|
|
||||||
|
|
||||||
! Output:
|
|
||||||
! ncount number of symbols requiring correction (-1 for no KV decode)
|
|
||||||
! nhist maximum number of identical symbol values
|
|
||||||
! decoded decoded message (if ncount >=0)
|
|
||||||
! ltext true if decoded message is free text
|
|
||||||
! nft 0=no decode; 1=FT decode; 2=hinted decode
|
|
||||||
|
|
||||||
use prog_args !shm_key, exe_dir, data_dir
|
|
||||||
use packjt
|
|
||||||
use jt65_mod
|
|
||||||
use timer_module, only: timer
|
|
||||||
|
|
||||||
real s3(64,63)
|
|
||||||
character decoded*22, apmessage*22
|
|
||||||
character*12 mycall_12,hiscall_12
|
|
||||||
character*6 mycall,hiscall,hisgrid
|
|
||||||
integer apsymbols(12),ap(12)
|
|
||||||
integer dat4(12)
|
|
||||||
integer mrsym(63),mr2sym(63),mrprob(63),mr2prob(63)
|
|
||||||
integer correct(63),tmp(63)
|
|
||||||
logical ltext,ljt65apon
|
|
||||||
common/chansyms65/correct
|
|
||||||
save
|
|
||||||
if(mode65.eq.-99) stop !Silence compiler warning
|
|
||||||
mycall=mycall_12(1:6)
|
|
||||||
hiscall=hiscall_12(1:6)
|
|
||||||
|
|
||||||
apsymbols=-1
|
|
||||||
if(ljt65apon) then
|
|
||||||
apmessage=mycall//" "//hiscall//" RRR"
|
|
||||||
call packmsg(apmessage,apsymbols,itype,.false.)
|
|
||||||
if(itype.ne.1) then
|
|
||||||
write(*,*) "Error - problem with apsymbols"
|
|
||||||
apsymbols=-1
|
|
||||||
endif
|
|
||||||
if(nQSOProgress.eq.0) then ! Look for MyCall ??? ??? using APS4
|
|
||||||
apsymbols(5:12)=-1
|
|
||||||
elseif(nQSOProgress.ge.1.and.nQSOProgress.le.2) then ! Look for MyCall DxCall ???
|
|
||||||
apsymbols(10:12)=-1
|
|
||||||
elseif(nQSOProgress.ge.3) then
|
|
||||||
continue
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
qual=0.
|
|
||||||
nbirdie=20
|
|
||||||
npct=50
|
|
||||||
afac1=1.1
|
|
||||||
nft=0
|
|
||||||
nfail=0
|
|
||||||
decoded=' '
|
|
||||||
call pctile(s3,4032,npct,base)
|
|
||||||
s3=s3/base
|
|
||||||
s3a=s3 !###
|
|
||||||
|
|
||||||
! Get most reliable and second-most-reliable symbol values, and their
|
|
||||||
! probabilities
|
|
||||||
1 call demod64a(s3,nadd,afac1,mrsym,mrprob,mr2sym,mr2prob,ntest,nlow)
|
|
||||||
|
|
||||||
call chkhist(mrsym,nhist,ipk) !Test for birdies and QRM
|
|
||||||
if(nhist.ge.nbirdie) then
|
|
||||||
nfail=nfail+1
|
|
||||||
call pctile(s3,4032,npct,base)
|
|
||||||
s3(ipk,1:63)=base
|
|
||||||
if(nfail.gt.30) then
|
|
||||||
decoded=' '
|
|
||||||
ncount=-1
|
|
||||||
go to 900
|
|
||||||
endif
|
|
||||||
go to 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
mrs=mrsym
|
|
||||||
mrs2=mr2sym
|
|
||||||
|
|
||||||
call graycode65(mrsym,63,-1) !Remove gray code
|
|
||||||
call interleave63(mrsym,-1) !Remove interleaving
|
|
||||||
call interleave63(mrprob,-1)
|
|
||||||
|
|
||||||
call graycode65(mr2sym,63,-1) !Remove gray code and interleaving
|
|
||||||
call interleave63(mr2sym,-1) !from second-most-reliable symbols
|
|
||||||
call interleave63(mr2prob,-1)
|
|
||||||
|
|
||||||
do ipass=1,2
|
|
||||||
ap=-1
|
|
||||||
if(ipass.eq.2 .and. count(apsymbols.ge.0).gt.0) then
|
|
||||||
ap=apsymbols
|
|
||||||
endif
|
|
||||||
ntry=0
|
|
||||||
call timer('ftrsd ',0)
|
|
||||||
param=0
|
|
||||||
call ftrsdap(mrsym,mrprob,mr2sym,mr2prob,ap,ntrials,correct,param,ntry)
|
|
||||||
call timer('ftrsd ',1)
|
|
||||||
ncandidates=param(0)
|
|
||||||
nhard=param(1)
|
|
||||||
nsoft=param(2)
|
|
||||||
nerased=param(3)
|
|
||||||
rtt=0.001*param(4)
|
|
||||||
ntotal=param(5)
|
|
||||||
qual=0.001*param(7)
|
|
||||||
nd0=81
|
|
||||||
r0=0.87
|
|
||||||
if(naggressive.eq.10) then
|
|
||||||
nd0=83
|
|
||||||
r0=0.90
|
|
||||||
endif
|
|
||||||
|
|
||||||
if(ntotal.le.nd0 .and. rtt.le.r0) then
|
|
||||||
nft=1
|
|
||||||
nap=count(ap.ge.0)
|
|
||||||
nft=1+ishft(nap,2)
|
|
||||||
endif
|
|
||||||
|
|
||||||
if(nft.gt.0) exit
|
|
||||||
enddo
|
|
||||||
|
|
||||||
if(nft.eq.0 .and. iand(ndepth,32).eq.32) then
|
|
||||||
qmin=2.0 - 0.1*naggressive
|
|
||||||
call timer('hint65 ',0)
|
|
||||||
call hint65(s3,mrs,mrs2,nadd,nflip,mycall,hiscall,hisgrid,qual,decoded)
|
|
||||||
if(qual.ge.qmin) then
|
|
||||||
nft=2
|
|
||||||
ncount=0
|
|
||||||
else
|
|
||||||
decoded=' '
|
|
||||||
ntry=0
|
|
||||||
endif
|
|
||||||
call timer('hint65 ',1)
|
|
||||||
go to 900
|
|
||||||
endif
|
|
||||||
|
|
||||||
ncount=-1
|
|
||||||
decoded=' '
|
|
||||||
ltext=.false.
|
|
||||||
if(nft.gt.0) then
|
|
||||||
! Turn the corrected symbol array into channel symbols for subtraction;
|
|
||||||
! pass it back to jt65a via common block "chansyms65".
|
|
||||||
do i=1,12
|
|
||||||
dat4(i)=correct(13-i)
|
|
||||||
enddo
|
|
||||||
do i=1,63
|
|
||||||
tmp(i)=correct(64-i)
|
|
||||||
enddo
|
|
||||||
correct(1:63)=tmp(1:63)
|
|
||||||
call interleave63(correct,63,1)
|
|
||||||
call graycode65(correct,63,1)
|
|
||||||
call unpackmsg(dat4,decoded,.false.,' ') !Unpack the user message
|
|
||||||
ncount=0
|
|
||||||
if(iand(dat4(10),8).ne.0) ltext=.true.
|
|
||||||
endif
|
|
||||||
900 continue
|
|
||||||
if(nft.eq.1 .and. nhard.lt.0) decoded=' '
|
|
||||||
|
|
||||||
return
|
|
||||||
end subroutine extract
|
|
||||||
|
|
||||||
subroutine getpp(workdat,p)
|
|
||||||
|
|
||||||
use jt65_mod
|
|
||||||
integer workdat(63)
|
|
||||||
integer a(63)
|
|
||||||
|
|
||||||
a(1:63)=workdat(63:1:-1)
|
|
||||||
call interleave63(a,1)
|
|
||||||
call graycode(a,63,1,a)
|
|
||||||
|
|
||||||
psum=0.
|
|
||||||
do j=1,63
|
|
||||||
i=a(j)+1
|
|
||||||
x=s3a(i,j)
|
|
||||||
s3a(i,j)=0.
|
|
||||||
psum=psum + x
|
|
||||||
s3a(i,j)=x
|
|
||||||
enddo
|
|
||||||
p=psum/63.0
|
|
||||||
|
|
||||||
return
|
|
||||||
end subroutine getpp
|
|
@ -1,227 +0,0 @@
|
|||||||
/*
|
|
||||||
ftrsdap.c
|
|
||||||
|
|
||||||
A soft-decision decoder for the JT65 (63,12) Reed-Solomon code.
|
|
||||||
|
|
||||||
This decoding scheme is built around Phil Karn's Berlekamp-Massey
|
|
||||||
errors and erasures decoder. The approach is inspired by a number of
|
|
||||||
publications, including the stochastic Chase decoder described
|
|
||||||
in "Stochastic Chase Decoding of Reed-Solomon Codes", by Leroux et al.,
|
|
||||||
IEEE Communications Letters, Vol. 14, No. 9, September 2010 and
|
|
||||||
"Soft-Decision Decoding of Reed-Solomon Codes Using Successive Error-
|
|
||||||
and-Erasure Decoding," by Soo-Woong Lee and B. V. K. Vijaya Kumar.
|
|
||||||
|
|
||||||
Steve Franke K9AN and Joe Taylor K1JT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "../ftrsd/rs2.h"
|
|
||||||
|
|
||||||
static void *rs;
|
|
||||||
void getpp_(int workdat[], float *pp);
|
|
||||||
|
|
||||||
void ftrsdap_(int mrsym[], int mrprob[], int mr2sym[], int mr2prob[],
|
|
||||||
int ap[], int* ntrials0, int correct[], int param[], int ntry[])
|
|
||||||
{
|
|
||||||
int rxdat[63], rxprob[63], rxdat2[63], rxprob2[63];
|
|
||||||
int workdat[63];
|
|
||||||
int indexes[63];
|
|
||||||
int era_pos[51];
|
|
||||||
int i, j, numera, nerr, nn=63;
|
|
||||||
int ntrials = *ntrials0;
|
|
||||||
int nhard=0,nhard_min=32768,nsoft=0,nsoft_min=32768;
|
|
||||||
int ntotal=0,ntotal_min=32768,ncandidates;
|
|
||||||
int nera_best=0;
|
|
||||||
float pp,pp1,pp2;
|
|
||||||
static unsigned int nseed;
|
|
||||||
|
|
||||||
// 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},
|
|
||||||
{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}};
|
|
||||||
|
|
||||||
|
|
||||||
// Initialize the KA9Q Reed-Solomon encoder/decoder
|
|
||||||
unsigned int symsize=6, gfpoly=0x43, fcr=3, prim=1, nroots=51;
|
|
||||||
rs=init_rs_int(symsize, gfpoly, fcr, prim, nroots, 0);
|
|
||||||
|
|
||||||
// Reverse the received symbol vectors for BM decoder
|
|
||||||
for (i=0; i<63; i++) {
|
|
||||||
rxdat[i]=mrsym[62-i];
|
|
||||||
rxprob[i]=mrprob[62-i];
|
|
||||||
rxdat2[i]=mr2sym[62-i];
|
|
||||||
rxprob2[i]=mr2prob[62-i];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set ap symbols and ap mask
|
|
||||||
for (i=0; i<12; i++) {
|
|
||||||
if(ap[i]>=0) {
|
|
||||||
rxdat[11-i]=ap[i];
|
|
||||||
rxprob2[11-i]=-1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort rxprob to find indexes of the least reliable symbols
|
|
||||||
int k, pass, tmp, nsym=63;
|
|
||||||
int probs[63];
|
|
||||||
for (i=0; i<63; i++) {
|
|
||||||
indexes[i]=i;
|
|
||||||
probs[i]=rxprob[i];
|
|
||||||
}
|
|
||||||
for (pass = 1; pass <= nsym-1; pass++) {
|
|
||||||
for (k = 0; k < nsym - pass; k++) {
|
|
||||||
if( probs[k] < probs[k+1] ) {
|
|
||||||
tmp = probs[k];
|
|
||||||
probs[k] = probs[k+1];
|
|
||||||
probs[k+1] = tmp;
|
|
||||||
tmp = indexes[k];
|
|
||||||
indexes[k] = indexes[k+1];
|
|
||||||
indexes[k+1] = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// See if we can decode using BM HDD, and calculate the syndrome vector.
|
|
||||||
memset(era_pos,0,51*sizeof(int));
|
|
||||||
numera=0;
|
|
||||||
memcpy(workdat,rxdat,sizeof(rxdat));
|
|
||||||
nerr=decode_rs_int(rs,workdat,era_pos,numera,1);
|
|
||||||
if( nerr >= 0 ) {
|
|
||||||
// Hard-decision decoding succeeded. Save codeword and some parameters.
|
|
||||||
nhard=0;
|
|
||||||
for (i=0; i<63; i++) {
|
|
||||||
if( workdat[i] != rxdat[i] ) nhard=nhard+1;
|
|
||||||
}
|
|
||||||
memcpy(correct,workdat,63*sizeof(int));
|
|
||||||
param[0]=0;
|
|
||||||
param[1]=nhard;
|
|
||||||
param[2]=0;
|
|
||||||
param[3]=0;
|
|
||||||
param[4]=0;
|
|
||||||
param[5]=0;
|
|
||||||
param[7]=1000*1000;
|
|
||||||
ntry[0]=0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Hard-decision decoding failed. Try the FT soft-decision method.
|
|
||||||
Generate random erasure-locator vectors and see if any of them
|
|
||||||
decode. This will generate a list of "candidate" codewords. The
|
|
||||||
soft distance between each candidate codeword and the received
|
|
||||||
word is estimated by finding the largest (pp1) and second-largest
|
|
||||||
(pp2) outputs from a synchronized filter-bank operating on the
|
|
||||||
symbol spectra, and using these to decide which candidate
|
|
||||||
codeword is "best".
|
|
||||||
*/
|
|
||||||
|
|
||||||
nseed=1; //Seed for random numbers
|
|
||||||
float ratio;
|
|
||||||
int thresh, nsum;
|
|
||||||
int thresh0[63];
|
|
||||||
ncandidates=0;
|
|
||||||
nsum=0;
|
|
||||||
int ii,jj;
|
|
||||||
for (i=0; i<nn; i++) {
|
|
||||||
nsum=nsum+rxprob[i];
|
|
||||||
j = indexes[62-i];
|
|
||||||
if( rxprob2[j]>=0 ) {
|
|
||||||
ratio = (float)rxprob2[j]/((float)rxprob[j]+0.01);
|
|
||||||
ii = 7.999*ratio;
|
|
||||||
jj = (62-i)/8;
|
|
||||||
thresh0[i] = 1.3*perr[ii][jj];
|
|
||||||
} else {
|
|
||||||
thresh0[i] = 0.0;
|
|
||||||
}
|
|
||||||
//printf("%d %d %d\n",i,j,rxdat[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(nsum<=0) return;
|
|
||||||
|
|
||||||
pp1=0.0;
|
|
||||||
pp2=0.0;
|
|
||||||
for (k=1; k<=ntrials; k++) {
|
|
||||||
memset(era_pos,0,51*sizeof(int));
|
|
||||||
memcpy(workdat,rxdat,sizeof(rxdat));
|
|
||||||
|
|
||||||
/*
|
|
||||||
Mark a subset of the symbols as erasures.
|
|
||||||
Run through the ranked symbols, starting with the worst, i=0.
|
|
||||||
NB: j is the symbol-vector index of the symbol with rank i.
|
|
||||||
*/
|
|
||||||
numera=0;
|
|
||||||
for (i=0; i<nn; i++) {
|
|
||||||
j = indexes[62-i];
|
|
||||||
thresh=thresh0[i];
|
|
||||||
long int ir;
|
|
||||||
|
|
||||||
// Generate a random number ir, 0 <= ir < 100 (see POSIX.1-2001 example).
|
|
||||||
nseed = nseed * 1103515245 + 12345;
|
|
||||||
ir = (unsigned)(nseed/65536) % 32768;
|
|
||||||
ir = (100*ir)/32768;
|
|
||||||
|
|
||||||
if((ir < thresh ) && numera < 51) {
|
|
||||||
era_pos[numera]=j;
|
|
||||||
numera=numera+1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nerr=decode_rs_int(rs,workdat,era_pos,numera,0);
|
|
||||||
if( nerr >= 0 ) {
|
|
||||||
// We have a candidate codeword. Find its hard and soft distance from
|
|
||||||
// the received word. Also find pp1 and pp2 from the full array
|
|
||||||
// s3(64,63) of synchronized symbol spectra.
|
|
||||||
ncandidates=ncandidates+1;
|
|
||||||
nhard=0;
|
|
||||||
nsoft=0;
|
|
||||||
for (i=0; i<63; i++) {
|
|
||||||
if(workdat[i] != rxdat[i]) {
|
|
||||||
nhard=nhard+1;
|
|
||||||
if(workdat[i] != rxdat2[i]) {
|
|
||||||
nsoft=nsoft+rxprob[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nsoft=63*nsoft/nsum;
|
|
||||||
ntotal=nsoft+nhard;
|
|
||||||
|
|
||||||
getpp_(workdat,&pp);
|
|
||||||
if(pp>pp1) {
|
|
||||||
pp2=pp1;
|
|
||||||
pp1=pp;
|
|
||||||
nsoft_min=nsoft;
|
|
||||||
nhard_min=nhard;
|
|
||||||
ntotal_min=ntotal;
|
|
||||||
memcpy(correct,workdat,63*sizeof(int));
|
|
||||||
nera_best=numera;
|
|
||||||
ntry[0]=k;
|
|
||||||
} else {
|
|
||||||
if(pp>pp2 && pp!=pp1) pp2=pp;
|
|
||||||
}
|
|
||||||
if(nhard_min <= 41 && ntotal_min <= 71) break;
|
|
||||||
}
|
|
||||||
if(k == ntrials) ntry[0]=k;
|
|
||||||
}
|
|
||||||
|
|
||||||
param[0]=ncandidates;
|
|
||||||
param[1]=nhard_min;
|
|
||||||
param[2]=nsoft_min;
|
|
||||||
param[3]=nera_best;
|
|
||||||
param[4]=1000.0*pp2/pp1;
|
|
||||||
param[5]=ntotal_min;
|
|
||||||
param[6]=ntry[0];
|
|
||||||
param[7]=1000.0*pp2;
|
|
||||||
param[8]=1000.0*pp1;
|
|
||||||
if(param[0]==0) param[2]=-1;
|
|
||||||
return;
|
|
||||||
}
|
|
@ -1,142 +0,0 @@
|
|||||||
subroutine gf64_osd(s3,cw)
|
|
||||||
use jt65_generator_matrix
|
|
||||||
|
|
||||||
real s3(64,63),xtmp(64),sympow_sorted(64,63),sympow(64,63)
|
|
||||||
integer ideinterleave_indices(63),indxs(64),isymval_sorted(64,63),isymval(64,63)
|
|
||||||
integer cw(63)
|
|
||||||
integer indx(63)
|
|
||||||
integer gmrb(12,63)
|
|
||||||
integer correct(63)
|
|
||||||
integer correctr(63)
|
|
||||||
integer correct_sorted(63)
|
|
||||||
integer candidate(63)
|
|
||||||
integer candidater(63)
|
|
||||||
integer itmp(63)
|
|
||||||
logical mask(63),first
|
|
||||||
data correct/ & ! K1ABC W9XYZ EN37
|
|
||||||
41, 0, 54, 46, 55, 29, 57, 35, 35, 48, 48, 61, &
|
|
||||||
21, 58, 25, 10, 50, 43, 28, 37, 10, 2, 61, 55, &
|
|
||||||
25, 5, 5, 57, 28, 11, 32, 45, 16, 55, 31, 46, &
|
|
||||||
44, 55, 34, 38, 50, 62, 52, 58, 17, 62, 35, 34, &
|
|
||||||
28, 21, 15, 47, 33, 20, 15, 28, 58, 4, 58, 61, &
|
|
||||||
59, 42, 2/
|
|
||||||
data first/.true./
|
|
||||||
save first,correctr
|
|
||||||
|
|
||||||
if(first) then
|
|
||||||
correctr=correct(63:1:-1)
|
|
||||||
! find indices of deinterleaved symbols
|
|
||||||
do i=1,63
|
|
||||||
ideinterleave_indices(i)=i
|
|
||||||
enddo
|
|
||||||
call interleave63(ideinterleave_indices,-1)
|
|
||||||
first=.false.
|
|
||||||
endif
|
|
||||||
! Sort the spectral powers in decreasing order, remove gray code
|
|
||||||
do i=1,63
|
|
||||||
xtmp=s3(:,i)
|
|
||||||
call indexx(xtmp,64,indxs)
|
|
||||||
sympow_sorted(:,i)=xtmp(indxs(64:1:-1))
|
|
||||||
indxs=indxs-1
|
|
||||||
call graycode65(indxs,64,-1)
|
|
||||||
isymval_sorted(:,i)=indxs(64:1:-1)
|
|
||||||
enddo
|
|
||||||
! Deinterleave symbol powers.
|
|
||||||
do i=1,63
|
|
||||||
isymval(:,i)=isymval_sorted(:,ideinterleave_indices(i))
|
|
||||||
sympow(:,i)=sympow_sorted(:,ideinterleave_indices(i))
|
|
||||||
enddo
|
|
||||||
|
|
||||||
! Now sort along the symbol index, using the largest spectral power at each index
|
|
||||||
xtmp(1:63)=sympow(1,1:63)
|
|
||||||
call indexx(xtmp(1:63),63,indx)
|
|
||||||
|
|
||||||
! Calculate some statistics
|
|
||||||
nhard=count(isymval(1,:).ne.correctr)
|
|
||||||
nerrtop4=count(isymval(1,indx(60:63)).ne.correctr(indx(60:63)))
|
|
||||||
nerrmid4=count(isymval(1,indx(56:59)).ne.correctr(indx(56:59)))
|
|
||||||
nerrbot4=count(isymval(1,indx(52:55)).ne.correctr(indx(52:55)))
|
|
||||||
do i=1,12
|
|
||||||
if(isymval(1,indx(64-i)).ne.correctr(indx(64-i))) then
|
|
||||||
write(*,'(i2,1x,64l1)') i,isymval(:,indx(64-i)).eq.correctr(indx(64-i))
|
|
||||||
endif
|
|
||||||
enddo
|
|
||||||
write(*,*) 'nerr, nerrtop4, nerrmid4, nerrbot4',nhard,nerrtop4,nerrmid4,nerrbot4
|
|
||||||
|
|
||||||
! The best 12 symbols will be used as the Most Reliable Basis
|
|
||||||
! Reorder the columns of the generator matrix in order of decreasing quality.
|
|
||||||
! do i=1,63
|
|
||||||
! indx=isymval(64,63+1-i)+1
|
|
||||||
! gmrb(:,i)=g(:,indx(63+1-i))
|
|
||||||
! enddo
|
|
||||||
! Put the generator matrix in standard form so that top 12 symbols are
|
|
||||||
! encoded systematically.
|
|
||||||
! call gf64_standardize_genmat(gmrb)
|
|
||||||
|
|
||||||
! Add various error patterns to the 12 basis symbols and reencode each one
|
|
||||||
! to get a list of codewords. For now, just find the zero'th order codeword.
|
|
||||||
! call gf64_encode(gmrb,isymval(64,indx(63:52:-1)),candidate)
|
|
||||||
! Undo the sorting to put the codeword symbols back into the "right" order.
|
|
||||||
! candidater=candidate(63:1:-1)
|
|
||||||
! candidate(indx)=candidater
|
|
||||||
|
|
||||||
! nerr=count(correctr.ne.candidate)
|
|
||||||
!write(*,*) 'Number of differences between candidate and correct codeword: ',nerr
|
|
||||||
! if( nerr .eq. 0 ) write(*,*) 'Successful decode'
|
|
||||||
return
|
|
||||||
end subroutine gf64_osd
|
|
||||||
|
|
||||||
subroutine gf64_standardize_genmat(gmrb)
|
|
||||||
use gf64math
|
|
||||||
integer gmrb(12,63),temp(63),gkk,gjk,gkkinv
|
|
||||||
do k=1,12
|
|
||||||
gkk=gmrb(k,k)
|
|
||||||
if(gkk.eq.0) then ! zero pivot - swap with the first row with nonzero value
|
|
||||||
do kk=k+1,12
|
|
||||||
if(gmrb(kk,k).ne.0) then
|
|
||||||
temp=gmrb(k,:)
|
|
||||||
gmrb(k,:)=gmrb(kk,:)
|
|
||||||
gmrb(kk,:)=temp
|
|
||||||
gkk=gmrb(k,k)
|
|
||||||
goto 20
|
|
||||||
endif
|
|
||||||
enddo
|
|
||||||
endif
|
|
||||||
20 gkkinv=gf64_inverse(gkk)
|
|
||||||
do ic=1,63
|
|
||||||
gmrb(k,ic)=gf64_product(gmrb(k,ic),gkkinv)
|
|
||||||
enddo
|
|
||||||
do j=1,12
|
|
||||||
if(j.ne.k) then
|
|
||||||
gjk=gmrb(j,k)
|
|
||||||
do ic=1,63
|
|
||||||
gmrb(j,ic)=gf64_sum(gmrb(j,ic),gf64_product(gmrb(k,ic),gjk))
|
|
||||||
enddo
|
|
||||||
endif
|
|
||||||
enddo
|
|
||||||
enddo
|
|
||||||
|
|
||||||
return
|
|
||||||
end subroutine gf64_standardize_genmat
|
|
||||||
|
|
||||||
subroutine gf64_encode(gg,message,codeword)
|
|
||||||
!
|
|
||||||
! Encoder for a (63,12) Reed-Solomon code.
|
|
||||||
! The generator matrix is supplied in array gg.
|
|
||||||
!
|
|
||||||
use gf64math
|
|
||||||
integer message(12) !Twelve 6-bit data symbols
|
|
||||||
integer codeword(63) !RS(63,12) codeword
|
|
||||||
integer gg(12,63)
|
|
||||||
|
|
||||||
codeword=0
|
|
||||||
do j=1,12
|
|
||||||
do i=1,63
|
|
||||||
iprod=gf64_product(message(j),gg(j,i))
|
|
||||||
codeword(i)=gf64_sum(codeword(i),iprod)
|
|
||||||
enddo
|
|
||||||
enddo
|
|
||||||
|
|
||||||
return
|
|
||||||
end subroutine gf64_encode
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
|||||||
module gf64math
|
|
||||||
! Basic math in GF(64), for JT65 and QRA64
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer :: gf64exp(0:62),gf64log(0:63)
|
|
||||||
|
|
||||||
! gf64exp: GF(64) decimal representation, indexed by logarithm
|
|
||||||
data gf64exp/ &
|
|
||||||
1, 2, 4, 8, 16, 32, 3, 6, 12, 24, &
|
|
||||||
48, 35, 5, 10, 20, 40, 19, 38, 15, 30, &
|
|
||||||
60, 59, 53, 41, 17, 34, 7, 14, 28, 56, &
|
|
||||||
51, 37, 9, 18, 36, 11, 22, 44, 27, 54, &
|
|
||||||
47, 29, 58, 55, 45, 25, 50, 39, 13, 26, &
|
|
||||||
52, 43, 21, 42, 23, 46, 31, 62, 63, 61, &
|
|
||||||
57, 49, 33/
|
|
||||||
|
|
||||||
! logarithms of GF(64) elements, indexed by decimal representation
|
|
||||||
data gf64log/ &
|
|
||||||
-1, 0, 1, 6, 2, 12, 7, 26, 3, 32, &
|
|
||||||
13, 35, 8, 48, 27, 18, 4, 24, 33, 16, &
|
|
||||||
14, 52, 36, 54, 9, 45, 49, 38, 28, 41, &
|
|
||||||
19, 56, 5, 62, 25, 11, 34, 31, 17, 47, &
|
|
||||||
15, 23, 53, 51, 37, 44, 55, 40, 10, 61, &
|
|
||||||
46, 30, 50, 22, 39, 43, 29, 60, 42, 21, &
|
|
||||||
20, 59, 57, 58/
|
|
||||||
|
|
||||||
contains
|
|
||||||
|
|
||||||
! Product of two GF(64) field elements
|
|
||||||
function gf64_product(i1,i2)
|
|
||||||
integer, intent(in) :: i1,i2
|
|
||||||
integer :: gf64_product
|
|
||||||
if(i1.ne.0.and.i2.ne.0) then
|
|
||||||
gf64_product=gf64exp(mod(gf64log(i1)+gf64log(i2),63))
|
|
||||||
else
|
|
||||||
gf64_product=0
|
|
||||||
endif
|
|
||||||
end function gf64_product
|
|
||||||
|
|
||||||
! Inverse of a GF(64) field element for arguments in [1,63]. Undefined otherwise.
|
|
||||||
function gf64_inverse(i1)
|
|
||||||
integer, intent(in) :: i1
|
|
||||||
integer :: gf64_inverse
|
|
||||||
if(i1.gt.1) then
|
|
||||||
gf64_inverse=gf64exp(63-gf64log(i1))
|
|
||||||
else
|
|
||||||
gf64_inverse=1
|
|
||||||
endif
|
|
||||||
end function gf64_inverse
|
|
||||||
|
|
||||||
! Sum two GF(64) field elements
|
|
||||||
function gf64_sum(i1,i2)
|
|
||||||
integer, intent(in) :: i1,i2
|
|
||||||
integer :: gf64_sum
|
|
||||||
gf64_sum=ieor(i1,i2)
|
|
||||||
end function gf64_sum
|
|
||||||
|
|
||||||
end module gf64math
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
|||||||
program jt65osdtest
|
|
||||||
!
|
|
||||||
! Demonstrate some procedures that can be used to implement an ordered-
|
|
||||||
! statistics decoder for JT65.
|
|
||||||
! 1. Test JT65 generator-matrix-based encoding by comparing codewords with
|
|
||||||
! those produced by the tried-and-true KA9Q encoder
|
|
||||||
! 2. Demonstrate how to reconfigure the generator matrix to make an arbitrary
|
|
||||||
! subset of 12 symbols the systematic symbols, and show that re-encoding using
|
|
||||||
! the subset of symbols regenerates the original codeword.
|
|
||||||
!
|
|
||||||
use jt65_generator_matrix
|
|
||||||
use gf64math
|
|
||||||
use packjt
|
|
||||||
|
|
||||||
character*22 message
|
|
||||||
integer m(12),cwka9q(63),cwk9an(63),cwtest(63)
|
|
||||||
integer gmrb(12,63)
|
|
||||||
data m/61,51,10,42,51,55, 3,29,53,55,58,42/ !"K9AN K1JT -25"
|
|
||||||
|
|
||||||
message="K1ABC W9XYZ EN37"
|
|
||||||
call packmsg(message,m,itype,.false.)
|
|
||||||
write(*,*) 'Message text: ',message
|
|
||||||
write(*,*) 'Message symbols:'
|
|
||||||
write(*,'(12i3)') m
|
|
||||||
|
|
||||||
! Encode using Karn encoder.
|
|
||||||
call rs_encode(m,cwka9q)
|
|
||||||
write(*,*) 'KA9Q codeword'
|
|
||||||
write(*,'(63i3)') cwka9q
|
|
||||||
! Encode using generator matrix.
|
|
||||||
call gf64_encode(g,m,cwk9an)
|
|
||||||
write(*,*) 'K9AN codeword'
|
|
||||||
write(*,'(63i3)') cwk9an
|
|
||||||
|
|
||||||
! The message symbols are the last 12 symbols of the codeword. For this test,
|
|
||||||
! "pretend" that the symbols at positions 1,3,5,7,9,11,13,15,17,19,21,23 are
|
|
||||||
! the best received symbols, i.e. the best symbols are all parity symbols.
|
|
||||||
! Reorder columns of the generator matrix so that the best symbols are in front
|
|
||||||
! and then use Gauss-Jordan elimination to create a generator matrix that
|
|
||||||
! can be used to re-encode the best 12 symbols, producing the same codeword
|
|
||||||
! that we started with.
|
|
||||||
gmrb=g
|
|
||||||
do i=1,12
|
|
||||||
gmrb(1:12,i)=g(1:12,2*i-1)
|
|
||||||
gmrb(1:12,i+12)=g(1:12,2*i)
|
|
||||||
enddo
|
|
||||||
|
|
||||||
call gf64_standardize_genmat(gmrb)
|
|
||||||
|
|
||||||
! Now demonstrate that we can use the revised generator matrix to encode the 12
|
|
||||||
! best symbols and recover the codeword that we started with.
|
|
||||||
m(1:12)=cwk9an(1:23:2) !Take symbols 1,3,5,...23 as the message
|
|
||||||
call gf64_encode(gmrb,m,cwtest) !reencode using the revised generator matrix
|
|
||||||
write(*,*) 'Re-encode using generator matrix reconfigured to use odd-index symbols starting at 1 as the message:'
|
|
||||||
write(*,'(12i3)') m
|
|
||||||
write(*,*) 'Re-encoded codeword should be the same as the original codeword:'
|
|
||||||
write(*,'(63i3)') cwtest !This should be the same as the original cw.
|
|
||||||
|
|
||||||
end program jt65osdtest
|
|
@ -477,9 +477,8 @@ contains
|
|||||||
enddo
|
enddo
|
||||||
|
|
||||||
nadd=nsum*ismo
|
nadd=nsum*ismo
|
||||||
call extract(s3c,nadd,mode65,ntrials,naggressive,ndepth,nflip,mycall, &
|
call extract(s3,nadd,mode65,ntrials,naggressive,ndepth,nflip,mycall, &
|
||||||
hiscall,hisgrid,nQSOProgress,ljt65apon,nexp_decode,ncount,nhist, &
|
hiscall,hisgrid,nexp_decode,ncount,nhist,decoded,ltext,nft,qual)
|
||||||
avemsg,ltext,nftt,qual)
|
|
||||||
if(nftt.eq.1) then
|
if(nftt.eq.1) then
|
||||||
nsmo=ismo
|
nsmo=ismo
|
||||||
param(9)=nsmo
|
param(9)=nsmo
|
||||||
|
@ -1033,7 +1033,6 @@ void MainWindow::writeSettings()
|
|||||||
m_settings->setValue("pwrBandTxMemory",m_pwrBandTxMemory);
|
m_settings->setValue("pwrBandTxMemory",m_pwrBandTxMemory);
|
||||||
m_settings->setValue("pwrBandTuneMemory",m_pwrBandTuneMemory);
|
m_settings->setValue("pwrBandTuneMemory",m_pwrBandTuneMemory);
|
||||||
m_settings->setValue ("FT8AP", ui->actionEnable_AP_FT8->isChecked ());
|
m_settings->setValue ("FT8AP", ui->actionEnable_AP_FT8->isChecked ());
|
||||||
m_settings->setValue ("JT65AP", ui->actionEnable_AP_JT65->isChecked ());
|
|
||||||
{
|
{
|
||||||
QList<QVariant> coeffs; // suitable for QSettings
|
QList<QVariant> coeffs; // suitable for QSettings
|
||||||
for (auto const& coeff : m_phaseEqCoefficients)
|
for (auto const& coeff : m_phaseEqCoefficients)
|
||||||
@ -1119,7 +1118,6 @@ void MainWindow::readSettings()
|
|||||||
m_pwrBandTxMemory=m_settings->value("pwrBandTxMemory").toHash();
|
m_pwrBandTxMemory=m_settings->value("pwrBandTxMemory").toHash();
|
||||||
m_pwrBandTuneMemory=m_settings->value("pwrBandTuneMemory").toHash();
|
m_pwrBandTuneMemory=m_settings->value("pwrBandTuneMemory").toHash();
|
||||||
ui->actionEnable_AP_FT8->setChecked (m_settings->value ("FT8AP", false).toBool());
|
ui->actionEnable_AP_FT8->setChecked (m_settings->value ("FT8AP", false).toBool());
|
||||||
ui->actionEnable_AP_JT65->setChecked (m_settings->value ("JT65AP", false).toBool());
|
|
||||||
{
|
{
|
||||||
auto const& coeffs = m_settings->value ("PhaseEqualizationCoefficients"
|
auto const& coeffs = m_settings->value ("PhaseEqualizationCoefficients"
|
||||||
, QList<QVariant> {0., 0., 0., 0., 0.}).toList ();
|
, QList<QVariant> {0., 0., 0., 0., 0.}).toList ();
|
||||||
@ -2583,7 +2581,7 @@ void MainWindow::decode() //decode()
|
|||||||
if(m_modeTx=="JT65") dec_data.params.ntxmode=65;
|
if(m_modeTx=="JT65") dec_data.params.ntxmode=65;
|
||||||
dec_data.params.nmode=9;
|
dec_data.params.nmode=9;
|
||||||
if(m_mode=="JT65") dec_data.params.nmode=65;
|
if(m_mode=="JT65") dec_data.params.nmode=65;
|
||||||
if(m_mode=="JT65") dec_data.params.ljt65apon = ui->actionEnable_AP_JT65->isVisible () && ui->actionEnable_AP_JT65->isChecked ();
|
if(m_mode=="JT65") dec_data.params.ljt65apon = false;
|
||||||
if(m_mode=="QRA64") dec_data.params.nmode=164;
|
if(m_mode=="QRA64") dec_data.params.nmode=164;
|
||||||
if(m_mode=="QRA64") dec_data.params.ntxmode=164;
|
if(m_mode=="QRA64") dec_data.params.ntxmode=164;
|
||||||
if(m_mode=="JT9+JT65") dec_data.params.nmode=9+65; // = 74
|
if(m_mode=="JT9+JT65") dec_data.params.nmode=9+65; // = 74
|
||||||
@ -4839,7 +4837,7 @@ void MainWindow::displayWidgets(int n)
|
|||||||
}
|
}
|
||||||
ui->cbFirst->setVisible ("FT8" == m_mode);
|
ui->cbFirst->setVisible ("FT8" == m_mode);
|
||||||
ui->actionEnable_AP_FT8->setVisible ("FT8" == m_mode);
|
ui->actionEnable_AP_FT8->setVisible ("FT8" == m_mode);
|
||||||
ui->actionEnable_AP_JT65->setVisible ("JT65" == m_mode);
|
// ui->actionEnable_AP_JT65->setVisible ("JT65" == m_mode);
|
||||||
ui->cbVHFcontest->setVisible(m_mode=="FT8" or m_mode=="MSK144");
|
ui->cbVHFcontest->setVisible(m_mode=="FT8" or m_mode=="MSK144");
|
||||||
ui->measure_check_box->setChecked (false);
|
ui->measure_check_box->setChecked (false);
|
||||||
ui->measure_check_box->setVisible ("FreqCal" == m_mode);
|
ui->measure_check_box->setVisible ("FreqCal" == m_mode);
|
||||||
|
@ -2532,7 +2532,6 @@ QPushButton[state="ok"] {
|
|||||||
<addaction name="actionInclude_averaging"/>
|
<addaction name="actionInclude_averaging"/>
|
||||||
<addaction name="actionInclude_correlation"/>
|
<addaction name="actionInclude_correlation"/>
|
||||||
<addaction name="actionEnable_AP_FT8"/>
|
<addaction name="actionEnable_AP_FT8"/>
|
||||||
<addaction name="actionEnable_AP_JT65"/>
|
|
||||||
<addaction name="actionEnable_AP_DXcall"/>
|
<addaction name="actionEnable_AP_DXcall"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenu" name="menuSave">
|
<widget class="QMenu" name="menuSave">
|
||||||
@ -3143,14 +3142,6 @@ QPushButton[state="ok"] {
|
|||||||
<string>Enable AP</string>
|
<string>Enable AP</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionEnable_AP_JT65">
|
|
||||||
<property name="checkable">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Enable AP</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionSolve_FreqCal">
|
<action name="actionSolve_FreqCal">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Solve for calibration parameters</string>
|
<string>Solve for calibration parameters</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user