⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ccdecoding.cpp

📁 在vc上做的802.16d ofdm phy的仿真
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			}
				
            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 + -