Home | History | Annotate | Download | only in fec
      1 /* K=15 r=1/6 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_viterbi615(int len){
     11 
     12   find_cpu_mode();
     13 
     14   switch(Cpu_mode){
     15   case PORT:
     16   default:
     17     return create_viterbi615_port(len);
     18 #ifdef __VEC__
     19   case ALTIVEC:
     20     return create_viterbi615_av(len);
     21 #endif
     22 #ifdef __i386__
     23   case MMX:
     24     return create_viterbi615_mmx(len);
     25   case SSE:
     26     return create_viterbi615_sse(len);
     27   case SSE2:
     28     return create_viterbi615_sse2(len);
     29 #endif
     30   }
     31 }
     32 
     33 void set_viterbi615_polynomial(int polys[6]){
     34 
     35   switch(Cpu_mode){
     36   case PORT:
     37   default:
     38     set_viterbi615_polynomial_port(polys);
     39     break;
     40 #ifdef __VEC__
     41   case ALTIVEC:
     42     set_viterbi615_polynomial_av(polys);
     43     break;
     44 #endif
     45 #ifdef __i386__
     46   case MMX:
     47     set_viterbi615_polynomial_mmx(polys);
     48     break;
     49   case SSE:
     50     set_viterbi615_polynomial_sse(polys);
     51     break;
     52   case SSE2:
     53     set_viterbi615_polynomial_sse2(polys);
     54     break;
     55 #endif
     56   }
     57 }
     58 
     59 /* Initialize Viterbi decoder for start of new frame */
     60 int init_viterbi615(void *p,int starting_state){
     61     switch(Cpu_mode){
     62     case PORT:
     63     default:
     64       return init_viterbi615_port(p,starting_state);
     65 #ifdef __VEC__
     66     case ALTIVEC:
     67       return init_viterbi615_av(p,starting_state);
     68 #endif
     69 #ifdef __i386__
     70     case MMX:
     71       return init_viterbi615_mmx(p,starting_state);
     72     case SSE:
     73       return init_viterbi615_sse(p,starting_state);
     74     case SSE2:
     75       return init_viterbi615_sse2(p,starting_state);
     76 #endif
     77     }
     78 }
     79 
     80 /* Viterbi chainback */
     81 int chainback_viterbi615(
     82       void *p,
     83       unsigned char *data, /* Decoded output data */
     84       unsigned int nbits, /* Number of data bits */
     85       unsigned int endstate){ /* Terminal encoder state */
     86 
     87     switch(Cpu_mode){
     88     case PORT:
     89     default:
     90       return chainback_viterbi615_port(p,data,nbits,endstate);
     91 #ifdef __VEC__
     92     case ALTIVEC:
     93       return chainback_viterbi615_av(p,data,nbits,endstate);
     94 #endif
     95 #ifdef __i386__
     96     case MMX:
     97       return chainback_viterbi615_mmx(p,data,nbits,endstate);
     98     case SSE:
     99       return chainback_viterbi615_sse(p,data,nbits,endstate);
    100     case SSE2:
    101       return chainback_viterbi615_sse2(p,data,nbits,endstate);
    102 #endif
    103     }
    104 }
    105 
    106 /* Delete instance of a Viterbi decoder */
    107 void delete_viterbi615(void *p){
    108     switch(Cpu_mode){
    109     case PORT:
    110     default:
    111       delete_viterbi615_port(p);
    112       break;
    113 #ifdef __VEC__
    114     case ALTIVEC:
    115       delete_viterbi615_av(p);
    116       break;
    117 #endif
    118 #ifdef __i386__
    119     case MMX:
    120       delete_viterbi615_mmx(p);
    121       break;
    122     case SSE:
    123       delete_viterbi615_sse(p);
    124       break;
    125     case SSE2:
    126       delete_viterbi615_sse2(p);
    127       break;
    128 #endif
    129     }
    130 }
    131 
    132 /* Update decoder with a block of demodulated symbols
    133  * Note that nbits is the number of decoded data bits, not the number
    134  * of symbols!
    135  */
    136 int update_viterbi615_blk(void *p,unsigned char syms[],int nbits){
    137     switch(Cpu_mode){
    138     case PORT:
    139     default:
    140       return update_viterbi615_blk_port(p,syms,nbits);
    141 #ifdef __VEC__
    142     case ALTIVEC:
    143       return update_viterbi615_blk_av(p,syms,nbits);
    144 #endif
    145 #ifdef __i386__
    146     case MMX:
    147       return update_viterbi615_blk_mmx(p,syms,nbits);
    148     case SSE:
    149       return update_viterbi615_blk_sse(p,syms,nbits);
    150     case SSE2:
    151       return update_viterbi615_blk_sse2(p,syms,nbits);
    152 #endif
    153     }
    154 }
    155 
    156