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

📄 function.c

📁 应用于无线通信的OFDM解调和RS解码源程序。64点FFT
💻 C
字号:
#include <stdio.h>
#include <math.h>
#include "Setting.H"
#include "RS.H"
#include "costable.h"
#include "sintable.h"
/* Input is in reverse order, output is in natural order;
 * FFT is sampling on the time, base on radix-2;
 */

void FFT(int Real[], int Imag[], WordType sign)
{
	WordType i, j, l, k, n1, n2;
	//float e;
	int TmpR, TmpI,WR, WI,UR,UI,index,Realk,Reali,Imagk,Imagi;
    int * point_Real = Real;
    int * point_Imag = Imag;
	int * pRealk,* pReali,* pImagk,* pImagi;

	/* Compute the power M: 2^M = FFTSize 
	for (M = 0, i = 1; ;)
	{
		M += 1;
		i *= 2;
		if (i == FFTSize)
		{
			break;
		}
	}*/

	/* Exchange data position in reverse order */
	for (j=0, i=0; i < FFTSize - 1; i++)
	{
		if (i < j)
		{
			TmpR = Real[j];
			TmpI = Imag[j];
			Real[j] = Real[i];
			Imag[j] = Imag[i];
			Real[i] = TmpR;
			Imag[i] = TmpI;
		}
		k = FFTSize / 2;
		while(k < (j + 1))
		{
			j -= k;
			k /= 2;
		}
		j += k;
	}
	

	/* Apply FFT */

	n1 = 1;
	for(l = 1; l <= 6; l++)
	{
		n2 = n1;
		n1 = 2 * n1;
		index = 1<<(6-l);
		for(j = 0; j < n2; j++)
		{
			UR = cos_tab[j*index];
			UI = -sign*sin_tab[j*index];
			for(i = j; i < FFTSize; i += n1)
			{
				k = i + n2;
				pRealk = point_Real+k;
				pReali = point_Real+i;
				pImagk = point_Imag+k;
				pImagi = point_Imag+i;
				Realk = *pRealk;
				Reali = *pReali;
				Imagk = *pImagk;
				Imagi = *pImagi;
				TmpR = (UR * Realk - UI * Imagk)>>14;
				TmpI = (UR * Imagk + UI * Realk)>>14;
				*pRealk = Reali - TmpR;
				*pImagk = Imagi - TmpI;
				*pReali += TmpR;
				*pImagi += TmpI;
				/*TmpR = (UR * Real[k] - UI * Imag[k])>>14;
				TmpI = (UR * Imag[k] + UI * Real[k])>>14;
				Real[k] = Real[i] - TmpR;
				Imag[k] = Imag[i] - TmpI;
				Real[i] += TmpR;
				Imag[i] += TmpI;*/
			}
		}
	}

	/* Adjust the amplitude if applying IFFT */
	if (sign == -1)
	{
		for(i = 0; i < FFTSize; i++)
		{
			Real[i] = Real[i] >> 6;
			Imag[i] = Imag[i] >> 6;
		}
	}
}

/* CONVBASE Converts the number base of the input data (DataIn):
 *   ConvBase(DType DataIn[], DType DataOut[], DType DataLen, DType sign)
 * From the current base (CurrBase) to the new base required (NewBase);
 * If the new base is less than the old base, e.g
 * NewBase = 2 and CurrBase = 8, the DataOut will have more
 * data words. For the above example DataOut will be 4 times
 * longer than DataIn;
 * The actual base used = 2^NewBase, thus NewBase = 8, is base 256;
 * E.g. DataIn = [ 2 64 20 ] with CurrBase = 8, NewBase = 2
 * DataOut = [0 0 0 2, 1 0 0 0, 0 1 1 0]
 * Note : Both the input and output data is in a serial format;
 * DataLen is the length of DataIn[];
 * Sign represents the ConvBase() function: 1 -> NewBase < CurrBase
 *                                          0 -> NewBase > CurrBase;
 *                                          Other -> No change;
 */
void ConvBase(DType DataIn[], DType DataOut[], WordType DataLen, WordType Sign)
{
	WordType i, j, k;
	DType *pDataIn = DataIn,*pDataOut = DataOut;
	if (Sign == 1)
	{
		/* Convert the input data into the smaller base required */
		for (i = 0; i < DataLen; i++)
		{
			pDataOut = DataOut + i * RSInforBit / CodewordBit;
			pDataIn = DataIn + i;
			for (j = 0; j < (RSInforBit / CodewordBit); j++)
			{
				/*DataOut[i * RSInforBit / CodewordBit + j] =
					 DataIn[i] & (DType)((1 << CodewordBit) - 1);
				DataIn[i] >>= CodewordBit;*/
				*pDataOut = *pDataIn & (DType)((1 << CodewordBit) - 1);
				*pDataIn >>= CodewordBit;
				pDataOut++;
			}
		}
	}
	else if (Sign == 0)
	{
		/* Convert back to larger base */
		j = 0;
		k = 0;
		for (i = 0; i < DataLen; i++)
		{
			if (k == 0)
			{
				DataOut[j] = 0;
			}
			DataOut[j] += (DType) (1 << (CodewordBit * k)) * DataIn[i];
			if (k == (RSInforBit / CodewordBit - 1))
			{
				j++;
				k = 0;
			}
			else
			{
				k++;
			}
		}
	}
	else
	{
		/* No change of base */
		for (i = 0; i < DataLen; i++)
		{
			DataOut[i] = DataIn[i];
		}
	}
}

/* Convert 2-bit binary code to Gray code */
void Gray2(DType DataIn[], WordType Length)
{
	WordType i;
	for (i = 0; i < Length; i++)
	{
		switch(DataIn[i])
		{
		case 0:
			DataIn[i] = 0;
			break;
		case 1:
			DataIn[i] = 1;
			break;
		case 2:
			DataIn[i] = 3;
			break;
		case 3:
			DataIn[i] = 2;
		}
	}
}

/* Convert the source encoded data to required format */
void SrcToChan(short SrcData[], DType ReqData[], WordType SymbolMark[], WordType BitMark[])
{
	WordType i;
	for (i = 0; i < SrcVector; i++)
	{
		if (BitMark[0] == 0)
		{
			ReqData[SymbolMark[0]] = SrcData[i];
		}
		else
		{
			ReqData[SymbolMark[0]] += SrcData[i] * (1 << BitMark[0]);
		}
		if (BitMark[0] == 5)
		{
			BitMark[0] = 0;
			SymbolMark[0]++;
		}
		else
		{
			BitMark[0]++;
		}
	}
}

/* Convert the channel decoded data to required source format */
void ChanToSrc(DType ChannelData[], short SrcData[], WordType PosMark[])
{
	WordType i, j;
	DType *pChaData = ChannelData;
	short *pSrcData = &SrcData[PosMark[0]];

	for (i = 0; i < RSInforSym; i++)
	{
		for (j = 0; j < RSInforBit; j++)
		{
			*pSrcData = (short) (*pChaData & 1);
			*pChaData >>= 1;
			(PosMark[0])++;
			pSrcData++;
		}
		pChaData++;
	}
}

/* Round the real data to nearest integer */
WordType Round(float RealData)
{
	WordType a = 1;
	if (RealData < 0)
	{
		a = -1;
		RealData = 0 - RealData;
	}
	if ((RealData < 0.5) || ((WordType)RealData != (WordType)(RealData - 0.5)))
	{
		return ((WordType)RealData * a);
	}
	else
	{
		return (((WordType)RealData + 1) * a);
	}
}

/* Generates a pseudorandom number */
unsigned short Random(unsigned int *Seed, unsigned short RandMax)
{
	*Seed= 2045 * (*Seed) + 1;
	*Seed= *Seed - (*Seed / 104877) * 104877;
	return (WordType)(*Seed & RandMax);
}

⌨️ 快捷键说明

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