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 */ 10void *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 32void 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 */ 59int 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 */ 80int 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 */ 106void 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 */ 135int 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