📄 viterbi.cpp
字号:
//********************************
//维特比译码器的类实现
#include "Viterbi.h"
Viterbi::Viterbi(int DecDepth)//构造函数
{
DecodeDepth=DecDepth;//设置译码深度
//建立并初始化所有缓存
D=new int*[8];//建立二维数组D[8][DecodeDepth];
for(int i=0;i<8;i++)
{
D[i]=new int[DecodeDepth];
Rstatus[i]=0;//寄存器初始化0
}
InCode=new int[DecodeDepth];
R=0;
}
Viterbi::~Viterbi()
{
for(int i=0;i<8;i++)
delete D[i];
delete []D;
delete [] InCode;
}
//********************************
//
//函数:ShiftIn(int *data,int index,int shift_length=DecodeDepth*2)
//功能:长为DecodeDepth*2的二进制序列移入设码器
//输入:data[index]--data[index+shift_length]
//返回:无
//************************************
void Viterbi::ShiftIn(int *data,int index)
{
int j=0;
for(int i=0;i<DecodeDepth;i++)
{
InCode[i]=bin2dec(data[index+j],data[index+1+j]);//把每两位二进制数移入后转为十进制数
j=j+2;//一次移两位
}
}
//********************************
//
//函数:bin2dec(int bithigh,int bitlow)
//功能:把输入的二进制变为十进制
//输入:bithigh高位二进制,bitlow低位二进制
//返回:转化后的十进制0,1,2,3
//************************************
int Viterbi::bin2dec(int bithigh,int bitlow)
{
int temp;
if(bitlow==0)
{
if(bithigh==0)
temp=0;
else temp=2;
}
else
{
if(bithigh==0)
temp=1;
else temp=3;
}
return temp;
}
void Viterbi::DecodeOut(int *data_out,int index)
{
int i,j;
// int **tempbuf;
// tempbuf=new int[4];
// for(i=0;i<4;i++)
// tempbuf[i]=new int[DecodeDepth];//定义临时缓存
//初始化
this->initi();
//从第二步开始判决
for(i=2;i<DecodeDepth;i++)//主LOOP
{
for(j=0;j<4;j++)//前四条路往下走,变成八条
{
//长度增加
switch(Rstatus[j])//根据每条路径对应的状态选路
{
case 0:
D[j][i]=0;
Rstatus[j]=0;//重设对应状态
D[j+4][i]=3;
Rstatus[j+4]=1;
break;
case 1:
D[j][i]=2;
Rstatus[j]=2;
D[j+4][i]=1;
Rstatus[j+4]=3;
break;
case 2:
D[j][i]=3;
Rstatus[j]=0;
D[j+4][i]=0;
Rstatus[j+4]=1;
break;
case 3:
D[j][i]=1;
Rstatus[j]=2;
D[j+4][i]=2;
Rstatus[j+4]=3;
break;
}
}
arrange(i+1);//排序,使得最小码距的序列存放在D0--D3中
//把主缓冲拷贝到临时缓冲
BufCopy(D[0],D[4],i+1);
BufCopy(D[1],D[5],i+1);
BufCopy(D[2],D[6],i+1);
BufCopy(D[3],D[7],i+1);
// for(int t=0;t<4;t++)
//
// Rstatus[t+4]=Rstatus[t];
}
//结束判决
//*******************
//D[0]中存放了最优序列,开始解码
for(i=0;i<DecodeDepth;i++)
{
switch(R)
{
case 0:
if(D[0][i]==0)
{
data_out[index+i]=0;
R=0;
}
else
{
data_out[index+i]=1;
R=1;
}break;
case 1:
if(D[0][i]==2)
{
data_out[index+i]=0;
R=2;
}
else
{
data_out[index+i]=1;
R=3;
}
break;
case 2:
if(D[0][i]==3)
{
data_out[index+i]=0;
R=0;
}
else
{
data_out[index+i]=1;
R=1;
}
break;
case 3:
if(D[0][i]==1)
{
data_out[index+i]=0;
R=2;
}
else
{
data_out[index+i]=1;
R=3;
}
break;
}
}
}
//********************************
//
//函数:BufCopy(int *src, int *dst, int inlength)
//功能:把长度为inlength的数据从src中复制到dst中
//输入:源和目的的首地址和长度
//返回:无
//************************************
void Viterbi::BufCopy(int *src, int *dst, int inlength)
{
for(int i=0;i<inlength;i++)//逐个复制
{
dst[i]=src[i];
}
}
//********************************
//
//函数:camplare(int *inbuf, int& distance)
//功能:比较inbuf序列和incode序列的码距,输出到distance
//输入:源首地址和长度
//返回:无
//************************************
void Viterbi::camplare(int *inbuf, int inlength,int& distance)
{
int count=0;//用于支路量度;
for(int i=0;i<inlength;i++)
{
switch(inbuf[i]^InCode[i])//用异或运算计算码距
{
case 0:
break;
case 1:
count++;
break;
case 2:
count++;
break;
case 3:
count=count+2;
break;
}
}
distance=count;
}
//********************************
//
//函数:arrange(int inlength)
//功能:对D[0]到D[8]按码距进行排序,排序后D[0]到D[3]存放码距最小的四个序列
//输入:当然序列的长度
//返回:无
//************************************
void Viterbi::arrange(int inlength)
{
int *distance;
int tempdst;
int *tempbuf;
tempbuf=new int[inlength];
int i,j;
distance=new int[8];//存放每个序列与输入待译码序列的码距
for(j=0;j<8;j++)
{
camplare(D[j],inlength,distance[j]);//逐个比较,得出码距放于distance[j]中
}
for(j=0;j<8;j++)//冒泡排序算法,最小的先浮上顶
{
for(i=7;i>j;i--)
{
if(distance[i]<distance[i-1])//交换
{
tempdst=distance[i-1];
distance[i-1]=distance[i];
distance[i]=tempdst;
//序列也交换
BufCopy(D[i-1],tempbuf,inlength);
BufCopy(D[i],D[i-1],inlength);
BufCopy(tempbuf,D[i],inlength);
//对应序列的寄存器状态也要交换
tempdst=Rstatus[i-1];
Rstatus[i-1]=Rstatus[i];
Rstatus[i]=tempdst;
}
}
}//排序结束
delete[] distance;
delete[] tempbuf;
}
void Viterbi::reset()
{
}
void Viterbi::initi()
{
R=Rstatus[0];
switch(Rstatus[0])
{
case 0:
{
D[0][0]=0;
D[0][1]=0;
Rstatus[0]=0;
D[1][0]=0;
D[1][1]=3;
Rstatus[1]=1;
D[2][0]=3;
D[2][1]=2;
Rstatus[2]=2;
D[3][0]=3;
D[3][1]=1;
Rstatus[3]=3;
}break;
case 1:
{
D[0][0]=2;
D[0][1]=3;
Rstatus[0]=0;
D[1][0]=2;
D[1][1]=0;
Rstatus[1]=1;
D[2][0]=1;
D[2][1]=1;
Rstatus[2]=2;
D[3][0]=1;
D[3][1]=2;
Rstatus[3]=3;
}
break;
case 2:
{
D[0][0]=3;
D[0][1]=0;
Rstatus[0]=0;
D[1][0]=3;
D[1][1]=3;
Rstatus[1]=1;
D[2][0]=0;
D[2][1]=2;
Rstatus[2]=2;
D[3][0]=0;
D[3][1]=1;
Rstatus[3]=3;
}
break;
case 3:
{
D[0][0]=1;
D[0][1]=3;
Rstatus[0]=0;
D[1][0]=1;
D[1][1]=0;
Rstatus[1]=1;
D[2][0]=2;
D[2][1]=1;
Rstatus[2]=2;
D[3][0]=2;
D[3][1]=2;
Rstatus[3]=3;
}
break;
}
BufCopy(D[0],D[4],2);
BufCopy(D[1],D[5],2);
BufCopy(D[2],D[6],2);
BufCopy(D[3],D[7],2);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -