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 16void *create_viterbi27(int len); 17void set_viterbi27_polynomial(int polys[2]); 18int init_viterbi27(void *vp,int starting_state); 19int update_viterbi27_blk(void *vp,unsigned char sym[],int npairs); 20int chainback_viterbi27(void *vp, unsigned char *data,unsigned int nbits,unsigned int endstate); 21void delete_viterbi27(void *vp); 22 23#ifdef __VEC__ 24void *create_viterbi27_av(int len); 25void set_viterbi27_polynomial_av(int polys[2]); 26int init_viterbi27_av(void *p,int starting_state); 27int chainback_viterbi27_av(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate); 28void delete_viterbi27_av(void *p); 29int update_viterbi27_blk_av(void *p,unsigned char *syms,int nbits); 30#endif 31 32#ifdef __i386__ 33void *create_viterbi27_mmx(int len); 34void set_viterbi27_polynomial_mmx(int polys[2]); 35int init_viterbi27_mmx(void *p,int starting_state); 36int chainback_viterbi27_mmx(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate); 37void delete_viterbi27_mmx(void *p); 38int update_viterbi27_blk_mmx(void *p,unsigned char *syms,int nbits); 39 40void *create_viterbi27_sse(int len); 41void set_viterbi27_polynomial_sse(int polys[2]); 42int init_viterbi27_sse(void *p,int starting_state); 43int chainback_viterbi27_sse(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate); 44void delete_viterbi27_sse(void *p); 45int update_viterbi27_blk_sse(void *p,unsigned char *syms,int nbits); 46 47void *create_viterbi27_sse2(int len); 48void set_viterbi27_polynomial_sse2(int polys[2]); 49int init_viterbi27_sse2(void *p,int starting_state); 50int chainback_viterbi27_sse2(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate); 51void delete_viterbi27_sse2(void *p); 52int update_viterbi27_blk_sse2(void *p,unsigned char *syms,int nbits); 53#endif 54 55void *create_viterbi27_port(int len); 56void set_viterbi27_polynomial_port(int polys[2]); 57int init_viterbi27_port(void *p,int starting_state); 58int chainback_viterbi27_port(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate); 59void delete_viterbi27_port(void *p); 60int 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 66void *create_viterbi29(int len); 67void set_viterbi29_polynomial(int polys[2]); 68int init_viterbi29(void *vp,int starting_state); 69int update_viterbi29_blk(void *vp,unsigned char syms[],int nbits); 70int chainback_viterbi29(void *vp, unsigned char *data,unsigned int nbits,unsigned int endstate); 71void delete_viterbi29(void *vp); 72 73#ifdef __VEC__ 74void *create_viterbi29_av(int len); 75void set_viterbi29_polynomial_av(int polys[2]); 76int init_viterbi29_av(void *p,int starting_state); 77int chainback_viterbi29_av(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate); 78void delete_viterbi29_av(void *p); 79int update_viterbi29_blk_av(void *p,unsigned char *syms,int nbits); 80#endif 81 82#ifdef __i386__ 83void *create_viterbi29_mmx(int len); 84void set_viterbi29_polynomial_mmx(int polys[2]); 85int init_viterbi29_mmx(void *p,int starting_state); 86int chainback_viterbi29_mmx(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate); 87void delete_viterbi29_mmx(void *p); 88int update_viterbi29_blk_mmx(void *p,unsigned char *syms,int nbits); 89 90void *create_viterbi29_sse(int len); 91void set_viterbi29_polynomial_sse(int polys[2]); 92int init_viterbi29_sse(void *p,int starting_state); 93int chainback_viterbi29_sse(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate); 94void delete_viterbi29_sse(void *p); 95int update_viterbi29_blk_sse(void *p,unsigned char *syms,int nbits); 96 97void *create_viterbi29_sse2(int len); 98void set_viterbi29_polynomial_sse2(int polys[2]); 99int init_viterbi29_sse2(void *p,int starting_state); 100int chainback_viterbi29_sse2(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate); 101void delete_viterbi29_sse2(void *p); 102int update_viterbi29_blk_sse2(void *p,unsigned char *syms,int nbits); 103#endif 104 105void *create_viterbi29_port(int len); 106void set_viterbi29_polynomial_port(int polys[2]); 107int init_viterbi29_port(void *p,int starting_state); 108int chainback_viterbi29_port(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate); 109void delete_viterbi29_port(void *p); 110int 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 117void *create_viterbi39(int len); 118void set_viterbi39_polynomial(int polys[3]); 119int init_viterbi39(void *vp,int starting_state); 120int update_viterbi39_blk(void *vp,unsigned char syms[],int nbits); 121int chainback_viterbi39(void *vp, unsigned char *data,unsigned int nbits,unsigned int endstate); 122void delete_viterbi39(void *vp); 123 124#ifdef __VEC__ 125void *create_viterbi39_av(int len); 126void set_viterbi39_polynomial_av(int polys[3]); 127int init_viterbi39_av(void *p,int starting_state); 128int chainback_viterbi39_av(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate); 129void delete_viterbi39_av(void *p); 130int update_viterbi39_blk_av(void *p,unsigned char *syms,int nbits); 131#endif 132 133#ifdef __i386__ 134void *create_viterbi39_mmx(int len); 135void set_viterbi39_polynomial_mmx(int polys[3]); 136int init_viterbi39_mmx(void *p,int starting_state); 137int chainback_viterbi39_mmx(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate); 138void delete_viterbi39_mmx(void *p); 139int update_viterbi39_blk_mmx(void *p,unsigned char *syms,int nbits); 140 141void *create_viterbi39_sse(int len); 142void set_viterbi39_polynomial_sse(int polys[3]); 143int init_viterbi39_sse(void *p,int starting_state); 144int chainback_viterbi39_sse(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate); 145void delete_viterbi39_sse(void *p); 146int update_viterbi39_blk_sse(void *p,unsigned char *syms,int nbits); 147 148void *create_viterbi39_sse2(int len); 149void set_viterbi39_polynomial_sse2(int polys[3]); 150int init_viterbi39_sse2(void *p,int starting_state); 151int chainback_viterbi39_sse2(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate); 152void delete_viterbi39_sse2(void *p); 153int update_viterbi39_blk_sse2(void *p,unsigned char *syms,int nbits); 154#endif 155 156void *create_viterbi39_port(int len); 157void set_viterbi39_polynomial_port(int polys[3]); 158int init_viterbi39_port(void *p,int starting_state); 159int chainback_viterbi39_port(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate); 160void delete_viterbi39_port(void *p); 161int 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 180void *create_viterbi615(int len); 181void set_viterbi615_polynomial(int polys[6]); 182int init_viterbi615(void *vp,int starting_state); 183int update_viterbi615_blk(void *vp,unsigned char *syms,int nbits); 184int chainback_viterbi615(void *vp, unsigned char *data,unsigned int nbits,unsigned int endstate); 185void delete_viterbi615(void *vp); 186 187#ifdef __VEC__ 188void *create_viterbi615_av(int len); 189void set_viterbi615_polynomial_av(int polys[6]); 190int init_viterbi615_av(void *p,int starting_state); 191int chainback_viterbi615_av(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate); 192void delete_viterbi615_av(void *p); 193int update_viterbi615_blk_av(void *p,unsigned char *syms,int nbits); 194#endif 195 196#ifdef __i386__ 197void *create_viterbi615_mmx(int len); 198void set_viterbi615_polynomial_mmx(int polys[6]); 199int init_viterbi615_mmx(void *p,int starting_state); 200int chainback_viterbi615_mmx(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate); 201void delete_viterbi615_mmx(void *p); 202int update_viterbi615_blk_mmx(void *p,unsigned char *syms,int nbits); 203 204void *create_viterbi615_sse(int len); 205void set_viterbi615_polynomial_sse(int polys[6]); 206int init_viterbi615_sse(void *p,int starting_state); 207int chainback_viterbi615_sse(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate); 208void delete_viterbi615_sse(void *p); 209int update_viterbi615_blk_sse(void *p,unsigned char *syms,int nbits); 210 211void *create_viterbi615_sse2(int len); 212void set_viterbi615_polynomial_sse2(int polys[6]); 213int init_viterbi615_sse2(void *p,int starting_state); 214int chainback_viterbi615_sse2(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate); 215void delete_viterbi615_sse2(void *p); 216int update_viterbi615_blk_sse2(void *p,unsigned char *syms,int nbits); 217 218#endif 219 220void *create_viterbi615_port(int len); 221void set_viterbi615_polynomial_port(int polys[6]); 222int init_viterbi615_port(void *p,int starting_state); 223int chainback_viterbi615_port(void *p,unsigned char *data,unsigned int nbits,unsigned int endstate); 224void delete_viterbi615_port(void *p); 225int update_viterbi615_blk_port(void *p,unsigned char *syms,int nbits); 226 227 228/* General purpose RS codec, 8-bit symbols */ 229void encode_rs_char(void *rs,unsigned char *data,unsigned char *parity); 230int decode_rs_char(void *rs,unsigned char *data,int *eras_pos, 231 int no_eras); 232void *init_rs_char(int symsize,int gfpoly, 233 int fcr,int prim,int nroots, 234 int pad); 235void free_rs_char(void *rs); 236 237/* General purpose RS codec, integer symbols */ 238void encode_rs_int(void *rs,int *data,int *parity); 239int decode_rs_int(void *rs,int *data,int *eras_pos,int no_eras); 240void *init_rs_int(int symsize,int gfpoly,int fcr, 241 int prim,int nroots,int pad); 242void free_rs_int(void *rs); 243 244/* CCSDS standard (255,223) RS codec with conventional (*not* dual-basis) 245 * symbol representation 246 */ 247void encode_rs_8(unsigned char *data,unsigned char *parity,int pad); 248int 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 */ 251void encode_rs_ccsds(unsigned char *data,unsigned char *parity,int pad); 252int 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 */ 257extern unsigned char Taltab[],Tal1tab[]; 258 259 260/* CPU SIMD instruction set available */ 261extern enum cpu_mode {UNKNOWN=0,PORT,MMX,SSE,SSE2,ALTIVEC} Cpu_mode; 262void 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__ 266static inline int parityb(unsigned char x){ 267 __asm__ __volatile__ ("test %1,%1;setpo %0" : "=g"(x) : "r" (x)); 268 return x; 269} 270#else 271void partab_init(); 272 273static 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 284static 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 */ 292double normal_rand(double mean, double std_dev); 293unsigned char addnoise(int sym,double amp,double gain,double offset,int clip); 294 295extern int Bitcnt[]; 296 297/* Dot product functions */ 298void *initdp(signed short coeffs[],int len); 299void freedp(void *dp); 300long dotprod(void *dp,signed short a[]); 301 302void *initdp_port(signed short coeffs[],int len); 303void freedp_port(void *dp); 304long dotprod_port(void *dp,signed short a[]); 305 306#ifdef __i386__ 307void *initdp_mmx(signed short coeffs[],int len); 308void freedp_mmx(void *dp); 309long dotprod_mmx(void *dp,signed short a[]); 310 311void *initdp_sse(signed short coeffs[],int len); 312void freedp_sse(void *dp); 313long dotprod_sse(void *dp,signed short a[]); 314 315void *initdp_sse2(signed short coeffs[],int len); 316void freedp_sse2(void *dp); 317long dotprod_sse2(void *dp,signed short a[]); 318#endif 319 320#ifdef __VEC__ 321void *initdp_av(signed short coeffs[],int len); 322void freedp_av(void *dp); 323long dotprod_av(void *dp,signed short a[]); 324#endif 325 326/* Sum of squares - accepts signed shorts, produces unsigned long long */ 327unsigned long long sumsq(signed short *in,int cnt); 328unsigned long long sumsq_port(signed short *in,int cnt); 329 330#ifdef __i386__ 331unsigned long long sumsq_mmx(signed short *in,int cnt); 332unsigned long long sumsq_sse(signed short *in,int cnt); 333unsigned long long sumsq_sse2(signed short *in,int cnt); 334#endif 335#ifdef __VEC__ 336unsigned long long sumsq_av(signed short *in,int cnt); 337#endif 338 339 340/* Low-level data structures and routines */ 341 342int cpu_features(void); 343 344#endif /* _FEC_H_ */ 345 346 347 348