1/* K=7 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_viterbi27(int len){ 11 find_cpu_mode(); 12 13 switch(Cpu_mode){ 14 case PORT: 15 default: 16 return create_viterbi27_port(len); 17#ifdef __VEC__ 18 case ALTIVEC: 19 return create_viterbi27_av(len); 20#endif 21#ifdef __i386__ 22 case MMX: 23 return create_viterbi27_mmx(len); 24 case SSE: 25 return create_viterbi27_sse(len); 26 case SSE2: 27 return create_viterbi27_sse2(len); 28#endif 29 } 30} 31 32void set_viterbi27_polynomial(int polys[2]){ 33 switch(Cpu_mode){ 34 case PORT: 35 default: 36 set_viterbi27_polynomial_port(polys); 37 break; 38#ifdef __VEC__ 39 case ALTIVEC: 40 set_viterbi27_polynomial_av(polys); 41 break; 42#endif 43#ifdef __i386__ 44 case MMX: 45 set_viterbi27_polynomial_mmx(polys); 46 break; 47 case SSE: 48 set_viterbi27_polynomial_sse(polys); 49 break; 50 case SSE2: 51 set_viterbi27_polynomial_sse2(polys); 52 break; 53#endif 54 } 55} 56 57/* Initialize Viterbi decoder for start of new frame */ 58int init_viterbi27(void *p,int starting_state){ 59 switch(Cpu_mode){ 60 case PORT: 61 default: 62 return init_viterbi27_port(p,starting_state); 63#ifdef __VEC__ 64 case ALTIVEC: 65 return init_viterbi27_av(p,starting_state); 66#endif 67#ifdef __i386__ 68 case MMX: 69 return init_viterbi27_mmx(p,starting_state); 70 case SSE: 71 return init_viterbi27_sse(p,starting_state); 72 case SSE2: 73 return init_viterbi27_sse2(p,starting_state); 74#endif 75 } 76} 77 78/* Viterbi chainback */ 79int chainback_viterbi27( 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_viterbi27_port(p,data,nbits,endstate); 89#ifdef __VEC__ 90 case ALTIVEC: 91 return chainback_viterbi27_av(p,data,nbits,endstate); 92#endif 93#ifdef __i386__ 94 case MMX: 95 return chainback_viterbi27_mmx(p,data,nbits,endstate); 96 case SSE: 97 return chainback_viterbi27_sse(p,data,nbits,endstate); 98 case SSE2: 99 return chainback_viterbi27_sse2(p,data,nbits,endstate); 100#endif 101 } 102} 103 104/* Delete instance of a Viterbi decoder */ 105void delete_viterbi27(void *p){ 106 switch(Cpu_mode){ 107 case PORT: 108 default: 109 delete_viterbi27_port(p); 110 break; 111#ifdef __VEC__ 112 case ALTIVEC: 113 delete_viterbi27_av(p); 114 break; 115#endif 116#ifdef __i386__ 117 case MMX: 118 delete_viterbi27_mmx(p); 119 break; 120 case SSE: 121 delete_viterbi27_sse(p); 122 break; 123 case SSE2: 124 delete_viterbi27_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_viterbi27_blk(void *p,unsigned char syms[],int nbits){ 135 if(p == NULL) 136 return -1; 137 138 switch(Cpu_mode){ 139 case PORT: 140 default: 141 update_viterbi27_blk_port(p,syms,nbits); 142 break; 143#ifdef __VEC__ 144 case ALTIVEC: 145 update_viterbi27_blk_av(p,syms,nbits); 146 break; 147#endif 148#ifdef __i386__ 149 case MMX: 150 update_viterbi27_blk_mmx(p,syms,nbits); 151 break; 152 case SSE: 153 update_viterbi27_blk_sse(p,syms,nbits); 154 break; 155 case SSE2: 156 update_viterbi27_blk_sse2(p,syms,nbits); 157 break; 158#endif 159 } 160 return 0; 161} 162