📄 ccdecoding.cpp
字号:
}
pl = *(pPreviousMtr + j ) - branchValue;
ph = *(pPreviousMtr + jh) + branchValue;
if (pl > ph)
{
*(pUpdateMtr + j2 + 1) = pl;
*(pTbMtr + j2 + 1) = 0;
}
else
{
*(pUpdateMtr + j2 + 1 ) = ph;
*(pTbMtr + j2 + 1 ) = 1;
}
}
//one time butterfly
if (*pUpdateMtr >= PMETRIC_SCALE_THRESH) // time to scale the path metric
{
for (j = 1; j < stateSize; j++)
{
*(pUpdateMtr + j) -= *pUpdateMtr;
}
*pUpdateMtr = 0;
}
//delete the overflow path metric
pDecIn += ccCodeRate; // move to input samples for next bit
pPreviousMtr += pBufferIndex;
pUpdateMtr -= pBufferIndex;
pBufferIndex *= -1;
}
pMeasureMtr = pUpdateMtr;
for (i = 0; i < ccCodeConstraint; i++) // trellis ramp down
{
pTbMtr = traceBackFlags[tbIndex++];
jStep = 1 << i;
branchMetric[0] = *(pDecIn + 1) + *pDecIn;
branchMetric[1] = *(pDecIn + 1) - *pDecIn;
branchMetric[2] = -branchMetric[1];
branchMetric[3] = -branchMetric[0];
for (j = 0; j < halfStates; j += jStep)
{
branchValue = branchMetric[*(bMapTable + j)];
jh = j + halfStates;
j2 = j << 1;
pl = *(pPreviousMtr + j ) + branchValue;
ph = *(pPreviousMtr + jh) - branchValue;
if (pl > ph)
{
*(pUpdateMtr + j2) = pl;
*(pTbMtr + j2) = 0;
}
else
{
*(pUpdateMtr + j2) = ph;
*(pTbMtr + j2) = 1;
}
}
pDecIn += ccCodeRate; // move to input samples for next bit
pPreviousMtr += pBufferIndex;
pUpdateMtr -= pBufferIndex;
pBufferIndex *= -1;
}
tbState = 0;
pDecOut += (ccInformLen + ccCodeConstraint);
// start trace-back operation
for (i = ccInformLen + ccCodeConstraint ; i > 0; i--)
{
pTbMtr = traceBackFlags[--tbIndex];
*(--pDecOut) = (Int8)(*(pTbMtr + tbState) & 1);
tbState = *pDecOut * halfStates + (tbState >> 1);
} // trace-back is done
//trace back
}
/*************************************************************************************
* Function: viSoftDecodingEnd()
*
* Functionality: viterbi soft decoding for ccrate = 1/2.
*
* Input:
* *pDecIn : pointer to the input soft data to be decoded
* ccInformLen: code size in terms of information bits (NOT the encoded
* bits), excluding the tail bits
* *bMapTable : pointer to the table than maps a state to the
* corresponding branch metric
* Output:
* *pDecOut : pointer to the output bits
* Input/Output
* *pMeasureMtc : load last time Measure Metric and conserve Measure Metric
************************************************************************************/
void viSoftDecodingEnd(Int8 *pDecOut, Int8 *pDecIn, Int16 ccInformLen, Int16 *bMapTable,
Int16 ccCodeRate, Int16 ccCodeConstraint, Int16 *pMeasureMtr)
{
Int16 traceBackFlags[MAX_CONV_LENGTH][MAX_CONV_STATES];//traceBackFlags[4110][64];
Int16 pathMetric[2][MAX_CONV_STATES];//pathMetric[2][64]
Int16 branchMetric[4];
Int16 stateSize, halfStates;
Int16 pBufferIndex = MAX_CONV_STATES, tbIndex = 0;
Int16 *pPreviousMtr, *pUpdateMtr, *pTbMtr, pl, ph, tbState;
Int16 i, j, j2, jh, jStep, branchValue;
stateSize = 1 << ccCodeConstraint;
halfStates = stateSize >> 1;
pUpdateMtr = pathMetric[1];
pPreviousMtr = pathMetric[0];
for (i = 0; i < MAX_CONV_STATES; i++)
{
pPreviousMtr[i] = pMeasureMtr[i];
}
//保留上一个symbol做完viterbi decoding的量度值
for (i = 0; i < ccCodeConstraint; i++) // trellis ramp-up
{
branchMetric[0] = *(pDecIn + 1) + *pDecIn;
branchMetric[1] = *(pDecIn + 1) - *pDecIn;
branchMetric[2] = -branchMetric[1];
branchMetric[3] = -branchMetric[0];
//根据不同的状态,设定不同的量度值
for (j = 0; j < halfStates; j++)
{
branchValue = branchMetric[*(bMapTable + j)];
j2 = j << 1;
jh = j + halfStates;
pl = *(pPreviousMtr +j ) + branchValue;
ph = *(pPreviousMtr +jh) - branchValue;
if (pl > ph)
{
*(pUpdateMtr + j2) = pl;
}
else
{
*(pUpdateMtr + j2) = ph;
}
pl = *(pPreviousMtr + j ) - branchValue;
ph = *(pPreviousMtr + jh) + branchValue;
if (pl > ph)
{
*(pUpdateMtr + j2 + 1) = pl;
}
else
{
*(pUpdateMtr + j2 + 1 ) = ph;
}
}
//one time butterfly
if (*pUpdateMtr >= PMETRIC_SCALE_THRESH) // time to scale the path metric
{
for (j = 1; j < stateSize; j++)
{
*(pUpdateMtr + j) -= *pUpdateMtr;
}
*pUpdateMtr = 0;
}
//delete the overflow path metric
pDecIn += ccCodeRate; // move to input samples for next bit
pPreviousMtr += pBufferIndex;
pUpdateMtr -= pBufferIndex;
pBufferIndex *= -1;
}
for (i = 0; i < (ccInformLen - ccCodeConstraint) ; i++) // add-compare-select (ACS) operations on regular trellis
{
pTbMtr = traceBackFlags[tbIndex++];
branchMetric[0] = *(pDecIn + 1) + *pDecIn;
branchMetric[1] = *(pDecIn + 1) - *pDecIn;
branchMetric[2] = -branchMetric[1];
branchMetric[3] = -branchMetric[0];
//根据不同的状态,设定不同的量度值
for (j = 0; j < halfStates; j++)
{
branchValue = branchMetric[*(bMapTable + j)];
j2 = j << 1;
jh = j + halfStates;
pl = *(pPreviousMtr +j ) + branchValue;
ph = *(pPreviousMtr +jh) - branchValue;
if (pl > ph)
{
*(pUpdateMtr + j2) = pl;
*(pTbMtr + j2) = 0;
}
else
{
*(pUpdateMtr + j2) = ph;
*(pTbMtr + j2) = 1;
}
pl = *(pPreviousMtr + j ) - branchValue;
ph = *(pPreviousMtr + jh) + branchValue;
if (pl > ph)
{
*(pUpdateMtr + j2 + 1) = pl;
*(pTbMtr + j2 + 1) = 0;
}
else
{
*(pUpdateMtr + j2 + 1 ) = ph;
*(pTbMtr + j2 + 1 ) = 1;
}
}
//one time butterfly
if (*pUpdateMtr >= PMETRIC_SCALE_THRESH) // time to scale the path metric
{
for (j = 1; j < stateSize; j++)
{
*(pUpdateMtr + j) -= *pUpdateMtr;
}
*pUpdateMtr = 0;
}
//delete the overflow path metric
pDecIn += ccCodeRate; // move to input samples for next bit
pPreviousMtr += pBufferIndex;
pUpdateMtr -= pBufferIndex;
pBufferIndex *= -1;
}
for (i = 0; i < ccCodeConstraint; i++) // trellis ramp down
{
pTbMtr = traceBackFlags[tbIndex++];
jStep = 1 << i;
branchMetric[0] = *(pDecIn + 1) + *pDecIn;
branchMetric[1] = *(pDecIn + 1) - *pDecIn;
branchMetric[2] = -branchMetric[1];
branchMetric[3] = -branchMetric[0];
for (j = 0; j < halfStates; j += jStep)
{
branchValue = branchMetric[*(bMapTable + j)];
jh = j + halfStates;
j2 = j << 1;
pl = *(pPreviousMtr + j ) + branchValue;
ph = *(pPreviousMtr + jh) - branchValue;
if (pl > ph)
{
*(pUpdateMtr + j2) = pl;
*(pTbMtr + j2) = 0;
}
else
{
*(pUpdateMtr + j2) = ph;
*(pTbMtr + j2) = 1;
}
}
pDecIn += ccCodeRate; // move to input samples for next bit
pPreviousMtr += pBufferIndex;
pUpdateMtr -= pBufferIndex;
pBufferIndex *= -1;
}
pMeasureMtr = pUpdateMtr;
tbState = 0;
pDecOut += ccInformLen; // start trace-back operation
for (i = ccInformLen; i > 0; i--)
{
pTbMtr = traceBackFlags[--tbIndex];
*(--pDecOut) = (Int8)(*(pTbMtr + tbState) & 1);
tbState = *pDecOut * halfStates + (tbState >> 1);
} // trace-back is done
//trace back
}
/*************************************************************************************
* Function : ccDecoding()
*
* Functionality : cc soft decoding for every code rate.
*
************************************************************************************/
void ccDecoding(Uint8 mode,
DlRxBurstParam *pDlRxBurstParam,
Int8 *pCcDecodingIn,
Uint16 ccDecodingInLength,
Uint16 ccRate,
Uint8 *pCcDecodingOut,
Uint16 ccDecodingOutLength)
{
Int8 dePunctureIn[MAX_CONV_LENGTH];
Int8 *pDePunctureIn = dePunctureIn;
Int8 viDecodingOut[MAX_CONV_LENGTH/2];
Int8 *pViDecodingOut = viDecodingOut;
Uint16 vtDecodInLength;
static Int16 tempMetric[MAX_CONV_STATES];
Int16 i,j;
switch(ccRate)
{
case ONE_HALF:
for (i = 0; i < ccDecodingInLength; i++)
{
*(pDePunctureIn++) = *(pCcDecodingIn++);
}
//ccDecodeTempLength = ccDecodingInLength;
break;
case TWO_THIRDS:
for (i = 0; i < ccDecodingInLength/3; i++)
{
*(pDePunctureIn++) = *(pCcDecodingIn++);
*(pDePunctureIn++) = *(pCcDecodingIn++);
*(pDePunctureIn++) = 0;
*(pDePunctureIn++) = *(pCcDecodingIn++);
}
//ccDecodeTempLength = ccDecodingInLength /3 * 4;
break;
case THREE_FOURTHS:
for (i = 0; i < ccDecodingInLength/4; i++)
{
*(pDePunctureIn++) = *(pCcDecodingIn++);
*(pDePunctureIn++) = *(pCcDecodingIn++);
*(pDePunctureIn++) = 0;
*(pDePunctureIn++) = *(pCcDecodingIn++);
*(pDePunctureIn++) = *(pCcDecodingIn++);
*(pDePunctureIn++) = 0;
}
//ccDecodeTempLength = ccDecodingInLength / 4 * 6;
break;
case FIVE_SIXTHS:
for (i = 0; i < ccDecodingInLength/6; i++)
{
*(pDePunctureIn++) = *(pCcDecodingIn++);
*(pDePunctureIn++) = *(pCcDecodingIn++);
*(pDePunctureIn++) = 0;
*(pDePunctureIn++) = *(pCcDecodingIn++);
*(pDePunctureIn++) = *(pCcDecodingIn++);
*(pDePunctureIn++) = 0;
*(pDePunctureIn++) = 0;
*(pDePunctureIn++) = *(pCcDecodingIn++);
*(pDePunctureIn++) = *(pCcDecodingIn++);
*(pDePunctureIn++) = 0;
}
//ccDecodeTempLength = ccDecodingInLength /6 * 10;
break;
default:
// printf("the code rate for convoluational coding is not available!");
break;
}
pDePunctureIn = &dePunctureIn[0];
vtDecodInLength = ccDecodingOutLength * 8 - CC_CODE_CONSTRAIT;
//CC_CODE_RATE = 2,CC_CODE_CONSTRAIT = 6
if ((*pDlRxBurstParam).burstSizeSym == 1)
{
viSoftDecoding (pViDecodingOut,
pDePunctureIn,
vtDecodInLength,
bMapTable,
CC_CODE_RATE,
CC_CODE_CONSTRAIT);
vtDecodInLength /= 8;
for (i = 0; i < vtDecodInLength; i++)
{
*pCcDecodingOut = 0;
for (j = 0; j < 8; j++)
{
*pCcDecodingOut ^= *pViDecodingOut++ << (7 - j);
}
pCcDecodingOut++;
}
*pCcDecodingOut = 0;
}
else
{
if ((*pDlRxBurstParam).ofdmSymIndex == 0)
{
viSoftDecodingStart (pViDecodingOut,
pDePunctureIn,
vtDecodInLength,
bMapTable,
CC_CODE_RATE,
CC_CODE_CONSTRAIT,
tempMetric);
for (i = 0; i < ccDecodingOutLength; i++)
{
*pCcDecodingOut = 0;
for (j = 0; j < 8; j++)
{
*pCcDecodingOut ^= *pViDecodingOut++ << (7 - j);
}
pCcDecodingOut++;
}
}
else
{
if ((*pDlRxBurstParam).ofdmSymIndex == (*pDlRxBurstParam).burstSizeSym -1)
{
viSoftDecodingEnd (pViDecodingOut,
pDePunctureIn,
vtDecodInLength,
bMapTable,
CC_CODE_RATE,
CC_CODE_CONSTRAIT,
tempMetric);
vtDecodInLength /= 8;
for (i = 0; i < vtDecodInLength; i++)
{
*pCcDecodingOut = 0;
for (j = 0; j < 8; j++)
{
*pCcDecodingOut ^= *pViDecodingOut++ << (7 - j);
}
pCcDecodingOut++;
}
}
else
{
viSoftDecodingMid (pViDecodingOut,
pDePunctureIn,
vtDecodInLength,
bMapTable,
CC_CODE_RATE,
CC_CODE_CONSTRAIT,
tempMetric);
*pCcDecodingOut = 0;
for (i = 0; i < ccDecodingOutLength; i++)
{
*pCcDecodingOut = 0;
for (j = 0; j < 8; j++)
{
*pCcDecodingOut ^= *pViDecodingOut++ << (7 - j);
}
pCcDecodingOut++;
}
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -