forked from Opendigitalradio/ka9q-fec
-
Notifications
You must be signed in to change notification settings - Fork 0
/
viterbi29.c
178 lines (170 loc) · 3.87 KB
/
viterbi29.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/* Switch to K=9 r=1/2 Viterbi decoder with optional Intel or PowerPC SIMD
* Copyright Feb 2004, Phil Karn, KA9Q
*/
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include "fec.h"
/* Create a new instance of a Viterbi decoder */
void *create_viterbi29(int len){
find_cpu_mode();
switch(Cpu_mode){
case PORT:
default:
return create_viterbi29_port(len);
#ifdef __VEC__
case ALTIVEC:
return create_viterbi29_av(len);
#endif
#ifdef __i386__
case MMX:
return create_viterbi29_mmx(len);
case SSE:
return create_viterbi29_sse(len);
case SSE2:
return create_viterbi29_sse2(len);
#endif
#ifdef __x86_64__
case SSE2:
return create_viterbi29_port(len);
#endif
}
}
void set_viterbi29_polynomial(int polys[2]){
switch(Cpu_mode){
case PORT:
default:
set_viterbi29_polynomial_port(polys);
break;
#ifdef __VEC__
case ALTIVEC:
set_viterbi29_polynomial_av(polys);
break;
#endif
#ifdef __i386__
case MMX:
set_viterbi29_polynomial_mmx(polys);
break;
case SSE:
set_viterbi29_polynomial_sse(polys);
break;
case SSE2:
set_viterbi29_polynomial_sse2(polys);
break;
#endif
#ifdef __x86_64__
case SSE2:
set_viterbi29_polynomial_port(polys);
break;
#endif
}
}
/* Initialize Viterbi decoder for start of new frame */
int init_viterbi29(void *p,int starting_state){
switch(Cpu_mode){
case PORT:
default:
return init_viterbi29_port(p,starting_state);
#ifdef __VEC__
case ALTIVEC:
return init_viterbi29_av(p,starting_state);
#endif
#ifdef __i386__
case MMX:
return init_viterbi29_mmx(p,starting_state);
case SSE:
return init_viterbi29_sse(p,starting_state);
case SSE2:
return init_viterbi29_sse2(p,starting_state);
#endif
#ifdef __x86_64__
case SSE2:
return init_viterbi29_port(p,starting_state);
#endif
}
}
/* Viterbi chainback */
int chainback_viterbi29(
void *p,
unsigned char *data, /* Decoded output data */
unsigned int nbits, /* Number of data bits */
unsigned int endstate){ /* Terminal encoder state */
switch(Cpu_mode){
case PORT:
default:
return chainback_viterbi29_port(p,data,nbits,endstate);
#ifdef __VEC__
case ALTIVEC:
return chainback_viterbi29_av(p,data,nbits,endstate);
#endif
#ifdef __i386__
case MMX:
return chainback_viterbi29_mmx(p,data,nbits,endstate);
case SSE:
return chainback_viterbi29_sse(p,data,nbits,endstate);
case SSE2:
return chainback_viterbi29_sse2(p,data,nbits,endstate);
#endif
#ifdef __x86_64__
case SSE2:
return chainback_viterbi29_port(p,data,nbits,endstate);
#endif
}
}
/* Delete instance of a Viterbi decoder */
void delete_viterbi29(void *p){
switch(Cpu_mode){
case PORT:
default:
delete_viterbi29_port(p);
break;
#ifdef __VEC__
case ALTIVEC:
delete_viterbi29_av(p);
break;
#endif
#ifdef __i386__
case MMX:
delete_viterbi29_mmx(p);
break;
case SSE:
delete_viterbi29_sse(p);
break;
case SSE2:
delete_viterbi29_sse2(p);
break;
#endif
#ifdef __x86_64__
case SSE2:
delete_viterbi29_port(p);
break;
#endif
}
}
/* Update decoder with a block of demodulated symbols
* Note that nbits is the number of decoded data bits, not the number
* of symbols!
*/
int update_viterbi29_blk(void *p,unsigned char syms[],int nbits){
switch(Cpu_mode){
case PORT:
default:
return update_viterbi29_blk_port(p,syms,nbits);
#ifdef __VEC__
case ALTIVEC:
return update_viterbi29_blk_av(p,syms,nbits);
#endif
#ifdef __i386__
case MMX:
return update_viterbi29_blk_mmx(p,syms,nbits);
case SSE:
return update_viterbi29_blk_sse(p,syms,nbits);
case SSE2:
return update_viterbi29_blk_sse2(p,syms,nbits);
#endif
#ifdef __x86_64__
case SSE2:
return update_viterbi29_blk_port(p,syms,nbits);
#endif
}
}