Home | History | Annotate | Download | only in fec
      1 /* K=7 r=1/2 Viterbi decoder with optional Intel or PowerPC SIMD
      2  * Copyright Feb 2004, Phil Karn, KA9Q
      3  */
      4 #include <stdio.h>
      5 #include <stdlib.h>
      6 #include <memory.h>
      7 #include "fec.h"
      8 
      9 /* Create a new instance of a Viterbi decoder */
     10 void *create_viterbi27(int len){
     11   find_cpu_mode();
     12 
     13   switch(Cpu_mode){
     14   case PORT:
     15   default:
     16     return create_viterbi27_port(len);
     17 #ifdef __VEC__
     18   case ALTIVEC:
     19     return create_viterbi27_av(len);
     20 #endif
     21 #ifdef __i386__
     22   case MMX:
     23     return create_viterbi27_mmx(len);
     24   case SSE:
     25     return create_viterbi27_sse(len);
     26   case SSE2:
     27     return create_viterbi27_sse2(len);
     28 #endif
     29   }
     30 }
     31 
     32 void set_viterbi27_polynomial(int polys[2]){
     33   switch(Cpu_mode){
     34   case PORT:
     35   default:
     36     set_viterbi27_polynomial_port(polys);
     37     break;
     38 #ifdef __VEC__
     39   case ALTIVEC:
     40     set_viterbi27_polynomial_av(polys);
     41     break;
     42 #endif
     43 #ifdef __i386__
     44   case MMX:
     45     set_viterbi27_polynomial_mmx(polys);
     46     break;
     47   case SSE:
     48     set_viterbi27_polynomial_sse(polys);
     49     break;
     50   case SSE2:
     51     set_viterbi27_polynomial_sse2(polys);
     52     break;
     53 #endif
     54   }
     55 }
     56 
     57 /* Initialize Viterbi decoder for start of new frame */
     58 int init_viterbi27(void *p,int starting_state){
     59     switch(Cpu_mode){
     60     case PORT:
     61     default:
     62       return init_viterbi27_port(p,starting_state);
     63 #ifdef __VEC__
     64     case ALTIVEC:
     65       return init_viterbi27_av(p,starting_state);
     66 #endif
     67 #ifdef __i386__
     68     case MMX:
     69       return init_viterbi27_mmx(p,starting_state);
     70     case SSE:
     71       return init_viterbi27_sse(p,starting_state);
     72     case SSE2:
     73       return init_viterbi27_sse2(p,starting_state);
     74 #endif
     75     }
     76 }
     77 
     78 /* Viterbi chainback */
     79 int chainback_viterbi27(
     80       void *p,
     81       unsigned char *data, /* Decoded output data */
     82       unsigned int nbits, /* Number of data bits */
     83       unsigned int endstate){ /* Terminal encoder state */
     84 
     85     switch(Cpu_mode){
     86     case PORT:
     87     default:
     88       return chainback_viterbi27_port(p,data,nbits,endstate);
     89 #ifdef __VEC__
     90     case ALTIVEC:
     91       return chainback_viterbi27_av(p,data,nbits,endstate);
     92 #endif
     93 #ifdef __i386__
     94     case MMX:
     95       return chainback_viterbi27_mmx(p,data,nbits,endstate);
     96     case SSE:
     97       return chainback_viterbi27_sse(p,data,nbits,endstate);
     98     case SSE2:
     99       return chainback_viterbi27_sse2(p,data,nbits,endstate);
    100 #endif
    101     }
    102 }
    103 
    104 /* Delete instance of a Viterbi decoder */
    105 void delete_viterbi27(void *p){
    106     switch(Cpu_mode){
    107     case PORT:
    108     default:
    109       delete_viterbi27_port(p);
    110       break;
    111 #ifdef __VEC__
    112     case ALTIVEC:
    113       delete_viterbi27_av(p);
    114       break;
    115 #endif
    116 #ifdef __i386__
    117     case MMX:
    118       delete_viterbi27_mmx(p);
    119       break;
    120     case SSE:
    121       delete_viterbi27_sse(p);
    122       break;
    123     case SSE2:
    124       delete_viterbi27_sse2(p);
    125       break;
    126 #endif
    127     }
    128 }
    129 
    130 /* Update decoder with a block of demodulated symbols
    131  * Note that nbits is the number of decoded data bits, not the number
    132  * of symbols!
    133  */
    134 int update_viterbi27_blk(void *p,unsigned char syms[],int nbits){
    135   if(p == NULL)
    136     return -1;
    137 
    138   switch(Cpu_mode){
    139   case PORT:
    140   default:
    141     update_viterbi27_blk_port(p,syms,nbits);
    142     break;
    143 #ifdef __VEC__
    144   case ALTIVEC:
    145     update_viterbi27_blk_av(p,syms,nbits);
    146     break;
    147 #endif
    148 #ifdef __i386__
    149   case MMX:
    150     update_viterbi27_blk_mmx(p,syms,nbits);
    151     break;
    152   case SSE:
    153     update_viterbi27_blk_sse(p,syms,nbits);
    154     break;
    155   case SSE2:
    156     update_viterbi27_blk_sse2(p,syms,nbits);
    157     break;
    158 #endif
    159   }
    160   return 0;
    161 }
    162