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

📄 gsmmlse.c

📁 基于MATLAB的GSM仿真系统 并附有直接画出性能曲线的简化程序。
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "GSMMLSE.h"

void  GSMEQ(int TS[26],double sigRecv[2][BURSTLEN*OVERSAMPLE],
			int GSMRecvBurst[BURSTLEN],int init,int offset,int mode)
{
	double gEstArray[2][CHANNELMEMLEN];
	double yArray[2][BURSTLEN];
	double xArray[2][CHANNELMEMLEN];
	struct GSMMVAState GSMMVATrellis[MVAState][200];
	struct GSMMVAOut MVAOut[BURSTLEN];
	double sigTS[2][TRAINLEN*OVERSAMPLE];
	double sigDerot[2][BURSTLEN*OVERSAMPLE];

	int i,j;
	double sigLow[2];


		//first, mapping Training Sequence to anti-podal signal
		for (i=0;i<TRAINLEN;i++)
		{
			GSMMVA_SigMap(TS[i],sigLow);
			for (j=0;j<OVERSAMPLE;j++)
			{
				sigTS[0][i*OVERSAMPLE+j]=sigLow[0];
				sigTS[1][i*OVERSAMPLE+j]=sigLow[1];
			}
		}
		//second, derotating of received signal
		GSMDerotation(sigRecv,sigDerot,init);
		//third, doing channel estimation
		GSMChannelEst(sigTS,sigDerot,offset,gEstArray);
		//forth, match filtering
		GSMMatFilter(sigDerot,gEstArray,offset,yArray);
		GSMCorelation(gEstArray,xArray);
		//fifth, computing output bits using Modified VA
		GSMMVA(yArray,xArray,mode,GSMMVATrellis,MVAOut);
/*		for (i = 0;i<BURSTLEN;i++)
		{
			yArray[0][i] = sigDerot[0][i*OVERSAMPLE+offset];
			yArray[1][i] = sigDerot[1][i*OVERSAMPLE+offset];
		}
		GSMMVA(yArray,gEstArray,mode,GSMMVATrellis,MVAOut);	
*/
		//sixth, recover tail bits
		for (i = 0;i<3;i++)
		{
			MVAOut[i].hard = 0;
			MVAOut[BURSTLEN-1-i].hard = 0;
		}
		//seventh, copy to var GSMRecvBurst
		for (i = 0;i<BURSTLEN;i++)
		{
			GSMRecvBurst[i] = MVAOut[i].hard;
		}
}

/*int  GSMDerotation(double rArray[2][BURSTLEN*OVERSAMPLE],
				   double retValue[2][BURSTLEN*OVERSAMPLE],int init)
{
	int i,j;
	
	
	for (i = 0;i<BURSTLEN;i++)
	{
		for (j = 0;j<OVERSAMPLE;j++)
		{
			switch(((i+1+init)%OVERSAMPLE))
			{
				case 0:
				retValue[0][i*OVERSAMPLE+j] = rArray[0][i*OVERSAMPLE+j];
				retValue[1][i*OVERSAMPLE+j] = rArray[1][i*OVERSAMPLE+j];
				break;
				
				case 1:
				retValue[0][i*OVERSAMPLE+j] = rArray[1][i*OVERSAMPLE+j];
				retValue[1][i*OVERSAMPLE+j] = -rArray[0][i*OVERSAMPLE+j];
				break;
				
				case 2:
				retValue[0][i*OVERSAMPLE+j] = -rArray[0][i*OVERSAMPLE+j];
				retValue[1][i*OVERSAMPLE+j] = -rArray[1][i*OVERSAMPLE+j];
				break;
				
				case 3:
				retValue[0][i*OVERSAMPLE+j] = -rArray[1][i*OVERSAMPLE+j];
				retValue[1][i*OVERSAMPLE+j] = rArray[0][i*OVERSAMPLE+j];
				break;
				
				default:
				printf("Invalid Case in Derotation.\n");
				while(1)
				{
					//sleep(2000);
				}
				break;
			}
		}
	}
	return 0;
}*/


//此程序用来解旋转;
//作者:沈亮
int GSMDerotation(double rArray[2][BURSTLEN*OVERSAMPLE],
				   double re_Array[2][BURSTLEN*OVERSAMPLE],int init)
  //说明:
  //double rArray应该为[2][592];
  //double re_Array[2][lie] 为输出数组;

{     
//state有四个状态,具体定义见下;
//state=0 --------  -j;
//state=1 --------  -1;
//state=2 --------  j;
//state=3 --------  1;
//流程如下:-j  --------  -1 -------- j --------- 1;
     int state=init;//初始状态,可改;
     int i;
     for(i=0;i<BURSTLEN;i++) 
	 {
       	 int q;
       	 q=4*i;  //下标,依据offset的值,每隔4点算1次;
       	 switch(state)
       	    {
               case 0:
                    //-j状态;

				    //第一个插值点;
                    re_Array[0][q]=rArray[1][q];//re_array的RE;
                    re_Array[1][q]=-rArray[0][q];//re_array的IM;

                    //第二个插值点;
                    re_Array[0][q+1]=rArray[1][q+1];//re_array的RE;
                    re_Array[1][q+1]=-rArray[0][q+1];//re_array的IM;

                    //第三个插值点;
                    re_Array[0][q+2]=rArray[1][q+2];//re_array的RE;
                    re_Array[1][q+2]=-rArray[0][q+2];//re_array的IM;

                    //第四个插值点;
                    re_Array[0][q+3]=rArray[1][q+3];//re_array的RE;
                    re_Array[1][q+3]=-rArray[0][q+3];//re_array的IM;

                    state=1;
                    break;
                   
               case 1:
                    //-1状态;

				    //第一个插值点;
                    re_Array[0][q]=-rArray[0][q];//re_array的RE;
                    re_Array[1][q]=-rArray[1][q];//re_array的IM;

                    //第二个插值点;
                    re_Array[0][q+1]=-rArray[0][q+1];//re_array的RE;
                    re_Array[1][q+1]=-rArray[1][q+1];//re_array的IM;

                    //第三个插值点;
                    re_Array[0][q+2]=-rArray[0][q+2];//re_array的RE;
                    re_Array[1][q+2]=-rArray[1][q+2];//re_array的IM;

                    //第四个插值点;
                    re_Array[0][q+3]=-rArray[0][q+3];//re_array的RE;
                    re_Array[1][q+3]=-rArray[1][q+3];//re_array的IM;

                    state=2;
                    break;
                    
               case 2:
                    //j状态; 

				    //第一个插值点;
                    re_Array[0][q]=-rArray[1][q];//re_array的RE;
                    re_Array[1][q]=rArray[0][q];//re_array的IM;

                    //第二个插值点;
                    re_Array[0][q+1]=-rArray[1][q+1];//re_array的RE;
                    re_Array[1][q+1]=rArray[0][q+1];//re_array的IM;

                    //第三个插值点;
                    re_Array[0][q+2]=-rArray[1][q+2];//re_array的RE;
                    re_Array[1][q+2]=rArray[0][q+2];//re_array的IM;

                    //第四个插值点;
                    re_Array[0][q+3]=-rArray[1][q+3];//re_array的RE;
                    re_Array[1][q+3]=rArray[0][q+3];//re_array的IM;

                    state=3;
                    break;
                    
               case 3:
                    //1状态;

				    //第一个插值点;
                    re_Array[0][q]=rArray[0][q];//re_array的RE;
                    re_Array[1][q]=rArray[1][q];//re_array的IM;

                    //第二个插值点;
                    re_Array[0][q+1]=rArray[0][q+1];//re_array的RE;
                    re_Array[1][q+1]=rArray[1][q+1];//re_array的IM;

                    //第三个插值点;
                    re_Array[0][q+2]=rArray[0][q+2];//re_array的RE;
                    re_Array[1][q+2]=rArray[1][q+2];//re_array的IM;

                    //第四个插值点;
                    re_Array[0][q+3]=rArray[0][q+3];//re_array的RE;
                    re_Array[1][q+3]=rArray[1][q+3];//re_array的IM;

                    state=0;
                    break;
                    
               } //end switch;
             }//end for;
	 return 0;
} //end function; 



int  GSMChannelEst(double trSeqArray[2][TRAINLEN*OVERSAMPLE],
       double uArray[2][BURSTLEN*OVERSAMPLE],int offset,double gEstArray[2][CHANNELMEMLEN])
{
	double tempgEstArray[2][CHANNELMEMLEN*OVERSAMPLE];
	double aArray[2][16][CHANNELMEMLEN*OVERSAMPLE];
	double Re1,Re2,Im1,Im2;
	int i,j,m;
	//int k;
	
	//Initialize Matrix A
	for (i = 0;i<16;i++)
	{
		for (j = 0;j<CHANNELMEMLEN;j++)
		{
			for (m = 0;m<OVERSAMPLE;m++)
			{
				aArray[0][i][j*OVERSAMPLE+m] = trSeqArray[0][(i+5-j)*OVERSAMPLE+m];
				aArray[1][i][j*OVERSAMPLE+m] = trSeqArray[1][(i+5-j)*OVERSAMPLE+m];
			}
		}
	}
	
	//Surppose (A.^H*A).^-1 = I6
	/*for (j = 0;j<CHANNELMEMLEN;j++)
	{
		for (k = 0;k<CHANNELMEMLEN;k++)
		{
			m = 0;
			Re1 = 0;
			Re2 = 0;
			Im1 = 0;
			Im2 = 0;
			for (i = 0;i<16;i++)
			{
				Re1 = Re1+aArray[0][i][j*OVERSAMPLE+m]*aArray[0][i][k*OVERSAMPLE+m];
				Re2 = Re2+aArray[1][i][j*OVERSAMPLE+m]*aArray[1][i][k*OVERSAMPLE+m];
				Im1 = Im1+aArray[0][i][j*OVERSAMPLE+m]*aArray[1][i][k*OVERSAMPLE+m];
				Im2 = Im2-aArray[1][i][j*OVERSAMPLE+m]*aArray[0][i][k*OVERSAMPLE+m];
			}
			printf("%.2f+j%.2f ",Re1+Re2,Im1+Im2);
		}
		printf("\n");
	}*/
	
	//Channel Estimate
	for (i = 0;i<CHANNELMEMLEN;i++)
	{
		for (j = 0;j<OVERSAMPLE;j++)
		{
			tempgEstArray[0][i*OVERSAMPLE+j] = 0;
			tempgEstArray[1][i*OVERSAMPLE+j] = 0;
			for (m = 0;m<16;m++)
			{
				Re1 = aArray[0][m][i*OVERSAMPLE+j]*uArray[0][(66+m)*OVERSAMPLE+j];
				Re2 = aArray[1][m][i*OVERSAMPLE+j]*uArray[1][(66+m)*OVERSAMPLE+j];
				Im1 = aArray[0][m][i*OVERSAMPLE+j]*uArray[1][(66+m)*OVERSAMPLE+j];
				Im2 = aArray[1][m][i*OVERSAMPLE+j]*uArray[0][(66+m)*OVERSAMPLE+j];
				tempgEstArray[0][i*OVERSAMPLE+j] = Re1+Re2+tempgEstArray[0][i*OVERSAMPLE+j];
				tempgEstArray[1][i*OVERSAMPLE+j] = Im1-Im2+tempgEstArray[1][i*OVERSAMPLE+j];
			}
		}
	}
	
	//Select samples according to offset
	for (i = 0;i<CHANNELMEMLEN;i++)
	{
		gEstArray[0][i] = tempgEstArray[0][i*OVERSAMPLE+offset]/16;
		gEstArray[1][i] = tempgEstArray[1][i*OVERSAMPLE+offset]/16;
	}
	
	return 0;
}


int  GSMMatFilter(double uArray[2][BURSTLEN*OVERSAMPLE],
       double gEstArray[2][CHANNELMEMLEN],int offset,double yArray[2][BURSTLEN])
{	
	//Expend with 0s to compute uArray at the end
	double uTempArray[2][(BURSTLEN+CHANNELMEMLEN-1)];
	double Re1,Re2,Im1,Im2;
	int i,j;
	
	//Initializing uTempArray
	for (i = 0;i<BURSTLEN;i++)
	{
		uTempArray[0][i] = uArray[0][i*OVERSAMPLE+offset];
		uTempArray[1][i] = uArray[1][i*OVERSAMPLE+offset];
	}
	for (i = 0;i<(CHANNELMEMLEN-1);i++)
	{
		uTempArray[0][i+BURSTLEN] = 0;
		uTempArray[1][i+BURSTLEN] = 0;
	}
	
	//Match Filtering
	for (i = (CHANNELMEMLEN-1);i<(BURSTLEN+CHANNELMEMLEN-1);i++)
	{
		Re1 = 0;
		Re2 = 0;
		Im1 = 0;
		Im2 = 0;
		for (j = 0;j<CHANNELMEMLEN;j++)
		{
			Re1 = Re1+uTempArray[0][(i-j)]*gEstArray[0][CHANNELMEMLEN-1-j];
			Re2 = Re2+uTempArray[1][(i-j)]*gEstArray[1][CHANNELMEMLEN-1-j];
			Im1 = Im1-uTempArray[0][(i-j)]*gEstArray[1][CHANNELMEMLEN-1-j];
			Im2 = Im2+uTempArray[1][(i-j)]*gEstArray[0][CHANNELMEMLEN-1-j];
		}
		yArray[0][(i-(CHANNELMEMLEN-1))] = Re1+Re2;
		yArray[1][(i-(CHANNELMEMLEN-1))] = Im1+Im2;
	}
	return 0;
}


int  GSMCorelation(double gEstArray[2][CHANNELMEMLEN],double xArray[2][CHANNELMEMLEN])
{
	double tempgEstArray[2][CHANNELMEMLEN+CHANNELMEMLEN];
	double Re1,Re2,Im1,Im2;
	int i,j;
	
	
	//Initializing tempgEstArray
	for (i = 0;i<6;i++)
	{
		tempgEstArray[0][i] = gEstArray[0][i];
		tempgEstArray[1][i] = gEstArray[1][i];
		tempgEstArray[0][i+6] = 0;
		tempgEstArray[1][i+6] = 0;
	}
	
	//Corelation Computation
	for (i = 0;i<6;i++)
	{
		Re1 = 0;
		Re2 = 0;
		Im1 = 0;
		Im2 = 0;
		for (j = 0;j<6;j++)
		{
			Re1 = Re1+tempgEstArray[0][i+j]*gEstArray[0][j];
			Re2 = Re2-tempgEstArray[1][i+j]*(-1)*gEstArray[1][j];
			Im1 = Im1+tempgEstArray[0][i+j]*(-1)*gEstArray[1][j];
			Im2 = Im2+tempgEstArray[1][i+j]*gEstArray[0][j];			
		}
		xArray[0][i] = Re1+Re2;
		xArray[1][i] = Im1+Im2;
	}
	return 0;
}


//Following Belongs to MVA
/************************************
/in Phase I it is BPSK
/logic    0      1
/ret      1     -1
/************************************/
int  GSMMVA_SigMap(int possibleData,double sigLow[2])
{
	//double sigLow[2];
	
	switch(possibleData)
	{
	case 0:
		sigLow[0] = 1;
		sigLow[1] = 0;
		break;
		
	case 1:
		sigLow[0] = -1;
		sigLow[1] = 0;
		break;
		
	default:
		break;
	}
	return 0;
}

/**************************************
/Finite State Machine
/**************************************/
/*int  GSMMVA_FSM(int currentState,int possibleData)
{
	int temp_possibleData;
	int temp_currentState;
	int nextState;
	
	temp_currentState = (currentState<<1);
	temp_currentState = (temp_currentState&0x0000001f);
	temp_possibleData = (possibleData&0x00000001);
	nextState = (temp_currentState|temp_possibleData);
	
	return nextState;
}*/

/****************************************
/Compute Inc Metric for each path
/****************************************/
double  GSMMVA_IncMetric(int cnt,int dataHistory[CHANNELMEMLEN],
       double xArray[2][CHANNELMEMLEN],double yArray[2][BURSTLEN])
{
	double RetPart1,RetPart2_1,RetPart2_2;
	double sigHistory[2][CHANNELMEMLEN];
	double tempComplx[2][1],tempSig[2];
	double RetValue;
	int i;
	
	//Signal Mapping
	for (i = 0;i<CHANNELMEMLEN;i++)
	{
		GSMMVA_SigMap(dataHistory[i],tempSig);
		sigHistory[0][i] = tempSig[0];
		sigHistory[1][i] = tempSig[1];
	}
	
	//2Re(Ik* Yk)
	RetPart1 = 2*(sigHistory[0][0]*yArray[0][cnt]+sigHistory[1][0]*yArray[1][cnt]);
	
	//C(Sk,Sk-1)
	RetPart2_1 = (sigHistory[0][0]*sigHistory[0][0]+sigHistory[1][0]*sigHistory[1][0])*xArray[0][0];
	tempComplx[0][0] = 0;
	tempComplx[1][0] = 0;
	for (i = 1;i<CHANNELMEMLEN;i++)
	{
		tempComplx[0][0] = tempComplx[0][0]+xArray[0][i]*sigHistory[0][i]
		                   -xArray[1][i]*sigHistory[1][i];
		tempComplx[1][0] = tempComplx[1][0]+xArray[1][i]*sigHistory[0][i]
		                   +xArray[0][i]*sigHistory[1][i];
	}
	RetPart2_2 = 2*(sigHistory[0][0]*tempComplx[0][0]+sigHistory[1][0]*tempComplx[1][0]);
	RetValue = RetPart1-RetPart2_1-RetPart2_2;
	
	return RetValue;
}




/**************************************
/Finite State Machine

⌨️ 快捷键说明

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