1/* Switch to K=9 r=1/3 Viterbi decoder with optional Intel or PowerPC SIMD
2 * Copyright Aug 2006, 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_viterbi39(int len){
11  find_cpu_mode();
12
13  switch(Cpu_mode){
14  case PORT:
15  default:
16    return create_viterbi39_port(len);
17#ifdef __VEC__
18  case ALTIVEC:
19    return create_viterbi39_av(len);
20#endif
21#ifdef __i386__
22  case MMX:
23    return create_viterbi39_mmx(len);
24  case SSE:
25    return create_viterbi39_sse(len);
26  case SSE2:
27    return create_viterbi39_sse2(len);
28#endif
29  }
30}
31
32void set_viterbi39_polynomial(int polys[3]){
33  switch(Cpu_mode){
34  case PORT:
35  default:
36    set_viterbi39_polynomial_port(polys);
37    break;
38#ifdef __VEC__
39  case ALTIVEC:
40    set_viterbi39_polynomial_av(polys);
41    break;
42#endif
43#ifdef __i386__
44  case MMX:
45    set_viterbi39_polynomial_mmx(polys);
46    break;
47  case SSE:
48    set_viterbi39_polynomial_sse(polys);
49    break;
50  case SSE2:
51    set_viterbi39_polynomial_sse2(polys);
52    break;
53#endif
54  }
55}
56
57
58/* Initialize Viterbi decoder for start of new frame */
59int init_viterbi39(void *p,int starting_state){
60    switch(Cpu_mode){
61    case PORT:
62    default:
63      return init_viterbi39_port(p,starting_state);
64#ifdef __VEC__
65    case ALTIVEC:
66      return init_viterbi39_av(p,starting_state);
67#endif
68#ifdef __i386__
69    case MMX:
70      return init_viterbi39_mmx(p,starting_state);
71    case SSE:
72      return init_viterbi39_sse(p,starting_state);
73    case SSE2:
74      return init_viterbi39_sse2(p,starting_state);
75#endif
76    }
77}
78
79/* Viterbi chainback */
80int chainback_viterbi39(
81      void *p,
82      unsigned char *data, /* Decoded output data */
83      unsigned int nbits, /* Number of data bits */
84      unsigned int endstate){ /* Terminal encoder state */
85
86    switch(Cpu_mode){
87    case PORT:
88    default:
89      return chainback_viterbi39_port(p,data,nbits,endstate);
90#ifdef __VEC__
91    case ALTIVEC:
92      return chainback_viterbi39_av(p,data,nbits,endstate);
93#endif
94#ifdef __i386__
95    case MMX:
96      return chainback_viterbi39_mmx(p,data,nbits,endstate);
97    case SSE:
98      return chainback_viterbi39_sse(p,data,nbits,endstate);
99    case SSE2:
100      return chainback_viterbi39_sse2(p,data,nbits,endstate);
101#endif
102    }
103}
104
105/* Delete instance of a Viterbi decoder */
106void delete_viterbi39(void *p){
107    switch(Cpu_mode){
108    case PORT:
109    default:
110      delete_viterbi39_port(p);
111      break;
112#ifdef __VEC__
113    case ALTIVEC:
114      delete_viterbi39_av(p);
115      break;
116#endif
117#ifdef __i386__
118    case MMX:
119      delete_viterbi39_mmx(p);
120      break;
121    case SSE:
122      delete_viterbi39_sse(p);
123      break;
124    case SSE2:
125      delete_viterbi39_sse2(p);
126      break;
127#endif
128    }
129}
130
131/* Update decoder with a block of demodulated symbols
132 * Note that nbits is the number of decoded data bits, not the number
133 * of symbols!
134 */
135int update_viterbi39_blk(void *p,unsigned char syms[],int nbits){
136    switch(Cpu_mode){
137    case PORT:
138    default:
139      return update_viterbi39_blk_port(p,syms,nbits);
140#ifdef __VEC__
141    case ALTIVEC:
142      return update_viterbi39_blk_av(p,syms,nbits);
143#endif
144#ifdef __i386__
145    case MMX:
146      return update_viterbi39_blk_mmx(p,syms,nbits);
147    case SSE:
148      return update_viterbi39_blk_sse(p,syms,nbits);
149    case SSE2:
150      return update_viterbi39_blk_sse2(p,syms,nbits);
151#endif
152    }
153}
154