📄 gsmmlse.c
字号:
/**************************************/
int GSMMVA_FSM(int currentState,int possibleData)
{
int temp_possibleData;
int temp_currentState;
int nextState;
temp_currentState = (currentState<<1);
temp_currentState = (temp_currentState&0x0000003f);
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 gEstArray[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++)
{
if (i<=cnt)
{
GSMMVA_SigMap(dataHistory[i],tempSig);
sigHistory[0][i] = tempSig[0];
sigHistory[1][i] = tempSig[1];
}
}
//YH(n)
RetPart2_1 = 0;
RetPart2_2 = 0;
for (i = 0;i<CHANNELMEMLEN;i++)
{
if (i<=cnt)
{
RetPart2_1 = RetPart2_1+gEstArray[0][i]*sigHistory[0][i]-gEstArray[1][i]*sigHistory[1][i];//Re
RetPart2_2 = RetPart2_2+gEstArray[1][i]*sigHistory[0][i]+gEstArray[0][i]*sigHistory[1][i];//Im
}
}
//MH(n)
RetValue = -((yArray[0][cnt]-RetPart2_1)*(yArray[0][cnt]-RetPart2_1)
+(yArray[1][cnt]-RetPart2_2)*(yArray[1][cnt]-RetPart2_2));
return RetValue;
}
*/
/***************************************
/Modified Viterbi Algorithm
/Core Part
/***************************************/
void GSMMVA(double yArray[2][BURSTLEN],double xArray[2][CHANNELMEMLEN],int mode,
struct GSMMVAState GSMMVATrellis[MVAState][200],struct GSMMVAOut MVAOut[BURSTLEN])
//xArray = gEstArray
{
int cnt,i,j;//,m,n;
int tempState;
int maxPathState;
int tempMask;
double incMetric;
int dataHistory[CHANNELMEMLEN];
struct GSMMVAOut tempMVAOut[BURSTLEN+CHANNELMEMLEN]; //one for soft,one for hard
//Initialization
cnt = 0;
for (i = 0;i<CHANNELMEMLEN;i++)
{
dataHistory[i] = 0;
}
for (i = 0;i<200;i++)
{
for(j = 0;j<MVAState;j++)
{
GSMMVATrellis[j][i].stateNum = j;
GSMMVATrellis[j][i].totalMetric = 0;
GSMMVATrellis[j][i].preState1 = ELSEWHERE;
GSMMVATrellis[j][i].preState2 = ELSEWHERE;
GSMMVATrellis[j][i].nextState1 = ELSEWHERE;
GSMMVATrellis[j][i].nextState2 = ELSEWHERE;
GSMMVATrellis[j][i].timeCount = i;
}
}
GSMMVATrellis[0][0].preState1 = 0;
GSMMVATrellis[0][0].preState2 = 0;
//Begin From State 0
while (cnt<=CHANNELMEMLEN)
{
for (j = 0;j<MVAState;j++)
{
for (i = 0;i<CHANNELMEMLEN;i++)
{
dataHistory[i] = 0;
}
if ((GSMMVATrellis[j][cnt].preState1!=ELSEWHERE)||(GSMMVATrellis[j][cnt].preState2!=ELSEWHERE))
{
GSMMVATrellis[j][cnt].nextState1 = GSMMVA_FSM(GSMMVATrellis[j][cnt].stateNum,0);
GSMMVATrellis[j][cnt].nextState2 = GSMMVA_FSM(GSMMVATrellis[j][cnt].stateNum,1);
if (j<(MVAState/2))
{
GSMMVATrellis[GSMMVATrellis[j][cnt].nextState1][cnt+1].preState1 = GSMMVATrellis[j][cnt].stateNum;
GSMMVATrellis[GSMMVATrellis[j][cnt].nextState2][cnt+1].preState1 = GSMMVATrellis[j][cnt].stateNum;
}
if (j>=(MVAState/2))
{
GSMMVATrellis[GSMMVATrellis[j][cnt].nextState1][cnt+1].preState2 = GSMMVATrellis[j][cnt].stateNum;
GSMMVATrellis[GSMMVATrellis[j][cnt].nextState2][cnt+1].preState2 = GSMMVATrellis[j][cnt].stateNum;
}
//Compute Metric
//Construct dataHistory
if (cnt>0)
{
tempMask = 0x00000001;
for (i = 1;i<CHANNELMEMLEN;i++)
{
dataHistory[i] = ((GSMMVATrellis[j][cnt].stateNum)&tempMask)>>(i-1);
tempMask = (tempMask<<1);
}
}
//Case1 - Move 0 into dataHistory[0],others shift right
dataHistory[0] = 0;
incMetric = GSMMVA_IncMetric(cnt,dataHistory,xArray,yArray);
if (j<(MVAState/2))
{
GSMMVATrellis[GSMMVATrellis[j][cnt].nextState1][cnt+1].totalMetric1
=GSMMVATrellis[j][cnt].totalMetric+incMetric;
GSMMVATrellis[GSMMVATrellis[j][cnt].nextState1][cnt+1].totalMetric
= GSMMVATrellis[GSMMVATrellis[j][cnt].nextState1][cnt+1].totalMetric1;
}
if (j>=(MVAState/2))
{
GSMMVATrellis[GSMMVATrellis[j][cnt].nextState1][cnt+1].totalMetric2
=GSMMVATrellis[j][cnt].totalMetric+incMetric;
GSMMVATrellis[GSMMVATrellis[j][cnt].nextState1][cnt+1].totalMetric
= GSMMVATrellis[GSMMVATrellis[j][cnt].nextState1][cnt+1].totalMetric2;
}
//Case2 - Move 1 into dataHistory[0],others shift right
dataHistory[0] = 1;
incMetric = GSMMVA_IncMetric(cnt,dataHistory,xArray,yArray);
if (j<(MVAState/2))
{
GSMMVATrellis[GSMMVATrellis[j][cnt].nextState2][cnt+1].totalMetric1
=GSMMVATrellis[j][cnt].totalMetric+incMetric;
GSMMVATrellis[GSMMVATrellis[j][cnt].nextState2][cnt+1].totalMetric
= GSMMVATrellis[GSMMVATrellis[j][cnt].nextState2][cnt+1].totalMetric1;
}
if (j>=(MVAState/2))
{
GSMMVATrellis[GSMMVATrellis[j][cnt].nextState2][cnt+1].totalMetric2
=GSMMVATrellis[j][cnt].totalMetric+incMetric;
GSMMVATrellis[GSMMVATrellis[j][cnt].nextState2][cnt+1].totalMetric
= GSMMVATrellis[GSMMVATrellis[j][cnt].nextState2][cnt+1].totalMetric2;
}
}
}
cnt++;
//For Debug
/* if (cnt<4)
{
printf("cnt:%d ",cnt);
for (j = 0;j<pow(2,cnt);j++)
{
if ((int)GSMMVATrellis[j][cnt].totalMetric == 0)
{
printf("%d ",GSMMVATrellis[j][cnt].stateNum);
if (GSMMVATrellis[j][cnt].stateNum%2 != GSMFrame[cnt-1])
{
printf("ERROR!!!!!!!!\n");
}
else
{
printf("PASS!!!!!\n");
}
}
}
}
*/
}
//For debug
/* for (i = 0;i<MVAState;i++)
{
printf("%d pre1:%d pre2:%d next1:%d next2:%d met1:%f met2:%f tot:%f\n",i,
GSMMVATrellis[i][cnt].preState1,GSMMVATrellis[i][cnt].preState2,
GSMMVATrellis[i][cnt].nextState1,GSMMVATrellis[i][cnt].nextState2,
GSMMVATrellis[i][cnt].totalMetric1,GSMMVATrellis[i][cnt].totalMetric2,
GSMMVATrellis[i][cnt].totalMetric);
}
*/
//Add,Compare,Choose
while ((cnt>CHANNELMEMLEN)&&(cnt<BURSTLEN))
{
for (j = 0;j<MVAState;j++)
{
//Compare and Choose
if (GSMMVATrellis[j][cnt].totalMetric1>=GSMMVATrellis[j][cnt].totalMetric2)
{
GSMMVATrellis[j][cnt].totalMetric = GSMMVATrellis[j][cnt].totalMetric1;
if ((j%2)==0)
{
GSMMVATrellis[GSMMVATrellis[j][cnt].preState2][cnt-1].nextState1 = ELSEWHERE;
}
if ((j%2)==1)
{
GSMMVATrellis[GSMMVATrellis[j][cnt].preState2][cnt-1].nextState2 = ELSEWHERE;
}
GSMMVATrellis[j][cnt].preState2 = ELSEWHERE;
}
if (GSMMVATrellis[j][cnt].totalMetric1<GSMMVATrellis[j][cnt].totalMetric2)
{
GSMMVATrellis[j][cnt].totalMetric = GSMMVATrellis[j][cnt].totalMetric2;
if ((j%2)==0)
{
GSMMVATrellis[GSMMVATrellis[j][cnt].preState1][cnt-1].nextState1 = ELSEWHERE;
}
if ((j%2)==1)
{
GSMMVATrellis[GSMMVATrellis[j][cnt].preState1][cnt-1].nextState2 = ELSEWHERE;
}
GSMMVATrellis[j][cnt].preState1 = ELSEWHERE;
}
//Add
GSMMVATrellis[j][cnt].nextState1 = GSMMVA_FSM(GSMMVATrellis[j][cnt].stateNum,0);
GSMMVATrellis[j][cnt].nextState2 = GSMMVA_FSM(GSMMVATrellis[j][cnt].stateNum,1);
if (j<(MVAState/2))
{
GSMMVATrellis[GSMMVATrellis[j][cnt].nextState1][cnt+1].preState1 = GSMMVATrellis[j][cnt].stateNum;
GSMMVATrellis[GSMMVATrellis[j][cnt].nextState2][cnt+1].preState1 = GSMMVATrellis[j][cnt].stateNum;
}
if (j>=(MVAState/2))
{
GSMMVATrellis[GSMMVATrellis[j][cnt].nextState1][cnt+1].preState2 = GSMMVATrellis[j][cnt].stateNum;
GSMMVATrellis[GSMMVATrellis[j][cnt].nextState2][cnt+1].preState2 = GSMMVATrellis[j][cnt].stateNum;
}
//Compute Metric
//Construct dataHistory
if (cnt>0)
{
tempMask = 0x00000001;
for (i = 1;i<CHANNELMEMLEN;i++)
{
dataHistory[i] = ((GSMMVATrellis[j][cnt].stateNum)&tempMask)>>(i-1);
tempMask = (tempMask<<1);
}
}
//Case1 - Move 0 into dataHistory[0],others shift right
dataHistory[0] = 0;
incMetric = GSMMVA_IncMetric(cnt,dataHistory,xArray,yArray);
if (j<(MVAState/2))
{
GSMMVATrellis[GSMMVATrellis[j][cnt].nextState1][cnt+1].totalMetric1
=GSMMVATrellis[j][cnt].totalMetric+incMetric;
}
if (j>=(MVAState/2))
{
GSMMVATrellis[GSMMVATrellis[j][cnt].nextState1][cnt+1].totalMetric2
=GSMMVATrellis[j][cnt].totalMetric+incMetric;
}
//Case2 - Move 1 into dataHistory[0],others shift right
dataHistory[0] = 1;
incMetric = GSMMVA_IncMetric(cnt,dataHistory,xArray,yArray);
if (j<(MVAState/2))
{
GSMMVATrellis[GSMMVATrellis[j][cnt].nextState2][cnt+1].totalMetric1
=GSMMVATrellis[j][cnt].totalMetric+incMetric;
}
if (j>=(MVAState/2))
{
GSMMVATrellis[GSMMVATrellis[j][cnt].nextState2][cnt+1].totalMetric2
=GSMMVATrellis[j][cnt].totalMetric+incMetric;
}
}//end of for j=0~31
//For debug
/* printf("cnt:%d /////////////////////////////\n",cnt);
for (i = 0;i<MVAState;i++)
{
printf("%d pre1:%d pre2:%d next1:%d next2:%d met1:%f met2:%f tot:%f\n",i,
GSMMVATrellis[i][cnt].preState1,GSMMVATrellis[i][cnt].preState2,
GSMMVATrellis[i][cnt].nextState1,GSMMVATrellis[i][cnt].nextState2,
GSMMVATrellis[i][cnt].totalMetric1,GSMMVATrellis[i][cnt].totalMetric2,
GSMMVATrellis[i][cnt].totalMetric);
}
*/
if ((cnt >30)&&(mode==1))
{
//GSMMVA_Goback;
}
//For Debug
/* printf("cnt:%d ",cnt);
for (j = 0;j<MVAState;j++)
{
if ((int)GSMMVATrellis[j][cnt].totalMetric == 0)
{
printf("%d ",GSMMVATrellis[j][cnt].stateNum);
if (GSMMVATrellis[j][cnt].stateNum%2 != GSMFrame[cnt-1])
{
printf("ERROR!!!!!!!!\n");
}
else
{
printf("PASS!!!!!\n");
}
}
}
*/
cnt++;
}//end of while
//In the end,Converge
for (j = 0;j<(MVAState);j++)
{
if ((GSMMVATrellis[j][cnt].preState1!=ELSEWHERE)||(GSMMVATrellis[j][cnt].preState2!=ELSEWHERE))
{
//Compare and Choose
if ((GSMMVATrellis[j][cnt].totalMetric1)>=(GSMMVATrellis[j][cnt].totalMetric2))
{
GSMMVATrellis[j][cnt].totalMetric = GSMMVATrellis[j][cnt].totalMetric1;
if ((j%2)==0)
{
GSMMVATrellis[GSMMVATrellis[j][cnt].preState2][cnt-1].nextState1 = ELSEWHERE;
}
if ((j%2)==1)
{
GSMMVATrellis[GSMMVATrellis[j][cnt].preState2][cnt-1].nextState2 = ELSEWHERE;
}
GSMMVATrellis[j][cnt].preState2 = ELSEWHERE;
}
if (GSMMVATrellis[j][cnt].totalMetric1<GSMMVATrellis[j][cnt].totalMetric2)
{
GSMMVATrellis[j][cnt].totalMetric = GSMMVATrellis[j][cnt].totalMetric2;
if ((j%2)==0)
{
GSMMVATrellis[GSMMVATrellis[j][cnt].preState1][cnt-1].nextState1 = ELSEWHERE;
}
if ((j%2)==1)
{
GSMMVATrellis[GSMMVATrellis[j][cnt].preState1][cnt-1].nextState2 = ELSEWHERE;
}
GSMMVATrellis[j][cnt].preState1 = ELSEWHERE;
}
}
}
//For debug
/*printf("cnt:%d /////////////////////////////\n",cnt);
for (i = 0;i<MVAState;i++)
{
printf("%d pre1:%d pre2:%d next1:%d next2:%d met1:%f met2:%f tot:%f\n",i,
GSMMVATrellis[i][cnt].preState1,GSMMVATrellis[i][cnt].preState2,
GSMMVATrellis[i][cnt].nextState1,GSMMVATrellis[i][cnt].nextState2,
GSMMVATrellis[i][cnt].totalMetric1,GSMMVATrellis[i][cnt].totalMetric2,
GSMMVATrellis[i][cnt].totalMetric);
}*/
//Terminate
maxPathState = 0;
for (j = 1;j<(MVAState);j++)
{
if (GSMMVATrellis[j][cnt].totalMetric>GSMMVATrellis[maxPathState][cnt].totalMetric)
{
maxPathState = GSMMVATrellis[j][cnt].stateNum;
}
}
//For debug
/* for (i = 0;i<32;i++)
{
printf("cnt:%d state:%d pre1:%d pre2:%d next1:%d next2:%d\n",cnt,i,
GSMMVATrellis[i][cnt].preState1,GSMMVATrellis[i][cnt].preState2,
GSMMVATrellis[i][cnt].nextState1,GSMMVATrellis[i][cnt].nextState2);
}
*/
//At last,get out all the sequence
if ((maxPathState%2)==0)
{
tempMVAOut[cnt].hard = 0;
}
if ((maxPathState%2)==1)
{
tempMVAOut[cnt].hard = 1;
}
//For Debug
/*if (tempMVAOut[cnt].hard != GSMFrame[cnt-1])
{
printf("ERROR!!!!!!!!\n");
}
else
{
printf("PASS!!!!!\n");
}*/
if (GSMMVATrellis[maxPathState][cnt].preState1!=ELSEWHERE)
{
tempState = GSMMVATrellis[maxPathState][cnt].preState1;
}
if (GSMMVATrellis[maxPathState][cnt].preState2!=ELSEWHERE)
{
tempState = GSMMVATrellis[maxPathState][cnt].preState2;
}
//tempMVAOut[cnt].hard = 0;
for (i = cnt-1;i>=1;i--)
{
//For Debug
//printf("i:%d State:%d tot:%1.1f ",i,tempState,GSMMVATrellis[tempState][i].totalMetric);
if ((tempState%2)==0)
{
tempMVAOut[i].hard = 0;
}
if ((tempState%2)==1)
{
tempMVAOut[i].hard = 1;
}
//For Debug
/*if (tempMVAOut[i].hard != GSMFrame[i-1])
{
printf("ERROR!!!!!!!!\n");
}
else
{
printf("PASS!!!!!\n");
}*/
if (GSMMVATrellis[tempState][i].preState1!=ELSEWHERE)
{
tempState = GSMMVATrellis[tempState][i].preState1;
continue;
}
if (GSMMVATrellis[tempState][i].preState2!=ELSEWHERE)
{
tempState = GSMMVATrellis[tempState][i].preState2;
continue;
}
}
for (i = 0;i<BURSTLEN;i++)
{
MVAOut[i].hard = tempMVAOut[i+1].hard;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -