Home | History | Annotate | Download | only in fec
      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