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 */ 10void *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 32void 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 */ 58int 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 */ 79int 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 */ 105void 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 */ 134int 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