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

📄 decode.cpp

📁 veterbi 编解码程序
💻 CPP
字号:
#include <windows.h>
#include <stdio.h>

#include "decode.h"

/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
const static int statustable[64][4]={	{0,1,1,0},{1,1,0,0},{1,0,0,1},{0,0,1,1},//64种状态,每个当前状态有两个后续状态
								{1,0,0,1},{0,0,1,1},{0,1,1,0},{1,1,0,0},//后续上状态:  [0]:G1,[1]:G2;	后续下状态: [2]:G1,[3]:G2;
								{0,1,1,0},{1,1,0,0},{1,0,0,1},{0,0,1,1},
								{1,0,0,1},{0,0,1,1},{0,1,1,0},{1,1,0,0},
								{0,0,1,1},{1,0,0,1},{1,1,0,0},{0,1,1,0},
								{1,1,0,0},{0,1,1,0},{0,0,1,1},{1,0,0,1},
								{0,0,1,1},{1,0,0,1},{1,1,0,0},{0,1,1,0},
								{1,1,0,0},{0,1,1,0},{0,0,1,1},{1,0,0,1},
								{1,0,0,1},{0,0,1,1},{0,1,1,0},{1,1,0,0},
								{0,1,1,0},{1,1,0,0},{1,0,0,1},{0,0,1,1},
								{1,0,0,1},{0,0,1,1},{0,1,1,0},{1,1,0,0},
								{0,1,1,0},{1,1,0,0},{1,0,0,1},{0,0,1,1},
								{1,1,0,0},{0,1,1,0},{0,0,1,1},{1,0,0,1},
								{0,0,1,1},{1,0,0,1},{1,1,0,0},{0,1,1,0},
								{1,1,0,0},{0,1,1,0},{0,0,1,1},{1,0,0,1},
								{0,0,1,1},{1,0,0,1},{1,1,0,0},{0,1,1,0}	};
////////////////////////////////////////////////////////////////////
static BYTE BV(BYTE i)//类似于avr中的_BV()函数
{
	BYTE out=0x01;
	return (out<<i);
}

static BYTE get(BYTE i,BYTE num)//获得num比特的值
{
	return (i&BV(num))>>num;
}

static void set(PBYTE i,BYTE num,BYTE enset)
{
	if(enset)
		*i=*i|BV(num);//对num比特置位
	else
		*i=*i&(~BV(num));//对num比特复位
}

static int bmgup(int i,PBYTE data)
{
	int a,b;
	a=(statustable[i][0]==data[0])?0:1;
	b=(statustable[i][1]==data[1])?0:1;
	return (a+b);
}

static int bmgdown(int i,PBYTE data)
{
	int a,b;
	a=(statustable[i][2]==data[0])?0:1;
	b=(statustable[i][3]==data[1])?0:1;
	return (a+b);
}

static int judge(int *totalms)
{
	int a,b=0;
	int temp=totalms[0];

	for(a=1;a<64;a++)
	{
		if(totalms[a]<temp)
		{
			temp=totalms[a];b=a;
		}
	}
	return b;
}

void viterbi_jbx(PBYTE data,PBYTE outdata,int *totalms1,int *totalms2,PBYTE route1,PBYTE route2,int *eninitial)//加比选单元
{
	static int routenum=0,outnum=0,outbyte=7;
	//routenum:用于译码深度,outnum:译码输出数据的字节数,outbyte:当前译码输出字节的比特数

	int upms1,upms2,downms1,downms2;//本次度量
	int i;//statusnum
	int j;

	if(*eninitial==1)//重新初始化
	{
		routenum=0,outnum=0,outbyte=7;
		//重新初始化完成
		*eninitial=0;
	}

	for(i=0;i<32;i++)//由状态表的特点决定
	{
		upms1=bmgup(i,data);
		upms2=bmgup((i+32),data);
		downms1=bmgdown(i,data);
		downms2=bmgdown((i+32),data);
		
		if((totalms1[i]+upms1)<(totalms1[i+32]+upms2))
		{
			totalms2[2*i]=totalms1[i]+upms1;
			for(j=0;j<routenum;j++)
				*(route2+2*i*DEPTH+j)=*(route1+i*DEPTH+j);
			*(route2+2*i*DEPTH+routenum)=0;
		}
		else
		{
			totalms2[2*i]=totalms1[i+32]+upms2;
			for(j=0;j<routenum;j++)
				*(route2+2*i*DEPTH+j)=*(route1+(i+32)*DEPTH+j);
			*(route2+2*i*DEPTH+routenum)=0;
		}

		if((totalms1[i]+downms1)<(totalms1[i+32]+downms2))
		{
			totalms2[2*i+1]=totalms1[i]+downms1;
			for(j=0;j<routenum;j++)
				*(route2+(2*i+1)*DEPTH+j)=*(route1+i*DEPTH+j);
			*(route2+(2*i+1)*DEPTH+routenum)=1;
		}
		else
		{
			totalms2[2*i+1]=totalms1[i+32]+downms2;
			for(j=0;j<routenum;j++)
				*(route2+(2*i+1)*DEPTH+j)=*(route1+(i+32)*DEPTH+j);
			*(route2+(2*i+1)*DEPTH+routenum)=1;
		}
	}

	if(routenum==(DEPTH-1))//达到译码深度
	{
		set(&outdata[outnum],outbyte--,*route2);
		//set(&outdata[outnum],outbyte--,*(route2+judge(totalms2)*DEPTH));//可以judge(),结果差不多。
		
		for(i=0;i<64;i++)//把输出的路径删了
			for(j=0;j<(DEPTH-1);j++)
				*(route2+i*DEPTH+j)=*(route2+i*DEPTH+j+1);

		if(outbyte<0)//error:outbyte==0
		{
			outbyte=7;
			outnum++;
		}
	}
	else
		routenum++;

}

void decode_once(PBYTE data,PBYTE outdata,int *eninitial)//一次译码
{
	static int totalms1[64]={	0,6,9,9,15,9,12,12,21,15,12,12,12,18,15,15,	//强制输入6个0,使树状图展开为64个节点,并保存相应的度量。
								21,27,18,18,18,12,15,15,18,12,21,21,15,21,	//这样,在真实数据进来时,就不需要树状图展开这一步了
								18,18,24,24,33,27,21,21,18,24,21,21,12,18,
								18,18,21,15,21,21,18,12,24,24,21,27,18,18,
								21,27,21,21,24,18						};

	static int totalms2[64]={	0,6,9,9,15,9,12,12,21,15,12,12,12,18,15,15,	//强制输入6个0,使树状图展开为64个节点,并保存相应的度量。
								21,27,18,18,18,12,15,15,18,12,21,21,15,21,	//这样,在真实数据进来时,就不需要树状图展开这一步了
								18,18,24,24,33,27,21,21,18,24,21,21,12,18,
								18,18,21,15,21,21,18,12,24,24,21,27,18,18,
								21,27,21,21,24,18						};
	static BYTE route1[64][DEPTH],route2[64][DEPTH];//保存路径
	static int select=0;//改变route1与route2,totalms1与totalms2作用

	if(*eninitial==1)//重新初始化
	{
		int i,j;
		int totalms[64]={0,6,9,9,15,9,12,12,21,15,12,12,12,18,15,15,	//强制输入6个0,使树状图展开为64个节点,并保存相应的度量。
								21,27,18,18,18,12,15,15,18,12,21,21,15,21,	//这样,在真实数据进来时,就不需要树状图展开这一步了
								18,18,24,24,33,27,21,21,18,24,21,21,12,18,
								18,18,21,15,21,21,18,12,24,24,21,27,18,18,
								21,27,21,21,24,18						};
		for(i=0;i<64;i++)
		{	
			totalms1[i]=totalms[i];totalms2[i]=totalms[i];
		}
		for(i=0;i<64;i++)
			for(j=0;j<DEPTH;j++)
			{	route1[i][j]=0;route2[i][j]=0;	}
		select=0;
	}

	if(select==0)
	{
		viterbi_jbx(data,outdata,totalms1,totalms2,&route1[0][0],&route2[0][0],eninitial);
		select=1;
	}
	else
	{
		viterbi_jbx(data,outdata,totalms2,totalms1,&route2[0][0],&route1[0][0],eninitial);
		select=0;
	}
}

void decode_byte(BYTE inbyte,PBYTE outdata,int *eninitial)//译码一个比特(8bit)
{
	int i;
	BYTE data[2];
	for(i=3;i>-1;i--)//error is:	for(i=3;i<-1;i--)
	{
		data[0]=get(inbyte,2*i+1);//G1
		data[1]=get(inbyte,2*i);//G2
		decode_once(data,outdata,eninitial);
	}
	//实际中还需要防止累计度量溢出
}

//当前采用硬判决。可改为软判决。
//inData:	7	6	5	4	3	2	1	0
//编码顺序:0	1	2	3	4	5	6	7

//outData[0]:	7	6	5	4	3	2	1	0
//				G1	G2  G1	G2	G1	G2	G1	G2
//编码结果顺序:   0	   1	   2	   3
	
//outData[1]:	7	6	5	4	3	2	1	0
//				G1	G2  G1	G2	G1	G2	G1	G2
//编码结果顺序:   4	   5	   6	   7

void decode(PBYTE indata,PBYTE outdata,int count,int initial)//采用(2,1,7)卷积码
{
	static int eninitial;//是否重新初始化

	int i;

	eninitial=initial;
	for(i=0;i<count;i++)
	{	
		decode_byte(indata[i],outdata,&eninitial);
	}
	for(i=0;i<10;i++)
	{
		decode_byte(0x00,outdata,&eninitial);
	}
}

⌨️ 快捷键说明

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