From 8a2e3e50d9a48d895bb080978df4d5d48a078b34 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Thu, 15 Feb 2024 14:14:51 -0500 Subject: [PATCH] Commit ftrsd3.c. (Not used at present, and not fully updated from ftrsd2.c.) --- lib/superfox/ftrsd3.c | 217 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 lib/superfox/ftrsd3.c diff --git a/lib/superfox/ftrsd3.c b/lib/superfox/ftrsd3.c new file mode 100644 index 000000000..1bbe0fb1e --- /dev/null +++ b/lib/superfox/ftrsd3.c @@ -0,0 +1,217 @@ +/* + ftrsd3.c + + A soft-decision decoder for Reed-Solomon codes. + + 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 "rs2.h" + +static void *rs; +void getpp3_(int workdat[], float *pp); + +void ftrsd3_(int rxdat[], int rxprob[], int rxdat2[], int rxprob2[], + int* ntrials0, int correct[], int param[], int ntry[]) +{ + // int rxdat[127], rxprob[127], rxdat2[127], rxprob2[127]; + int workdat[127]; + int indexes[127]; + int era_pos[79]; + int i, j, numera, nerr, nn=127; + 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}}; + + printf("A\n"); +// Initialize the KA9Q Reed-Solomon encoder/decoder + unsigned int symsize=7, gfpoly=0x89, fcr=3, prim=1, nroots=79; + rs=init_rs_int(symsize, gfpoly, fcr, prim, nroots, 0); + printf("B\n"); + +// Sort rxprob to find indexes of the least reliable symbols + int k, pass, tmp, nsym=127; + int probs[127]; + for (i=0; i<127; i++) { + indexes[i]=i; + probs[i]=rxprob[i]; + } + printf("C\n"); + + 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; + } + } + } + printf("D\n"); + +// See if we can decode using BM HDD, and calculate the syndrome vector. + memset(era_pos,0,79*sizeof(int)); + numera=0; + memcpy(workdat,rxdat,127*sizeof(int)); + nerr=decode_rs_int(rs,workdat,era_pos,numera,1); + printf("E\n"); + + if( nerr >= 0 ) { + // Hard-decision decoding succeeded. Save codeword and some parameters. + nhard=0; + for (i=0; i<127; i++) { + if( workdat[i] != rxdat[i] ) nhard=nhard+1; + } + memcpy(correct,workdat,127*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; + } + + if(nerr==-1) { + printf("nerr:', %d\n",nerr); + 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[127]; + ncandidates=0; + nsum=0; + int ii,jj; + 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,127) of synchronized symbol spectra. + ncandidates=ncandidates+1; + nhard=0; + nsoft=0; + for (i=0; i<127; i++) { + if(workdat[i] != rxdat[i]) { + nhard=nhard+1; + if(workdat[i] != rxdat2[i]) { + nsoft=nsoft+rxprob[i]; + } + } + } + nsoft=127*nsoft/nsum; + ntotal=nsoft+nhard; + + pp=0.; + // getpp3_(workdat,&pp); + if(pp>pp1) { + pp2=pp1; + pp1=pp; + nsoft_min=nsoft; + nhard_min=nhard; + ntotal_min=ntotal; + memcpy(correct,workdat,127*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]= pp1 > 0 ? 1000.0*pp2/pp1 : 1000.0; + 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; +}