📄 ccdecoding.cpp
字号:
/***************************************************************************
* Copyright (c) 2003, Coast Co. Ltd.
*
* All rights reserved.
*
*
* Filename:ccDecoding.cpp
*
* File Description:
*
* Implementation of the tcm decoding defined in IEEE 802.16 SCa.
* -------------------------------------------------------------------------
*
* Revision:2.0
* Author :Hu Bo
* Date :18/12/2004
*
* Revision Details
* -----------------------------------------
*
****************************************************************************/
/*****************************************************************************
* Include Files
****************************************************************************/
#include "global_var.h"
#include "typedef.h"
#include "globalMacro.h"
#include "ccDecoding.h"
/*************************************************************************************
* Function: viSoftDecoding()
*
* 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
*
************************************************************************************/
void viSoftDecoding(Int8 *pDecOut, Int8 *pDecIn, Int16 ccInformLen, Int16 *bMapTable,
Int16 ccCodeRate, Int16 ccCodeConstraint)
{
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, jMax, jStep, branchValue;
stateSize = 1 << ccCodeConstraint;
halfStates = stateSize >> 1;
pUpdateMtr = pathMetric[1];
pPreviousMtr = pathMetric[0];
*pPreviousMtr = 0; // clear up path metric
for (i = 0; i < ccCodeConstraint; i++) // trellis ramp-up
{
jMax = 1 << i;
//根据不同的状态,设定不同的量度值
branchMetric[0] = *(pDecIn + 1) + *pDecIn;//00
branchMetric[1] = *(pDecIn + 1) - *pDecIn;//10
branchMetric[2] = -branchMetric[1];//01
branchMetric[3] = -branchMetric[0];//11
for (j = 0; j < jMax; j++)
{
branchValue = branchMetric[*(bMapTable + j)];
j2 = j << 1;
*(pUpdateMtr + j2) = *(pPreviousMtr + j) + branchValue;
*(pUpdateMtr + j2 + 1) = *(pPreviousMtr + j) - branchValue;
}
pDecIn += ccCodeRate; // move to input samples for next bit
pPreviousMtr += pBufferIndex;//let pUpdateMtr be next pUpdateMtr
pUpdateMtr -= pBufferIndex;//delete the last pPreviousMtr
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;
}
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: viSoftDecodingStart()
*
* 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 viSoftDecodingStart(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, jMax, jStep, branchValue;
stateSize = 1 << ccCodeConstraint;
halfStates = stateSize >> 1;
pUpdateMtr = pathMetric[1];
pPreviousMtr = pathMetric[0];
*pPreviousMtr = 0; // clear up path metric
for (i = 0; i < ccCodeConstraint; i++)
{
pDecIn[2*i+2*(ccInformLen+ccCodeConstraint)] = 0;
pDecIn[2*i+2*(ccInformLen+ccCodeConstraint)+1] = 0;
} //添0,使其回到0状态
for (i = 0; i < ccCodeConstraint; i++) // trellis ramp-up
{
jMax = 1 << i;
//根据不同的状态,设定不同的量度值
branchMetric[0] = *(pDecIn + 1) + *pDecIn;//00
branchMetric[1] = *(pDecIn + 1) - *pDecIn;//10
branchMetric[2] = -branchMetric[1];//01
branchMetric[3] = -branchMetric[0];//11
for (j = 0; j < jMax; j++)
{
branchValue = branchMetric[*(bMapTable + j)];
j2 = j << 1;
*(pUpdateMtr + j2) = *(pPreviousMtr + j) + branchValue;
*(pUpdateMtr + j2 + 1) = *(pPreviousMtr + j) - branchValue;
}
pDecIn += ccCodeRate; // move to input samples for next bit
pPreviousMtr += pBufferIndex;//let pUpdateMtr be next pUpdateMtr
pUpdateMtr -= pBufferIndex;//delete the last pPreviousMtr
pBufferIndex *= -1;
}
for (i = 0; i < ccInformLen ; 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;
}
pMeasureMtr = pUpdateMtr; //conserve the Measure Metric
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: viSoftDecodingMid()
*
* 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 viSoftDecodingMid(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++)
{
pDecIn[2*i+2*(ccInformLen+ccCodeConstraint)] = 0;
pDecIn[2*i+2*(ccInformLen+ccCodeConstraint)+1] = 0;
} //添0,使其回到0状态
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 ; 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -