📄 viterbi216.cpp
字号:
#include "viterbi216.h"
//-----以下为函数部分-----
//---------------------------------------------------------------------------
CViterbi_216::CViterbi_216()
{
Decode_States = 64; //状态数 2^m*k0
Branch_Num = 2; //从一个状态延伸的分支数 n0
Path_Length = 64; //路径保留长度 5*m < L < 10*m
Path_Num = 32; //保存幸存路径个数
First_Use = 1;
Initial();
}
//---------------------------------------------------------------------------
CViterbi_216::~CViterbi_216()
{
;
}
//---------------------------------------------------------------------------
void CViterbi_216::Initial()
{
unsigned char NowStates;
int OneNum;
int i, j;
//状态发生器:产生2^k0*m_个状态和分支值
for(i=0; i<Decode_States; i++){
for(j=0; j<Branch_Num; j++){
NowStates = (i<<1) | j;
OneNum = WeightInt(NowStates & G1);
Branch_Tab[i][j] = OneNum % 2;
OneNum = WeightInt(NowStates & G2);
Branch_Tab[i][j] = (Branch_Tab[i][j] << 1) | (OneNum % 2);
}
}
Init_Num = 0;//幸存路径预装载个数,Init_Num 的计算方法如下 2^Init_Num = Path_Num
i = Path_Num;
while(i > 1){
Init_Num++;
i = i / 2;
}
}
//---------------------------------------------------------------------------
int CViterbi_216::Viterbi216(unsigned char *InBuf, int InLength, unsigned char *OutBuf, int Star_Mode)
{
int i, j, p;
int ReadBit = 0;
int WriteByte = 0;
int OutBit = 0;
int Now_States = 0;
int Temp_d, Temp_Hm, Temp_Lm;
unsigned char NowCod;
//表示处理非连续卷积码编码数据或者连续卷积码编码数据的第一个缓存
if((Star_Mode == 0) | (First_Use == 1)){
//初始化幸存路径结构
for(i=0; i<Path_Num; i++){
Survivor_Save[i].Sum_d = 0;
Survivor_Save[i].H_m32 = 0;
Survivor_Save[i].L_m32 = 0;
}
//首先:将幸存路径存储缓存装载满
for(i=0,j=1; i<Init_Num; i++){
//每个时刻输出2比特,和接收序列对应时刻的码组比较汉明距离
NowCod = InBuf[ReadBit/8] >> (6-ReadBit%8);//从接收序列中取出一个码组
NowCod = NowCod & 0x03;
ReadBit += 2;
//累加器:进行距离累加
for(p=0; p<j; p++){
Survivor_Save[p].Sum_d = Survivor_Temp[p].Sum_d;
Survivor_Save[p].H_m32 = Survivor_Temp[p].H_m32;
Survivor_Save[p].L_m32 = Survivor_Temp[p].L_m32;
Now_States = char(Survivor_Save[p].L_m32 & 0x3f);
Survivor_Temp[p].Sum_d = Survivor_Save[p].Sum_d +
WeightInt(NowCod ^ Branch_Tab[Now_States][0]);
Survivor_Temp[p].L_m32 = (Survivor_Save[p].L_m32<<1) | 0;
Survivor_Temp[p+j].Sum_d = Survivor_Save[p].Sum_d +
WeightInt(NowCod ^ Branch_Tab[Now_States][1]);
Survivor_Temp[p+j].L_m32 = (Survivor_Save[p].L_m32<<1) | 1;
}
j = 2 * j;
for(p=0; p<j; p++){
Survivor_Save[p].Sum_d = Survivor_Temp[p].Sum_d;
Survivor_Save[p].H_m32 = Survivor_Temp[p].H_m32;
Survivor_Save[p].L_m32 = Survivor_Temp[p].L_m32;
}
}
//用选择法对Survivor_Save[].Sum_d按由小到大排序
//在此可以不排序,但是排序后效果更好,可以减少Path_Num的个数
/*for(i=0; i<Path_Num-1; i++){
for(j=i+1; j<Path_Num; j++){
if(Survivor_Save[j].Sum_d < Survivor_Save[i].Sum_d){
Temp_d = Survivor_Save[i].Sum_d;
Temp_Hm = Survivor_Save[i].H_m32;
Temp_Lm = Survivor_Save[i].L_m32;
Survivor_Save[i].Sum_d = Survivor_Save[j].Sum_d;
Survivor_Save[i].H_m32 = Survivor_Save[j].H_m32;
Survivor_Save[i].L_m32 = Survivor_Save[j].L_m32;
Survivor_Save[j].Sum_d = Temp_d;
Survivor_Save[j].H_m32 = Temp_Hm;
Survivor_Save[j].L_m32 = Temp_Lm;
}
}
}//*/
OutBit = Init_Num;
First_Use = 0;
}
//第二步:对数据进行纠错译码
for( ; ReadBit<InLength*8; ){
//判决器:输出汉明距离最小的幸存路径的高32比特,有多个最小时输出任意一个
if(OutBit == Path_Length){
//输出最小路径的高32比特信息序列
OutBuf[WriteByte++] = char(Survivor_Save[0].H_m32>>24);
OutBuf[WriteByte++] = char(Survivor_Save[0].H_m32>>16);
OutBuf[WriteByte++] = char(Survivor_Save[0].H_m32>>8);
OutBuf[WriteByte++] = char(Survivor_Save[0].H_m32);
OutBit = 32;
}
//接收序列各个时刻的循环
//每个时刻输出2比特,和接收序列对应时刻的码组比较得到汉明距离
NowCod = InBuf[ReadBit/8] >> (6-ReadBit%8);//从接收序列中取出一个码组
NowCod = NowCod & 0x03;
ReadBit += 2;
//累加器:进行距离累加
for(j=0; j<Path_Num; j++){
Now_States = char(Survivor_Save[j].L_m32 & 0x3f);
Survivor_Temp[j].Sum_d = Survivor_Save[j].Sum_d +
WeightInt(NowCod ^ Branch_Tab[Now_States][0]);
Survivor_Temp[j].H_m32 = Survivor_Save[j].H_m32<<1 |
Survivor_Save[j].L_m32>>31;
Survivor_Temp[j].L_m32 = Survivor_Save[j].L_m32<<1;
Survivor_Temp[j+Path_Num].Sum_d = Survivor_Save[j].Sum_d +
WeightInt(NowCod ^ Branch_Tab[Now_States][1]);
Survivor_Temp[j+Path_Num].H_m32 = Survivor_Save[j].H_m32<<1 |
Survivor_Save[j].L_m32>>31;
Survivor_Temp[j+Path_Num].L_m32 = (Survivor_Save[j].L_m32<<1) | 1;
}
//比较器:比较各条路径的距离,保留相对较小的Path_Num条
//用选择法对Survivor_Temp[].Sum_d按由小到大排序
for(i=0; i<Path_Num; i++){
for(j=i+1; j<2*Path_Num; j++){
if(Survivor_Temp[j].Sum_d < Survivor_Temp[i].Sum_d){
Temp_d = Survivor_Temp[i].Sum_d;
Temp_Hm = Survivor_Temp[i].H_m32;
Temp_Lm = Survivor_Temp[i].L_m32;
Survivor_Temp[i].Sum_d = Survivor_Temp[j].Sum_d;
Survivor_Temp[i].H_m32 = Survivor_Temp[j].H_m32;
Survivor_Temp[i].L_m32 = Survivor_Temp[j].L_m32;
Survivor_Temp[j].Sum_d = Temp_d;
Survivor_Temp[j].H_m32 = Temp_Hm;
Survivor_Temp[j].L_m32 = Temp_Lm;
}
}
}
//将较小的Path_Num条存入幸存路径结构缓存
for(i=0; i<Path_Num; i++){
Survivor_Save[i].Sum_d = Survivor_Temp[i].Sum_d;
Survivor_Save[i].H_m32 = Survivor_Temp[i].H_m32;
Survivor_Save[i].L_m32 = Survivor_Temp[i].L_m32;
}
OutBit++;
}
//第三步:对数据尾部的处理,
//输出汉明距离最小的幸存路径的OutBit个比特(位权较低的OutBit个),有多个最小的输出任意一个
if(OutBit == 64){
OutBuf[WriteByte++] = char(Survivor_Save[0].H_m32>>24);
OutBuf[WriteByte++] = char(Survivor_Save[0].H_m32>>16);
OutBuf[WriteByte++] = char(Survivor_Save[0].H_m32>>8);
OutBuf[WriteByte++] = char(Survivor_Save[0].H_m32);
OutBuf[WriteByte++] = char(Survivor_Save[0].L_m32>>24);
OutBuf[WriteByte++] = char(Survivor_Save[0].L_m32>>16);
OutBuf[WriteByte++] = char(Survivor_Save[0].L_m32>>8);
OutBuf[WriteByte++] = char(Survivor_Save[0].L_m32);
}
else{
if(OutBit > 32){
Temp_Hm = (Survivor_Save[0].H_m32<<(64-OutBit)) | (Survivor_Save[0].L_m32>>(OutBit-32));
OutBuf[WriteByte++] = char(Temp_Hm>>24);
OutBuf[WriteByte++] = char(Temp_Hm>>16);
OutBuf[WriteByte++] = char(Temp_Hm>>8);
OutBuf[WriteByte++] = char(Temp_Hm);
OutBit -= 32;
}
Temp_Lm = Survivor_Save[0].L_m32 << (32-OutBit);
while(OutBit > 0){
OutBuf[WriteByte++] = char(Temp_Lm>>24);
Temp_Lm = Temp_Lm << 8;
OutBit -= 8;
}
}
//第四步:如果处理的是连续数据,要将较小幸存路径的汉明距离缩小,避免溢出
/*for(i=1; i<Path_Num; i++){
if((Survivor_Save[i].Sum_d - Survivor_Save[0].Sum_d) > Path_Length)
Survivor_Save[i].Sum_d = Path_Length;
else
Survivor_Save[i].Sum_d -= Survivor_Save[0].Sum_d;
}
Survivor_Save[0].Sum_d = 0;
//*/
//维特比译码结束
return WriteByte;
}
//---------------------------------------------------------------------------
int CViterbi_216::Encode_216(unsigned char * InBuf, int InLength, unsigned char * OutBuf, int Now_State)
{
int ReadBit;
int ReadByte;
int WriteBit;
unsigned char Now_m;
unsigned char Now_Encode;
for(ReadByte=0,WriteBit=0; ReadByte<InLength; ReadByte++){
for(ReadBit=0; ReadBit<8; ReadBit++){
Now_m = InBuf[ReadByte]>>(7-ReadBit);
Now_m = Now_m & 0x01;
Now_Encode = Branch_Tab[Now_State][Now_m];
Now_State = Now_State<<1 | Now_m;
Now_State = Now_State & 0x3f;
OutBuf[WriteBit/8] = (OutBuf[WriteBit/8]<<2) | Now_Encode;
WriteBit += 2;
}
}
if(WriteBit != 2*8*InLength)
return 0xff;
return Now_State;
}
//---------------------------------------------------------------------------
int WeightInt(int x)
{
int countx = 0;
while(x)
{
countx ++;
x = x&(x-1);
}
return countx;
}
//每次将最低位的“1”去掉
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -