?? decode.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);
}
//實際中還需要防止累計度量溢出
}
//當前采用硬判決??筛臑檐浥袥Q。
//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 + -