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

📄 卷积码c源码.txt

📁 crc和卷积码的实现
💻 TXT
📖 第 1 页 / 共 2 页
字号:
* viterbi.cpp jdg 2005/04/20 
一个(k,n,K)的卷积码的维特比译码算法 
*/
#define k 1 //一次输入序列的长度
#define n 3 //一次输出序列的长度
#define K 3 //约束长度
#define DECODER_STATES 4 //状态数2^(K-1)*k
#define BRANCH_NUM 2 //从一个状态延伸的分支数
#define PATH_LENGTH 16 //路径保留长度
#include <stdlib.h>
#include "stdafx.h"
//#include "viterbi.h"
//#include "encode.cpp"
//#include "randsource.cpp"

/* 多项式生成 g1=1[00000001](1) ,
g2=x^2+1[00000101](5),
g3=x^2+x^1+1[00000111](7) 

*/

int g[n][K*k]={1,0,0,
1,0,1,
   1,1,1 };

//-------------------------------分支结构定义
struct branch
{
int state_index,//状态索引
     input[k],//输入信息
     output[n];//输出码子
double cm; //量度
};

//------------------------------状态结构定义
struct state
  { 
double sum_cm;//累积量度
struct branch branchs[BRANCH_NUM];//下一个状态数组
       int   survivor[PATH_LENGTH]; //幸存路径
   struct branch best_branch; //到达的2^k条分支中最好的一条

}; 
state states[DECODER_STATES];

//------------------------------二进制随机信源生成函数

int randsource(int *x,int length)
{ int i;
printf("正在生成长度为 %d 的二进制的随机数序列x[] 。。。\n",length);
for(i=0; i<length; i++) 
{
   if (i%10==0) printf("\n");
*(x+i)= rand() % 2;
   printf("%d,", *(x+i) );
}
return 0; 
}

//------------------------------把整数变成数组向量函数
int int_to_vector(int x,int *vector,int vlength)
{
  int i;
  for(i=0;i<vlength;i++)
   *(vector+i)=x>>i&1;
  return 0;
}

//------------------------------计算分支量度,cm=cm+Rjm*(2*Cjm-1);
double compute_cm(int *r,int *c) 
{
  int x;
  double cm=0.0;
  for(x=0;x<n;x++) 
    cm+=r[x]*(2*c[x]-1);
    //cm+=(r>>x)*(2*(c>>x)-1);
  return cm;
}

//编码函数,input输入,ilength输入长度,output输出,olength输出长度,,currentstate当前状态
int con_encode(int *input ,int ilength,int *output,int olength ,int *currentstate)
{
  int out[n],
    i,j,x,p=0, //循环变量
    reg[K*k]; //移位寄存器
  for(i=0;i<ilength/k;i++) //对每k位输入bit循环
  {
    for(j=0;j<k;j++) //把输入的k位bit送入移位寄存器 
     reg[j]=*(input+i+j); 
    for (j=k;j<K*k;j++) //把当前状态放人移位寄存器
      reg[j]=*(currentstate+j-k); 
    for(j=0;j<K*k;j++) //生成输出的n位bit信息 
    {
      for(x=0;x<n;x++)
        out[x]+=g[x][j]^reg[j];
    }
    for(x=0;x<n;x++)
    {
*(output+p)=out[x];
     p++;
      if (p>olength) 
        printf("\n 输出长度超过预定义输出数字长度,请检查输出数组定义!\n");
    }

    for(j=0;j<(K-1)*k;j++)
*(currentstate+j)=reg[j];
  }

  return 0;

}

/* Viterbi算法解卷积码函数,参数说明
r:解调输出序列,
rlength:r的长度
decode:解码后的序列
dlength:decode的长度
*/
int ViterbiDecode(int *r,int rlength,int *decoded,int dlength)
{
  int i,j,x,y;
  int rm[n],//接收向量
    cur_state[(K-1)*k];//当前状态向量
  double temp_cm,temp_sum_cm[DECODER_STATES];//临时量度
int *temp_input[DECODER_STATES];//临时变量
  int one=0,zero=0;
  //各状态初始化
  for (i=0;i<DECODER_STATES;i++)
  {
states[i].sum_cm=-65535;
    for(j=0;j<BRANCH_NUM;j++)
    {
      states[i].branchs[j].state_index=i<<k^j;
     int_to_vector(j,states[i].branchs[j].input,k);
      int_to_vector(i,cur_state,(K-1)*k);
con_encode(states[i].branchs[j].input,k,states[i].branchs[j].output,n ,cur_state);
    }

    for(j=0;j<PATH_LENGTH;j++)
      states[i].survivor[j]=-1;
  }
states[0].sum_cm=0.0;
//-----------------------------初始化完毕
//-----------------------------对每个接收的n维矢量循环
for (x=0;x<rlength/n;x++) 
  { 
  
    for (i=0;i<n;i++) //从接收序列中取出一个码子的长度
      rm[i]=*(r+x+i);

for (i=0;i<DECODER_STATES;i++) //对每个状态循环
  {
for (j=0;j<DECODER_STATES;j++)
      {
for(y=0;y<BRANCH_NUM;y++)
        {
          if (states[j].branchs[y].state_index==i)
          {
            //计算分支量度
            temp_cm=states[j].sum_cm+compute_cm(rm,states[j].branchs[y].output);
if (temp_sum_cm[i]<temp_cm) 
            {
              temp_sum_cm[i]=temp_cm;
temp_input[i]=states[j].branchs[y].input;
            }
            break;
          }
        }
      }

    }
     for(i=0;i<k;i++)
     *(decoded+x+i)=states[0].survivor[PATH_LENGTH-1-i];
for (i=0;i<DECODER_STATES;i++) 
     {
       states[i].sum_cm=temp_sum_cm[i];
       for(j=PATH_LENGTH-1;j>k-1;j--)
       states[i].survivor[j]=states[i].survivor[j-k];
       for (j=0;j<k;j++)
         states[i].survivor[k-1-j]=*(temp_input[i]+j);
     }
  }
return 0;

}

int _tmain(int argc, _TCHAR* argv[])
{
  //int i;
  int x[100];
  randsource(x,100);
  /*
  printf("encoded stream...\n");
  for(i=0;i<100;i++)
  {  
  printf(" %d " ,con_encode(1));
  }
  printf("\n decoded stream...\n");
  for(i=0;i<100;i++)
  {  
   printf(" %d",ViterbiDecode(con_encode(1)));
  }
  */

  return 0;
} 


//


我把我的viterbi程序贴出来,欢迎高手指教
//文件名:Viterbi216.h
//作 用:对1/2码率,N=7的卷积码进行维特比译码(硬判决)
//作 者:蒋岩
//时 间:2005.7.25
//版 本:VC--1.0
//说 明:
/*(n0,k0,m)卷积码的字母定义:
*n0——每个时刻编码器输出码元个数
*k0——每个时刻编码器输入信息元个数
*m——输入的信息组在编码器中的存储的单位时间
*N=m+1——编码约束度,编码过程中相互约束的子码个数
*df=10——自由距离,由卷积码的生成多项式决定
*维特比译码输出信息元误码率算法
*Pme=2^df * Pe^(df/2)——(Pe为信道的误码率)
*例:Pe=10^-2,则Pme=10^-7
*/

//---------------------------------------------------------------------------
#ifndef VITERBI_216_H
#define VITERBI_216_H

#define  G1  0x6d  //G1 = 1101101
#define  G2  0x4f  //G2 = 1001111

//---------------------------------------------------------------------------
class CViterbi_216
{
private:
  
protected:
  
public:
  int Decode_States;  //状态数 2^m*k0
  int Branch_Num;    //从一个状态延伸的分支数 n0
  int Path_Length;  //路径保留长度 5*m < L < 10*m
  int Path_Num;    //保存幸存路径个数
  int Init_Num;    //幸存路径预装载个数,Init_Num 的计算方法如下 2^Init_Num = Path_Num
  int First_Use;    //是否第一次处理缓存的标志

  //-----分支缓存定义-----
  //Branch_Tab[Decode_States][Branch_Num]
  //移位寄存器在各个状态下输入“0”或“1”对应的输出结果表
  unsigned char Branch_Tab[64][2];

  //-----幸存路径结构定义-----
  //同时也是距离寄存器和信息序列寄存器
  struct Survivor {
    int Sum_d;//幸存路径的累积距离
    unsigned int H_m32;//幸存路径的信息存储变量,高32比特
    unsigned int L_m32;//幸存路径的信息存储变量,低32比特
  };
  Survivor Survivor_Save[64];
  //保存幸存路径的结构缓存(结构缓存个数 = Path_Num)
  Survivor Survivor_Temp[128];
  //临时幸存路径的结构缓存(结构缓存个数 = Path_Num * Branch_Num)

public:
CViterbi_216();
  virtual ~CViterbi_216();
  void Initial(void);

  int Encode_216(unsigned char * InBuf, int InLength, unsigned char * OutBuf, int Now_State);
  //编码正确返回编码后移位寄存器的状态;编码出错则返回0xff;
  int  Viterbi216(unsigned char * InBuf, int InLength, unsigned char * OutBuf, int Star_Mode);
  //Star_Mode 表示启动该函数的方式,
  //Star_Mode == 0 表示处理非连续卷积码编码数据
  //Star_Mode == 1 表示处理连续卷积码编码数据
  
};
//---------------------------------------------------------------------------
#endif

//-----以下为函数部分-----
//---------------------------------------------------------------------------
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:nitial(void)
{
  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)
{

⌨️ 快捷键说明

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