How to use Viterbi decoder from GNU Radio library

2.2k Views Asked by At

I need to make Viterbi decoding of some convolutional-encoded signal. My application shall work with large files, therefore I cannot insert all the signal into a heap, so I need to process a data by a sequence of separate buffers. I have found a good library for Viterbi decoding - Encoder and a Viterbi decoder in C++ on the dr. Dobbs. I have applied the decoder from the libarary, it works correct, but doesn't provide a function for continuous use (call a function many times for each signal buffer with considering of previous calculations). Then I have found the GNU Radio C++ library which provide the necessary functions. But I don't understand how to use its functions, because it doesn't provide a documentation. It contains the example of Viterbi decoding with is present below:

extern "C" {
#include <gnuradio/fec/viterbi.h>
}

#include <cstdio>
#include <cmath>

#define MAXCHUNKSIZE 4096
#define MAXENCSIZE MAXCHUNKSIZE*16

int main()
{
  unsigned char data[MAXCHUNKSIZE];
  signed char syms[MAXENCSIZE];
  int count = 0;

  // Initialize metric table
  int mettab[2][256];
  int amp = 100;  // What is it? ***
  float RATE=0.5;
  float ebn0 = 12.0;
  float esn0 = RATE*pow(10.0, ebn0/10);
  gen_met(mettab, amp, esn0, 0.0, 4);

  // Initialize decoder state
  struct viterbi_state state0[64];
  struct viterbi_state state1[64];
  unsigned char viterbi_in[16];
  viterbi_chunks_init(state0);

  while (!feof(stdin)) {
    unsigned int n = fread(syms, 1, MAXENCSIZE, stdin);
    unsigned char *out = data;

    for (unsigned int i = 0; i < n; i++) {

      // FIXME: This implements hard decoding by slicing the input stream
      unsigned char sym = syms[i] > 0 ? -amp : amp; // What is it? ***

      // Write the symbol to the decoder input
      viterbi_in[count % 4] = sym;

      // Every four symbols, perform the butterfly2 operation
      if ((count % 4) == 3) {
        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);
      fwrite(out++, 1, 1, stdout);
    }
      }

      count++;
    }
  }

  return 0;
}

File viterbi.c from it also contains the next function viterbi(), without a declaration:

/* 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] */
    ) { ...

Also I found one more implementation for Viterbi decoding - The Spiral project. But it also doesn't contain a normal description and doesn't want to compile. And two more implementation on the ExpertCore and Forward Error Correction DSP library.

My question: Can anyone understand how to use the above GNU Radio's implementation of the Viterbi algorithm for continuous use for binary interleaved digital signal (Encoder parameters of my signal: K=7 rate=1/2, every bit in my file is a demodulated sample of a signal)?

0

There are 0 best solutions below