viterbi29.c 3.87 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
/* Switch to K=9 r=1/2 Viterbi decoder with optional Intel or PowerPC SIMD
 * Copyright Feb 2004, Phil Karn, KA9Q
 */
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include "fec.h"

/* Create a new instance of a Viterbi decoder */
void *create_viterbi29(int len){
  find_cpu_mode();

  switch(Cpu_mode){
  case PORT:
  default:
    return create_viterbi29_port(len);
#ifdef __VEC__
  case ALTIVEC:
    return create_viterbi29_av(len);
#endif
#ifdef __i386__
  case MMX:
    return create_viterbi29_mmx(len);
  case SSE:
    return create_viterbi29_sse(len);
  case SSE2:
    return create_viterbi29_sse2(len);
#endif
#ifdef __x86_64__
  case SSE2:
    return create_viterbi29_port(len);
#endif
  }
}

void set_viterbi29_polynomial(int polys[2]){
  switch(Cpu_mode){
  case PORT:
  default:
    set_viterbi29_polynomial_port(polys);
    break;
#ifdef __VEC__
  case ALTIVEC:
    set_viterbi29_polynomial_av(polys);
    break;
#endif
#ifdef __i386__
  case MMX:
    set_viterbi29_polynomial_mmx(polys);
    break;
  case SSE:
    set_viterbi29_polynomial_sse(polys);
    break;
  case SSE2:
    set_viterbi29_polynomial_sse2(polys);
    break;
#endif
#ifdef __x86_64__
  case SSE2:
    set_viterbi29_polynomial_port(polys);
    break;
#endif
  }
}

/* Initialize Viterbi decoder for start of new frame */
int init_viterbi29(void *p,int starting_state){
    switch(Cpu_mode){
    case PORT:
    default:
      return init_viterbi29_port(p,starting_state);
#ifdef __VEC__
    case ALTIVEC:
      return init_viterbi29_av(p,starting_state);
#endif
#ifdef __i386__
    case MMX:
      return init_viterbi29_mmx(p,starting_state);
    case SSE:
      return init_viterbi29_sse(p,starting_state);
    case SSE2:
      return init_viterbi29_sse2(p,starting_state);
#endif
#ifdef __x86_64__
    case SSE2:
      return init_viterbi29_port(p,starting_state);
#endif
    }
}

/* Viterbi chainback */
int chainback_viterbi29(
      void *p,
      unsigned char *data, /* Decoded output data */
      unsigned int nbits, /* Number of data bits */
      unsigned int endstate){ /* Terminal encoder state */

    switch(Cpu_mode){
    case PORT:
    default:
      return chainback_viterbi29_port(p,data,nbits,endstate);
#ifdef __VEC__
    case ALTIVEC:
      return chainback_viterbi29_av(p,data,nbits,endstate);
#endif
#ifdef __i386__
    case MMX:
      return chainback_viterbi29_mmx(p,data,nbits,endstate);
    case SSE:
      return chainback_viterbi29_sse(p,data,nbits,endstate);
    case SSE2:
      return chainback_viterbi29_sse2(p,data,nbits,endstate);
#endif
#ifdef __x86_64__
    case SSE2:
      return chainback_viterbi29_port(p,data,nbits,endstate);
#endif
    }
}

/* Delete instance of a Viterbi decoder */
void delete_viterbi29(void *p){
    switch(Cpu_mode){
    case PORT:
    default:
      delete_viterbi29_port(p);
      break;
#ifdef __VEC__
    case ALTIVEC:
      delete_viterbi29_av(p);
      break;
#endif
#ifdef __i386__
    case MMX:
      delete_viterbi29_mmx(p);
      break;
    case SSE:
      delete_viterbi29_sse(p);
      break;
    case SSE2:
      delete_viterbi29_sse2(p);
      break;
#endif
#ifdef __x86_64__
    case SSE2:
      delete_viterbi29_port(p);
      break;
#endif
    }
}

/* Update decoder with a block of demodulated symbols
 * Note that nbits is the number of decoded data bits, not the number
 * of symbols!
 */
int update_viterbi29_blk(void *p,unsigned char syms[],int nbits){
    switch(Cpu_mode){
    case PORT:
    default:
      return update_viterbi29_blk_port(p,syms,nbits);
#ifdef __VEC__
    case ALTIVEC:
      return update_viterbi29_blk_av(p,syms,nbits);
#endif
#ifdef __i386__
    case MMX:
      return update_viterbi29_blk_mmx(p,syms,nbits);
    case SSE:
      return update_viterbi29_blk_sse(p,syms,nbits);
    case SSE2:
      return update_viterbi29_blk_sse2(p,syms,nbits);
#endif
#ifdef __x86_64__
    case SSE2:
      return update_viterbi29_blk_port(p,syms,nbits);
#endif
    }
}