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