blob: 6dda51f922f3b6ac5db265094943bb7e2ee9078d [file] [log] [blame]
Bill Yi4e213d52015-06-23 13:53:11 -07001/* 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