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

📄 viterbi37.c

📁 一些纠错编码的c程序实现
💻 C
字号:
/* Convolutional encoder and Viterbi decoder for K=7 rate=1/3 code
 * Copyright 1999 Phil Karn, KA9Q
 * May be used under the terms of the GNU Public License
 */

#include <memory.h>
#include "viterbi37.h"
#define NULL ((void *)0)

int Rate = 3;

extern unsigned char Partab[];	/* Parity lookup table */

/* Convolutionally encode data into binary symbols */
encode37(
unsigned char *symbols,
unsigned char *data,
unsigned int nbytes,
unsigned int startstate,
unsigned int endstate)
{
  int i;
  unsigned char encstate = startstate;

  while(nbytes-- != 0){
    for(i=7;i>=0;i--){
      encstate = (encstate << 1) | ((*data >> i) & 1);
      *symbols++ = Partab[encstate & POLYA];
      *symbols++ = Partab[encstate & POLYB];
      *symbols++ = Partab[encstate & POLYC];
    }
    data++;
  }
  /* Flush out tail */
  for(i=5;i>=0;i--){
    encstate = (encstate << 1) | ((endstate >> i) & 1);
    *symbols++ = Partab[encstate & POLYA];
    *symbols++ = Partab[encstate & POLYB];
    *symbols++ = Partab[encstate & POLYC];
  }
  return 0;
}

/* Viterbi decoder for rate 1/3, k=7 code */
int
viterbi37(
unsigned long *metric,	/* Final path metric (returned value) */
unsigned char *data,	/* Decoded output data */
unsigned char *symbols,	/* Raw deinterleaved input symbols */
unsigned int nbits,	/* Number of output bits */
int mettab[2][256],	/* Metric table, [sent sym][rx symbol] */
int startstate,         /* Encoder starting state */
int endstate            /* Encoder ending state */
){
  int bitcnt = -6; /* K-1 */
  int i,mets[8];
  unsigned long dec,paths[(nbits+6)*2],*pp;
  long cmetric[64],nmetric[64];
	
  startstate &= 63;
  endstate &= 63;

  /* Initialize starting metrics */
  for(i=0;i<64;i++)
    cmetric[i] = -999999;
  cmetric[startstate] = 0;
  
  pp = paths;
  for(;;){
    /* Read input symbol triplet and compute branch metrics */
    mets[0] = mettab[0][symbols[0]] + mettab[0][symbols[1]] + mettab[0][symbols[2]];
    mets[1] = mettab[0][symbols[0]] + mettab[0][symbols[1]] + mettab[1][symbols[2]];
    mets[3] = mettab[0][symbols[0]] + mettab[1][symbols[1]] + mettab[1][symbols[2]];
    mets[2] = mettab[0][symbols[0]] + mettab[1][symbols[1]] + mettab[0][symbols[2]];
    mets[6] = mettab[1][symbols[0]] + mettab[1][symbols[1]] + mettab[0][symbols[2]];
    mets[7] = mettab[1][symbols[0]] + mettab[1][symbols[1]] + mettab[1][symbols[2]];
    mets[5] = mettab[1][symbols[0]] + mettab[0][symbols[1]] + mettab[1][symbols[2]];
    mets[4] = mettab[1][symbols[0]] + mettab[0][symbols[1]] + mettab[0][symbols[2]];
    symbols += 3;
    
    /* These macro calls were generated by genbut.c
     * and rearranged by hand for speed
     */
    dec = 0;
    BUTTERFLY(0,0);
    BUTTERFLY(14,0);
    BUTTERFLY(2,7);
    BUTTERFLY(12,7);
    BUTTERFLY(1,6);
    BUTTERFLY(15,6);
    BUTTERFLY(3,1);
    BUTTERFLY(13,1);
    BUTTERFLY(4,5);
    BUTTERFLY(10,5);
    BUTTERFLY(6,2);
    BUTTERFLY(8,2);
    BUTTERFLY(5,3);
    BUTTERFLY(11,3);
    BUTTERFLY(7,4);
    BUTTERFLY(9,4);
    *pp++ = dec;
    dec = 0;
    
    BUTTERFLY(19,0);
    BUTTERFLY(29,0);
    BUTTERFLY(17,7);
    BUTTERFLY(31,7);
    BUTTERFLY(18,6);
    BUTTERFLY(28,6);
    BUTTERFLY(16,1);
    BUTTERFLY(30,1);
    BUTTERFLY(23,5);
    BUTTERFLY(25,5);
    BUTTERFLY(21,2);
    BUTTERFLY(27,2);
    BUTTERFLY(22,3);
    BUTTERFLY(24,3);
    BUTTERFLY(20,4);
    BUTTERFLY(26,4);
    *pp++ = dec;
    
    if(++bitcnt == nbits){
      *metric = nmetric[endstate];
      break;
    }
    
    /* Read input symbol pair and compute branch metrics */
    mets[0] = mettab[0][symbols[0]] + mettab[0][symbols[1]] + mettab[0][symbols[2]];
    mets[1] = mettab[0][symbols[0]] + mettab[0][symbols[1]] + mettab[1][symbols[2]];
    mets[3] = mettab[0][symbols[0]] + mettab[1][symbols[1]] + mettab[1][symbols[2]];
    mets[2] = mettab[0][symbols[0]] + mettab[1][symbols[1]] + mettab[0][symbols[2]];
    mets[6] = mettab[1][symbols[0]] + mettab[1][symbols[1]] + mettab[0][symbols[2]];
    mets[7] = mettab[1][symbols[0]] + mettab[1][symbols[1]] + mettab[1][symbols[2]];
    mets[5] = mettab[1][symbols[0]] + mettab[0][symbols[1]] + mettab[1][symbols[2]];
    mets[4] = mettab[1][symbols[0]] + mettab[0][symbols[1]] + mettab[0][symbols[2]];
    symbols += 3;
    
    /* These macro calls were generated by genbut.c
     * and rearranged by hand for speed
     */
    dec = 0;
    BUTTERFLY2(0,0);
    BUTTERFLY2(14,0);
    BUTTERFLY2(2,7);
    BUTTERFLY2(12,7);
    BUTTERFLY2(1,6);
    BUTTERFLY2(15,6);
    BUTTERFLY2(3,1);
    BUTTERFLY2(13,1);
    BUTTERFLY2(4,5);
    BUTTERFLY2(10,5);
    BUTTERFLY2(6,2);
    BUTTERFLY2(8,2);
    BUTTERFLY2(5,3);
    BUTTERFLY2(11,3);
    BUTTERFLY2(7,4);
    BUTTERFLY2(9,4);
    *pp++ = dec;
    dec = 0;
    
    BUTTERFLY2(19,0);
    BUTTERFLY2(29,0);
    BUTTERFLY2(17,7);
    BUTTERFLY2(31,7);
    BUTTERFLY2(18,6);
    BUTTERFLY2(28,6);
    BUTTERFLY2(16,1);
    BUTTERFLY2(30,1);
    BUTTERFLY2(23,5);
    BUTTERFLY2(25,5);
    BUTTERFLY2(21,2);
    BUTTERFLY2(27,2);
    BUTTERFLY2(22,3);
    BUTTERFLY2(24,3);
    BUTTERFLY2(20,4);
    BUTTERFLY2(26,4);
    *pp++ = dec;
    
    if(++bitcnt == nbits){
      /* Or state with best metric, if no tail */
      *metric = cmetric[endstate];
      break;
    }
  }
  /* Chain back from terminal state to produce decoded data */
  if(data == NULL)
    return 0;/* Discard output */
  memset(data,0,(nbits+7)/8); /* round up in case nbits % 8 != 0 */
  for(i=nbits-1;i >= 0;i--){
    pp -= 2;
    if(pp[endstate >> 5] & (1 << (endstate & 31))){
      endstate |= 64;	/* 2^(K-1) */
      data[i>>3] |= 0x80 >> (i&7);
    }
    endstate >>= 1;
  }
  return 0;
}

⌨️ 快捷键说明

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