/* MSHV decoderpom * Copyright 2020 Hrisimir Hristov, LZ2HV * (Edited by Harper Innes, VK1TTY - to remove Gendered Language and Replace with Non-Gendered language) NOTE:May be used under the terms of the GNU General Public License (GPL) */ //#include "decoderms.h" #include "decoderpom.h" #include #include //#include //// F2A /// //nflags=FFTW_ESTIMATE; //if (npatience==1) nflags=FFTW_ESTIMATE_PATIENT; //if (npatience==2) nflags=FFTW_MEASURE; //if (npatience==3) nflags=FFTW_PATIENT; //if (npatience==4) nflags=FFTW_EXHAUSTIVE; // MSK144 four2a_c2c nfft=32768 7 plans four2a_d2c none // MSKMS four2a_c2c nfft=32768 7 plans four2a_d2c none // JTMS four2a_c2c nfft=20552 20 plans four2a_d2c nfft=524288 4 plans + ZAP only // FSK441 four2a_c2c nfft=32768 8 plans four2a_d2c nfft=524288 4 plans + ZAP only // ISCAT four2a_c2c nfft=73728 2 plans four2a_d2c nfft=524288 4 plans + ZAP only // JT6M four2a_c2c nfft=512 1 plans four2a_d2c nfft=524288 4 plans + ZAP only // FT8 four2a_c2c nfft=180000 4 plans four2a_d2c nfft=192000 3 plans // FT4 four2a_c2c nfft=72576 4 plans four2a_d2c nfft=72576 2 plans // JT65 four2a_c2c nfft=2048 2 plans four2a_d2c nfft=8192 1 plans // PI4 four2a_c2c none four2a_d2c nfft=768000 3 plans // Q65 four2a_c2c 1440000 for x120sec //static int retr = 0; //static int cplu = 0; #define SLPAMIN 2000 //2000 importent SLPAMIN > SLPASTEP #define SLPASTEP 1000 //1000 importent SLPAMIN > SLPASTEP static bool _block_th_all_ = false; //need to be static for all static int _wait_t_ = SLPAMIN - SLPASTEP; //need to be static for all static int setup_c2c_d2c_(bool &wait,fftw_plan &p,double complex *a,int nfft,int isign,int iform,double *d = 0) { if (_block_th_all_ || !wait) { _wait_t_ += SLPASTEP; wait = true; //retr++; qDebug()<<"retry---->"<NPMAX || nfft>NPAMAX) return; bool found_plan = false; int z = 0; for (z = 0; z < cpd; ++z) { if (nfft==nn_d2c[z] && isign==ns_d2c[z] && iform==nf_d2c[z]) { found_plan = true; break; } } int cfft = nfft; if (iform==0) cfft = nfft/2; for (int i = 0; i < nfft; ++i) { if (imax) { max = a[i]; } } return max; } int PomAll::maxloc_da_end_to_beg(double*a,int a_beg,int a_end) { double max = a[a_end]; int loc = a_end; for (int i = a_end-1; i >= a_beg; i--) { if (a[i]>max) { loc = i; max = a[i]; } } return loc; } /*int PomAll::minloc_da(double *da,int count) { int pos = 0; double min = da[0]; for (int i= 1; i < count; ++i)//MAXMSG { if (da[i].GT. <.LT. >=.GE. <=.LE. if (x>1.259e-10) { if (x<0.000001) x=0.000001; db=10.0*log10(x); } return db; } double PomAll::determ(double array_[10][10],int norder) { //real*8 function determ(array,norder) //implicit real*8 (a-h,o-z) //real*8 array(10,10) double determ=1.0; for (int k = 0; k.GT. <.LT. >=.GE. <=.LE. double xi=x[i]; double yi=y[i]; double weight=0.0; if (mode<0) weight=1.0/fabs(yi); else if (mode==0) weight=1.0; else weight=1.0/(sigmay[i]*sigmay[i]); //qDebug()<<"weight"<.GT. <.LT. >=.GE. <=.LE. inc=1;//inc=1; c1: inc=3*inc+1; if (inc<=n) goto c1; c2: inc=inc/3; //qDebug()<<"INC="<v) { a[j]=a[j-inc]; j=j-inc; if (j<=inc) goto c4; goto c3; } c4: a[j]=v; } if (inc>1) goto c2; } double PomAll::pctile_shell(double *x,int npts,int npct) { double xpct = 1.0; int NMAX=141072;// 100000;//100000 32768 //real*4 x(npts) //double tmp[NMAX];// ={0.0};//real*4 tmp(NMAX) //double *tmp = new double[NMAX];// ={0.0};//real*4 tmp(NMAX) int j =0; //c++ ==.EQ. !=.NE. >.GT. <.LT. >=.GE. <=.LE. if (npts<=0) { xpct=1.0; goto c900; } if (npts>NMAX) return xpct; // if(npts.gt.NMAX) stop for (j = 0; j < npts; j++) pctile_shell_tmp[j]=x[j]; // tmp(1:npts)=x +beg shell(npts,pctile_shell_tmp); j=(int)((double)npts*0.01*npct); //sort(npts,tmp); if (j<0) j=0;//0 if(j.lt.1) j=1 if (j>npts-1) j=npts-1; // if(j.gt.npts) j=npts xpct=pctile_shell_tmp[j]; c900: return xpct; } int PomAll::maxloc_da_beg_to_end(double*a,int a_beg,int a_end) { double max = a[a_beg]; int loc = a_beg; for (int i = a_beg; i < a_end; i++)//1.68 i++ ok { if (a[i]>max) { loc = i; max = a[i]; } } return loc; } void PomAll::zero_double_comp_beg_end(double complex*d,int begin,int end) { for (int i = begin; i 0) << n<> n>>m n shifted right by m bits //double complex t[cou_a]; //garmi hv v1.42 //double complex t[cou_a*2+ish+50]; //garmi hv v1.43 ok double complex *t = new double complex[cou_a+100]; //garmi pri goliam count hv v1.43 correct ok for (int i=0; i< cou_a; i++) t[i]=a[i]; if (ish>0) { for (int i = 0; i < cou_a; i++) { if (i+ish.GT. <.LT. >=.GE. <=.LE. c1: if (ir-l= 0; i--) {//do i=j-1,1,-1 if (arr[indx[i]]<=a) goto c2; indx[i+1]=indx[i]; } i=-1;//-1-hv 0; c2: indx[i+1]=indxt; //if(indxt>350 || indxt<5) //qDebug()<<"indxt="<arr[indx[ir]]) { itemp=indx[l+1]; indx[l+1]=indx[ir]; indx[ir]=itemp; } //c++ ==.EQ. !=.NE. >.GT. <.LT. >=.GE. <=.LE. if (arr[indx[l]]>arr[indx[ir]]) { itemp=indx[l]; indx[l]=indx[ir]; indx[ir]=itemp; } if (arr[indx[l+1]]>arr[indx[l]]) { itemp=indx[l+1]; indx[l+1]=indx[l]; indx[l]=itemp; } i=l+1; j=ir; indxt=indx[l]; a=arr[indxt]; c3: //continue i=i+1; if (arr[indx[i]]a) goto c4; if (jNSTACK) return;//stop //'NSTACK too small in indexx' if (ir-i+1>=j-l) { istack[jstack]=ir; istack[jstack-1]=i; ir=j-1; } else { istack[jstack]=j-1; istack[jstack-1]=l; l=i; } } goto c1; } bool PomAll::isStandardCall(QString w)//2.61 same as MultiAnswerModW { //static QRegularExpression standard_call_re { // R"( // ^\s* # optional leading spaces // ( [A-Z]{0,2} | [A-Z][0-9] | [0-9][A-Z] ) # part 1 // ( [0-9][A-Z]{0,3} ) # part 2 // (/R | /P)? # optional suffix // \s*$ # optional trailing spaces // )", QRegularExpression::CaseInsensitiveOption | QRegularExpression::ExtendedPatternSyntaxOption}; //return standard_call_re.match (w).hasMatch (); QRegExp rx("^\\s*([A-Z]{0,2}|[A-Z][0-9]|[0-9][A-Z])([0-9][A-Z]{0,3})(/R|/P)?\\s*$"); rx.setCaseSensitivity(Qt::CaseInsensitive); bool res0 = rx.exactMatch(w); //qDebug()<=1; --i) {//do i=n,2,-1 if (w.at(i).isDigit()) break;//exit } iarea=i; //!Right-most digit (call area) short npdig=0; //!Digits before call area short nplet=0; //!Letters before call area for (i = 0; i < iarea; ++i) {//do i=1,iarea-1 if (w.at(i).isDigit()) npdig++; if (w.at(i).isLetter()) nplet++; } short nslet=0; //!Letters in suffix for (i = iarea+1; i < n; ++i) {//do i=iarea+1,n if (w.at(i).isLetter()) nslet++; } if (iarea<1 || iarea>2 || nplet==0 || npdig>=iarea || nslet>3) res = false; if (!res || !spr) res = false; return res; }*/ /*bool PomAll::is_digit(char c) { bool res = false; if (c>='0' && c<='9') res = true; return res; } bool PomAll::is_letter(char c) { bool res = false; if (c>='A' && c<='Z') res = true; return res; } bool PomAll::isStandardCall(QString callsign0)//not correct XX2XX/P or R is standard { char callsign[100]; strncpy(callsign,callsign0.toUtf8(),32); int n = callsign0.count(); bool res = true; bool spr = true; if (n<2) return false; if (callsign[n-2]=='/') { if (callsign[n-1]=='P' || callsign[n-1]=='R') n = n - 2; else spr = false; } //! Check for standard callsign int iarea=-1; //int n = strlen(callsign); //n=len(trim(callsign)) int i; for (i = n-1; i >=1; --i) {//do i=n,2,-1 if (is_digit(callsign[i])) break;//exit } iarea=i; //!Right-most digit (call area) int npdig=0; //!Digits before call area int nplet=0; //!Letters before call area for (i = 0; i < iarea; ++i) {//do i=1,iarea-1 if (is_digit(callsign[i])) npdig++; if (is_letter(callsign[i])) nplet++; } int nslet=0; //!Letters in suffix for (i = iarea+1; i < n; ++i) {//do i=iarea+1,n if (is_letter(callsign[i])) nslet++; } //c++ ==.EQ. !=.NE. >.GT. <.LT. >=.GE. <=.LE. //if(iarea<2 || iarea>3 || nplet==0 || npdig>=iarea-1 || nslet>3) if (iarea<1 || iarea>2 || nplet==0 || npdig>=iarea || nslet>3) res = false; if (!res || !spr) res = false; return res; }*/ //// END POMALL /// //// POMFT /// #define MN_NM_NRW_FT_174_91 #include "../HvMsPlayer/libsound/HvGenFt8/bpdecode_ft8_174_91.h" /*PomFt::PomFt() { lastpat_ft8_2 = 0; inext_ft8_2 = 0; first_osd174_91 = true; twopi=8.0*atan(1.0); } PomFt::~PomFt() {}*/ void PomFt::initPomFt() { //pomAll.initPomAll();//2.66 no pctile_shell no need init lastpat_ft8_2 = -1;//0; inext_ft8_2 = -1;//0; first_osd174_91 = true; first_enc174_91_nocrc = true; twopi=8.0*atan(1.0); pi=4.0*atan(1.0); } /* #include "../HvMsPlayer/libsound/boost/boost_14.hpp" short crc14_pomft(unsigned char const * data, int length) { return boost::augmented_crc<14, TRUNCATED_POLYNOMIAL14>(data, length); } short PomFt::crc14(unsigned char const * data, int length) { return crc14_pomft(data,length); } */ void PomFt::nuttal_window(double *win,int n) { double a0=0.3635819; double a1=-0.4891775; double a2=0.1365995; double a3=-0.0106411; for (int i = 0; i < n; ++i) {//do i=1,n //win[i]=a0+a1*cos(2*pi*(i-1)/(n))+a2*cos(4*pi*(i-1)/(n))+a3*cos(6*pi*(i-1)/(n)); win[i]=a0+a1*cos(2.0*pi*(double)i/(double)n)+a2*cos(4.0*pi*(double)i/(double)n)+a3*cos(6.0*pi*(double)i/(double)n); } } void PomFt::normalizebmet(double *bmet,int n) { double bmetav = 0.0; double bmet2av = 0.0; for (int z = 0; z < n; ++z) { bmetav+=bmet[z];////bmetav=sum(bmet)/real(n) bmet2av+=bmet[z]*bmet[z];//bmet2av=sum(bmet*bmet)/real(n) } //bmetav=sum(bmet)/real(n) //bmet2av=sum(bmet*bmet)/real(n) bmetav=bmetav/(double)n; bmet2av=bmet2av/(double)n; double var=bmet2av-bmetav*bmetav;//var=bmet2av-bmetav*bmetav double bmetsig = 0.0; if ( var > 0.0 ) //c++ ==.EQ. !=.NE. >.GT. <.LT. >=.GE. <=.LE. bmetsig=sqrt(var); else bmetsig=sqrt(bmet2av); if (bmetsig<=0.00001)//2.68 crash no devide by zero bmetsig=0.00001; //if (bmetsig<=0.00001) qDebug()<<"bmetsig="<.GT. <.LT. >=.GE. <=.LE. if ( x < 0.0 ) { isign=-1.0; z=fabs(x); } if ( z <= 0.664 ) { y=x/0.83; return; } else if ( z <= 0.9217 ) { y=isign*(z - 0.4064)/0.322; return; } else if ( z <= 0.9951 ) { y=isign*(z - 0.8378)/0.0524; return; } else if ( z <= 0.9998 ) { y=isign*(z - 0.9914)/0.0012; return; } else { y=isign*7.0; return; } } void PomFt::mrbencode91(bool *me,bool *codeword,bool g2_[91][174],int N,int K) { for (int i = 0; i < N; ++i) codeword[i]=0; for (int i = 0; i < K; ++i) {//do i=1,K if ( me[i] == 1 ) //then { for (int j = 0; j < N; ++j) codeword[j]=(codeword[j] ^ g2_[i][j]); //(1:N,i) } } } void PomFt::nextpat_step1_91(bool *mi,int k,int iorder,int &iflag) { //iorder = 3; if ( iflag <= 0 ) { iflag=-1; return; } int beg = iflag - 1; int end = iflag + iorder; if (end > k) end = k; //qDebug()<<"beg end="<= beg && i < beg + iorder) mi[i]=1; else mi[i]=0; } iflag--; } bool PomFt::any_ca_iand_ca_eq1_91(bool *a,bool *b,int count) { bool res = false; for (int i = 0; i < count; ++i) { if ((a[i] & b[i])==1) { res = true; break; } } return res; } void PomFt::boxit91(bool &reset,bool *e2,int ntau,int npindex,int i1,int i2) { /*integer*1 e2(1:ntau) v2 integer indexes(5000,2),fp(0:525000),np(5000) v1 integer indexes(4000,2),fp(0:525000),np(4000) logical reset common/boxes/indexes,fp,np*/ if (reset) { //patterns=-1 //sc=-1 for (int i = 0; i < 525000; ++i) fp_ft8_2[i]=-1; for (int i = 0; i < 5000; ++i) { np_ft8_2[i]=-1; indexes_ft8_2_[0][i]=-1; indexes_ft8_2_[1][i]=-1; } reset=false; } indexes_ft8_2_[0][npindex]=i1; indexes_ft8_2_[1][npindex]=i2; //Left Shift ISHFT ISHFT(N,M) (M > 0) << n<> n>>m n shifted right by m bits int ipat=0; for (int i = 0; i < ntau; ++i)//ntau=19,14 {//do i=1,ntau if (e2[i]==1) ipat+=(1 << ((ntau-1)-i)); //??? hv->(ntau-1) ipat=ipat+ishft(1,ntau-i) } //qDebug()<<"ipatipat="<.GT. <.LT. >=.GE. <=.LE. if (lastpat_ft8_2!=ipat && index>=0) //hv>=0 if(lastpat.ne.ipat .and. index>0) then then ! return first set of indices { i1=indexes_ft8_2_[0][index];//i1=indexes(index,1) i2=indexes_ft8_2_[1][index];//i2=indexes(index,2) inext_ft8_2=np_ft8_2[index]; //inext=np(index) } else if (lastpat_ft8_2==ipat && inext_ft8_2>=0)//hv>=0 elseif(lastpat.eq.ipat .and. inext>0) then { i1=indexes_ft8_2_[0][inext_ft8_2];//i1=indexes(inext,1) i2=indexes_ft8_2_[1][inext_ft8_2];//i2=indexes(inext,2) inext_ft8_2=np_ft8_2[inext_ft8_2]; //inext=np(inext) } else { i1=-1; i2=-1; inext_ft8_2=-1; } lastpat_ft8_2=ipat; } void PomFt::bshift1(bool *a,int cou_a,int ish) { //HV for single shift vareable //Left Shift ISHFT ISHFT(N,M) (M > 0) << n<> n>>m n shifted right by m bits //double complex t[cou_a]; //garmi hv v1.42 //double complex t[cou_a*2+ish+50]; //garmi hv v1.43 ok bool *t = new bool[cou_a+100]; //garmi pri goliam count hv v1.43 correct ok for (int i=0; i< cou_a; i++) t[i]=a[i]; if (ish>0) { for (int i = 0; i < cou_a; i++) { if (i+ish.GT. <.LT. >=.GE. <=.LE. int maxiterations=30; //int max_iterations=40;//for FT4 /*for (int i = 0; i<3; ++i) { for (int j = 0; j3) maxosd=3; if (maxosd==0) //then //! osd with channel llrs { nosd=1; for (int i = 0; i < N; ++i) zsave_[0][i]=llr[i]; } else if (maxosd>0)// then ! nosd=maxosd; else if (maxosd<0) //then ! just bp nosd=0; for (int i = 0; i0.0)//cw=0 //where( zn .gt. 0. ) cw=1 cw[i]=1; else cw[i]=0; //if (iter<=maxosd) if (iter.GT. <.LT. >=.GE. <=.LE. // diff -> if(iter.gt.0 .and. iter.le.maxosd) then //if (iter>0 && iter<=maxosd) if (iter81) m96[i]=cw[i-5];//m96(83:96)=cw(78:91) {m96[i]=cw[i-5]; qDebug()<.GT. <.LT. >=.GE. <=.LE. { /*if (llr[i]>=0.0) hdec[i]=1; else hdec[i]=0;*/ hdec[i]=0; if (llr[i]>=0.0) hdec[i]=1; nxor[i]=hdec[i] ^ cw[i]; //nxor=ieor(hdec,cw) dmin+=(double)nxor[i]*fabs(llr[i]); //dmin=sum(nxor*abs(llr)) } //for (int i = 0; i < N; ++i) //dmin+=nxor[i]*fabs(llr[i]);//dmin=sum(nxor*abs(llr)) //ntype=1 return; } } if ( iter > 0 ) //! this code block implements an early stopping criterion { //if( iter.gt.10000 ) int nd=ncheck-nclast; if ( nd < 0 ) //! # of unsatisfied parity checks decreased ncnt=0; //! reset counter else ncnt++; //ncnt=ncnt+1; //! write(*,*) iter,ncheck,nd,ncnt if ( ncnt >= 5 && iter >= 10 && ncheck > 15)//if( ncnt .ge. 5 .and. iter .ge. 10 .and. ncheck .gt. 15) then { nharderror=-1; //if (iter<5) qDebug()<<"iter FFFFF="<.GT. <.LT. >=.GE. <=.LE. {//do i=1,nosd for (int j = 0; j < N; ++j) zn[j]=zsave_[io][j];//zn=zsave(:,i) double dminosd = 0.0; osd174_91_1(zn,apmask,norder,message91,cw,nharderror,dminosd);//Keff=91 if (nharderror>0)//then { for (int i = 0; i < N; ++i) //where(llr .ge. 0) hdec=1 //c++ ==.EQ. !=.NE. >.GT. <.LT. >=.GE. <=.LE. { /*if (llr[i]>=0.0) hdec[i]=1; else hdec[i]=0;*/ hdec[i]=0; if (llr[i]>=0.0) hdec[i]=1; nxor[i]=hdec[i] ^ cw[i]; //nxor=ieor(hdec,cw) dmin+=(double)nxor[i]*fabs(llr[i]); //dmin=sum(nxor*abs(llr)) } //qDebug()<> (3-jj)));//if( btest(istr,4-jj) ) gen(irow,i)=1 } } } first_enc174_91_nocrc=false; } for (int i = 0; i < 83; ++i) { int nsum=0; for (int j = 0; j < 91; ++j) { nsum+=message910[j]*gen_osd174_91_nocrc[j][i];//nsum=nsum+message(j)*gen(i,j); } pchecks[i]=fmod(nsum,2); } // codeword(1:K)=message // codeword(K+1:N)=pchecks for (int i = 0; i < K; ++i)//91 codeword[i]=message910[i]; for (int i = 0; i < M; ++i)//174-91=83 codeword[i+91]=pchecks[i]; } void PomFt::osd174_91_1(double *llr,/*int Keff=91*/bool *apmask,int ndeep,bool *message91,bool *cw,int &nhardmin,double &dmin) { const int N=174; const int K=91; const int M=N-K;// M=83 double rx[N]; bool apmaskr[N]; bool apmaskr2[N]; bool hdec[N+2]; bool hdec2[N+2]; double absrx[N]; double absrx2[N]; bool genmrb_[N][K];//(K,N) bool g2_[K][N]; //(N,K) int indices[N]; int indx[N]; bool temp[K]; bool m0[K]; bool c0[N]; int nxor[N+2]; bool misub[K+5]; bool me[K],mi[K]; bool ce[N]; bool e2sub[M];//e2sub(N-K) bool e2[M];//e2(N-K) bool ui[M];//ui(N-K) bool r2pat[M]; bool cw_t[N]; bool m96[96+5]; //bool decoded[K];//91 //qDebug()<.GT. <.LT. >=.GE. <=.LE. {//do i=1,k bool message910[120]; for (int j = 0; j < 91; ++j) message910[j]=0; message910[i]=1; /*if (i<77) { //m96=0 //m96(1:91)=message91 //call get_crc14(m96,96,ncrc14) //write(c14,'(b14.14)') ncrc14 //read(c14,'(14i1)') message91(78:91) for (int j = 77; j < K; ++j) message91[j]=0;//message91(78:k)=0 }*/ encode174_91_nocrc(message910,cw); for (int j = 0; j < N; ++j) gen_osd174_91_[j][i]=cw[j]; } first_osd174_91=false; } for (int i = 0; i < N; ++i)//c++ ==.EQ. !=.NE. >.GT. <.LT. >=.GE. <=.LE. { rx[i]=llr[i];//rx=llr apmaskr[i]=apmask[i];//apmaskr=apmask hdec[i]=0;//hdec=0 if (rx[i]>=0.0) hdec[i]=1; // where(rx .ge. 0) hdec=1 absrx[i]=fabs(rx[i]);//absrx=abs(rx) } //if (N>0)//2.12 no needed pomAll.indexx_msk(absrx,N-1,indx);//call indexx(absrx,N,indx) //! Re-order the columns of the generator matrix in order of decreasing reliability. for (int i = 0; i < N; ++i) {//do i=1,N for (int j = 0; j < K; ++j) genmrb_[i][j]=gen_osd174_91_[indx[(N-1)-i]][j];//genmrb(1:K,i)=gen(1:K,indx(N+1-i)) indices[i]=indx[(N-1)-i];//indices[i]=indx(N+1-i) } //! Do gaussian elimination to create a generator matrix with the most reliable //! received bits in positions 1:K in order of decreasing reliability (more or less). int iflag=0; for (int id = 0; id < K; ++id) {//do id=1,K //! diagonal element indices for (int icol = id; icol < K+20; ++icol)//+20 ??? {//do icol=id,K+20 ! The 20 is ad hoc - beware iflag=0; if ( genmrb_[icol][id] == 1 ) //then (id,icol) //c++ ==.EQ. !=.NE. >.GT. <.LT. >=.GE. <=.LE. { iflag=1; if ( icol != id ) //then ! reorder column;//if( icol .ne. id ) then ! reorder column { for (int z = 0; z < K; ++z) { temp[z]=genmrb_[id][z];//temp(1:K)=genmrb(1:K,id) genmrb_[id][z]=genmrb_[icol][z];//genmrb(1:K,id)=genmrb(1:K,icol) genmrb_[icol][z]=temp[z];//genmrb(1:K,icol)=temp(1:K) } int itmp=indices[id]; indices[id]=indices[icol]; indices[icol]=itmp; } for (int ii = 0; ii < K; ++ii) {//do ii=1,K if ( ii != id && genmrb_[id][ii] == 1 ) //then if( ii != id && genmrb(ii,id) .eq. 1 ) then { for (int z = 0; z < N; ++z) genmrb_[z][ii]=(genmrb_[z][ii] ^ genmrb_[z][id]);//genmrb(ii,1:N)=ieor(genmrb(ii,1:N),genmrb(id,1:N)) } } break; //exit } } } for (int i = 0; i < N; ++i) { for (int j = 0; j < K; ++j)//char genmrb_[N][K]; g2_[j][i]=genmrb_[i][j]; //g2=transpose(genmrb) } //! The hard decisions for the K MRB bits define the order 0 message, m0. //! Encode m0 using the modified generator matrix to find the "order 0" codeword. //! Flip various combinations of bits in m0 and re-encode to generate a list of //! codewords. Return the member of the list that has the smallest Euclidean //! distance to the received word. for (int i = 0; i < N; ++i)// N { hdec2[i]=hdec[indices[i]]; //hdec=hdec(indices) absrx2[i]=absrx[indices[i]]; //absrx=absrx(indices) //rx_t[i]=rx[indices[i]]; //rx=rx(indices) apmaskr2[i]=apmaskr[indices[i]]; //apmaskr=apmaskr(indices) } for (int i = 0; i < K; ++i) m0[i]=hdec2[i]; // m0=hdec(1:K) ! zero'th order message //! zero'th order message mrbencode91(m0,c0,g2_,N,K);// mrbencode91(m0,c0,g2,N,K); nhardmin = 0; dmin = 0.0; for (int i = 0; i < N; ++i) { nxor[i]=(c0[i] ^ hdec2[i]); nhardmin+=nxor[i];//nhardmin=sum(nxor) dmin+=(double)nxor[i]*absrx2[i]; } for (int i = 0; i < N; ++i) cw[i]=c0[i]; int nt=0; int nrejected=0; int nord = 0; int npre1 = 0; int npre2 = 0; int ntheta = 0; int ntau = 0; int ntotal=0; if (ndeep==0) goto c998; //! norder=0 //c++ ==.EQ. !=.NE. >.GT. <.LT. >=.GE. <=.LE. if (ndeep>6) ndeep=6; if ( ndeep==1) { nord=1; npre1=0; npre2=0; nt=40; ntheta=12; } else if (ndeep==2) { nord=1; npre1=1; npre2=0; nt=40; ntheta=12;//2.2.0org=ntheta=10; ntheta=12; } else if (ndeep==3) { nord=1; npre1=1; npre2=1; nt=40; ntheta=12; ntau=14; } else if (ndeep==4) { nord=2; npre1=1; npre2=1; //npre2=0; nt=40; ntheta=12; ntau=17;//ntau=19; } else if (ndeep==5) { nord=3;//nord=2; npre1=1; npre2=1; nt=40; ntheta=12; ntau=15;//ntau=19; } else //if (ndeep==6) { nord=4; npre1=1; npre2=1; nt=95; ntheta=12; ntau=15; } for (int iorder = 1; iorder <= nord; ++iorder) {//do iorder=1,nord for (int z = 0; z < K-iorder; ++z) //misub(1:K-iorder)=0 misub[z]=0; for (int z = K-iorder; z < K; ++z) misub[z]=1; // misub(K-iorder+1:K)=1 iflag=K-iorder; //iflag=K-iorder+1 while (iflag >= 0 ) //c++ ==.EQ. !=.NE. >.GT. <.LT. >=.GE. <=.LE. {//do while(iflag .ge.0) int iend = 0; if (iorder==nord && npre1==0) iend=iflag; else iend=0;//iend=1 double d1 = 0.0; //double dd = 0.0; //int nd1Kpt = 0; for (int n1 = iflag; n1 >= iend; --n1) {//do n1=iflag,iend,-1 for (int x = 0; x < K; ++x) mi[x]=misub[x];//mi=misub mi[n1]=1;//mi(n1)=1; //if(any(iand(apmaskr(1:K),mi).eq.1)) continue;//cycle if (any_ca_iand_ca_eq1_91(apmaskr2,mi,K)) continue;//cycle ntotal++; for (int x = 0; x < K; ++x) me[x]=(m0[x] ^ mi[x]);//me=ieor(m0,mi) int nd1Kpt = 0; //double d1 = 0.0; //hv testsed //error hv -> if (n1==iflag) { mrbencode91(me,ce,g2_,N,K); for (int x = 0; x < M; ++x)//K=91 M=87 { e2sub[x]=(ce[K+x] ^ hdec2[K+x]);//e2sub=ieor(ce(K+1:N),hdec(K+1:N)) e2[x]=e2sub[x]; } nd1Kpt = 0; for (int x = 0; x < nt; ++x)//nt=40 K=87 M=87 nd1Kpt+=e2sub[x];//nd1Kpt=sum(e2sub(1:nt))+1; nd1Kpt = nd1Kpt + 1; d1 = 0.0; for (int x = 0; x < K; ++x) d1+=(double)(me[x] ^ hdec2[x])*absrx2[x];//d1=sum(ieor(me(1:K),hdec(1:K))*absrx(1:K)) } else { for (int x = 0; x < M; ++x) e2[x]=(e2sub[x] ^ g2_[n1][K+x]);//e2=ieor(e2sub,g2(K+1:N,n1)) nd1Kpt = 0; for (int x = 0; x < nt; ++x) nd1Kpt+=e2[x];//nd1Kpt=sum(e2(1:nt))+2 nd1Kpt = nd1Kpt + 2; } if (nd1Kpt <= ntheta) //c++ ==.EQ. !=.NE. >.GT. <.LT. >=.GE. <=.LE. { mrbencode91(me,ce,g2_,N,K); for (int x = 0; x < N; ++x) nxor[x]=(ce[x] ^ hdec2[x]);//nxor=ieor(ce,hdec) double dd = 0.0; if (n1==iflag) { dd = 0.0; for (int x = 0; x < M; ++x) dd+=(double)e2sub[x]*absrx2[K+x];//dd=d1+sum(e2sub*absrx(K+1:N)) dd=d1 + dd; } else { //dd=d1+ieor(ce(n1),hdec(n1))*absrx(n1)+sum(e2*absrx(K+1:N)) dd = 0.0; for (int x = 0; x < M; ++x) dd+=(double)e2[x]*absrx2[K+x]; dd = d1+(double)(ce[n1] ^ hdec2[n1])*absrx2[n1] + dd; } if ( dd < dmin ) { dmin=dd; for (int x = 0; x < N; ++x) cw[x]=ce[x];//cw=ce nhardmin = 0; for (int x = 0; x < N; ++x) nhardmin+=nxor[x];//nhardmin=sum(nxor) //nd1Kptbest=nd1Kpt; } } else nrejected++; } /*QString sss = "";///gen_osd174_[174][87]; for (int z= 0; z < 87; z++)//decoded=87 cw-174 { sss.append(QString("%1").arg((int)misub[z])); sss.append(","); } qDebug()<<"222 mi="<= 0; --i1) {//do i1=K,1,-1 for (int i2 = i1-1; i2 >= 0; --i2)//hv ??? i1-1 {//do i2=i1-1,1,-1 //ntotal=ntotal+1; for (int x = 0; x < ntau; ++x)//char g2_[87][174];//(N=174,K=87); ntau=19,14 mi[x]=(g2_[i1][K+x] ^ g2_[i2][K+x]);//mi=ieor(g2(K+1:K+ntau,i1),g2(K+1:K+ntau,i2)) boxit91(reset,mi,ntau,ntotal,i1,i2);//call boxit(reset,mi(1:ntau),ntau,ntotal,i1,i2) ntotal++; } } //int ncount2=0; //int ntotal2=0; reset=true; //! Now run through again and do the second pre-processing rule for (int z = 0; z < K-nord; ++z) //misub(1:K-iorder)=0 misub[z]=0; for (int z = K-nord; z < K; ++z) misub[z]=1; // misub(K-iorder+1:K)=1 iflag=K-nord; //iflag=K-iorder+1 while (iflag>=0)//c++ ==.EQ. !=.NE. >.GT. <.LT. >=.GE. <=.LE. { for (int z = 0; z < K; ++z) me[z]=(m0[z] ^ misub[z]);//me=ieor(m0,misub) mrbencode91(me,ce,g2_,N,K); for (int z = 0; z < M; ++z) e2sub[z]=(ce[K+z] ^ hdec2[K+z]);//e2sub=ieor(ce(K+1:N),hdec(K+1:N)) for (int i2 = -1; i2 < ntau; ++i2)//hv ntau+1 do i2=0,ntau {//do i2=0,ntau //ntotal2++;// no use??? for (int x = 0; x < M; ++x) ui[x]=0; if (i2>-1) ui[i2]=1; ///hv i2>0 if(i2>0) ui(i2)=1 for (int x = 0; x < M; ++x) r2pat[x]=(e2sub[x] ^ ui[x]);//r2pat=ieor(e2sub,ui) c778: // continue; int in1=-1;//hv reset -1 int in2=-1;//hv reset -1 fetchit91(reset,r2pat,ntau,in1,in2);//fetchit(reset,r2pat(1:ntau),ntau,in1,in2) if (in1>=0 && in2>=0)//hv >=0 if(in1>0.and.in2>0) then { //ncount2++; for (int z = 0; z < K; ++z) mi[z]=misub[z]; mi[in1]=1; mi[in2]=1; int sum_mi = 0; for (int z = 0; z < K; ++z) sum_mi+=mi[z]; //if(sum(mi).lt.nord+npre1+npre2.or.any(iand(apmaskr(1:K),mi).eq.1)) cycle if (sum_mi81) m96[i]=cw[i-5];//m96(83:96)=cw(78:91) } } int nbadcrc; get_crc14(m96,96,nbadcrc); //qDebug()<