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 */
create_viterbi27(int len)10 void *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
set_viterbi27_polynomial(int polys[2])32 void 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 */
init_viterbi27(void * p,int starting_state)58 int 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 */
chainback_viterbi27(void * p,unsigned char * data,unsigned int nbits,unsigned int endstate)79 int 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 */
delete_viterbi27(void * p)105 void 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 */
update_viterbi27_blk(void * p,unsigned char syms[],int nbits)134 int 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