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

📄 codec.cpp

📁 这个程序主要是基于空时编码的编解码实现过程。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/**************************************************************************************/
/*                                                                                    */
/*                                 force to zero                                      */
/*                        for convolutional 1/2 code only                             */
/*                                                                                    */
/**************************************************************************************/

#include <iostream.h>
#include <string.h>
#include "Global.h"
#include "Codec.h"
#include <math.h>

#define		MAX( a, b )		( a > b ? a : b )
#define		MIN( a, b )		( a < b ? a : b )

extern IO			IO;
/******************************************************************************************
function : Initialization and parameters check of the turbo-SPC CODEC
input    :	Nuser			-- number of user
			Datalen			-- length of data
			Codewordlen		-- length of codeword
			Enum			-- number of recursive bit
			Fnum			-- number of non-recursive bit
			Nestdim			-- number of component code
			Spctrellislen	-- length of the trellis
			Nodeorder		-- node order of the trellis
			Spcnpoly		-- numerator polynome -- less significate bit represents 2^0
			Spcdpoly 		-- denominator polynome 
******************************************************************************************/
void SpcCoDec::Init( int Nuser, int Datalen, int Codewordlen, int Enum, int Fnum, int Nestdim, int Spctrellislen, int Nodeorder, int Spcnpoly, int Spcdpoly, int Spcinternum )
{
	NUser = Nuser;
	DataLen = Datalen;	
	CodewordLen = Codewordlen;
	NestDim = Nestdim;
	EfoldNum = Enum;
	FfoldNum = Fnum;
	FoldNum = EfoldNum + FfoldNum;
	TrellisLen = Spctrellislen;
	NodeOrder = Nodeorder;
	NodeNum = 1 << Nodeorder;
	Npoly = Spcnpoly;
	Dpoly = Spcdpoly;
	SpcInterNum = Spcinternum;
	Rate	= (float) DataLen / (float) CodewordLen;

	SpcCoDec::Check( );
	SpcCoDec::MemoryAllocation( );
	ConvSpc.Init( NodeOrder, TrellisLen+NodeOrder, Npoly, Dpoly );// Initialization of the convolutional SPC

	//set up the interleaver
	if( FfoldNum == 0 ) EInterleaver( );
	else FInterleaver( );
}

/******************************************************************************************
function : interleaver of the code with only recrsive component
******************************************************************************************/
void SpcCoDec::EInterleaver( )
{
	int i, j;

	for( j=0; j<DataLen; j++ ) ShaffleRule[0][j] = j;
	for( i=0; i<NestDim; i++ ) 
	{
		for( j=0; j<DataLen; j++ ) ShaffleRule[i][j] = j;
		Scramble( &ShaffleRule[i][0], DataLen, SpcInterNum );
	}
}
/******************************************************************************************
function : interleaver of the code with both recrsive and non-recursive component
******************************************************************************************/
void SpcCoDec::FInterleaver( )
{
	int i, j, k, m, n, kk;

	int *temp = new int [DataLen];
	int Length = TrellisLen;
	int Elength = ( DataLen * EfoldNum ) / FoldNum;
	int Flength = DataLen - Elength;
	int SegLength = FoldNum / NestDim;
	int a = Length * SegLength;

	for( i=0; i<NestDim; i++)
	{
		for( n=0, k=0; k<FoldNum; k+=SegLength ) for( j=0; j<Length; j++ )
		{
			m = j * FoldNum + k;
			for( kk=k; kk<k+SegLength; kk++ ) temp[n++] = m++;
		}
		CyclicShift( temp, DataLen, i*a );
		Scramble( temp, Elength, SpcInterNum );
		Scramble( &temp[Elength], Flength, SpcInterNum );
		for( n=0, k=0; k<FoldNum; k+=SegLength ) for( j=0; j<Length; j++ )
		{
			m = j * FoldNum + k;
			for( kk=k; kk<k+SegLength; kk++ ) ShaffleRule[i][m++] = temp[n++];
		}
	}
	delete [] temp;
}
/******************************************************************************************
function : parameters check of the turbo-SPC
******************************************************************************************/
void SpcCoDec::Check( )
{
//	if( _SpcNodeOrder != CODEORDER ) SystemIO.ErrorMessage( "_SpcNodeOrder != CODEORDER" );
	if( DataLen % FoldNum != 0 ) IO.ErrorMessage( "turbo-SPC: DataLen % FoldNum != 0" );
	if( EfoldNum == 0 ) IO.ErrorMessage( "EfoldNum=0 ==> SIMPLE parity check -- use another prog." );
	if( FfoldNum != 0 )
	{
		if( FoldNum % NestDim != 0 ) IO.ErrorMessage( "turbo-SPC: FoldNum % NestDim != 0" ); // NOTE: there is something wrong here
		if( DataLen % NestDim != 0 ) IO.ErrorMessage( "turbo-SPC: DataLen % NestDim != 0" );
	}
}
/******************************************************************************************
function : memory allocation for the turbo-SPC
******************************************************************************************/
void SpcCoDec::MemoryAllocation( )
{
	int i, j;

	DataIn = new int [TrellisLen];
	ParityOut = new int [TrellisLen];

	Zin = new float [DataLen];
	tmpbf = new float [DataLen];
	Eparity = new float [TrellisLen];	Fparity = new float [TrellisLen];

	EparityBf = new float* [TrellisLen];	FparityBf = new float* [TrellisLen];
	for( i=0; i<TrellisLen; i++ )
	{	EparityBf[i] = new float [EfoldNum];	FparityBf[i] = new float [FfoldNum];	}

	Border = new float** [NUser];
	for( i=0; i<NUser; i++ ) Border[i] = new float* [2];
	for( i=0; i<NUser; i++ ) for( j=0; j<2; j++ ) Border[i][j] = new float [NodeNum];

	ExInf = new float** [NUser];
	for( i=0; i<NUser; i++ ) ExInf[i] = new float* [NestDim];
	for( i=0; i<NUser; i++ ) for( j=0; j<NestDim; j++ ) ExInf[i][j] = new float [DataLen];

	ShaffleRule = new int* [NestDim];
	for( i=0; i<NestDim; i++ ) ShaffleRule[i] = new int [DataLen];
}
/******************************************************************************************
function : free the allocated memory used in turbo-SPC
******************************************************************************************/
void SpcCoDec::End( )
{
	int i, j;

	ConvSpc.End( );
	delete [] DataIn;
	delete [] ParityOut;

	delete [] Zin;
	delete [] tmpbf;
	delete [] Eparity;	delete [] Fparity;

	for( i=0; i<TrellisLen; i++ )
	{	delete [] EparityBf[i];		delete [] FparityBf[i];		}
	delete [] EparityBf;	delete [] FparityBf;

	for( i=0; i<NUser; i++ ) for( j=0; j<2; j++ ) delete [] Border[i][j];
	for( i=0; i<NUser; i++ ) delete [] Border[i];
	delete [] Border;

	for( i=0; i<NUser; i++ ) for( j=0; j<NestDim; j++ ) delete [] ExInf[i][j];
	for( i=0; i<NUser; i++ ) delete [] ExInf[i];
	delete [] ExInf;
}
/******************************************************************************************
function : encoder of turbo-SPC
input    : rawData
output   : *Codeword
******************************************************************************************/
void SpcCoDec::Encoder( int *Codeword , int *rawData )
{
	int i, j, k, m, p;
	int state;
	int t = DataLen + NestDim * TrellisLen;

	for( i=0; i<DataLen; i++ ) Codeword[i] = rawData[i];//_RawData[Nuser][i];
	for( p=DataLen, i=0; i<NestDim; i++ )
	{
		state = 0;
		for( m=0, j=0; j<TrellisLen; j++ )
		{
			DataIn[j] = rawData[ShaffleRule[i][m++]]; //_RawData[Nuser][ShaffleRule[i][m++]];
			for( k=1; k<EfoldNum; k++ ) DataIn[j] ^= rawData[ShaffleRule[i][m++]]; //_RawData[Nuser][ShaffleRule[i][m++]];
			m += FfoldNum;
		}
		ConvSpc.Encoder( &DataIn[0], &ParityOut[0], &state );
		for( m=EfoldNum, j=0; j<TrellisLen; j++ )
		{
			Codeword[p] = ParityOut[j];
			for( k=EfoldNum; k<FoldNum; k++ ) Codeword[p] ^= rawData[ShaffleRule[i][m++]];//_RawData[Nuser][ShaffleRule[i][m++]];
			m += EfoldNum;
			p++;
		}
		for( j=0; j<2*NodeOrder; j++ ) Codeword[t++] = ConvSpc.TermTable[state][j];
	}
}
/******************************************************************************************
function : decoder of turbo-SPC
input    : NUser, *Codeword -- LR value
output   : *Codeword
******************************************************************************************/
/*
void SpcCoDec::Decoder( int Nuser, float *Codeword, char *Flag )
{
	float buffer [DATALEN] ,  temp[DATALEN];
	int i, j, p=DataLen+NestDim*TrellisLen;
	for( i=0; i<NestDim; i++ )
	{
		BorderReSet( Nuser );
		for( j=0; j<DataLen; j++ ) buffer[j]=Zin[j] = Codeword[ShaffleRule[i][j]] - ExInf[Nuser][i][j];
		MapDecoding( &Codeword[DataLen+(i*TrellisLen)], &Codeword[p+(2*i*NodeOrder)], Nuser, i, Flag );// the major decoding step 
		for( j=0; j<DataLen; j++ ) Codeword[ShaffleRule[i][j]] = Zin[j];
	}
}
*/
void SpcCoDec::Decoder( int Nuser, float *Codeword, char *Flag )
{
	float buffer [DATALEN] ;
	int i, j, p=DataLen+NestDim*TrellisLen;
	for( j=0; j<DataLen; j++ ) Codeword[j] = Codeword[j] + Sum_Ex[j] ;
	
	for( i=0; i<NestDim; i++ )
	{
		BorderReSet( Nuser );
		for( j=0; j<DataLen; j++ ) buffer[j]=Zin[j] = Codeword[ShaffleRule[i][j]] - ExInf[Nuser][i][j];
		MapDecoding( &Codeword[DataLen+(i*TrellisLen)], &Codeword[p+(2*i*NodeOrder)], Nuser, i, Flag );// the major decoding step 
		for( j=0; j<DataLen; j++ ) Codeword[ShaffleRule[i][j]] = Zin[j];
		for( j=0; j<DataLen; j++ )	ExInf[Nuser][i][j] =  Zin[j] - buffer[j] ;
	}
	for( j=0; j<DataLen; j++ ) Sum_Ex[j] = 0;
	for( i=0; i<NestDim; i++ ) for( j=0; j<DataLen; j++ )Sum_Ex[ShaffleRule[i][j]] += ExInf[Nuser][i][j];
}

//*/
void SpcCoDec::BorderReSet( int Nuser )
{
	int i;

	for( i=1; i<NodeNum; i++ )
		Border[Nuser][0][i] = Border[Nuser][1][i] = LS;;
	Border[Nuser][0][0] = Border[Nuser][1][0] = 0;
}


/******************************************************************************************
function : decoder of convolutional-SPC
******************************************************************************************/
void SpcCoDec::MapDecoding( float *Parity, float *Tail, int Nuser, int dim, char *Flag )
{
	Apriori( Parity, Tail );
	ConvSpc.BCJR( &Border[Nuser][0][0], &Border[Nuser][1][0] );
	Aposteriori( Nuser, dim, Parity, Tail, Flag );
}
/******************************************************************************************
function : handle the information output from the BCJR
******************************************************************************************/
void SpcCoDec::Aposteriori( int Nuser, int dim, float *Parity, float *Tail, char *Flag )
{
	int i, m;

	for( i=0; i<DataLen; i++ ) tmpbf[i] = Zin[i];

	for( i=0; i<TrellisLen; i++ )
	{
		Eparity[i] = ConvSpc.LlrAdd(ConvSpc.aPP[i][0],ConvSpc.aPP[i][1])-ConvSpc.LlrAdd(ConvSpc.aPP[i][2],ConvSpc.aPP[i][3])-Eparity[i];
		Fparity[i] = ConvSpc.LlrAdd(ConvSpc.aPP[i][0],ConvSpc.aPP[i][2])-ConvSpc.LlrAdd(ConvSpc.aPP[i][1],ConvSpc.aPP[i][3])-Fparity[i];
	}

	m = TrellisLen;
	if( strcmp( Flag, "ParityRequire" ) == 0 ) for( i=0; i<NodeOrder; i++ )
	{
		Tail[2*i] = ConvSpc.LlrAdd(ConvSpc.aPP[m][0],ConvSpc.aPP[m][1])-ConvSpc.LlrAdd(ConvSpc.aPP[m][2],ConvSpc.aPP[m][3]);
		Tail[2*i+1] = ConvSpc.LlrAdd(ConvSpc.aPP[m][0],ConvSpc.aPP[m][2])-ConvSpc.LlrAdd(ConvSpc.aPP[m][1],ConvSpc.aPP[m][3]);
		m++;
	}

	for( m=0, i=0; i<TrellisLen; i++, m += FoldNum )
		PostPreDec( &Zin[m], Eparity[i], &EparityBf[i][0], EfoldNum );

	for( i=0; i<TrellisLen; i++ ) Eparity[i] = Parity[i];

	// "ParityRequire" -- extrinstic information of parity are provided
	// "ParityNotRequire" -- extrinstic information of parity are NOT provided
	if( strcmp( Flag, "ParityRequire" ) == 0 )
	{
		if( FfoldNum == 0 ) for( i=0; i<TrellisLen; i++ ) Parity[i] = ( Parity[i] + Fparity[i] );
		else if( FfoldNum == 1 ) for( m=EfoldNum, i=0; i<TrellisLen; i++, m+=FoldNum ) 
			Parity[i] = ( Parity[i] + Plr( Fparity[i], Zin[m] ) );
		else for( m=EfoldNum, i=0; i<TrellisLen; i++, m+=FoldNum )
			Parity[i] = ( Parity[i] + Plr( Fparity[i], Plr( Zin[m], FparityBf[i][0] ) ) );
	}

	if( FfoldNum != 0 ) for( m=EfoldNum, i=0; i<TrellisLen; i++, m+=FoldNum )
		PostPreDec( &Zin[m], Plr( Eparity[i], Fparity[i] ), &FparityBf[i][0], FfoldNum );

	//for( i=0; i<DataLen; i++ )	ExInf[Nuser][dim][i] = Zin[i] - tmpbf[i];
}
/******************************************************************************************
function : sub-function of SpcCoDec::Aposteriori( int Nuser, int dim, float *Parity )
******************************************************************************************/
void SpcCoDec::PostPreDec( float *Zin, float Parity, float *bf, int blength )
{
	int i;

	for( i=0; i<blength; i++ ) Zin[i] = Zin[i] + Plr( Parity, bf[i] );
}
/******************************************************************************************
function : prepare the information for the BCJR
******************************************************************************************/
void SpcCoDec::Apriori( float *Parity, float *Tail )
{
	int i, j, m;

	for( m=0, i=0; i<TrellisLen; i++ )
	{
		PrePrtDec( &Zin[m], &Eparity[i], &EparityBf[i][0], EfoldNum );
		m += EfoldNum;
		PrePrtDec( &Zin[m], &Fparity[i], &FparityBf[i][0], FfoldNum );
		m += FfoldNum;
	}

	if( FfoldNum == 0 ) for( i=0; i<TrellisLen; i++ ) Fparity[i] = Parity[i];
	else for( i=0; i<TrellisLen; i++ ) Fparity[i] = Plr( Fparity[i], Parity[i] );

	for( i=0; i<TrellisLen; i++ )
	{
		for( j=0; j<NodeNum; j++ )
		{
			if( ConvSpc.Bcode[j][0] == 0 ) ConvSpc.CodeInf[i][j][0] = Eparity[i] + Fparity[i];
			else ConvSpc.CodeInf[i][j][0] = Eparity[i];
			if( ConvSpc.Bcode[j][1] == 0 ) ConvSpc.CodeInf[i][j][1] = Fparity[i];
			else ConvSpc.CodeInf[i][j][1] = 0;
		}		
	}

	m = TrellisLen;
	for( i=0; i<NodeOrder; i++ )
	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -