• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /* User include file for libfec
2   * Copyright 2004, Phil Karn, KA9Q
3   * May be used under the terms of the GNU Lesser General Public License (LGPL)
4   */
5  
6  #ifndef _FEC_H_
7  #define _FEC_H_
8  
9  /* r=1/2 k=7 convolutional encoder polynomials
10   * The NASA-DSN convention is to use V27POLYA inverted, then V27POLYB
11   * The CCSDS/NASA-GSFC convention is to use V27POLYB, then V27POLYA inverted
12   */
13  #define	V27POLYA	0x6d
14  #define	V27POLYB	0x4f
15  
16  void *create_viterbi27(int len);
17  void set_viterbi27_polynomial(int polys[2]);
18  int init_viterbi27(void *vp,int starting_state);
19  int update_viterbi27_blk(void *vp,unsigned char sym[],int npairs);
20  int chainback_viterbi27(void *vp, unsigned char *data,unsigned int nbits,unsigned int endstate);
21  void delete_viterbi27(void *vp);
22  
23  #ifdef __VEC__
24  void *create_viterbi27_av(int len);
25  void set_viterbi27_polynomial_av(int polys[2]);
26  int init_viterbi27_av(void *p,int starting_state);
27  int chainback_viterbi27_av(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate);
28  void delete_viterbi27_av(void *p);
29  int update_viterbi27_blk_av(void *p,unsigned char *syms,int nbits);
30  #endif
31  
32  #ifdef __i386__
33  void *create_viterbi27_mmx(int len);
34  void set_viterbi27_polynomial_mmx(int polys[2]);
35  int init_viterbi27_mmx(void *p,int starting_state);
36  int chainback_viterbi27_mmx(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate);
37  void delete_viterbi27_mmx(void *p);
38  int update_viterbi27_blk_mmx(void *p,unsigned char *syms,int nbits);
39  
40  void *create_viterbi27_sse(int len);
41  void set_viterbi27_polynomial_sse(int polys[2]);
42  int init_viterbi27_sse(void *p,int starting_state);
43  int chainback_viterbi27_sse(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate);
44  void delete_viterbi27_sse(void *p);
45  int update_viterbi27_blk_sse(void *p,unsigned char *syms,int nbits);
46  
47  void *create_viterbi27_sse2(int len);
48  void set_viterbi27_polynomial_sse2(int polys[2]);
49  int init_viterbi27_sse2(void *p,int starting_state);
50  int chainback_viterbi27_sse2(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate);
51  void delete_viterbi27_sse2(void *p);
52  int update_viterbi27_blk_sse2(void *p,unsigned char *syms,int nbits);
53  #endif
54  
55  void *create_viterbi27_port(int len);
56  void set_viterbi27_polynomial_port(int polys[2]);
57  int init_viterbi27_port(void *p,int starting_state);
58  int chainback_viterbi27_port(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate);
59  void delete_viterbi27_port(void *p);
60  int update_viterbi27_blk_port(void *p,unsigned char *syms,int nbits);
61  
62  /* r=1/2 k=9 convolutional encoder polynomials */
63  #define	V29POLYA	0x1af
64  #define	V29POLYB	0x11d
65  
66  void *create_viterbi29(int len);
67  void set_viterbi29_polynomial(int polys[2]);
68  int init_viterbi29(void *vp,int starting_state);
69  int update_viterbi29_blk(void *vp,unsigned char syms[],int nbits);
70  int chainback_viterbi29(void *vp, unsigned char *data,unsigned int nbits,unsigned int endstate);
71  void delete_viterbi29(void *vp);
72  
73  #ifdef __VEC__
74  void *create_viterbi29_av(int len);
75  void set_viterbi29_polynomial_av(int polys[2]);
76  int init_viterbi29_av(void *p,int starting_state);
77  int chainback_viterbi29_av(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate);
78  void delete_viterbi29_av(void *p);
79  int update_viterbi29_blk_av(void *p,unsigned char *syms,int nbits);
80  #endif
81  
82  #ifdef __i386__
83  void *create_viterbi29_mmx(int len);
84  void set_viterbi29_polynomial_mmx(int polys[2]);
85  int init_viterbi29_mmx(void *p,int starting_state);
86  int chainback_viterbi29_mmx(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate);
87  void delete_viterbi29_mmx(void *p);
88  int update_viterbi29_blk_mmx(void *p,unsigned char *syms,int nbits);
89  
90  void *create_viterbi29_sse(int len);
91  void set_viterbi29_polynomial_sse(int polys[2]);
92  int init_viterbi29_sse(void *p,int starting_state);
93  int chainback_viterbi29_sse(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate);
94  void delete_viterbi29_sse(void *p);
95  int update_viterbi29_blk_sse(void *p,unsigned char *syms,int nbits);
96  
97  void *create_viterbi29_sse2(int len);
98  void set_viterbi29_polynomial_sse2(int polys[2]);
99  int init_viterbi29_sse2(void *p,int starting_state);
100  int chainback_viterbi29_sse2(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate);
101  void delete_viterbi29_sse2(void *p);
102  int update_viterbi29_blk_sse2(void *p,unsigned char *syms,int nbits);
103  #endif
104  
105  void *create_viterbi29_port(int len);
106  void set_viterbi29_polynomial_port(int polys[2]);
107  int init_viterbi29_port(void *p,int starting_state);
108  int chainback_viterbi29_port(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate);
109  void delete_viterbi29_port(void *p);
110  int update_viterbi29_blk_port(void *p,unsigned char *syms,int nbits);
111  
112  /* r=1/3 k=9 convolutional encoder polynomials */
113  #define	V39POLYA	0x1ed
114  #define	V39POLYB	0x19b
115  #define	V39POLYC	0x127
116  
117  void *create_viterbi39(int len);
118  void set_viterbi39_polynomial(int polys[3]);
119  int init_viterbi39(void *vp,int starting_state);
120  int update_viterbi39_blk(void *vp,unsigned char syms[],int nbits);
121  int chainback_viterbi39(void *vp, unsigned char *data,unsigned int nbits,unsigned int endstate);
122  void delete_viterbi39(void *vp);
123  
124  #ifdef __VEC__
125  void *create_viterbi39_av(int len);
126  void set_viterbi39_polynomial_av(int polys[3]);
127  int init_viterbi39_av(void *p,int starting_state);
128  int chainback_viterbi39_av(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate);
129  void delete_viterbi39_av(void *p);
130  int update_viterbi39_blk_av(void *p,unsigned char *syms,int nbits);
131  #endif
132  
133  #ifdef __i386__
134  void *create_viterbi39_mmx(int len);
135  void set_viterbi39_polynomial_mmx(int polys[3]);
136  int init_viterbi39_mmx(void *p,int starting_state);
137  int chainback_viterbi39_mmx(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate);
138  void delete_viterbi39_mmx(void *p);
139  int update_viterbi39_blk_mmx(void *p,unsigned char *syms,int nbits);
140  
141  void *create_viterbi39_sse(int len);
142  void set_viterbi39_polynomial_sse(int polys[3]);
143  int init_viterbi39_sse(void *p,int starting_state);
144  int chainback_viterbi39_sse(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate);
145  void delete_viterbi39_sse(void *p);
146  int update_viterbi39_blk_sse(void *p,unsigned char *syms,int nbits);
147  
148  void *create_viterbi39_sse2(int len);
149  void set_viterbi39_polynomial_sse2(int polys[3]);
150  int init_viterbi39_sse2(void *p,int starting_state);
151  int chainback_viterbi39_sse2(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate);
152  void delete_viterbi39_sse2(void *p);
153  int update_viterbi39_blk_sse2(void *p,unsigned char *syms,int nbits);
154  #endif
155  
156  void *create_viterbi39_port(int len);
157  void set_viterbi39_polynomial_port(int polys[3]);
158  int init_viterbi39_port(void *p,int starting_state);
159  int chainback_viterbi39_port(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate);
160  void delete_viterbi39_port(void *p);
161  int update_viterbi39_blk_port(void *p,unsigned char *syms,int nbits);
162  
163  
164  /* r=1/6 k=15 Cassini convolutional encoder polynomials without symbol inversion
165   * dfree = 56
166   * These bits may be left-right flipped from some textbook representations;
167   * here I have the bits entering the shift register from the right (low) end
168   *
169   * Some other spacecraft use the same code, but with the polynomials in a different order.
170   * E.g., Mars Pathfinder and STEREO swap POLYC and POLYD. All use alternate symbol inversion,
171   * so use set_viterbi615_polynomial() as appropriate.
172   */
173  #define	V615POLYA	042631
174  #define	V615POLYB	047245
175  #define V615POLYC       056507
176  #define V615POLYD       073363
177  #define V615POLYE       077267
178  #define V615POLYF       064537
179  
180  void *create_viterbi615(int len);
181  void set_viterbi615_polynomial(int polys[6]);
182  int init_viterbi615(void *vp,int starting_state);
183  int update_viterbi615_blk(void *vp,unsigned char *syms,int nbits);
184  int chainback_viterbi615(void *vp, unsigned char *data,unsigned int nbits,unsigned int endstate);
185  void delete_viterbi615(void *vp);
186  
187  #ifdef __VEC__
188  void *create_viterbi615_av(int len);
189  void set_viterbi615_polynomial_av(int polys[6]);
190  int init_viterbi615_av(void *p,int starting_state);
191  int chainback_viterbi615_av(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate);
192  void delete_viterbi615_av(void *p);
193  int update_viterbi615_blk_av(void *p,unsigned char *syms,int nbits);
194  #endif
195  
196  #ifdef __i386__
197  void *create_viterbi615_mmx(int len);
198  void set_viterbi615_polynomial_mmx(int polys[6]);
199  int init_viterbi615_mmx(void *p,int starting_state);
200  int chainback_viterbi615_mmx(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate);
201  void delete_viterbi615_mmx(void *p);
202  int update_viterbi615_blk_mmx(void *p,unsigned char *syms,int nbits);
203  
204  void *create_viterbi615_sse(int len);
205  void set_viterbi615_polynomial_sse(int polys[6]);
206  int init_viterbi615_sse(void *p,int starting_state);
207  int chainback_viterbi615_sse(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate);
208  void delete_viterbi615_sse(void *p);
209  int update_viterbi615_blk_sse(void *p,unsigned char *syms,int nbits);
210  
211  void *create_viterbi615_sse2(int len);
212  void set_viterbi615_polynomial_sse2(int polys[6]);
213  int init_viterbi615_sse2(void *p,int starting_state);
214  int chainback_viterbi615_sse2(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate);
215  void delete_viterbi615_sse2(void *p);
216  int update_viterbi615_blk_sse2(void *p,unsigned char *syms,int nbits);
217  
218  #endif
219  
220  void *create_viterbi615_port(int len);
221  void set_viterbi615_polynomial_port(int polys[6]);
222  int init_viterbi615_port(void *p,int starting_state);
223  int chainback_viterbi615_port(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate);
224  void delete_viterbi615_port(void *p);
225  int update_viterbi615_blk_port(void *p,unsigned char *syms,int nbits);
226  
227  
228  /* General purpose RS codec, 8-bit symbols */
229  void encode_rs_char(void *rs,unsigned char *data,unsigned char *parity);
230  int decode_rs_char(void *rs,unsigned char *data,int *eras_pos,
231  		   int no_eras);
232  void *init_rs_char(int symsize,int gfpoly,
233  		   int fcr,int prim,int nroots,
234  		   int pad);
235  void free_rs_char(void *rs);
236  
237  /* General purpose RS codec, integer symbols */
238  void encode_rs_int(void *rs,int *data,int *parity);
239  int decode_rs_int(void *rs,int *data,int *eras_pos,int no_eras);
240  void *init_rs_int(int symsize,int gfpoly,int fcr,
241  		  int prim,int nroots,int pad);
242  void free_rs_int(void *rs);
243  
244  /* CCSDS standard (255,223) RS codec with conventional (*not* dual-basis)
245   * symbol representation
246   */
247  void encode_rs_8(unsigned char *data,unsigned char *parity,int pad);
248  int decode_rs_8(unsigned char *data,int *eras_pos,int no_eras,int pad);
249  
250  /* CCSDS standard (255,223) RS codec with dual-basis symbol representation */
251  void encode_rs_ccsds(unsigned char *data,unsigned char *parity,int pad);
252  int decode_rs_ccsds(unsigned char *data,int *eras_pos,int no_eras,int pad);
253  
254  /* Tables to map from conventional->dual (Taltab) and
255   * dual->conventional (Tal1tab) bases
256   */
257  extern unsigned char Taltab[],Tal1tab[];
258  
259  
260  /* CPU SIMD instruction set available */
261  extern enum cpu_mode {UNKNOWN=0,PORT,MMX,SSE,SSE2,ALTIVEC} Cpu_mode;
262  void find_cpu_mode(void); /* Call this once at startup to set Cpu_mode */
263  
264  /* Determine parity of argument: 1 = odd, 0 = even */
265  #ifdef __i386__
parityb(unsigned char x)266  static inline int parityb(unsigned char x){
267    __asm__ __volatile__ ("test %1,%1;setpo %0" : "=g"(x) : "r" (x));
268    return x;
269  }
270  #else
271  void partab_init();
272  
parityb(unsigned char x)273  static inline int parityb(unsigned char x){
274    extern unsigned char Partab[256];
275    extern int P_init;
276    if(!P_init){
277      partab_init();
278    }
279    return Partab[x];
280  }
281  #endif
282  
283  
parity(int x)284  static inline int parity(int x){
285    /* Fold down to one byte */
286    x ^= (x >> 16);
287    x ^= (x >> 8);
288    return parityb(x);
289  }
290  
291  /* Useful utilities for simulation */
292  double normal_rand(double mean, double std_dev);
293  unsigned char addnoise(int sym,double amp,double gain,double offset,int clip);
294  
295  extern int Bitcnt[];
296  
297  /* Dot product functions */
298  void *initdp(signed short coeffs[],int len);
299  void freedp(void *dp);
300  long dotprod(void *dp,signed short a[]);
301  
302  void *initdp_port(signed short coeffs[],int len);
303  void freedp_port(void *dp);
304  long dotprod_port(void *dp,signed short a[]);
305  
306  #ifdef __i386__
307  void *initdp_mmx(signed short coeffs[],int len);
308  void freedp_mmx(void *dp);
309  long dotprod_mmx(void *dp,signed short a[]);
310  
311  void *initdp_sse(signed short coeffs[],int len);
312  void freedp_sse(void *dp);
313  long dotprod_sse(void *dp,signed short a[]);
314  
315  void *initdp_sse2(signed short coeffs[],int len);
316  void freedp_sse2(void *dp);
317  long dotprod_sse2(void *dp,signed short a[]);
318  #endif
319  
320  #ifdef __VEC__
321  void *initdp_av(signed short coeffs[],int len);
322  void freedp_av(void *dp);
323  long dotprod_av(void *dp,signed short a[]);
324  #endif
325  
326  /* Sum of squares - accepts signed shorts, produces unsigned long long */
327  unsigned long long sumsq(signed short *in,int cnt);
328  unsigned long long sumsq_port(signed short *in,int cnt);
329  
330  #ifdef __i386__
331  unsigned long long sumsq_mmx(signed short *in,int cnt);
332  unsigned long long sumsq_sse(signed short *in,int cnt);
333  unsigned long long sumsq_sse2(signed short *in,int cnt);
334  #endif
335  #ifdef __VEC__
336  unsigned long long sumsq_av(signed short *in,int cnt);
337  #endif
338  
339  
340  /* Low-level data structures and routines */
341  
342  int cpu_features(void);
343  
344  #endif /* _FEC_H_ */
345  
346  
347  
348