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

📄 ccdecoding.cpp

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