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 */ 10void *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 33void 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 */ 60int 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 */ 81int 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 */ 107void 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 */ 136int 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