diff options
author | Andrej Rode <mail@andrejro.de> | 2018-02-06 01:21:02 +0100 |
---|---|---|
committer | Andrej Rode <mail@andrejro.de> | 2018-02-07 18:55:45 +0100 |
commit | 81858b8677c3746d1bbf04e3e9bc3369cd5d6636 (patch) | |
tree | 3ae2ed2a0b856a0a6aa2fe705ab5a1228bbcfb76 | |
parent | dfc6dd7f0c878f4550c38fd7ef44e7dc0caadebe (diff) |
fec: convert viterbi sub-library to valid C++ in correct namespace
-rw-r--r-- | gnuradio-runtime/include/gnuradio/math.h | 3 | ||||
-rw-r--r-- | gr-fec/include/gnuradio/fec/viterbi.h | 52 | ||||
-rw-r--r-- | gr-fec/lib/ccsds_encoder_impl.cc | 2 | ||||
-rw-r--r-- | gr-fec/lib/decode_ccsds_27_fb_impl.h | 3 | ||||
-rw-r--r-- | gr-fec/lib/encode_ccsds_27_bb_impl.cc | 2 | ||||
-rw-r--r-- | gr-fec/lib/viterbi/CMakeLists.txt | 1 | ||||
-rw-r--r-- | gr-fec/lib/viterbi/decode.cc | 12 | ||||
-rw-r--r-- | gr-fec/lib/viterbi/encode.cc | 4 | ||||
-rw-r--r-- | gr-fec/lib/viterbi/metrics.c | 127 | ||||
-rw-r--r-- | gr-fec/lib/viterbi/viterbi.c | 487 |
10 files changed, 354 insertions, 339 deletions
diff --git a/gnuradio-runtime/include/gnuradio/math.h b/gnuradio-runtime/include/gnuradio/math.h index e60f56b594..ff41006912 100644 --- a/gnuradio-runtime/include/gnuradio/math.h +++ b/gnuradio-runtime/include/gnuradio/math.h @@ -31,6 +31,9 @@ #include <gnuradio/api.h> #include <gnuradio/gr_complex.h> +#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ +#define M_LOG2E 1.4426950408889634074 /* log_2 e */ + namespace gr { static inline bool diff --git a/gr-fec/include/gnuradio/fec/viterbi.h b/gr-fec/include/gnuradio/fec/viterbi.h index 5827f1e9b6..4ba64ed1ed 100644 --- a/gr-fec/include/gnuradio/fec/viterbi.h +++ b/gr-fec/include/gnuradio/fec/viterbi.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Free Software Foundation, Inc. + * Copyright 2008,2018 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -24,30 +24,40 @@ * But it fits so nicely into a 32-bit machine word... */ +#ifndef INCLUDED_VITERBI_H +#define INCLUDED_VITERBI_H + #include <gnuradio/fec/api.h> -struct viterbi_state { - unsigned long path; /* Decoded path to this state */ - long metric; /* Cumulative metric to this state */ -}; +namespace gr { + namespace fec { + + struct FEC_API viterbi_state { + unsigned long path; /* Decoded path to this state */ + long metric; /* Cumulative metric to this state */ + }; + + FEC_API + void gen_met(int mettab[2][256], /* Metric table */ + int amp, /* Signal amplitude */ + double esn0, /* Es/N0 ratio in dB */ + double bias, /* Metric bias */ + int scale); /* Scale factor */ -FEC_API -int gen_met(int mettab[2][256], /* Metric table */ - int amp, /* Signal amplitude */ - double esn0, /* Es/N0 ratio in dB */ - double bias, /* Metric bias */ - int scale); /* Scale factor */ + FEC_API unsigned char + encode(unsigned char *symbols, unsigned char *data, + unsigned int nbytes,unsigned char encstate); -FEC_API unsigned char -encode(unsigned char *symbols, unsigned char *data, - unsigned int nbytes,unsigned char encstate); + FEC_API void + viterbi_chunks_init(struct viterbi_state* state); -FEC_API void -viterbi_chunks_init(struct viterbi_state* state); + FEC_API void + viterbi_butterfly2(unsigned char *symbols, int mettab[2][256], + struct viterbi_state *state0, struct viterbi_state *state1); - FEC_API void -viterbi_butterfly2(unsigned char *symbols, int mettab[2][256], - struct viterbi_state *state0, struct viterbi_state *state1); + FEC_API unsigned char + viterbi_get_output(struct viterbi_state *state, unsigned char *outbuf); + } +} -FEC_API unsigned char -viterbi_get_output(struct viterbi_state *state, unsigned char *outbuf); +#endif /* INCLUDED_VITERBI_H */ diff --git a/gr-fec/lib/ccsds_encoder_impl.cc b/gr-fec/lib/ccsds_encoder_impl.cc index 2a2228a8ed..4c873a5288 100644 --- a/gr-fec/lib/ccsds_encoder_impl.cc +++ b/gr-fec/lib/ccsds_encoder_impl.cc @@ -28,9 +28,7 @@ #include <gnuradio/fec/generic_encoder.h> #include <cstdio> -extern "C" { #include <gnuradio/fec/viterbi.h> -} namespace gr { namespace fec { diff --git a/gr-fec/lib/decode_ccsds_27_fb_impl.h b/gr-fec/lib/decode_ccsds_27_fb_impl.h index 83fed604d4..fff01d2374 100644 --- a/gr-fec/lib/decode_ccsds_27_fb_impl.h +++ b/gr-fec/lib/decode_ccsds_27_fb_impl.h @@ -24,10 +24,7 @@ #define INCLUDED_FEC_DECODE_CCSDS_27_FB_IMPL_H #include <gnuradio/fec/decode_ccsds_27_fb.h> - -extern "C" { #include <gnuradio/fec/viterbi.h> -} namespace gr { namespace fec { diff --git a/gr-fec/lib/encode_ccsds_27_bb_impl.cc b/gr-fec/lib/encode_ccsds_27_bb_impl.cc index 56518777c7..e81cfaa75e 100644 --- a/gr-fec/lib/encode_ccsds_27_bb_impl.cc +++ b/gr-fec/lib/encode_ccsds_27_bb_impl.cc @@ -27,9 +27,7 @@ #include "encode_ccsds_27_bb_impl.h" #include <gnuradio/io_signature.h> -extern "C" { #include <gnuradio/fec/viterbi.h> -} namespace gr { namespace fec { diff --git a/gr-fec/lib/viterbi/CMakeLists.txt b/gr-fec/lib/viterbi/CMakeLists.txt index 10c5940246..5bbbc24ebf 100644 --- a/gr-fec/lib/viterbi/CMakeLists.txt +++ b/gr-fec/lib/viterbi/CMakeLists.txt @@ -43,6 +43,7 @@ endif(MSVC) ######################################################################## # Append gnuradio-runtime library sources ######################################################################## +SET_SOURCE_FILES_PROPERTIES( ${viterbi_sources} PROPERTIES LANGUAGE CXX ) list(APPEND gnuradio_fec_sources ${viterbi_sources}) ######################################################################## diff --git a/gr-fec/lib/viterbi/decode.cc b/gr-fec/lib/viterbi/decode.cc index 0af0b34483..3b948818fe 100644 --- a/gr-fec/lib/viterbi/decode.cc +++ b/gr-fec/lib/viterbi/decode.cc @@ -27,9 +27,7 @@ * */ -extern "C" { #include <gnuradio/fec/viterbi.h> -} #include <cstdio> #include <cmath> @@ -52,10 +50,10 @@ int main() gen_met(mettab, amp, esn0, 0.0, 4); // Initialize decoder state - struct viterbi_state state0[64]; - struct viterbi_state state1[64]; + struct gr::fec::viterbi_state state0[64]; + struct gr::fec::viterbi_state state1[64]; unsigned char viterbi_in[16]; - viterbi_chunks_init(state0); + gr::fec::viterbi_chunks_init(state0); while (!feof(stdin)) { unsigned int n = fread(syms, 1, MAXENCSIZE, stdin); @@ -71,11 +69,11 @@ int main() // Every four symbols, perform the butterfly2 operation if ((count % 4) == 3) { - viterbi_butterfly2(viterbi_in, mettab, state0, state1); + gr::fec::viterbi_butterfly2(viterbi_in, mettab, state0, state1); // Every sixteen symbols, perform the readback operation if ((count > 64) && (count % 16) == 11) { - viterbi_get_output(state0, out); + gr::fec::viterbi_get_output(state0, out); fwrite(out++, 1, 1, stdout); } } diff --git a/gr-fec/lib/viterbi/encode.cc b/gr-fec/lib/viterbi/encode.cc index 4e152781f0..bf857ff7b8 100644 --- a/gr-fec/lib/viterbi/encode.cc +++ b/gr-fec/lib/viterbi/encode.cc @@ -29,9 +29,7 @@ * */ -extern "C" { #include <gnuradio/fec/viterbi.h> -} #include <cstdio> @@ -46,7 +44,7 @@ int main() while (!feof(stdin)) { unsigned int n = fread(data, 1, MAXCHUNKSIZE, stdin); - encoder_state = encode(syms, data, n, encoder_state); + encoder_state = gr::fec::encode(syms, data, n, encoder_state); fwrite(syms, 1, n*16, stdout); } diff --git a/gr-fec/lib/viterbi/metrics.c b/gr-fec/lib/viterbi/metrics.c index 0d91c301ff..c4aa7a07ed 100644 --- a/gr-fec/lib/viterbi/metrics.c +++ b/gr-fec/lib/viterbi/metrics.c @@ -39,6 +39,8 @@ */ #define OFFSET 128 +#include<gnuradio/math.h> + #include <stdlib.h> #include <math.h> @@ -51,76 +53,81 @@ extern double erf(double x); /* Logarithm base 2 */ #define gr_log2(x) (log(x)*M_LOG2E) +namespace gr{ + namespace fec{ + /* Generate log-likelihood metrics for 8-bit soft quantized channel * assuming AWGN and BPSK */ -void -gen_met(int mettab[2][256], /* Metric table, [sent sym][rx symbol] */ - int amp, /* Signal amplitude, units */ - double esn0, /* Es/N0 ratio in dB */ - double bias, /* Metric bias; 0 for viterbi, rate for sequential */ - int scale) /* Scale factor */ -{ - double noise; - int s,bit; - double metrics[2][256]; - double p0,p1; - - /* Es/N0 as power ratio */ - esn0 = pow(10.,esn0/10); - - noise = 0.5/esn0; /* only half the noise for BPSK */ - noise = sqrt(noise); /* noise/signal Voltage ratio */ - - /* Zero is a special value, since this sample includes all - * lower samples that were clipped to this value, i.e., it - * takes the whole lower tail of the curve - */ - p1 = normal(((0-OFFSET+0.5)/amp - 1)/noise); /* P(s|1) */ - - /* Prob of this value occurring for a 0-bit */ /* P(s|0) */ - p0 = normal(((0-OFFSET+0.5)/amp + 1)/noise); - metrics[0][0] = gr_log2(2*p0/(p1+p0)) - bias; - metrics[1][0] = gr_log2(2*p1/(p1+p0)) - bias; - - for(s=1;s<255;s++){ - /* P(s|1), prob of receiving s given 1 transmitted */ - p1 = normal(((s-OFFSET+0.5)/amp - 1)/noise) - - normal(((s-OFFSET-0.5)/amp - 1)/noise); - - /* P(s|0), prob of receiving s given 0 transmitted */ - p0 = normal(((s-OFFSET+0.5)/amp + 1)/noise) - - normal(((s-OFFSET-0.5)/amp + 1)/noise); + void + gen_met(int mettab[2][256], /* Metric table, [sent sym][rx symbol] */ + int amp, /* Signal amplitude, units */ + double esn0, /* Es/N0 ratio in dB */ + double bias, /* Metric bias; 0 for viterbi, rate for sequential */ + int scale) /* Scale factor */ + { + double noise; + int s,bit; + double metrics[2][256]; + double p0,p1; + + /* Es/N0 as power ratio */ + esn0 = pow(10.,esn0/10); + + noise = 0.5/esn0; /* only half the noise for BPSK */ + noise = sqrt(noise); /* noise/signal Voltage ratio */ + + /* Zero is a special value, since this sample includes all + * lower samples that were clipped to this value, i.e., it + * takes the whole lower tail of the curve + */ + p1 = normal(((0-OFFSET+0.5)/amp - 1)/noise); /* P(s|1) */ + + /* Prob of this value occurring for a 0-bit */ /* P(s|0) */ + p0 = normal(((0-OFFSET+0.5)/amp + 1)/noise); + metrics[0][0] = gr_log2(2*p0/(p1+p0)) - bias; + metrics[1][0] = gr_log2(2*p1/(p1+p0)) - bias; + + for(s=1;s<255;s++){ + /* P(s|1), prob of receiving s given 1 transmitted */ + p1 = normal(((s-OFFSET+0.5)/amp - 1)/noise) - + normal(((s-OFFSET-0.5)/amp - 1)/noise); + + /* P(s|0), prob of receiving s given 0 transmitted */ + p0 = normal(((s-OFFSET+0.5)/amp + 1)/noise) - + normal(((s-OFFSET-0.5)/amp + 1)/noise); #ifdef notdef - printf("P(%d|1) = %lg, P(%d|0) = %lg\n",s,p1,s,p0); + printf("P(%d|1) = %lg, P(%d|0) = %lg\n",s,p1,s,p0); #endif - metrics[0][s] = gr_log2(2*p0/(p1+p0)) - bias; - metrics[1][s] = gr_log2(2*p1/(p1+p0)) - bias; - } - /* 255 is also a special value */ - /* P(s|1) */ - p1 = 1 - normal(((255-OFFSET-0.5)/amp - 1)/noise); - /* P(s|0) */ - p0 = 1 - normal(((255-OFFSET-0.5)/amp + 1)/noise); - - metrics[0][255] = gr_log2(2*p0/(p1+p0)) - bias; - metrics[1][255] = gr_log2(2*p1/(p1+p0)) - bias; + metrics[0][s] = gr_log2(2*p0/(p1+p0)) - bias; + metrics[1][s] = gr_log2(2*p1/(p1+p0)) - bias; + } + /* 255 is also a special value */ + /* P(s|1) */ + p1 = 1 - normal(((255-OFFSET-0.5)/amp - 1)/noise); + /* P(s|0) */ + p0 = 1 - normal(((255-OFFSET-0.5)/amp + 1)/noise); + + metrics[0][255] = gr_log2(2*p0/(p1+p0)) - bias; + metrics[1][255] = gr_log2(2*p1/(p1+p0)) - bias; #ifdef notdef - /* The probability of a raw symbol error is the probability - * that a 1-bit would be received as a sample with value - * 0-128. This is the offset normal curve integrated from -Inf to 0. - */ - printf("symbol Pe = %lg\n",normal(-1/noise)); + /* The probability of a raw symbol error is the probability + * that a 1-bit would be received as a sample with value + * 0-128. This is the offset normal curve integrated from -Inf to 0. + */ + printf("symbol Pe = %lg\n",normal(-1/noise)); #endif - for(bit=0;bit<2;bit++){ - for(s=0;s<256;s++){ - /* Scale and round to nearest integer */ - mettab[bit][s] = floor(metrics[bit][s] * scale + 0.5); + for(bit=0;bit<2;bit++){ + for(s=0;s<256;s++){ + /* Scale and round to nearest integer */ + mettab[bit][s] = floor(metrics[bit][s] * scale + 0.5); #ifdef notdef - printf("metrics[%d][%d] = %lg, mettab = %d\n", - bit,s,metrics[bit][s],mettab[bit][s]); + printf("metrics[%d][%d] = %lg, mettab = %d\n", + bit,s,metrics[bit][s],mettab[bit][s]); #endif + } + } } } } diff --git a/gr-fec/lib/viterbi/viterbi.c b/gr-fec/lib/viterbi/viterbi.c index 3c247a3868..11b9f79b9a 100644 --- a/gr-fec/lib/viterbi/viterbi.c +++ b/gr-fec/lib/viterbi/viterbi.c @@ -1,6 +1,6 @@ /* * Copyright 1995 Phil Karn, KA9Q - * Copyright 2008 Free Software Foundation, Inc. + * Copyright 2008,2018 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -86,270 +86,275 @@ extern unsigned char Partab[]; /* Parity lookup table */ -/* Convolutionally encode data into binary symbols */ -unsigned char -encode(unsigned char *symbols, - unsigned char *data, - unsigned int nbytes, - unsigned char encstate) -{ - int i; - - while(nbytes-- != 0){ - for(i=7;i>=0;i--){ - encstate = (encstate << 1) | ((*data >> i) & 1); - *symbols++ = Partab[encstate & POLYA]; - *symbols++ = Partab[encstate & POLYB]; +namespace gr { + namespace fec { + + /* Convolutionally encode data into binary symbols */ + unsigned char + encode(unsigned char *symbols, + unsigned char *data, + unsigned int nbytes, + unsigned char encstate) + { + int i; + + while(nbytes-- != 0){ + for(i=7;i>=0;i--){ + encstate = (encstate << 1) | ((*data >> i) & 1); + *symbols++ = Partab[encstate & POLYA]; + *symbols++ = Partab[encstate & POLYB]; + } + data++; + } + + return encstate; } - data++; - } - return encstate; -} + /* Viterbi decoder */ + int + viterbi(unsigned long *metric, /* Final path metric (returned value) */ + unsigned char *data, /* Decoded output data */ + unsigned char *symbols, /* Raw deinterleaved input symbols */ + unsigned int nbits, /* Number of output bits */ + int mettab[2][256] /* Metric table, [sent sym][rx symbol] */ + ){ + unsigned int bitcnt = 0; + int mets[4]; + long bestmetric; + int beststate,i; + struct viterbi_state state0[64],state1[64],*state,*next; -/* Viterbi decoder */ -int -viterbi(unsigned long *metric, /* Final path metric (returned value) */ - unsigned char *data, /* Decoded output data */ - unsigned char *symbols, /* Raw deinterleaved input symbols */ - unsigned int nbits, /* Number of output bits */ - int mettab[2][256] /* Metric table, [sent sym][rx symbol] */ - ){ - unsigned int bitcnt = 0; - int mets[4]; - long bestmetric; - int beststate,i; - struct viterbi_state state0[64],state1[64],*state,*next; - - state = state0; - next = state1; - - /* Initialize starting metrics to prefer 0 state */ - state[0].metric = 0; - for(i=1;i<64;i++) - state[i].metric = -999999; - state[0].path = 0; - - for(bitcnt = 0;bitcnt < nbits;bitcnt++){ - /* Read input symbol pair and compute all possible branch - * metrics - */ - mets[0] = mettab[0][symbols[0]] + mettab[0][symbols[1]]; - mets[1] = mettab[0][symbols[0]] + mettab[1][symbols[1]]; - mets[2] = mettab[1][symbols[0]] + mettab[0][symbols[1]]; - mets[3] = mettab[1][symbols[0]] + mettab[1][symbols[1]]; - symbols += 2; - - /* These macro calls were generated by genbut.c */ - BUTTERFLY(0,0); - BUTTERFLY(1,1); - BUTTERFLY(2,3); - BUTTERFLY(3,2); - BUTTERFLY(4,3); - BUTTERFLY(5,2); - BUTTERFLY(6,0); - BUTTERFLY(7,1); - BUTTERFLY(8,0); - BUTTERFLY(9,1); - BUTTERFLY(10,3); - BUTTERFLY(11,2); - BUTTERFLY(12,3); - BUTTERFLY(13,2); - BUTTERFLY(14,0); - BUTTERFLY(15,1); - BUTTERFLY(16,2); - BUTTERFLY(17,3); - BUTTERFLY(18,1); - BUTTERFLY(19,0); - BUTTERFLY(20,1); - BUTTERFLY(21,0); - BUTTERFLY(22,2); - BUTTERFLY(23,3); - BUTTERFLY(24,2); - BUTTERFLY(25,3); - BUTTERFLY(26,1); - BUTTERFLY(27,0); - BUTTERFLY(28,1); - BUTTERFLY(29,0); - BUTTERFLY(30,2); - BUTTERFLY(31,3); - - /* Swap current and next states */ - if(bitcnt & 1){ state = state0; next = state1; - } else { - state = state1; - next = state0; - } - // ETTUS - //if(bitcnt > nbits-7){ - /* In tail, poison non-zero nodes */ - //for(i=1;i<64;i += 2) - // state[i].metric = -9999999; - //} - /* Produce output every 8 bits once path memory is full */ - if((bitcnt % 8) == 5 && bitcnt > 32){ - /* Find current best path */ + + /* Initialize starting metrics to prefer 0 state */ + state[0].metric = 0; + for(i=1;i<64;i++) + state[i].metric = -999999; + state[0].path = 0; + + for(bitcnt = 0;bitcnt < nbits;bitcnt++){ + /* Read input symbol pair and compute all possible branch + * metrics + */ + mets[0] = mettab[0][symbols[0]] + mettab[0][symbols[1]]; + mets[1] = mettab[0][symbols[0]] + mettab[1][symbols[1]]; + mets[2] = mettab[1][symbols[0]] + mettab[0][symbols[1]]; + mets[3] = mettab[1][symbols[0]] + mettab[1][symbols[1]]; + symbols += 2; + + /* These macro calls were generated by genbut.c */ + BUTTERFLY(0,0); + BUTTERFLY(1,1); + BUTTERFLY(2,3); + BUTTERFLY(3,2); + BUTTERFLY(4,3); + BUTTERFLY(5,2); + BUTTERFLY(6,0); + BUTTERFLY(7,1); + BUTTERFLY(8,0); + BUTTERFLY(9,1); + BUTTERFLY(10,3); + BUTTERFLY(11,2); + BUTTERFLY(12,3); + BUTTERFLY(13,2); + BUTTERFLY(14,0); + BUTTERFLY(15,1); + BUTTERFLY(16,2); + BUTTERFLY(17,3); + BUTTERFLY(18,1); + BUTTERFLY(19,0); + BUTTERFLY(20,1); + BUTTERFLY(21,0); + BUTTERFLY(22,2); + BUTTERFLY(23,3); + BUTTERFLY(24,2); + BUTTERFLY(25,3); + BUTTERFLY(26,1); + BUTTERFLY(27,0); + BUTTERFLY(28,1); + BUTTERFLY(29,0); + BUTTERFLY(30,2); + BUTTERFLY(31,3); + + /* Swap current and next states */ + if(bitcnt & 1){ + state = state0; + next = state1; + } else { + state = state1; + next = state0; + } + // ETTUS + //if(bitcnt > nbits-7){ + /* In tail, poison non-zero nodes */ + //for(i=1;i<64;i += 2) + // state[i].metric = -9999999; + //} + /* Produce output every 8 bits once path memory is full */ + if((bitcnt % 8) == 5 && bitcnt > 32){ + /* Find current best path */ + bestmetric = state[0].metric; + beststate = 0; + for(i=1;i<64;i++){ + if(state[i].metric > bestmetric){ + bestmetric = state[i].metric; + beststate = i; + } + } +#ifdef notdef + printf("metrics[%d] = %d state = %lx\n",beststate, + state[beststate].metric,state[beststate].path); +#endif + *data++ = state[beststate].path >> 24; + } + + } + /* Output remaining bits from 0 state */ + // ETTUS Find best state instead bestmetric = state[0].metric; beststate = 0; for(i=1;i<64;i++){ - if(state[i].metric > bestmetric){ - bestmetric = state[i].metric; - beststate = i; - } + if(state[i].metric > bestmetric){ + bestmetric = state[i].metric; + beststate = i; + } } -#ifdef notdef - printf("metrics[%d] = %d state = %lx\n",beststate, - state[beststate].metric,state[beststate].path); -#endif + if((i = bitcnt % 8) != 6) + state[beststate].path <<= 6-i; + *data++ = state[beststate].path >> 24; + *data++ = state[beststate].path >> 16; + *data++ = state[beststate].path >> 8; + *data = state[beststate].path; + //printf ("BS = %d\tBSM = %d\tM0 = %d\n",beststate,state[beststate].metric,state[0].metric); + *metric = state[beststate].metric; + return 0; } - } - /* Output remaining bits from 0 state */ - // ETTUS Find best state instead - bestmetric = state[0].metric; - beststate = 0; - for(i=1;i<64;i++){ - if(state[i].metric > bestmetric){ - bestmetric = state[i].metric; - beststate = i; + + void + viterbi_chunks_init(struct viterbi_state* state) { + // Initialize starting metrics to prefer 0 state + int i; + state[0].metric = 0; + state[0].path = 0; + for(i=1;i<64;i++) + state[i].metric = -999999; } - } - if((i = bitcnt % 8) != 6) - state[beststate].path <<= 6-i; - - *data++ = state[beststate].path >> 24; - *data++ = state[beststate].path >> 16; - *data++ = state[beststate].path >> 8; - *data = state[beststate].path; - //printf ("BS = %d\tBSM = %d\tM0 = %d\n",beststate,state[beststate].metric,state[0].metric); - *metric = state[beststate].metric; - return 0; -} + void + viterbi_butterfly8(unsigned char *symbols, int mettab[2][256], struct viterbi_state *state0, struct viterbi_state *state1) + { + unsigned int bitcnt; + int mets[4]; -void -viterbi_chunks_init(struct viterbi_state* state) { - // Initialize starting metrics to prefer 0 state - int i; - state[0].metric = 0; - state[0].path = 0; - for(i=1;i<64;i++) - state[i].metric = -999999; -} + struct viterbi_state *state, *next; + state = state0; + next = state1; + // Operate on 16 symbols (8 bits) at a time + for(bitcnt = 0;bitcnt < 8;bitcnt++){ + // Read input symbol pair and compute all possible branch metrics + mets[0] = mettab[0][symbols[0]] + mettab[0][symbols[1]]; + mets[1] = mettab[0][symbols[0]] + mettab[1][symbols[1]]; + mets[2] = mettab[1][symbols[0]] + mettab[0][symbols[1]]; + mets[3] = mettab[1][symbols[0]] + mettab[1][symbols[1]]; + symbols += 2; + + // These macro calls were generated by genbut.c + BUTTERFLY(0,0);BUTTERFLY(1,1);BUTTERFLY(2,3);BUTTERFLY(3,2); + BUTTERFLY(4,3);BUTTERFLY(5,2);BUTTERFLY(6,0);BUTTERFLY(7,1); + BUTTERFLY(8,0);BUTTERFLY(9,1);BUTTERFLY(10,3);BUTTERFLY(11,2); + BUTTERFLY(12,3);BUTTERFLY(13,2);BUTTERFLY(14,0);BUTTERFLY(15,1); + BUTTERFLY(16,2);BUTTERFLY(17,3);BUTTERFLY(18,1);BUTTERFLY(19,0); + BUTTERFLY(20,1);BUTTERFLY(21,0);BUTTERFLY(22,2);BUTTERFLY(23,3); + BUTTERFLY(24,2);BUTTERFLY(25,3);BUTTERFLY(26,1);BUTTERFLY(27,0); + BUTTERFLY(28,1);BUTTERFLY(29,0);BUTTERFLY(30,2);BUTTERFLY(31,3); + + // Swap current and next states + if(bitcnt & 1){ + state = state0; + next = state1; + } else { + state = state1; + next = state0; + } + } + } + + void + viterbi_butterfly2(unsigned char *symbols, int mettab[2][256], struct viterbi_state *state0, struct viterbi_state *state1) + { + //unsigned int bitcnt; + int mets[4]; -void -viterbi_butterfly8(unsigned char *symbols, int mettab[2][256], struct viterbi_state *state0, struct viterbi_state *state1) -{ - unsigned int bitcnt; - int mets[4]; - - struct viterbi_state *state, *next; - state = state0; - next = state1; - // Operate on 16 symbols (8 bits) at a time - for(bitcnt = 0;bitcnt < 8;bitcnt++){ - // Read input symbol pair and compute all possible branch metrics - mets[0] = mettab[0][symbols[0]] + mettab[0][symbols[1]]; - mets[1] = mettab[0][symbols[0]] + mettab[1][symbols[1]]; - mets[2] = mettab[1][symbols[0]] + mettab[0][symbols[1]]; - mets[3] = mettab[1][symbols[0]] + mettab[1][symbols[1]]; - symbols += 2; - - // These macro calls were generated by genbut.c - BUTTERFLY(0,0);BUTTERFLY(1,1);BUTTERFLY(2,3);BUTTERFLY(3,2); - BUTTERFLY(4,3);BUTTERFLY(5,2);BUTTERFLY(6,0);BUTTERFLY(7,1); - BUTTERFLY(8,0);BUTTERFLY(9,1);BUTTERFLY(10,3);BUTTERFLY(11,2); - BUTTERFLY(12,3);BUTTERFLY(13,2);BUTTERFLY(14,0);BUTTERFLY(15,1); - BUTTERFLY(16,2);BUTTERFLY(17,3);BUTTERFLY(18,1);BUTTERFLY(19,0); - BUTTERFLY(20,1);BUTTERFLY(21,0);BUTTERFLY(22,2);BUTTERFLY(23,3); - BUTTERFLY(24,2);BUTTERFLY(25,3);BUTTERFLY(26,1);BUTTERFLY(27,0); - BUTTERFLY(28,1);BUTTERFLY(29,0);BUTTERFLY(30,2);BUTTERFLY(31,3); - - // Swap current and next states - if(bitcnt & 1){ + struct viterbi_state *state, *next; state = state0; next = state1; - } else { + // Operate on 4 symbols (2 bits) at a time + + // Read input symbol pair and compute all possible branch metrics + mets[0] = mettab[0][symbols[0]] + mettab[0][symbols[1]]; + mets[1] = mettab[0][symbols[0]] + mettab[1][symbols[1]]; + mets[2] = mettab[1][symbols[0]] + mettab[0][symbols[1]]; + mets[3] = mettab[1][symbols[0]] + mettab[1][symbols[1]]; + + // These macro calls were generated by genbut.c + BUTTERFLY(0,0);BUTTERFLY(1,1);BUTTERFLY(2,3);BUTTERFLY(3,2); + BUTTERFLY(4,3);BUTTERFLY(5,2);BUTTERFLY(6,0);BUTTERFLY(7,1); + BUTTERFLY(8,0);BUTTERFLY(9,1);BUTTERFLY(10,3);BUTTERFLY(11,2); + BUTTERFLY(12,3);BUTTERFLY(13,2);BUTTERFLY(14,0);BUTTERFLY(15,1); + BUTTERFLY(16,2);BUTTERFLY(17,3);BUTTERFLY(18,1);BUTTERFLY(19,0); + BUTTERFLY(20,1);BUTTERFLY(21,0);BUTTERFLY(22,2);BUTTERFLY(23,3); + BUTTERFLY(24,2);BUTTERFLY(25,3);BUTTERFLY(26,1);BUTTERFLY(27,0); + BUTTERFLY(28,1);BUTTERFLY(29,0);BUTTERFLY(30,2);BUTTERFLY(31,3); + state = state1; next = state0; + + // Read input symbol pair and compute all possible branch metrics + mets[0] = mettab[0][symbols[2]] + mettab[0][symbols[3]]; + mets[1] = mettab[0][symbols[2]] + mettab[1][symbols[3]]; + mets[2] = mettab[1][symbols[2]] + mettab[0][symbols[3]]; + mets[3] = mettab[1][symbols[2]] + mettab[1][symbols[3]]; + + // These macro calls were generated by genbut.c + BUTTERFLY(0,0);BUTTERFLY(1,1);BUTTERFLY(2,3);BUTTERFLY(3,2); + BUTTERFLY(4,3);BUTTERFLY(5,2);BUTTERFLY(6,0);BUTTERFLY(7,1); + BUTTERFLY(8,0);BUTTERFLY(9,1);BUTTERFLY(10,3);BUTTERFLY(11,2); + BUTTERFLY(12,3);BUTTERFLY(13,2);BUTTERFLY(14,0);BUTTERFLY(15,1); + BUTTERFLY(16,2);BUTTERFLY(17,3);BUTTERFLY(18,1);BUTTERFLY(19,0); + BUTTERFLY(20,1);BUTTERFLY(21,0);BUTTERFLY(22,2);BUTTERFLY(23,3); + BUTTERFLY(24,2);BUTTERFLY(25,3);BUTTERFLY(26,1);BUTTERFLY(27,0); + BUTTERFLY(28,1);BUTTERFLY(29,0);BUTTERFLY(30,2);BUTTERFLY(31,3); } - } -} -void -viterbi_butterfly2(unsigned char *symbols, int mettab[2][256], struct viterbi_state *state0, struct viterbi_state *state1) -{ - //unsigned int bitcnt; - int mets[4]; - - struct viterbi_state *state, *next; - state = state0; - next = state1; - // Operate on 4 symbols (2 bits) at a time - - // Read input symbol pair and compute all possible branch metrics - mets[0] = mettab[0][symbols[0]] + mettab[0][symbols[1]]; - mets[1] = mettab[0][symbols[0]] + mettab[1][symbols[1]]; - mets[2] = mettab[1][symbols[0]] + mettab[0][symbols[1]]; - mets[3] = mettab[1][symbols[0]] + mettab[1][symbols[1]]; - - // These macro calls were generated by genbut.c - BUTTERFLY(0,0);BUTTERFLY(1,1);BUTTERFLY(2,3);BUTTERFLY(3,2); - BUTTERFLY(4,3);BUTTERFLY(5,2);BUTTERFLY(6,0);BUTTERFLY(7,1); - BUTTERFLY(8,0);BUTTERFLY(9,1);BUTTERFLY(10,3);BUTTERFLY(11,2); - BUTTERFLY(12,3);BUTTERFLY(13,2);BUTTERFLY(14,0);BUTTERFLY(15,1); - BUTTERFLY(16,2);BUTTERFLY(17,3);BUTTERFLY(18,1);BUTTERFLY(19,0); - BUTTERFLY(20,1);BUTTERFLY(21,0);BUTTERFLY(22,2);BUTTERFLY(23,3); - BUTTERFLY(24,2);BUTTERFLY(25,3);BUTTERFLY(26,1);BUTTERFLY(27,0); - BUTTERFLY(28,1);BUTTERFLY(29,0);BUTTERFLY(30,2);BUTTERFLY(31,3); - - state = state1; - next = state0; - - // Read input symbol pair and compute all possible branch metrics - mets[0] = mettab[0][symbols[2]] + mettab[0][symbols[3]]; - mets[1] = mettab[0][symbols[2]] + mettab[1][symbols[3]]; - mets[2] = mettab[1][symbols[2]] + mettab[0][symbols[3]]; - mets[3] = mettab[1][symbols[2]] + mettab[1][symbols[3]]; - - // These macro calls were generated by genbut.c - BUTTERFLY(0,0);BUTTERFLY(1,1);BUTTERFLY(2,3);BUTTERFLY(3,2); - BUTTERFLY(4,3);BUTTERFLY(5,2);BUTTERFLY(6,0);BUTTERFLY(7,1); - BUTTERFLY(8,0);BUTTERFLY(9,1);BUTTERFLY(10,3);BUTTERFLY(11,2); - BUTTERFLY(12,3);BUTTERFLY(13,2);BUTTERFLY(14,0);BUTTERFLY(15,1); - BUTTERFLY(16,2);BUTTERFLY(17,3);BUTTERFLY(18,1);BUTTERFLY(19,0); - BUTTERFLY(20,1);BUTTERFLY(21,0);BUTTERFLY(22,2);BUTTERFLY(23,3); - BUTTERFLY(24,2);BUTTERFLY(25,3);BUTTERFLY(26,1);BUTTERFLY(27,0); - BUTTERFLY(28,1);BUTTERFLY(29,0);BUTTERFLY(30,2);BUTTERFLY(31,3); -} + unsigned char + viterbi_get_output(struct viterbi_state *state, unsigned char *outbuf) { + // Produce output every 8 bits once path memory is full + // if((bitcnt % 8) == 5 && bitcnt > 32) { -unsigned char -viterbi_get_output(struct viterbi_state *state, unsigned char *outbuf) { - // Produce output every 8 bits once path memory is full - // if((bitcnt % 8) == 5 && bitcnt > 32) { - - // Find current best path - unsigned int i,beststate; - int bestmetric; - - bestmetric = state[0].metric; - beststate = 0; - for(i=1;i<64;i++) - if(state[i].metric > bestmetric) { - bestmetric = state[i].metric; - beststate = i; + // Find current best path + unsigned int i,beststate; + int bestmetric; + + bestmetric = state[0].metric; + beststate = 0; + for(i=1;i<64;i++) + if(state[i].metric > bestmetric) { + bestmetric = state[i].metric; + beststate = i; + } + *outbuf = state[beststate].path >> 24; + return bestmetric; } - *outbuf = state[beststate].path >> 24; - return bestmetric; -} -//printf ("BS = %d\tBSM = %d\tM0 = %d\n",beststate,state[beststate].metric,state[0].metric); -// In tail, poison non-zero nodes -//if(bits_out > packet_size-7) -// for(i=1;i<64;i += 2) -// state[i].metric = -9999999; + //printf ("BS = %d\tBSM = %d\tM0 = %d\n",beststate,state[beststate].metric,state[0].metric); + // In tail, poison non-zero nodes + //if(bits_out > packet_size-7) + // for(i=1;i<64;i += 2) + // state[i].metric = -9999999; + } +} |