diff --git a/lib/qra/q65/qra65.c b/lib/qra/q65/qra65.c
deleted file mode 100644
index efb3e94a0..000000000
--- a/lib/qra/q65/qra65.c
+++ /dev/null
@@ -1,795 +0,0 @@
-// qra65.c
-// QRA65 modes encoding/decoding functions
-//
-// (c) 2020 - Nico Palermo, IV3NWV - Microtelecom Srl, Italy
-// ------------------------------------------------------------------------------
-// This file is part of the qracodes project, a Forward Error Control
-// encoding/decoding package based on Q-ary RA (Repeat and Accumulate) LDPC codes.
-//
-// qracodes is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-// qracodes is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with qracodes source distribution.
-// If not, see .
-
-#include
-#include
-#include
-
-#include "qra65.h"
-#include "pdmath.h"
-
-
-static int _qra65_crc6(int *x, int sz);
-static void _qra65_crc12(int *y, int *x, int sz);
-
-
-int qra65_init(qra65_codec_ds *pCodec, const qracode *pqracode)
-{
- // Eb/No value for which we optimize the decoder metric (AWGN/Rayleigh cases)
- const float EbNodBMetric = 2.8f;
- const float EbNoMetric = (float)pow(10,EbNodBMetric/10);
-
- float R; // code effective rate (after puncturing)
- int nm; // bits per symbol
-
- if (!pCodec)
- return -1; // why do you called me?
-
- if (!pqracode)
- return -2; // invalid qra code
-
- if (pqracode->M!=64)
- return -3; // QRA65 supports only codes over GF(64)
-
- pCodec->pQraCode = pqracode;
-
- // allocate buffers used by encoding/decoding functions
- pCodec->x = (int*)malloc(pqracode->K*sizeof(int));
- pCodec->y = (int*)malloc(pqracode->N*sizeof(int));
- pCodec->qra_v2cmsg = (float*)malloc(pqracode->NMSG*pqracode->M*sizeof(float));
- pCodec->qra_c2vmsg = (float*)malloc(pqracode->NMSG*pqracode->M*sizeof(float));
- pCodec->ix = (float*)malloc(pqracode->N*pqracode->M*sizeof(float));
- pCodec->ex = (float*)malloc(pqracode->N*pqracode->M*sizeof(float));
-
- if (pCodec->x== NULL ||
- pCodec->y== NULL ||
- pCodec->qra_v2cmsg== NULL ||
- pCodec->qra_c2vmsg== NULL ||
- pCodec->ix== NULL ||
- pCodec->ex== NULL) {
- qra65_free(pCodec);
- return -4; // out of memory
- }
-
- // compute and store the AWGN/Rayleigh Es/No ratio for which we optimize
- // the decoder metric
- nm = _qra65_get_bits_per_symbol(pqracode);
- R = _qra65_get_code_rate(pqracode);
- pCodec->decoderEsNoMetric = 1.0f*nm*R*EbNoMetric;
-
- return 1;
-}
-
-void qra65_free(qra65_codec_ds *pCodec)
-{
- if (!pCodec)
- return;
-
- // free internal buffers
- if (pCodec->x!=NULL)
- free(pCodec->x);
-
- if (pCodec->y!=NULL)
- free(pCodec->y);
-
- if (pCodec->qra_v2cmsg!=NULL)
- free(pCodec->qra_v2cmsg);
-
- if (pCodec->qra_c2vmsg!=NULL)
- free(pCodec->qra_c2vmsg);
-
- if (pCodec->ix!=NULL)
- free(pCodec->ix);
-
- if (pCodec->ex!=NULL)
- free(pCodec->ex);
-
- pCodec->pQraCode = NULL;
- pCodec->x = NULL;
- pCodec->y = NULL;
- pCodec->qra_v2cmsg = NULL;
- pCodec->qra_c2vmsg = NULL;
- pCodec->qra_v2cmsg = NULL;
- pCodec->ix = NULL;
- pCodec->ex = NULL;
-
- return;
-}
-
-int qra65_encode(const qra65_codec_ds *pCodec, int *pOutputCodeword, const int *pInputMsg)
-{
- const qracode *pQraCode;
- int *px;
- int *py;
- int nK;
- int nN;
-
- if (!pCodec)
- return -1; // which codec?
-
- pQraCode = pCodec->pQraCode;
- px = pCodec->x;
- py = pCodec->y;
- nK = _qra65_get_message_length(pQraCode);
- nN = _qra65_get_codeword_length(pQraCode);
-
- // copy the information symbols into the internal buffer
- memcpy(px,pInputMsg,nK*sizeof(int));
-
- // compute and append the appropriate CRC if required
- switch (pQraCode->type) {
- case QRATYPE_NORMAL:
- break;
- case QRATYPE_CRC:
- case QRATYPE_CRCPUNCTURED:
- px[nK] = _qra65_crc6(px,nK);
- break;
- case QRATYPE_CRCPUNCTURED2:
- _qra65_crc12(px+nK,px,nK);
- break;
- default:
- return -2; // code type not supported
- }
-
- // encode with the given qra code
- qra_encode(pQraCode,py,px);
-
- // puncture the CRC symbols as required
- // and copy the result to the destination buffer
- switch (pQraCode->type) {
- case QRATYPE_NORMAL:
- case QRATYPE_CRC:
- // no puncturing
- memcpy(pOutputCodeword,py,nN*sizeof(int));
- break;
- case QRATYPE_CRCPUNCTURED:
- // strip the single CRC symbol from the encoded codeword
- memcpy(pOutputCodeword,py,nK*sizeof(int)); // copy the systematic symbols
- memcpy(pOutputCodeword+nK,py+nK+1,(nN-nK)*sizeof(int)); // copy the check symbols skipping the CRC symbol
- break;
- case QRATYPE_CRCPUNCTURED2:
- // strip the 2 CRC symbols from the encoded codeword
- memcpy(pOutputCodeword,py,nK*sizeof(int)); // copy the systematic symbols
- memcpy(pOutputCodeword+nK,py+nK+2,(nN-nK)*sizeof(int)); // copy the check symbols skipping the two CRC symbols
- break;
- default:
- return -2; // code type unsupported
- }
-
- return 1; // ok
-}
-
-int qra65_intrinsics(qra65_codec_ds *pCodec, float *pIntrinsics, const float *pInputEnergies)
-{
- // compute observations intrinsics probabilities
- // for the AWGN/Rayleigh channels
-
- // NOTE:
- // A true Rayleigh channel metric would require that the channel gains were known
- // for each symbol in the codeword. Such gains cannot be estimated reliably when
- // the Es/No ratio is small. Therefore we compute intrinsic probabilities assuming
- // that, on average, these channel gains are unitary.
- // In general it is even difficult to estimate the Es/No ratio for the AWGN channel
- // Therefore we always compute the intrinsic probabilities assuming that the Es/No
- // ratio is known and equal to the constant decoderEsNoMetric. This assumption will
- // generate the true intrinsic probabilities only when the actual Eb/No ratio is
- // equal to this constant. As in all the other cases the probabilities are evaluated
- // with a wrong scaling constant we can expect that the decoder performance at different
- // Es/No will be worse. Anyway, since the EsNoMetric constant has been chosen so that the
- // decoder error rate is about 50%, we obtain almost optimal error rates down to
- // any useful Es/No ratio.
-
- const qracode *pQraCode;
- int nN, nBits;
- float EsNoMetric;
-
- if (pCodec==NULL)
- return -1; // which codec?
-
- pQraCode = pCodec->pQraCode;
- nN = _qra65_get_codeword_length(pQraCode);
- nBits = pQraCode->m;
-
- EsNoMetric = pCodec->decoderEsNoMetric;
- qra_mfskbesselmetric(pIntrinsics,pInputEnergies,nBits,nN,EsNoMetric);
-
- return 1; // success
-}
-
-int qra65_esnodb(const qra65_codec_ds *pCodec, float *pEsNodB, const int *ydec, const float *pInputEnergies)
-{
- // compute average Es/No for the AWGN/Rayleigh channel cases
-
- int k,j;
- float sigplusnoise=0;
- float noise=0;
- int nN, nM;
- const float *pIn = pInputEnergies;
- const int *py = ydec;
- float EsNodB;
-
- nN = qra65_get_codeword_length(pCodec);
- nM = qra65_get_alphabet_size(pCodec);
-
- for (k=0;k4)
- return QRA65_DECODE_INVPARAMS; // invalid submode
-
- // As the symbol duration in QRA65 is longer than in QRA64 the fading tables continue
- // to be valid if the B90 parameter is scaled by the actual symbol rate
- // Compute index to most appropriate weighting function coefficients
- hidx = (int)(logf(B90*TS_QRA65/TS_QRA64)/logf(1.09f) - 0.499f);
-
-// if (hidx<0 || hidx > 64)
-// // index of weighting function out of range
-// // B90 out of range
-// return QRA65_DECODE_INVPARAMS;
-
- // Unlike in QRA64 we accept any B90, anyway limiting it to
- // the extreme cases (0.9 to 210 Hz approx.)
- if (hidx<0)
- hidx = 0;
- else
- if (hidx > 64)
- hidx=64;
-
- // select the appropriate weighting fading coefficients array
- if (fadingModel==0) { // gaussian fading model
- // point to gaussian energy weighting taps
- hlen = glen_tab_gauss[hidx]; // hlen = (L+1)/2 (where L=(odd) number of taps of w fun)
- hptr = gptr_tab_gauss[hidx]; // pointer to the first (L+1)/2 coefficients of w fun
- }
- else if (fadingModel==1) {
- // point to lorentzian energy weighting taps
- hlen = glen_tab_lorentz[hidx]; // hlen = (L+1)/2 (where L=(odd) number of taps of w fun)
- hptr = gptr_tab_lorentz[hidx]; // pointer to the first (L+1)/2 coefficients of w fun
- }
- else
- return QRA65_DECODE_INVPARAMS; // invalid fading model
-
- // compute (euristically) the optimal decoder metric accordingly the given spread amount
- // We assume that the decoder 50% decoding threshold is:
- // Es/No(dB) = Es/No(AWGN)(dB) + 8*log(B90)/log(240)(dB)
- // that's to say, at the maximum Doppler spread bandwidth (240 Hz for QRA64)
- // there's a ~8 dB Es/No degradation over the AWGN case
- fTemp = 8.0f*logf(B90)/logf(240.0f); // assumed Es/No degradation for the given fading bandwidth
- EsNoMetric = pCodec->decoderEsNoMetric*powf(10.0f,fTemp/10.0f);
-
- nM = qra65_get_alphabet_size(pCodec);
- nN = qra65_get_codeword_length(pCodec);
- nBinsPerTone = 1<ffNoiseVar = fNoiseVar;
- pCodec->ffEsNoMetric = EsNoMetric;
- pCodec->nBinsPerTone = nBinsPerTone;
- pCodec->nBinsPerSymbol = nBinsPerSymbol;
- pCodec->nWeights = hlen;
- weight = pCodec->ffWeight;
-
- // compute the fast fading weights accordingly to the Es/No ratio
- // for which we compute the exact intrinsics probabilities
- for (k=0;kmaxlogp) // keep track of the max
- maxlogp = fTemp;
- pCurIx[k]=fTemp;
-
- pCurBin += nBinsPerTone; // next tone
- }
-
- // exponentiate and accumulate the normalization constant
- sumix = 0.0f;
- for (k=0;knBinsPerTone;
- nBinsPerSymbol = pCodec->nBinsPerSymbol;
- nWeights = pCodec->nWeights;
- ffNoiseVar = pCodec->ffNoiseVar;
- ffEsNoMetric = pCodec->ffEsNoMetric;
- nTotWeights = 2*nWeights-1;
-
- // compute symbols energy (noise included) summing the
- // energies pertaining to the decoded symbols in the codeword
-
- EsPlusWNo = 0.0f;
- pCurSym = pInputEnergies + nM; // point to first central bin of first symbol tone
- for (n=0;npQraCode;
- ix = pCodec->ix;
- ex = pCodec->ex;
-
- nK = _qra65_get_message_length(pQraCode);
- nN = _qra65_get_codeword_length(pQraCode);
- nM = pQraCode->M;
- nBits = pQraCode->m;
-
- px = pCodec->x;
- py = pCodec->y;
-
- // Depuncture intrinsics observations as required by the code type
- switch (pQraCode->type) {
- case QRATYPE_CRCPUNCTURED:
- memcpy(ix,pIntrinsics,nK*nM*sizeof(float)); // information symbols
- pd_init(PD_ROWADDR(ix,nM,nK),pd_uniform(nBits),nM); // crc
- memcpy(ix+(nK+1)*nM,pIntrinsics+nK*nM,(nN-nK)*nM*sizeof(float)); // parity checks
- break;
- case QRATYPE_CRCPUNCTURED2:
- memcpy(ix,pIntrinsics,nK*nM*sizeof(float)); // information symbols
- pd_init(PD_ROWADDR(ix,nM,nK),pd_uniform(nBits),nM); // crc
- pd_init(PD_ROWADDR(ix,nM,nK+1),pd_uniform(nBits),nM); // crc
- memcpy(ix+(nK+2)*nM,pIntrinsics+nK*nM,(nN-nK)*nM*sizeof(float)); // parity checks
- break;
- case QRATYPE_NORMAL:
- case QRATYPE_CRC:
- default:
- // no puncturing
- memcpy(ix,pIntrinsics,nN*nM*sizeof(float)); // as they are
- }
-
- // mask the intrinsics with the available a priori knowledge
- if (pAPMask!=NULL)
- _qra65_mask(pQraCode,ix,pAPMask,pAPSymbols);
-
-
- // Compute the extrinsic symbols probabilities with the message-passing algorithm
- // Stop if the extrinsics information does not converges to unity
- // within the given number of iterations
- rc = qra_extrinsic( pQraCode,
- ex,
- ix,
- 100,
- pCodec->qra_v2cmsg,
- pCodec->qra_c2vmsg);
-
- if (rc<0)
- // failed to converge to a solution
- return QRA65_DECODE_FAILED;
-
- // decode the information symbols (punctured information symbols included)
- qra_mapdecode(pQraCode,px,ex,ix);
-
- // verify CRC match
-
- switch (pQraCode->type) {
- case QRATYPE_CRC:
- case QRATYPE_CRCPUNCTURED:
- crc6=_qra65_crc6(px,nK); // compute crc-6
- if (crc6!=px[nK])
- return QRA65_DECODE_CRCMISMATCH; // crc doesn't match
- break;
- case QRATYPE_CRCPUNCTURED2:
- _qra65_crc12(crc12, px,nK); // compute crc-12
- if (crc12[0]!=px[nK] ||
- crc12[1]!=px[nK+1])
- return QRA65_DECODE_CRCMISMATCH; // crc doesn't match
- break;
- case QRATYPE_NORMAL:
- default:
- // nothing to check
- break;
- }
-
- // copy the decoded msg to the user buffer (excluding punctured symbols)
- if (pDecodedMsg)
- memcpy(pDecodedMsg,px,nK*sizeof(int));
-
- if (pDecodedCodeword==NULL) // user is not interested in it
- return rc; // return the number of iterations required to decode
-
- // crc matches therefore we can reconstruct the transmitted codeword
- // reencoding the information available in px...
-
- qra_encode(pQraCode, py, px);
-
- // ...and strip the punctured symbols from the codeword
- switch (pQraCode->type) {
- case QRATYPE_CRCPUNCTURED:
- memcpy(pDecodedCodeword,py,nK*sizeof(int));
- memcpy(pDecodedCodeword+nK,py+nK+1,(nN-nK)*sizeof(int)); // puncture crc-6 symbol
- break;
- case QRATYPE_CRCPUNCTURED2:
- memcpy(pDecodedCodeword,py,nK*sizeof(int));
- memcpy(pDecodedCodeword+nK,py+nK+2,(nN-nK)*sizeof(int)); // puncture crc-12 symbols
- break;
- case QRATYPE_CRC:
- case QRATYPE_NORMAL:
- default:
- memcpy(pDecodedCodeword,py,nN*sizeof(int)); // no puncturing
- }
-
- return rc; // return the number of iterations required to decode
-
-}
-
-
-
-
-// helper functions -------------------------------------------------------------
-
-int _qra65_get_message_length(const qracode *pCode)
-{
- // return the actual information message length (in symbols)
- // excluding any punctured symbol
-
- int nMsgLength;
-
- switch (pCode->type) {
- case QRATYPE_NORMAL:
- nMsgLength = pCode->K;
- break;
- case QRATYPE_CRC:
- case QRATYPE_CRCPUNCTURED:
- // one information symbol of the underlying qra code is reserved for CRC
- nMsgLength = pCode->K-1;
- break;
- case QRATYPE_CRCPUNCTURED2:
- // two code information symbols are reserved for CRC
- nMsgLength = pCode->K-2;
- break;
- default:
- nMsgLength = -1;
- }
-
- return nMsgLength;
-}
-
-int _qra65_get_codeword_length(const qracode *pCode)
-{
- // return the actual codeword length (in symbols)
- // excluding any punctured symbol
-
- int nCwLength;
-
- switch (pCode->type) {
- case QRATYPE_NORMAL:
- case QRATYPE_CRC:
- // no puncturing
- nCwLength = pCode->N;
- break;
- case QRATYPE_CRCPUNCTURED:
- // the CRC symbol is punctured
- nCwLength = pCode->N-1;
- break;
- case QRATYPE_CRCPUNCTURED2:
- // the two CRC symbols are punctured
- nCwLength = pCode->N-2;
- break;
- default:
- nCwLength = -1;
- }
-
- return nCwLength;
-}
-
-float _qra65_get_code_rate(const qracode *pCode)
-{
- return 1.0f*_qra65_get_message_length(pCode)/_qra65_get_codeword_length(pCode);
-}
-
-int _qra65_get_alphabet_size(const qracode *pCode)
-{
- return pCode->M;
-}
-int _qra65_get_bits_per_symbol(const qracode *pCode)
-{
- return pCode->m;
-}
-static void _qra65_mask(const qracode *pcode, float *ix, const int *mask, const int *x)
-{
- // mask intrinsic information ix with available a priori knowledge
-
- int k,kk, smask;
- const int nM=pcode->M;
- const int nm=pcode->m;
- int nK;
-
- // Exclude from masking the symbols which have been punctured.
- // nK is the length of the mask and x arrays, which do
- // not include any punctured symbol
- nK = _qra65_get_message_length(pcode);
-
- // for each symbol set to zero the probability
- // of the values which are not allowed by
- // the a priori information
-
- for (k=0;k>1) ^ CRC6_GEN_POL;
- else
- sr = (sr>>1);
- t>>=1;
- }
- }
-
- return sr;
-}
-
-static void _qra65_crc12(int *y, int *x, int sz)
-{
- int k,j,t,sr = 0;
- for (k=0;k>1) ^ CRC12_GEN_POL;
- else
- sr = (sr>>1);
- t>>=1;
- }
- }
-
- y[0] = sr&0x3F;
- y[1] = (sr>>6);
-}
-
-
diff --git a/lib/qra/q65/qra65.h b/lib/qra/q65/qra65.h
deleted file mode 100644
index ffa383279..000000000
--- a/lib/qra/q65/qra65.h
+++ /dev/null
@@ -1,101 +0,0 @@
-// qra65.h
-// QRA65 modes encoding/decoding functions
-//
-// (c) 2020 - Nico Palermo, IV3NWV - Microtelecom Srl, Italy
-// ------------------------------------------------------------------------------
-// This file is part of the qracodes project, a Forward Error Control
-// encoding/decoding package based on Q-ary RA (Repeat and Accumulate) LDPC codes.
-//
-// qracodes is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-// qracodes is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with qracodes source distribution.
-// If not, see .
-
-#ifndef _qra65_h
-#define _qra65_h
-
-#include "qracodes.h"
-
-// Error codes returned by qra65_decode(...)
-#define QRA65_DECODE_INVPARAMS -1
-#define QRA65_DECODE_FAILED -2
-#define QRA65_DECODE_CRCMISMATCH -3
-
-// maximum number of weights for the fast-fading metric evaluation
-#define QRA65_FASTFADING_MAXWEIGTHS 65
-
-typedef struct {
- const qracode *pQraCode; // qra code to be used by the codec
- float decoderEsNoMetric; // value for which we optimize the decoder metric
- int *x; // codec input
- int *y; // codec output
- float *qra_v2cmsg; // decoder v->c messages
- float *qra_c2vmsg; // decoder c->v messages
- float *ix; // decoder intrinsic information
- float *ex; // decoder extrinsic information
- // variables used to compute the intrinsics in the fast-fading case
- int nBinsPerTone;
- int nBinsPerSymbol;
- float ffNoiseVar;
- float ffEsNoMetric;
- int nWeights;
- float ffWeight[QRA65_FASTFADING_MAXWEIGTHS];
-} qra65_codec_ds;
-
-int qra65_init(qra65_codec_ds *pCodec, const qracode *pQraCode);
-void qra65_free(qra65_codec_ds *pCodec);
-
-int qra65_encode(const qra65_codec_ds *pCodec, int *pOutputCodeword, const int *pInputMsg);
-
-int qra65_intrinsics(qra65_codec_ds *pCodec, float *pIntrinsics, const float *pInputEnergies);
-
-int qra65_intrinsics_fastfading(qra65_codec_ds *pCodec,
- float *pIntrinsics, // intrinsic symbol probabilities output
- const float *pInputEnergies, // received energies input
- const int submode, // submode idx (0=A ... 4=E)
- const float B90, // spread bandwidth (90% fractional energy)
- const int fadingModel); // 0=Gaussian 1=Lorentzian fade model
-
-
-int qra65_decode(qra65_codec_ds *pCodec,
- int* pDecodedCodeword,
- int *pDecodedMsg,
- const float *pIntrinsics,
- const int *pAPMask,
- const int *pAPSymbols);
-
-int qra65_esnodb(const qra65_codec_ds *pCodec,
- float *pEsNodB,
- const int *ydec,
- const float *pInputEnergies);
-
-int qra65_esnodb_fastfading(
- const qra65_codec_ds *pCodec,
- float *pEsNodB,
- const int *ydec,
- const float *pInputEnergies);
-
-
-#define qra65_get_message_length(pCodec) _qra65_get_message_length((pCodec)->pQraCode)
-#define qra65_get_codeword_length(pCodec) _qra65_get_codeword_length((pCodec)->pQraCode)
-#define qra65_get_code_rate(pCodec) _qra65_get_code_rate((pCodec)->pQraCode)
-#define qra65_get_alphabet_size(pCodec) _qra65_get_alphabet_size((pCodec)->pQraCode)
-#define qra65_get_bits_per_symbol(pCodec) _qra65_get_bits_per_symbol((pCodec)->pQraCode)
-
-// internally used but made publicly available for the defines above
-int _qra65_get_message_length(const qracode *pCode);
-int _qra65_get_codeword_length(const qracode *pCode);
-float _qra65_get_code_rate(const qracode *pCode);
-void _qra65_mask(const qracode *pcode, float *ix, const int *mask, const int *x);
-int _qra65_get_alphabet_size(const qracode *pCode);
-int _qra65_get_bits_per_symbol(const qracode *pCode);
-
-#endif // _qra65_h
\ No newline at end of file