?? viterbi.cpp
字號:
#include "viterbi216.h"
//-----以下為函數(shù)部分-----
//---------------------------------------------------------------------------
CViterbi_216::CViterbi_216()
{
Decode_States = 64; //狀態(tài)數(shù) 2^m*k0
Branch_Num = 2; //從一個狀態(tài)延伸的分支數(shù) n0
Path_Length = 64; //路徑保留長度 5*m < L < 10*m
Path_Num = 32; //保存幸存路徑個數(shù)
First_Use = 1;
Initial();
}
//---------------------------------------------------------------------------
CViterbi_216::~CViterbi_216()
{
;
}
//---------------------------------------------------------------------------
void CViterbi_216::Initial()
{
unsigned char NowStates;
int OneNum;
int i, j;
//狀態(tài)發(fā)生器:產(chǎn)生2^k0*m_個狀態(tài)和分支值
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;//幸存路徑預(yù)裝載個數(shù),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;
//表示處理非連續(xù)卷積碼編碼數(shù)據(jù)或者連續(xù)卷積碼編碼數(shù)據(jù)的第一個緩存
if((Star_Mode == 0) | (First_Use == 1)){
//初始化幸存路徑結(jié)構(gòu)
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比特,和接收序列對應(yīng)時刻的碼組比較漢明距離
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的個數(shù)
/*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;
}
//第二步:對數(shù)據(jù)進行糾錯譯碼
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;
}
//接收序列各個時刻的循環(huán)
//每個時刻輸出2比特,和接收序列對應(yīng)時刻的碼組比較得到漢明距離
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條存入幸存路徑結(jié)構(gòu)緩存
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++;
}
//第三步:對數(shù)據(jù)尾部的處理,
//輸出漢明距離最小的幸存路徑的OutBit個比特(位權(quán)較低的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;
}
}
//第四步:如果處理的是連續(xù)數(shù)據(jù),要將較小幸存路徑的漢明距離縮小,避免溢出
/*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;
//*/
//維特比譯碼結(jié)束
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”去掉
//---------------------------------------------------------------------------
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -