📄 gsmmlse.c
字号:
#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 + -