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__ 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 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 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