如何使用GNU Radio库中的Viterbi解码器

时间:2017-01-24 14:22:11

标签: c++ signal-processing gnu viterbi

我需要对某些convolutional-encoded信号进行维特比解码。我的应用程序应该使用大文件,因此我无法将所有信号插入堆中,因此我需要通过一系列单独的缓冲区处理数据。我找到了一个很好的Viterbi解码库 - Encoder and a Viterbi decoder in C++ on the dr. Dobbs。我已经应用了libarary中的解码器,它工作正常,但没有提供连续使用的功能(考虑到以前的计算,为每个信号缓冲区多次调用一个函数)。然后我找到了提供GNU Radio C++ librarythe necessary functions。但我不明白如何使用它的功能,因为它没有提供文档。它包含the example of Viterbi decoding,如下所示:

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;
}

来自它的文件viterbi.c还包含下一个函数viterbi(),没有声明:

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

我还发现了另外一个维特比解码实现 - The Spiral project。但它也不包含正常的描述,也不想编译。以及ExpertCoreForward Error Correction DSP library上的另外两项实施。

我的问题:任何人都可以理解如何使用上面的GNU Radio实现的Viterbi算法连续使用二进制交错数字信号(我的信号的编码器参数:K = 7 rate = 1 / 2,我文件中的每一位都是一个解调的信号样本)?

1 个答案:

答案 0 :(得分:0)

我不是gnuradio的专家,但我正在努力解决类似问题。

来自

[1] https://github.com/gnuradio/gnuradio/blob/master/gr-fec/lib/viterbi/viterbi.c

[2] https://github.com/gnuradio/gnuradio/blob/master/gr-fec/lib/viterbi/metrics.c

我们可以看到他们已经在使用K = 7,速率= 1/2编码器和BPSK调制。因此,如果您使用的多项式是相同的(搜索POLYA和POLYB)并且调制是相同的,我相信您可以使用示例代码。

放大器参数是BPSK信号的幅度,见[2]。

从viterbi()函数[1]的实现看起来你不能以你想要的方式使用它:它看起来不像你可以在调用的两次调用之间传递状态,但如果你使用viterbi_butterfly2(或任何其他版本)它应该是可能的。