Friday, August 10, 2018

Re: [Discuss-gnuradio] gr-fec Viterbi example

/*
* hex2bin - simple hex to bin filter
* antirez@invece.org - under GPL version 2
*/
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>

static int hex2bin (void)
{
char hex[3];
int d = 0;
unsigned char c;
int stdin_fd = fileno(stdin);
int n_read;

while ((n_read = read(stdin_fd, hex, sizeof(hex)-1)) > 0)
{
if (n_read == 1)
{
if (hex[0] != '\n')
{
fprintf (stderr, "input parse error, odd digits in hex file\n");
return (1);
}
return (1);
}
hex[2] = '\0';
sscanf (hex, "%x", &d);
c = (unsigned char) d;
printf ("%c", c);
}
return (0);
}

static int bin2hex (void)
{
int stdin_fd = fileno(stdin);
int n_read;
unsigned char c;

#ifdef _WIN32
setmode (fileno(stdin), O_BINARY);
setmode (fileno(stdout), O_BINARY);
#endif

while ((n_read = read(stdin_fd, &c, 1)) > 0)
printf ("%.2x", c);
return (0);
}

int main (int argc, char **argv)
{
if (argc >= 2 && strstr(argv[1], "-r"))
return bin2hex();
return hex2bin();
}
--- a/gr-fec/include/gnuradio/fec/viterbi.h 2015-12-16 20:39:46
+++ b/gr-fec/include/gnuradio/fec/viterbi.h 2018-08-10 12:33:59
@@ -24,6 +24,13 @@
* But it fits so nicely into a 32-bit machine word...
*/

+#ifndef INCLUDED_VITERBI_H
+#define INCLUDED_VITERBI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#include <gnuradio/fec/api.h>

struct viterbi_state {
@@ -51,3 +58,10 @@

FEC_API unsigned char
viterbi_get_output(struct viterbi_state *state, unsigned char *outbuf);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /* INCLUDED_VITERBI_H */
+
--- a/gr-fec/lib/viterbi/decode.cc 2015-12-16 20:39:46
+++ b/gr-fec/lib/viterbi/decode.cc 2018-08-10 14:05:31
@@ -49,14 +49,21 @@
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);

+#ifdef _WIN32
+ setmode (fileno(stdin), O_BINARY);
+ setmode (fileno(stdout), O_BINARY);
+#endif
+
while (!feof(stdin)) {
unsigned int n = fread(syms, 1, MAXENCSIZE, stdin);
unsigned char *out = data;

--- a/gr-fec/lib/viterbi/encode.cc 2015-12-16 20:39:46
+++ b/gr-fec/lib/viterbi/encode.cc 2018-08-10 14:05:55
@@ -44,6 +44,11 @@
unsigned char data[MAXCHUNKSIZE];
unsigned char syms[MAXENCSIZE];

+#ifdef _WIN32
+ setmode (fileno(stdin), O_BINARY);
+ setmode (fileno(stdout), O_BINARY);
+#endif
+
while (!feof(stdin)) {
unsigned int n = fread(data, 1, MAXCHUNKSIZE, stdin);
encoder_state = encode(syms, data, n, encoder_state);

--- a/gr-fec/lib/viterbi/metrics.c 2015-12-16 20:39:46
+++ b/gr-fec/lib/viterbi/metrics.c 2018-08-10 09:57:03
@@ -30,6 +30,8 @@
*
*/

+#include <gnuradio/fec/viterbi.h>
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -42,8 +44,10 @@
#include <stdlib.h>
#include <math.h>

-//declare erf in case it was missing in math.h and provided for by the build system
-extern double erf(double x);
+#ifndef HAVE_ERF
+ //declare erf in case it was missing in math.h and provided for by the build system
+ extern double erf(double x);
+#endif

/* Normal function integrated from -Inf to x. Range: 0-1 */
#define normal(x) (0.5 + 0.5*erf((x)/M_SQRT2))
@@ -54,7 +58,7 @@
/* Generate log-likelihood metrics for 8-bit soft quantized channel
* assuming AWGN and BPSK
*/
-void
+int
gen_met(int mettab[2][256], /* Metric table, [sent sym][rx symbol] */
int amp, /* Signal amplitude, units */
double esn0, /* Es/N0 ratio in dB */
@@ -123,4 +127,5 @@
#endif
}
}
+ return (0);
}
Jean-Michel FRIEDT wrote:

> I am currently investigating LRPT (as used by METEOR-M2) and am
> stuck with the Viterbi decoder. While trying to use
> https://github.com/gnuradio/gnuradio/blob/master/gr-fec/lib/viterbi/decode.cc
> which implements

I tried building this program on Windows and failed. Since it's
missing in viterbi/CmakeLists.txt, I fail to see it's built by
default. How did you compile it? Are you sure it wasn't written
on a big-endian machine?

On Windows at least, the viterbi.h + decode.cc + encode.cc are
not up-to-date. Missing proper dllexport, setmode(fd,O_BINARY)
etc. etc.

Anyway, with some patching I was able to link and run them.
But I have no data to test the Viterbi encoder/decoder with.
Could you please ship some files to me?

> I am unable to encode the sync word 0x1ACFFC1D to the expected result
> 0xfc 0xa2 0xb6 0x3d 0xb0 0x0d 0x97 0x94 as explained at
> https://www.teske.net.br/lucas/2016/11/goes-satellite-hunt-part-3-frame-decoder/
> I know this encoded sync word is correct because cross-correlating the
> METEOR stream (after proper constellation rotation) with this word gives
> a correlation peak every 16384 samples (=1024 byte sentence * 8 bits/byte * 2
> bits/Viterbi encoder).
>
> I am doing (word.bin was generated with Octave's fwrite function)
> $ xxd word.bin
> 00000000: 1acf fc1d 0000 0000 0000                 ..........
> and then
> $ cat word.bin | ./viterbi/encode > t.bin
> but
> $ xxd t.bin
> 00000000: 0000 0000 0000 0101 0001 0001 0101 0001  ................
> 00000010: 0001 0000 0100 0001 0101 0000 0000 0100  ................
> 00000020: 0001 0000 0101 0101 0101 0101 0000 0100  ................
> 00000030: 0001 0100 0100 0000 0001 0100 0100 0101  ................
> 00000040: 0000 0001 0001 0101 0001 0101 0000 0000  ................
> does not match the expected bit sequence which should be
> word=[1 1 1 1 1 1 0 0 ... %  fc
>       1 0 1 0 0 0 1 0 ... %  a2
>       1 0 1 1 0 1 1 0 ... %  b6
>       0 0 1 1 1 1 0 1 ... %  3d
>       1 0 1 1 0 0 0 0 ... %  b0
>       0 0 0 0 1 1 0 1 ... %  0d
>       1 0 0 1 0 1 1 1 ... %  97
>       1 0 0 1 0 1 0 0 ... %  94

I had no lock with 'xxd -revert' to check your results here
I used the attached hex2bin.c instead.

And BTW, my patches also attached.

--
--gv

No comments:

Post a Comment