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

📄 viterbi.cpp

📁 压缩包内为本人写的(2,1,3)卷积码编码器和维特比(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 + -