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

📄 mlc.cpp

📁 Dream.exe soft source (Visual C++)
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************\
 * Technische Universitaet Darmstadt, Institut fuer Nachrichtentechnik
 * Copyright (c) 2001
 *
 * Author(s):
 *	Volker Fischer
 *
 * Description:
 *	Multi-level-channel (de)coder (MLC)
 *
 ******************************************************************************
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
\******************************************************************************/

#include "MLC.h"


/* Implementation *************************************************************/
/******************************************************************************\
* MLC-encoder                                                                  *
\******************************************************************************/
void CMLCEncoder::ProcessDataInternal(CParameter& Parameter)
{
	int	i, j;
	int iElementCounter;

	/* Energy dispersal ----------------------------------------------------- */
	/* VSPP is treated as a separate part for energy dispersal */
	EnergyDisp.ProcessData(pvecInputData);


	/* Partitioning of input-stream ----------------------------------------- */
	iElementCounter = 0;

	if (iL[2] == 0)
	{
		/* Standard departitioning */
		/* Protection level A */
		for (j = 0; j < iLevels; j++)
		{
			/* Bits */
			for (i = 0; i < iM[j][0]; i++)
			{
				vecEncInBuffer[j][i] =
					BitToSoft((*pvecInputData)[iElementCounter]);

				iElementCounter++;
			}
		}

		/* Protection level B */
		for (j = 0; j < iLevels; j++)
		{
			/* Bits */
			for (i = 0; i < iM[j][1]; i++)
			{
				vecEncInBuffer[j][iM[j][0] + i] =
					BitToSoft((*pvecInputData)[iElementCounter]);

				iElementCounter++;
			}
		}
	}
	else
	{
		/* Special partitioning with hierarchical modulation. First set
		   hierarchical bits at the beginning, then append the rest */
		/* Hierarchical frame (always "iM[0][1]"). "iM[0][0]" is always "0" in
		   this case */
		for (i = 0; i < iM[0][1]; i++)
		{
			vecEncInBuffer[0][i] =
				BitToSoft((*pvecInputData)[iElementCounter]);

			iElementCounter++;
		}


		/* Protection level A (higher protected part) */
		for (j = 1; j < iLevels; j++)
		{
			/* Bits */
			for (i = 0; i < iM[j][0]; i++)
			{
				vecEncInBuffer[j][i] =
					BitToSoft((*pvecInputData)[iElementCounter]);

				iElementCounter++;
			}
		}

		/* Protection level B  (lower protected part) */
		for (j = 1; j < iLevels; j++)
		{
			/* Bits */
			for (i = 0; i < iM[j][1]; i++)
			{
				vecEncInBuffer[j][iM[j][0] + i] =
					BitToSoft((*pvecInputData)[iElementCounter]);

				iElementCounter++;
			}
		}
	}


	/* Convolutional encoder ------------------------------------------------ */
	for (j = 0; j < iLevels; j++)
		ConvEncoder[j].Encode(vecEncInBuffer[j], vecEncOutBuffer[j]);


	/* Bit interleaver ------------------------------------------------------ */
	for (j = 0; j < iLevels; j++)
		if (piInterlSequ[j] != -1)
			BitInterleaver[piInterlSequ[j]].Interleave(vecEncOutBuffer[j]);


	/* QAM mapping ---------------------------------------------------------- */
	QAMMapping.Map(vecEncOutBuffer[0],
				   vecEncOutBuffer[1],
				   vecEncOutBuffer[2],
				   vecEncOutBuffer[3],
				   vecEncOutBuffer[4],
				   vecEncOutBuffer[5], pvecOutputData);
}

void CMLCEncoder::InitInternal(CParameter& TransmParam)
{
	int i;
	int	iNumInBits;

	CalculateParam(TransmParam, eChannelType);
	
	iNumInBits = iL[0] + iL[1] + iL[2];


	/* Init modules --------------------------------------------------------- */
	/* Energy dispersal */
	EnergyDisp.Init(iNumInBits, iL[2]);

	/* Encoder */
	for (i = 0; i < iLevels; i++)
		ConvEncoder[i].Init(eCodingScheme, eChannelType, iN[0], iN[1],
			iM[i][0], iM[i][1], iCodeRate[i][0], iCodeRate[i][1], i);

	/* Bit interleaver */
	/* First init all possible interleaver (According table "TableMLC.h" ->
	   "Interleaver sequence") */
	if (eCodingScheme == CParameter::CS_3_HMMIX)
	{
		BitInterleaver[0].Init(iN[0], iN[1], 13);
		BitInterleaver[1].Init(iN[0], iN[1], 21);
	}
	else
	{
		BitInterleaver[0].Init(2 * iN[0], 2 * iN[1], 13);
		BitInterleaver[1].Init(2 * iN[0], 2 * iN[1], 21);
	}

	/* QAM-mapping */
	QAMMapping.Init(iN_mux, eCodingScheme);


	/* Allocate memory for internal bit-buffers ----------------------------- */
	for (i = 0; i < iLevels; i++)
	{
		/* Buffers for each encoder on all different levels */
		/* Add bits from higher protected and lower protected part */
		vecEncInBuffer[i].Init(iM[i][0] + iM[i][1]);
	
		/* Encoder output buffers for all levels. Must have the same length */
		vecEncOutBuffer[i].Init(iNumEncBits);
	}

	/* Define block-size for input and output */
	iInputBlockSize = iNumInBits;
	iOutputBlockSize = iN_mux;
}


/******************************************************************************\
* MLC-decoder                                                                  *
\******************************************************************************/
void CMLCDecoder::ProcessDataInternal(CParameter& ReceiverParam)
{
	int			i, j, k;
	int			iElementCounter;
	_BOOLEAN	bIteration;

	/* Save input signal for signal constellation. We cannot use the copy
	   operator of vector because the input vector is not of the same size as
	   our intermediate buffer, therefore the "for"-loop */
	for (i = 0; i < iInputBlockSize; i++)
		vecSigSpacBuf[i] = (*pvecInputData)[i].cSig;



#if 0
// TEST
static FILE* pFile = fopen("test/constellation.dat", "w");
if (eChannelType == CParameter::CT_MSC) {
for (i = 0; i < iInputBlockSize; i++)
	fprintf(pFile, "%e %e\n", vecSigSpacBuf[i].real(), vecSigSpacBuf[i].imag());
fflush(pFile);
}
// close all;load constellation.dat;constellation=complex(constellation(:,1),constellation(:,2));plot(constellation,'.')
#endif




	/* Iteration loop */
	for (k = 0; k < iNumIterations + 1; k++)
	{
		for (j = 0; j < iLevels; j++)
		{
			/* Metric ------------------------------------------------------- */
			if (k > 0)
				bIteration = TRUE;
			else
				bIteration = FALSE;

			MLCMetric.CalculateMetric(pvecInputData, vecMetric,
				vecSubsetDef[0], vecSubsetDef[1], vecSubsetDef[2],
				vecSubsetDef[3], vecSubsetDef[4], vecSubsetDef[5],
				j, bIteration);


			/* Bit deinterleaver -------------------------------------------- */
			if (piInterlSequ[j] != -1)
				BitDeinterleaver[piInterlSequ[j]].Deinterleave(vecMetric);


			/* Viterbi decoder ---------------------------------------------- */
			rAccMetric = ViterbiDecoder[j].Decode(vecMetric, vecDecOutBits[j]);

			/* The last branch of encoding and interleaving must not be used at
			   the very last loop */
			/* "iLevels - 1" for iLevels = 1, 2, 3
			   "iLevels - 2" for iLevels = 6 */
			if ((k < iNumIterations) ||
				((k == iNumIterations) && !(j >= iIndexLastBranch)))
			{
				/* Convolutional encoder ------------------------------------ */
				ConvEncoder[j].Encode(vecDecOutBits[j], vecSubsetDef[j]);


				/* Bit interleaver ------------------------------------------ */
				if (piInterlSequ[j] != -1)
				{
					BitInterleaver[piInterlSequ[j]].
						Interleave(vecSubsetDef[j]);
				}
			}
		}
	}


	/* De-partitioning of input-stream -------------------------------------- */
	iElementCounter = 0;

	if (iL[2] == 0)
	{
		/* Standard departitioning */
		/* Protection level A (higher protected part) */
		for (j = 0; j < iLevels; j++)
		{
			/* Bits */
			for (i = 0; i < iM[j][0]; i++)
			{
				(*pvecOutputData)[iElementCounter] =
					ExtractBit(vecDecOutBits[j][i]);

				iElementCounter++;
			}
		}

		/* Protection level B (lower protected part) */
		for (j = 0; j < iLevels; j++)
		{
			/* Bits */
			for (i = 0; i < iM[j][1]; i++)
			{
				(*pvecOutputData)[iElementCounter] =
					ExtractBit(vecDecOutBits[j][iM[j][0] + i]);

				iElementCounter++;
			}
		}
	}
	else
	{
		/* Special departitioning with hierarchical modulation. First set
		   hierarchical bits at the beginning, then append the rest */
		/* Hierarchical frame (always "iM[0][1]"). "iM[0][0]" is always "0" in
		   this case */
		for (i = 0; i < iM[0][1]; i++)
		{
			(*pvecOutputData)[iElementCounter] =
				ExtractBit(vecDecOutBits[0][i]);

			iElementCounter++;
		}

		/* Protection level A (higher protected part) */
		for (j = 1; j < iLevels; j++)
		{
			/* Bits */
			for (i = 0; i < iM[j][0]; i++)
			{
				(*pvecOutputData)[iElementCounter] =
					ExtractBit(vecDecOutBits[j][i]);

				iElementCounter++;
			}
		}

		/* Protection level B (lower protected part) */
		for (j = 1; j < iLevels; j++)
		{
			/* Bits */
			for (i = 0; i < iM[j][1]; i++)
			{
				(*pvecOutputData)[iElementCounter] =
					ExtractBit(vecDecOutBits[j][iM[j][0] + i]);

				iElementCounter++;
			}
		}
	}


	/* Energy dispersal ----------------------------------------------------- */
	/* VSPP is treated as a separate part for energy dispersal (7.2.2) */
	EnergyDisp.ProcessData(pvecOutputData);
}

void CMLCDecoder::InitInternal(CParameter& ReceiverParam)
{
	int i;

	/* First, calculate all necessary parameters for decoding process */
	CalculateParam(ReceiverParam, eChannelType);

	/* Reasonable number of iterations depends on coding scheme. With a
	   4-QAM no iteration is possible */
	if (eCodingScheme == CParameter::CS_1_SM)
		iNumIterations = 0;
	else
		iNumIterations = iInitNumIterations;

	/* Set this parameter to identify the last level of coder (important for
	   very last loop */
	if (eCodingScheme == CParameter::CS_3_HMMIX)
		iIndexLastBranch = iLevels - 2;
	else
		iIndexLastBranch = iLevels - 1;

	iNumOutBits = iL[0] + iL[1] + iL[2];

	/* Reset accumulated metric for reliability test of transmission */
	rAccMetric = (_REAL) 0.0;


	/* Init modules --------------------------------------------------------- */
	/* Energy dispersal */
	EnergyDisp.Init(iNumOutBits, iL[2]);

	/* Viterby decoder */
	for (i = 0; i < iLevels; i++)
		ViterbiDecoder[i].Init(eCodingScheme, eChannelType, iN[0], iN[1], 
			iM[i][0], iM[i][1], iCodeRate[i][0], iCodeRate[i][1], i);

	/* Encoder */
	for (i = 0; i < iLevels; i++)
		ConvEncoder[i].Init(eCodingScheme, eChannelType, iN[0], iN[1],
			iM[i][0], iM[i][1], iCodeRate[i][0], iCodeRate[i][1], i);

	/* Bit interleaver */
	/* First init all possible interleaver (According table "TableMLC.h" ->
	   "Interleaver sequence") */
	if (eCodingScheme == CParameter::CS_3_HMMIX)
	{
		BitDeinterleaver[0].Init(iN[0], iN[1], 13);
		BitDeinterleaver[1].Init(iN[0], iN[1], 21);
		BitInterleaver[0].Init(iN[0], iN[1], 13);
		BitInterleaver[1].Init(iN[0], iN[1], 21);
	}
	else
	{
		BitDeinterleaver[0].Init(2 * iN[0], 2 * iN[1], 13);
		BitDeinterleaver[1].Init(2 * iN[0], 2 * iN[1], 21);
		BitInterleaver[0].Init(2 * iN[0], 2 * iN[1], 13);
		BitInterleaver[1].Init(2 * iN[0], 2 * iN[1], 21);
	}
	
	/* Metric */
	MLCMetric.Init(iN_mux, eCodingScheme);


	/* Allocate memory for internal bit (metric) -buffers ------------------- */
	vecMetric.Init(iNumEncBits);

	/* Decoder output buffers for all levels. Have different length */
	for (i = 0; i < iLevels; i++)
		vecDecOutBits[i].Init(iM[i][0] + iM[i][1]);

	/* Buffers for subset definition (always number of encoded bits long) */
	for (i = 0; i < MC_MAX_NUM_LEVELS; i++)
		vecSubsetDef[i].Init(iNumEncBits);

	/* Init buffer for signal space */
	vecSigSpacBuf.Init(iN_mux);

	/* Define block-size for input and output */
	iInputBlockSize = iN_mux;
	iOutputBlockSize = iNumOutBits;
}

void CMLCDecoder::GetVectorSpace(CVector<_COMPLEX>& veccData)
{
	/* Init output vectors */
	veccData.Init(iN_mux);

	/* Do copying of data only if vector is of non-zero length which means that
	   the module was already initialized */
	if (iN_mux != 0)
	{
		/* Lock resources */
		Lock();

		/* Copy vectors */
		for (int i = 0; i < iN_mux; i++)
			veccData[i] = vecSigSpacBuf[i];

		/* Release resources */
		Unlock();
	}
}


/******************************************************************************\
* MLC base class                                                               *
\******************************************************************************/
void CMLC::CalculateParam(CParameter& Parameter, int iNewChannelType)
{
	int i;
	int iMSCDataLenPartA;

	switch (iNewChannelType)
	{
	/* FAC ********************************************************************/
	case CParameter::CT_FAC:
		eCodingScheme = CParameter::CS_1_SM;
		iN_mux = NUM_FAC_CELLS;

		iNumEncBits = NUM_FAC_CELLS * 2;

		iLevels = 1;

		/* Code rates for prot.-Level A and B for each level */
		/* Protection Level A */
		iCodeRate[0][0] = 0;

		/* Protection Level B */
		iCodeRate[0][1] = iCodRateCombFDC4SM;

		/* Define interleaver sequence for all levels */
		piInterlSequ = iInterlSequ4SM;


		/* iN: Number of OFDM-cells of each protection level ---------------- */
		iN[0] = 0;
		iN[1] = iN_mux;


		/* iM: Number of bits each level ------------------------------------ */
		iM[0][0] = 0;
		iM[0][1] = NUM_FAC_BITS_PER_BLOCK;


		/* iL: Number of bits each protection level ------------------------- */
		/* Higher protected part */
		iL[0] = 0;

		/* Lower protected part */
		iL[1] = iM[0][1];

⌨️ 快捷键说明

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