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