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 */
create_viterbi615(int len)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
set_viterbi615_polynomial(int polys[6])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 */
init_viterbi615(void * p,int starting_state)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 */
chainback_viterbi615(void * p,unsigned char * data,unsigned int nbits,unsigned int endstate)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 */
delete_viterbi615(void * p)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 */
update_viterbi615_blk(void * p,unsigned char syms[],int nbits)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