1 /* Switch to K=9 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_viterbi29(int len){ 11 find_cpu_mode(); 12 13 switch(Cpu_mode){ 14 case PORT: 15 default: 16 return create_viterbi29_port(len); 17 #ifdef __VEC__ 18 case ALTIVEC: 19 return create_viterbi29_av(len); 20 #endif 21 #ifdef __i386__ 22 case MMX: 23 return create_viterbi29_mmx(len); 24 case SSE: 25 return create_viterbi29_sse(len); 26 case SSE2: 27 return create_viterbi29_sse2(len); 28 #endif 29 } 30 } 31 32 void set_viterbi29_polynomial(int polys[2]){ 33 switch(Cpu_mode){ 34 case PORT: 35 default: 36 set_viterbi29_polynomial_port(polys); 37 break; 38 #ifdef __VEC__ 39 case ALTIVEC: 40 set_viterbi29_polynomial_av(polys); 41 break; 42 #endif 43 #ifdef __i386__ 44 case MMX: 45 set_viterbi29_polynomial_mmx(polys); 46 break; 47 case SSE: 48 set_viterbi29_polynomial_sse(polys); 49 break; 50 case SSE2: 51 set_viterbi29_polynomial_sse2(polys); 52 break; 53 #endif 54 } 55 } 56 57 /* Initialize Viterbi decoder for start of new frame */ 58 int init_viterbi29(void *p,int starting_state){ 59 switch(Cpu_mode){ 60 case PORT: 61 default: 62 return init_viterbi29_port(p,starting_state); 63 #ifdef __VEC__ 64 case ALTIVEC: 65 return init_viterbi29_av(p,starting_state); 66 #endif 67 #ifdef __i386__ 68 case MMX: 69 return init_viterbi29_mmx(p,starting_state); 70 case SSE: 71 return init_viterbi29_sse(p,starting_state); 72 case SSE2: 73 return init_viterbi29_sse2(p,starting_state); 74 #endif 75 } 76 } 77 78 /* Viterbi chainback */ 79 int chainback_viterbi29( 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_viterbi29_port(p,data,nbits,endstate); 89 #ifdef __VEC__ 90 case ALTIVEC: 91 return chainback_viterbi29_av(p,data,nbits,endstate); 92 #endif 93 #ifdef __i386__ 94 case MMX: 95 return chainback_viterbi29_mmx(p,data,nbits,endstate); 96 case SSE: 97 return chainback_viterbi29_sse(p,data,nbits,endstate); 98 case SSE2: 99 return chainback_viterbi29_sse2(p,data,nbits,endstate); 100 #endif 101 } 102 } 103 104 /* Delete instance of a Viterbi decoder */ 105 void delete_viterbi29(void *p){ 106 switch(Cpu_mode){ 107 case PORT: 108 default: 109 delete_viterbi29_port(p); 110 break; 111 #ifdef __VEC__ 112 case ALTIVEC: 113 delete_viterbi29_av(p); 114 break; 115 #endif 116 #ifdef __i386__ 117 case MMX: 118 delete_viterbi29_mmx(p); 119 break; 120 case SSE: 121 delete_viterbi29_sse(p); 122 break; 123 case SSE2: 124 delete_viterbi29_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_viterbi29_blk(void *p,unsigned char syms[],int nbits){ 135 switch(Cpu_mode){ 136 case PORT: 137 default: 138 return update_viterbi29_blk_port(p,syms,nbits); 139 #ifdef __VEC__ 140 case ALTIVEC: 141 return update_viterbi29_blk_av(p,syms,nbits); 142 #endif 143 #ifdef __i386__ 144 case MMX: 145 return update_viterbi29_blk_mmx(p,syms,nbits); 146 case SSE: 147 return update_viterbi29_blk_sse(p,syms,nbits); 148 case SSE2: 149 return update_viterbi29_blk_sse2(p,syms,nbits); 150 #endif 151 } 152 } 153