diff --git a/CMakeLists.txt b/CMakeLists.txt index 4486200b5..06c5b4b55 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -336,7 +336,6 @@ set (wsjt_FSRCS # put module sources first in the hope that they get rebuilt before use lib/crc.f90 lib/fftw3mod.f90 - lib/fsk4hf/gf64math.f90 lib/hashing.f90 lib/iso_c_utilities.f90 lib/jt4.f90 @@ -412,7 +411,7 @@ set (wsjt_FSRCS lib/fsk4hf/encode300.f90 lib/entail.f90 lib/ephem.f90 - lib/fsk4hf/extract_ap.f90 + lib/extract.f90 lib/extract4.f90 lib/extractmessage144.f90 lib/fsk4hf/extractmessage168.f90 @@ -516,7 +515,6 @@ set (wsjt_FSRCS lib/mskrtd.f90 lib/fsk4hf/msksoftsym.f90 lib/fsk4hf/msksoftsymw.f90 - lib/fsk4hf/gf64_osd.f90 lib/ft8/osd174.f90 lib/fsk4hf/osd300.f90 lib/pctile.f90 @@ -607,7 +605,7 @@ set (qra_CSRCS set (wsjt_CSRCS ${ka9q_CSRCS} - lib/fsk4hf/ftrsdap.c + lib/ftrsd/ftrsd2.c lib/sgran.c lib/golay24_table.c lib/gran.c @@ -1161,9 +1159,6 @@ target_link_libraries (wsjt_qtmm Qt5::Multimedia) add_executable (jt4sim lib/jt4sim.f90 wsjtx.rc) 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) target_link_libraries (jt65sim wsjt_fort wsjt_cxx) diff --git a/lib/decode65b.f90 b/lib/decode65b.f90 index 77aeaf8c0..3ff6dc017 100644 --- a/lib/decode65b.f90 +++ b/lib/decode65b.f90 @@ -21,9 +21,7 @@ subroutine decode65b(s2,nflip,nadd,mode65,ntrials,naggressive,ndepth, & enddo call extract(s3,nadd,mode65,ntrials,naggressive,ndepth,nflip,mycall, & - hiscall,hisgrid,nQSOProgress,ljt65apon,nexp_decode,ncount, & - nhist,decoded, & - ltext,nft,qual) + hiscall,hisgrid,nexp_decode,ncount,nhist,decoded,ltext,nft,qual) ! Suppress "birdie messages" and other garbage decodes: if(decoded(1:7).eq.'000AAA ') ncount=-1 diff --git a/lib/fsk4hf/extract_ap.f90 b/lib/fsk4hf/extract_ap.f90 deleted file mode 100644 index 5e7c08fb6..000000000 --- a/lib/fsk4hf/extract_ap.f90 +++ /dev/null @@ -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 diff --git a/lib/fsk4hf/ftrsdap.c b/lib/fsk4hf/ftrsdap.c deleted file mode 100644 index b2b85ddd9..000000000 --- a/lib/fsk4hf/ftrsdap.c +++ /dev/null @@ -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 -#include -#include -#include -#include -#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=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= 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; -} diff --git a/lib/fsk4hf/gf64_osd.f90 b/lib/fsk4hf/gf64_osd.f90 deleted file mode 100644 index 015e1a012..000000000 --- a/lib/fsk4hf/gf64_osd.f90 +++ /dev/null @@ -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 - diff --git a/lib/fsk4hf/gf64math.f90 b/lib/fsk4hf/gf64math.f90 deleted file mode 100644 index 1ace7c014..000000000 --- a/lib/fsk4hf/gf64math.f90 +++ /dev/null @@ -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 - diff --git a/lib/fsk4hf/jt65osdtest.f90 b/lib/fsk4hf/jt65osdtest.f90 deleted file mode 100644 index 6ef985cea..000000000 --- a/lib/fsk4hf/jt65osdtest.f90 +++ /dev/null @@ -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 diff --git a/lib/jt65_decode.f90 b/lib/jt65_decode.f90 index 0eb15277a..8138ea931 100644 --- a/lib/jt65_decode.f90 +++ b/lib/jt65_decode.f90 @@ -477,9 +477,8 @@ contains enddo nadd=nsum*ismo - call extract(s3c,nadd,mode65,ntrials,naggressive,ndepth,nflip,mycall, & - hiscall,hisgrid,nQSOProgress,ljt65apon,nexp_decode,ncount,nhist, & - avemsg,ltext,nftt,qual) + call extract(s3,nadd,mode65,ntrials,naggressive,ndepth,nflip,mycall, & + hiscall,hisgrid,nexp_decode,ncount,nhist,decoded,ltext,nft,qual) if(nftt.eq.1) then nsmo=ismo param(9)=nsmo diff --git a/mainwindow.cpp b/mainwindow.cpp index 6f318daa4..c9c5ded2d 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1033,7 +1033,6 @@ void MainWindow::writeSettings() m_settings->setValue("pwrBandTxMemory",m_pwrBandTxMemory); m_settings->setValue("pwrBandTuneMemory",m_pwrBandTuneMemory); m_settings->setValue ("FT8AP", ui->actionEnable_AP_FT8->isChecked ()); - m_settings->setValue ("JT65AP", ui->actionEnable_AP_JT65->isChecked ()); { QList coeffs; // suitable for QSettings for (auto const& coeff : m_phaseEqCoefficients) @@ -1119,7 +1118,6 @@ void MainWindow::readSettings() m_pwrBandTxMemory=m_settings->value("pwrBandTxMemory").toHash(); m_pwrBandTuneMemory=m_settings->value("pwrBandTuneMemory").toHash(); 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" , QList {0., 0., 0., 0., 0.}).toList (); @@ -2583,7 +2581,7 @@ void MainWindow::decode() //decode() if(m_modeTx=="JT65") dec_data.params.ntxmode=65; dec_data.params.nmode=9; 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.ntxmode=164; 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->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->measure_check_box->setChecked (false); ui->measure_check_box->setVisible ("FreqCal" == m_mode); diff --git a/mainwindow.ui b/mainwindow.ui index b9f4a2141..e1109d89c 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -2532,7 +2532,6 @@ QPushButton[state="ok"] { - @@ -3143,14 +3142,6 @@ QPushButton[state="ok"] { Enable AP - - - true - - - Enable AP - - Solve for calibration parameters