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

📄 mapremovecpfftequalization_oneframe.c

📁 OFDM系列之一:OFDM_demodulation OFDM系统实现的C语言实现。绝对好程序
💻 C
字号:
// Description:	operate on one frame of OFDM signals - remove CP, do FFT, ZF equalization
// Parameters:	u_OFDMsymbolCP: one frame of OFDM signal
//				estimatedCFR: the estimated channel frequency response over all sub-carriers and
//							  all OFDM symbols in one frame
//				fftSize: FFT size
//				dataSymbolNumberPerFrame: the number of data symbol in one OFDM frame
//				occupiedSubcarrierIndex: the index of data sub-carrier and pilot sub-carrier
//										 the index is a subset of {0, 1, ..., fftSzie-1}
//										 occupied sub-carriers do not include the DC sub-carrier
//				pilotPatternAndValue: pilot pattern and pilot symbol value in one frame of OFDM signal
//									  the parameter is a matrix and its entry is pilot symbol value or zero
//									  the entry is set to zero when the position is data
// Return:		u_equalizedDataSymbol:	the equalized data sub-carrier symbols

// Author: Wang Xinzheng
// Version: 1.0.0

#include "mapRemoveCpFFTequalization_oneFrame.h"

floatComplexVec* mapRemoveCpFFTequalization_oneFrame(floatComplexVec* u_OFDMsymbolCP,
													 floatComplexMatrix* estimatedCFR,
													 int fftSize,
													 int dataSymbolNumberPerFrame,
													 intVec* occupiedSubcarrierIndex,
													 floatComplexMatrix* pilotPatternAndValue)
{
	int i;
	int n;
	int m;
	int num;
	int len;
	int len1;
	int CpLength;		// CP length
	int OFDMsymbolPerFrame;				// the number OFDM symbols in one frame
	int numberOfOccupiedSubcarrier;				// the number of occupied sub-carriers
	floatComplexVec* oneOFDMsymbolCp;			// one OFDM symbol with CP
	floatComplexVec* u_subcarrierSymbol;		// the received frequency domain symbols on all sub-carriers
	floatComplexVec* u_equalizedDataSymbol;		// the equalized data sub-carrier symbols in one frame
	floatComplexVec* equalizedDataSymbol_oneSymbol;	// the equalized data sub-carrier symbols in one OFDM symbol
	intVec* dataSubcarrierIndex;		// data sub-carrier index in one OFDM symbol
	floatComplexVec* estimatedCFR_oneSymbol;	// the estimated CFR over one OFDM symbol

	OFDMsymbolPerFrame=pilotPatternAndValue->row;
	numberOfOccupiedSubcarrier=pilotPatternAndValue->col;

	// check the parameters occupiedSubcarrierIndex and pilotPatternAndValue
	if (numberOfOccupiedSubcarrier!=(int)occupiedSubcarrierIndex->len)
	{
		printf("Error! \"occupiedSubcarrierIndex\" and \"pilotPatternAndValue\" mismatch.\n");
		exit(0);
	}

	// check the parameters u_OFDMsymbolCP and pilotPatternAndValue
	if (u_OFDMsymbolCP->len % OFDMsymbolPerFrame != 0)
	{
		printf("Error! Input data contains an incomplete OFDM symbol.\n");
		exit(0);
	}

	// check the parameters u_OFDMsymbolCP and fftSize
	CpLength=u_OFDMsymbolCP->len/OFDMsymbolPerFrame-fftSize;
	if (CpLength<=0 || CpLength>=fftSize)
	{
		printf("Error! The CP length does not satisfy 0 < CpLength < fftSize.\n");
		exit(0);
	}

	// check the parameters estimatedCFR
	if ((int)estimatedCFR->row != OFDMsymbolPerFrame || (int)estimatedCFR->col != fftSize)
	{
		printf("Error! The parameter estimatedCFR has improper size.\n");
		exit(0);
	}

	// aquire the maximum number of the data symbols in one frame
	num=0;
	for (i=0; i<OFDMsymbolPerFrame; ++i)
	{
		for (n=0; n<numberOfOccupiedSubcarrier; ++n)
		{
			if (fabs(pilotPatternAndValue->a[i][n].re)<1e-5 &&
				fabs(pilotPatternAndValue->a[i][n].im)<1e-5)
			{
				++num;
			}
		}
	}

	// check the parameter dataSymbolNumberPerFrame
	if (dataSymbolNumberPerFrame>num)
	{
		printf("Error! the parameter \"dataSymbolNumberPerFrame\" is too large.\n");
		exit(0);
	}

	// check the parameter occupiedSubcarrierIndex
	for (i=0; i<(int) occupiedSubcarrierIndex->len; ++i)
	{
		if(occupiedSubcarrierIndex->a[i]<0 || occupiedSubcarrierIndex->a[i]>=fftSize)
		{
			printf("Error! The parameter \"occupiedSubcarrierIndex\" is invalid.\n");
			exit(0);
		}
	}

	// operate symbol by symbol
	u_equalizedDataSymbol=floatComplexVecAlloc(dataSymbolNumberPerFrame);
	len=0;		// record the number of data symbols that have been demodulated
	len1=0;		// record the number of data symbols that have been connected to the output vector
	for (i=0; i<OFDMsymbolPerFrame; ++i)
	{
		// get the number of data sub-carrier of the i-th OFDM symbol in one frame
		num=0;
		for (n=0; n<numberOfOccupiedSubcarrier; ++n)
		{
			if (fabs(pilotPatternAndValue->a[i][n].re)<1e-5 &&
				fabs(pilotPatternAndValue->a[i][n].im)<1e-5)
			{
				if (len<dataSymbolNumberPerFrame)
				{
					++num;		// count the data symbol in the i-th OFDM symbol
					++len;
				}
			}
		}

		if (num==0)			// if the i-th OFDM symbol contains no data symbol
		{
			continue;
		}

		// get the data sub-carrier index of the i-th OFDM symbol in one frame

		dataSubcarrierIndex=intVecAlloc(num);

		m=0;
		for (n=0; n<numberOfOccupiedSubcarrier; ++n)
		{
			if (fabs(pilotPatternAndValue->a[i][n].re)<1e-5 &&
				fabs(pilotPatternAndValue->a[i][n].im)<1e-5 &&
				m<num)
			{
				dataSubcarrierIndex->a[m]=occupiedSubcarrierIndex->a[n]; // find the corresponding sub-carrier index
				++m;
			}
		}

		// get one OFDM symbol with CP from the input data
		oneOFDMsymbolCp=floatComplexVecAlloc(fftSize+CpLength);
		for (n=0; n<fftSize+CpLength; ++n)
		{
			oneOFDMsymbolCp->a[n]=u_OFDMsymbolCP->a[i*(fftSize+CpLength)+n];
		}

		// remove CP and do FFT
		u_subcarrierSymbol=mapRemoveCpFFT(oneOFDMsymbolCp,CpLength);

		// get the CFR over the i-th OFDM symbol in one frame
		estimatedCFR_oneSymbol=floatComplexVecAlloc(fftSize);
		for (n=0; n<fftSize; ++n)
		{
			estimatedCFR_oneSymbol->a[n]=estimatedCFR->a[i][n];
		}

		// equalization
		equalizedDataSymbol_oneSymbol=mapEqualization(estimatedCFR_oneSymbol, u_subcarrierSymbol, dataSubcarrierIndex);

		// fill all the equalized data symbols into one vector
		for (n=0; n<num; ++n)	// "num" stores the number of data symbols in the i-th OFDM symbol
		{
			u_equalizedDataSymbol->a[len1]=equalizedDataSymbol_oneSymbol->a[n];
			++len1;
		}

		floatComplexVecFree(equalizedDataSymbol_oneSymbol);
		floatComplexVecFree(estimatedCFR_oneSymbol);
		floatComplexVecFree(oneOFDMsymbolCp);
		intVecFree(dataSubcarrierIndex);
		floatComplexVecFree(u_subcarrierSymbol);
	}

	return u_equalizedDataSymbol;
}



// Description:	operate on one frame of OFDM signals - remove CP, do FFT, ZF equalization
// Parameters:	u_OFDMsymbolCP: one frame of OFDM signal
//				estimatedCFR: the estimated channel frequency response over all sub-carriers and
//							  all OFDM symbols in one frame
//				fftSize: FFT size
//				CpLength1: the length of long CP or the length of short CPs that are for 6 OFDM symbols
//				CpLength2: the length of short CP that is for 1 OFDM symbol (it is zero in the case of long CP)
//				dataSymbolNumberPerFrame: the number of data symbol in one OFDM frame
//				occupiedSubcarrierIndex: the index of data sub-carrier and pilot sub-carrier
//										 the index is a subset of {0, 1, ..., fftSzie-1}
//										 occupied sub-carriers do not include the DC sub-carrier
//				pilotPatternAndValue: pilot pattern and pilot symbol value in one frame of OFDM signal
//									  the parameter is a matrix and its entry is pilot symbol value or zero
//									  the entry is set to zero when the position is data
// Return:		u_equalizedDataSymbol:	the equalized data sub-carrier symbols

// Author: Wang Xinzheng
// Version: 1.0.0

#include "mapRemoveCpFFTequalization_oneFrame.h"

floatComplexVec* mapRemoveCpFFTequalization_oneFrame2(floatComplexVec* u_OFDMsymbolCP,
													 floatComplexMatrix* estimatedCFR,
													 int fftSize,
													 int CpLength1,
													 int CpLength2,
													 int dataSymbolNumberPerFrame,
													 intVec* occupiedSubcarrierIndex,
													 floatComplexMatrix* pilotPatternAndValue)
{
	int i;
	int n;
	int m;
	int num;
	int len;
	int len1;
	int OFDMsymbolPerFrame;				// the number OFDM symbols in one frame
	int numberOfOccupiedSubcarrier;				// the number of occupied sub-carriers
	floatComplexVec* oneOFDMsymbolCp;			// one OFDM symbol with CP
	floatComplexVec* u_subcarrierSymbol;		// the received frequency domain symbols on all sub-carriers
	floatComplexVec* u_equalizedDataSymbol;		// the equalized data sub-carrier symbols in one frame
	floatComplexVec* equalizedDataSymbol_oneSymbol;	// the equalized data sub-carrier symbols in one OFDM symbol
	intVec* dataSubcarrierIndex;		// data sub-carrier index in one OFDM symbol
	floatComplexVec* estimatedCFR_oneSymbol;	// the estimated CFR over one OFDM symbol

	OFDMsymbolPerFrame=pilotPatternAndValue->row;
	numberOfOccupiedSubcarrier=pilotPatternAndValue->col;

	// check the number of OFDM symbols in one sub-frame
	if (OFDMsymbolPerFrame!=6 && OFDMsymbolPerFrame!=7)
	{
		printf("Error! One frame must contain 6 or 7 OFDM symbols.\n");
		exit(0);
	}

	// check the parameter CpLength2
	if (OFDMsymbolPerFrame==6 && CpLength2!=0)
	{
		printf("Error! CpLength2 must equal to 0 in long CP case.\n");
		exit(0);
	}
	if (OFDMsymbolPerFrame!=6 && (CpLength2<=0 || CpLength2>=fftSize))
	{
		printf("Error! CpLength2 must satisfy 0<CpLength2<fftSize in short CP case.\n");
		exit(0);
	}

	// check the parameter CpLength1
	if (CpLength1<=0 || CpLength1>=fftSize)
	{
		printf("Error! CpLength1 must satisfy 0<CpLength1<fftSize.\n");
		exit(0);
	}

	// check the parameters occupiedSubcarrierIndex and pilotPatternAndValue
	if (numberOfOccupiedSubcarrier!=(int)occupiedSubcarrierIndex->len)
	{
		printf("Error! \"occupiedSubcarrierIndex\" and \"pilotPatternAndValue\" mismatch.\n");
		exit(0);
	}

	// check the CP length, FFT size and the length of input data
	if (OFDMsymbolPerFrame==6 && OFDMsymbolPerFrame*(fftSize+CpLength1)!=(int)u_OFDMsymbolCP->len ||
		OFDMsymbolPerFrame==7 && 6*(fftSize+CpLength1)+1*(fftSize+CpLength2)!=(int)u_OFDMsymbolCP->len)
	{
		printf("Error! The length of input data, CP length and FFT size mismatch.\n");
		exit(0);
	}

	// check the parameters estimatedCFR
	if ((int)estimatedCFR->row != OFDMsymbolPerFrame || (int)estimatedCFR->col != fftSize)
	{
		printf("Error! The parameter estimatedCFR has improper size.\n");
		exit(0);
	}

	// aquire the maximum number of the data symbols in one frame
	num=0;
	for (i=0; i<OFDMsymbolPerFrame; ++i)
	{
		for (n=0; n<numberOfOccupiedSubcarrier; ++n)
		{
			if (fabs(pilotPatternAndValue->a[i][n].re)<1e-5 &&
				fabs(pilotPatternAndValue->a[i][n].im)<1e-5)
			{
				++num;
			}
		}
	}

	// check the parameter dataSymbolNumberPerFrame
	if (dataSymbolNumberPerFrame>num)
	{
		printf("Error! The parameter \"dataSymbolNumberPerFrame\" is too large.\n");
		exit(0);
	}

	// check the parameter occupiedSubcarrierIndex
	for (i=0; i<(int) occupiedSubcarrierIndex->len; ++i)
	{
		if(occupiedSubcarrierIndex->a[i]<0 || occupiedSubcarrierIndex->a[i]>=fftSize)
		{
			printf("Error! The parameter \"occupiedSubcarrierIndex\" is invalid.\n");
			exit(0);
		}
	}

	// operate symbol by symbol
	u_equalizedDataSymbol=floatComplexVecAlloc(dataSymbolNumberPerFrame);
	len=0;		// record the number of data symbols that have been demodulated
	len1=0;		// record the number of data symbols that have been connected to the output vector
	for (i=0; i<OFDMsymbolPerFrame; ++i)
	{
		// get the number of data sub-carrier of the i-th OFDM symbol in one frame
		num=0;
		for (n=0; n<numberOfOccupiedSubcarrier; ++n)
		{
			if (fabs(pilotPatternAndValue->a[i][n].re)<1e-5 &&
				fabs(pilotPatternAndValue->a[i][n].im)<1e-5)
			{
				if (len<dataSymbolNumberPerFrame)
				{
					++num;		// count the data symbol in the i-th OFDM symbol
					++len;
				}
			}
		}

		if (num==0)			// if the i-th OFDM symbol contains no data symbol
		{
			continue;
		}

		// get the data sub-carrier index of the i-th OFDM symbol in one frame

		dataSubcarrierIndex=intVecAlloc(num);

		m=0;
		for (n=0; n<numberOfOccupiedSubcarrier; ++n)
		{
			if (fabs(pilotPatternAndValue->a[i][n].re)<1e-5 &&
				fabs(pilotPatternAndValue->a[i][n].im)<1e-5 &&
				m<num)
			{
				dataSubcarrierIndex->a[m]=occupiedSubcarrierIndex->a[n]; // find the corresponding sub-carrier index
				++m;
			}
		}

		// get one OFDM symbol with CP from the input data
		if (CpLength2==0)	// long CP
		{
			oneOFDMsymbolCp=floatComplexVecAlloc(fftSize+CpLength1);
			for (n=0; n<(int)oneOFDMsymbolCp->len; ++n)
			{
				oneOFDMsymbolCp->a[n]=u_OFDMsymbolCP->a[i*(fftSize+CpLength1)+n];
			}
		}
		else	// short CP
		{
			oneOFDMsymbolCp=floatComplexVecAlloc(fftSize+(i==6 ? CpLength2 : CpLength1));
			for (n=0; n<(int)oneOFDMsymbolCp->len; ++n)
			{
				oneOFDMsymbolCp->a[n]=u_OFDMsymbolCP->a[i*(fftSize+CpLength1)+n];
			}
		}

		// remove CP and do FFT
		if (CpLength2==0)	// long CP
		{
			u_subcarrierSymbol=mapRemoveCpFFT(oneOFDMsymbolCp, CpLength1);
		}
		else	// short CP
		{
			u_subcarrierSymbol=mapRemoveCpFFT(oneOFDMsymbolCp, (i==6 ? CpLength2 : CpLength1));
		}

		// get the CFR over the i-th OFDM symbol in one frame
		estimatedCFR_oneSymbol=floatComplexVecAlloc(fftSize);
		for (n=0; n<fftSize; ++n)
		{
			estimatedCFR_oneSymbol->a[n]=estimatedCFR->a[i][n];
		}

		// equalization
		equalizedDataSymbol_oneSymbol=mapEqualization(estimatedCFR_oneSymbol, u_subcarrierSymbol, dataSubcarrierIndex);

		// fill all the equalized data symbols into one vector
		for (n=0; n<num; ++n)	// "num" stores the number of data symbols in the i-th OFDM symbol
		{
			u_equalizedDataSymbol->a[len1]=equalizedDataSymbol_oneSymbol->a[n];
			++len1;
		}

		floatComplexVecFree(equalizedDataSymbol_oneSymbol);
		floatComplexVecFree(estimatedCFR_oneSymbol);
		floatComplexVecFree(oneOFDMsymbolCp);
		intVecFree(dataSubcarrierIndex);
		floatComplexVecFree(u_subcarrierSymbol);
	}

	return u_equalizedDataSymbol;
}

⌨️ 快捷键说明

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