1 /* Switch to K=9 r=1/3 Viterbi decoder with optional Intel or PowerPC SIMD 2 * Copyright Aug 2006, 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_viterbi39(int len){ 11 find_cpu_mode(); 12 13 switch(Cpu_mode){ 14 case PORT: 15 default: 16 return create_viterbi39_port(len); 17 #ifdef __VEC__ 18 case ALTIVEC: 19 return create_viterbi39_av(len); 20 #endif 21 #ifdef __i386__ 22 case MMX: 23 return create_viterbi39_mmx(len); 24 case SSE: 25 return create_viterbi39_sse(len); 26 case SSE2: 27 return create_viterbi39_sse2(len); 28 #endif 29 } 30 } 31 32 void set_viterbi39_polynomial(int polys[3]){ 33 switch(Cpu_mode){ 34 case PORT: 35 default: 36 set_viterbi39_polynomial_port(polys); 37 break; 38 #ifdef __VEC__ 39 case ALTIVEC: 40 set_viterbi39_polynomial_av(polys); 41 break; 42 #endif 43 #ifdef __i386__ 44 case MMX: 45 set_viterbi39_polynomial_mmx(polys); 46 break; 47 case SSE: 48 set_viterbi39_polynomial_sse(polys); 49 break; 50 case SSE2: 51 set_viterbi39_polynomial_sse2(polys); 52 break; 53 #endif 54 } 55 } 56 57 58 /* Initialize Viterbi decoder for start of new frame */ 59 int init_viterbi39(void *p,int starting_state){ 60 switch(Cpu_mode){ 61 case PORT: 62 default: 63 return init_viterbi39_port(p,starting_state); 64 #ifdef __VEC__ 65 case ALTIVEC: 66 return init_viterbi39_av(p,starting_state); 67 #endif 68 #ifdef __i386__ 69 case MMX: 70 return init_viterbi39_mmx(p,starting_state); 71 case SSE: 72 return init_viterbi39_sse(p,starting_state); 73 case SSE2: 74 return init_viterbi39_sse2(p,starting_state); 75 #endif 76 } 77 } 78 79 /* Viterbi chainback */ 80 int chainback_viterbi39( 81 void *p, 82 unsigned char *data, /* Decoded output data */ 83 unsigned int nbits, /* Number of data bits */ 84 unsigned int endstate){ /* Terminal encoder state */ 85 86 switch(Cpu_mode){ 87 case PORT: 88 default: 89 return chainback_viterbi39_port(p,data,nbits,endstate); 90 #ifdef __VEC__ 91 case ALTIVEC: 92 return chainback_viterbi39_av(p,data,nbits,endstate); 93 #endif 94 #ifdef __i386__ 95 case MMX: 96 return chainback_viterbi39_mmx(p,data,nbits,endstate); 97 case SSE: 98 return chainback_viterbi39_sse(p,data,nbits,endstate); 99 case SSE2: 100 return chainback_viterbi39_sse2(p,data,nbits,endstate); 101 #endif 102 } 103 } 104 105 /* Delete instance of a Viterbi decoder */ 106 void delete_viterbi39(void *p){ 107 switch(Cpu_mode){ 108 case PORT: 109 default: 110 delete_viterbi39_port(p); 111 break; 112 #ifdef __VEC__ 113 case ALTIVEC: 114 delete_viterbi39_av(p); 115 break; 116 #endif 117 #ifdef __i386__ 118 case MMX: 119 delete_viterbi39_mmx(p); 120 break; 121 case SSE: 122 delete_viterbi39_sse(p); 123 break; 124 case SSE2: 125 delete_viterbi39_sse2(p); 126 break; 127 #endif 128 } 129 } 130 131 /* Update decoder with a block of demodulated symbols 132 * Note that nbits is the number of decoded data bits, not the number 133 * of symbols! 134 */ 135 int update_viterbi39_blk(void *p,unsigned char syms[],int nbits){ 136 switch(Cpu_mode){ 137 case PORT: 138 default: 139 return update_viterbi39_blk_port(p,syms,nbits); 140 #ifdef __VEC__ 141 case ALTIVEC: 142 return update_viterbi39_blk_av(p,syms,nbits); 143 #endif 144 #ifdef __i386__ 145 case MMX: 146 return update_viterbi39_blk_mmx(p,syms,nbits); 147 case SSE: 148 return update_viterbi39_blk_sse(p,syms,nbits); 149 case SSE2: 150 return update_viterbi39_blk_sse2(p,syms,nbits); 151 #endif 152 } 153 } 154