Giter Site home page Giter Site logo

quiet / libcorrect Goto Github PK

View Code? Open in Web Editor NEW
357.0 24.0 93.0 146 KB

C library for Convolutional codes and Reed-Solomon

License: BSD 3-Clause "New" or "Revised" License

C 94.62% CMake 3.92% C++ 0.77% Batchfile 0.69%
convolutional-codes reed-solomon fec viterbi-algorithm

libcorrect's Introduction

Quiet Modem Project logo

Build Status

Documentation

This library uses liquid SDR to transmit data through sound. This makes it suitable for sending data across a 3.5mm headphone jack or via speaker and mic. Quiet can build standalone binaries for encoding/decoding data via .wav files or for streaming through your soundcard via PortAudio. It can also be built as a library to be consumed by other C programs.

Build

With the dependencies installed, run ./bootstrap provided by this library, which will create a build directory and invoke cmake. If you would like to install it after building, do cd build && make install.

Profiles

The encoding and decoding processes are controlled by the profiles in quiet-profiles.json. Each profile contains a complete set of parameters such as modem type and error correction.

Cable

For cable transmission, use the cable- profiles. These will attempt to use nearly the full spectrum provided by your soundcard. As such, they contain many audible frequencies and should not be used on channels that could be heard by people.

Ultrasonic

The ultrasonic- profiles encode data through a very low bitrate, but the audio content lies above 16kHz, which should pass through audio equipment relatively well while being inaudible to the average person. This is a good option for sending data through a channel where you would prefer not to disrupt human listeners.

Dependencies

Acknowledgements

I'd like to thank the people who provided feedback and helped me with pull requests and advice on software

  • Joseph Gaeddert, for his excellent SDR library, encouragement, and feedback on all things DSP
  • Alon Zakai and @juj for advising me on emscripten and for taking my PRs
  • Jan-Ivar Bruaroey and Maire Reavy for helping me patch the echo cancellation behavior of Firefox's getUserMedia
  • Josh Gao for advising me on API design and C idioms.
  • Ryan Hitchman for extensive testing on Android Chrome
  • Fabrice Bellard for thoughtfully answering a stranger's question out of the blue about digital communications

libcorrect's People

Contributors

brian-armstrong avatar edwardbetts avatar joelsoncarl avatar pietern avatar racerxdl avatar tpetazzoni avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libcorrect's Issues

Interface to gather errors information

First of all, thanks to authors of this library!

I succeeded in encoding and decoding some data. But when i work with soft decisions decoder it would be really nice to see errors count and maybe info on which bits or bytes are corrupted.
I didnt find any interface functions to work with error buffer and im not event sure if its correct to access errors buffer from convolutional struct after decoding.

Could you please provide any info on how to operate with error buffer at this moment?
Could you add interface functions to work with error buffer?

Cross Compiling in ARM Platform

Hi,

I am new to libcorrect and CMake. I am taking over the existing code and I want to cross-compile it into an ARM7 platform in Linux. Where do I specify the compiler related information (compiler path, tool name prefix etc..), In other words, which environment variable do I need to look for.
Thanks
Nattu

Merging short_rs support

Hello, I'm trying to use this lib for CCSDS frame RS (10,6) checking. May I ask why the "short_rs" branch is not "merged" into the master? Are there any drawbacks in using this branch instead of master? Best regards and thanks for your work.

Quickstart usage

I must be really dumb but I find it impossible to understand how to start using this without knowing the details about roots of polynomials etc.

I've searched the issues and the code and found similar questions but nothing that helps

Could you possibly create pair of small example functions and add them to the README:

  • One which takes a message of length n bytes and adds p parity (is that the right word) bits,
  • One which takes an array of length n+p and writes out the original n byte message either in-place or to a different array.
    Reed-soloman or convolutional - it doesn't matter

That would help enormously - I'm lost at sea
Thank you

decode_rs_char() should return int

According to documention of libfec:

The decode_ functions correct the errors in a Reed-Solomon codeword of N symbols up to the capability of the code. An optional list of "erased" symbol indices may be given in the eras_pos array to assist the decoder; this parameter may be NULL if no erasures are given. The number of erased symbols must be given in the no_eras parameter.

The decoder corrects the symbols "in place", returning the number of symbols in error. If the codeword is uncorrectable, -1 is returned and the data block is unchanged. If eras_pos is non-null, it is used to return a list of corrected symbol positions, in no particular order. This means that the array passed through this parameter must have at least nroots elements to prevent a possible buffer overflow.

The decode_ functions return a count of corrected
symbols, or -1 if the block was uncorrectible.

However, in the compatibility layer, decode_rs_char() returns void, and there is no return value in erasure_locations.

Reed solomon decoder fails

See attached diff with test where Reed-Solomon fails to recover 11 bit error even though it has 32 bits of parity (16 error bits should be guaranteed).

a.zip

Using the convolutional decoder in streaming mode? (Continuous decoder)

Is there any way to utilize libcorrect as a continuous, streaming decoder simlar to the GNU Radio implementation?

In my current usecase, I am basically locking onto the right QPSK state of a signal based on BER calculations, decoding the stream data, and after the fact performing other operations such as deframing. I was looking into switching over to libcorrect for the decoder implementation, but from what I could see, there is no directly supported way of making it operate that way.

How would I go about doing so? I did take a look at the code, but I am not quite sure...

Thanks!

How to use this to encode block-based data

My data was like this: 1500 bytes per packet. the packet may lose or recieved correctly. how should use this library to encode my data?

as I can see in correct.h file
the encode function only accept 255 bytes or less data as input.

Undefined symbols for architecture x86_64:

Hello,
I am trying to use the correct library to implement convolutional codes, however cannot get the linker to find the definitions of the functions after following the instructions for installation. The following error happens with every function I try to use:

Undefined symbols for architecture x86_64:
"correct_convolutional_create(unsigned long, unsigned long, unsigned short const*)", referenced from:
_main in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I am including

#include <correct.h>

and the CMakelLists.txt file is as follows

cmake_minimum_required(VERSION 3.16)

project(ConvCodeTest)

set(CMAKE_CXX_STANDARD 14)

add_executable(ConvCodeTest main.cpp)
include_directories (/usr/local/include/)
link_directories (/usr/local/lib/)
target_link_libraries (ConvCodeTest /usr/local/lib/libcorrect.a)
target_link_libraries (ConvCodeTest /usr/local/lib/libcorrect.dylib)

Finally, changing all paths to the build directory doesn't help either.

Viterbi decoder msg size

Hi

correct_convolutional_decode contains a code calculating original message size which looks:

    size_t num_encoded_bytes =
        (num_encoded_bits % 8) ? (num_encoded_bits / 8 + 1) : (num_encoded_bits / 8);

however, coder defines following function for calculating encoded bits

size_t correct_convolutional_encode_len(correct_convolutional *conv, size_t msg_len) {
    size_t msgbits = 8 * msg_len;
    size_t encodedbits = conv->rate * (msgbits + conv->order + 1);
    return encodedbits;
}

Shouldn't decoder be based on coder message size calculation?
It seems that decoder returns invalid message size now.
Or I am missing something obvious?

Bug in correct_reed_solomon_decode()

I have a small problem with this function. If there was no error while the transmission, the last parameter is still empty. To fix this problem, I have to do something like this:
err = correct_reed_solomon_decode(rs->encoder, rs->encoded, rs->block_length, rs->recvmsg); if (rs->recvmsg[0] == 0) memcpy(rs->recvmsg, rs->encoded, rs->block_length);

I think this behavior is quite confusing, especially while the parameter is modified, if there was an error!

Using with C++

It seems, that the header of the Library is missing the extern "C" wrapper. It would be easier to use in C++ programs! I edited it for me by hand and it works just fine.

Add (at the beginning of the correct-header):

#ifdef __cplusplus
extern "C" {
#endif

Add (at the end of the correct-header):

#ifdef __cplusplus
}
#endif

Is this behaviour correct

Hi,
I don't know much about the reed Solomon coding but i have to implement one of the error correction method for my data on UART.
Maximum data length is 32 bytes.

I kept the minimum distance 32,polynomial 0x1f5 and it looks like it is able to recover up to 16 bytes of corrupted data.Can you please confirm if the behaviour is correct or not. also is it possible to increase the error correction rate from 16 byte to more?

#include "correct.h"
#include <stdint.h>
#include <stdio.h>
#include<string.h>
#include <time.h>
#include <stdlib.h>

#define ERROR -1
#define MIN_DISTANCE 32U

int EncodeBuffer(uint8_t * original_buff,uint8_t *encodedBuff,uint8_t len);
int DecodeBuffer(uint8_t * encoded_buff,uint8_t *original_buff,uint8_t len);

/Globals/
uint8_t msg[32];
uint8_t msg_out[64];
uint8_t msg_in[32];

int main(void)
{
#if 1
srand(time(NULL));

//Writing dummy data to buffers
while(1){
printf("======================================================START======================================================\n");
for (int i = 0; i < sizeof(msg); i++)
msg[i] = i;

printf("Original MSG\n");
for(int i=0;i<sizeof(msg);i++)
printf("%X ",msg[i]);
printf("\n");

EncodeBuffer(msg,msg_out,sizeof(msg));

//curropting the encoded buffer
#if 0
	int r =0;
	for(int i=0;i<16;i++)
	{
		r = rand() % 32;
		//printf("random num =%d ",r);
		msg_out[r] = ~msg_out[r];//0xff;	
	}
	#endif
	printf("error MSG\n");
	for(int i=0;i<sizeof(msg_out);i++)
	printf("%X ", msg_out[i]);
	printf("\n");
	
	if(ERROR == DecodeBuffer(msg_out,msg_in,sizeof(msg_out)))
	{
		printf("UNABLE TO DECODE\n");
	}
	else
	{
		printf("MSG decoded successfully\n");
		for(int i=0;i<sizeof(msg_in);i++)
		printf("%X ", msg_in[i]);
		printf("\n");
	}
	
	memset(msg,0x00,sizeof(msg));
	memset(msg_out,0x00,sizeof(msg_out));
	memset(msg_in,0x00,sizeof(msg_in));
	printf("======================================================END======================================================\n");
sleep(2);
}

#endif

return 0;

}

int EncodeBuffer(uint8_t * original_buff,uint8_t *encodedBuff,uint8_t len)
{
int code = 0;

correct_reed_solomon *rs = correct_reed_solomon_create(0x1f5, 6,1, MIN_DISTANCE);
code = correct_reed_solomon_encode(rs, original_buff, len, encodedBuff);

//print encoded msg
printf("MSG Encoded\n");
	for(int i=0;i<sizeof(msg_out);i++){
printf("%X ", encodedBuff[i]);}
printf("\n");

correct_reed_solomon_destroy(rs);

return code;

}

int DecodeBuffer(uint8_t * encoded_buff,uint8_t *original_buff,uint8_t len)
{
int code = 0;

correct_reed_solomon *rs = correct_reed_solomon_create(0x1f5, 6,1, MIN_DISTANCE);

code = correct_reed_solomon_decode(rs, encoded_buff, len, original_buff);
printf("No of bytes decoded = %d \n",code);
printf("\n");	

correct_reed_solomon_destroy(rs);

return code;

}

///////////////////////////////////////////OUTPUT

======================================================START======================================================
Original MSG
0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
MSG Encoded
0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 4A 9D 11 9 28 61 FC AE A4 AF 8D FA 4D C6 D7 97 46 56 76 30 CE D8 4C 3A C6 63 9B FB C7 53 8E 58
error MSG
0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 4A 9D 11 9 28 61 FC AE A4 AF 8D FA 4D C6 D7 97 46 56 76 30 CE D8 4C 3A C6 63 9B FB C7 53 8E 58
No of bytes decoded = 32

MSG decoded successfully
0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
======================================================END======================================================

error in execution

Hi
I am getting this error while running make command.

include/correct/reed-solomon/field.h:48:5: error: ‘for’ loop initial declarations are only allowed in C99 mode
for (field_operation_t i = 1; i < 512; i++) {

Please let me know how to resolve this
Thanks,
Minal

Can't compile on linux

It seens that one folder is missing in the repository. Using cmake, I get this problem:

:~/libcorrect/build$ cmake ..
-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Looking for dotprod in FEC
-- Looking for dotprod in FEC - not found
-- Looking for include file x86intrin.h
-- Looking for include file x86intrin.h - found
CMake Error at CMakeLists.txt:56 (add_subdirectory):
add_subdirectory given source "benchmarks" which is not an existing
directory.

-- Configuring incomplete, errors occurred!
See also "/home/teske/libcorrect/build/CMakeFiles/CMakeOutput.log".
See also "/home/teske/libcorrect/build/CMakeFiles/CMakeError.log".

“correct_convolutional_decode” work wrong when rate≥9.

Thanks to the author for your contribution!
I'm using the convolutional code of libcorrect. I have tested the libcorrect with rate from 2 to 10 with order 8 and I found that when the rate is 2 to 8 the “correct_convolutional_decode” output is right. However, when rate is 9 or 10, the output of “correct_convolutional_decode” is all zero. By the way, The result of "correct_convolutional_decode_soft" is right when rate=9. I want to know where the problem lies.

Thanks for your reply!

How Compile a simple program

I have installed libcorrect on ubuntu 16.0.4
Please tell me what compilation command i use
when i use this i get errors
gcc myFile.c libcorrect.so
I have put libcorrect.so in same path as source file.

Convolutional encoder output length

Hello and thanks to the autors for this library.

I am new to convolutional codes and I tried to understand the mechanism behind in order to use this library. So far, after reading the basics of encoding, I understood that the output should be twice the length of the input (in case of rate 1/2).
My questions is related to this function in encoder.c:

size_t correct_convolutional_encode_len(correct_convolutional *conv, size_t msg_len) {
    size_t msgbits = 8 * msg_len;
    size_t encodedbits = conv->rate * (msgbits + conv->order + 1);
    return encodedbits;
}

I don't understand the formula to calculate the encodedbits. Shouldn't it be something like msgbits*conv->rate ? Why do we send so many bits?
Could you please explain? It would be very helpful for me.

Thank you in advance,
Daria

shortened Reed-Solomon (10,6) code

I need subj for CCSDS AOS Space Data Link Protocol for generating the Frame Header Error Control

image

I am trying

const static uint16_t correct_rs_primitive_polynomial_shortened = 0x13;

size_t min_distance = 4;
correct_reed_solomon *rs = correct_reed_solomon_create(correct_rs_primitive_polynomial_shortened, 1, 1, min_distance);

uint8_t msg[6];
uint8_t msg_out[10];

correct_reed_solomon_encode(rs, msg, sizeof(msg), msg_out);

and seems I am wrong )

Tell me please is it possible usage your library out of box for this task or we need make some patch?

Thx.

memory leak in RS decoding

Hi,
My colleague has found a memory leak in the RS decoder. You do malloc(), but never call free().
I suggest that you take a look if the the same problem exists in your other decoders.

Piotr Szulc

False Positives

Hello @brian-armstrong and others,

I am still evaluating libcorrect for one of my projects. In the application, an eight-byte payload exists, and it consists of 4 bytes data + 4 bytes RS error correction code. Please see my test code below. There are three functions:

1st - A basic encoding/decoding code that works as expected.
2nd - This function works on five different payloads. Some bits of the payloads corrupted, but all of them are expected to recover. The library successfully decodes these payloads as expected.
3rd - This function encodes five different data (all is 4 bytes long) and obtains payloads. (4 bytes + 4 bytes = 8 bytes) Then, in the code, I intentionally distort ECC part of the payload. The expected behavior would be seeing all with decoding errors, but interestingly the library successfully decodes 3 of 5 payloads.

Is it a bug? Or am I doing something wrong?

Looking forward to seeing your feedback.

Thanks in advance.
meerd


#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

#include <correct.h>

/* ################################ ========================================= */

#define DATA_LENGTH     4
#define ECC_LENGTH      4
#define PAYLOAD_LENGTH  (DATA_LENGTH + ECC_LENGTH)

#define SAMPLE_COUNT   5

#define dump_bytes(msg, buf, size) \
    do { \
        unsigned int ctr_dump_bytes = 0; \
        printf("| %s | = ", msg); \
        for (; ctr_dump_bytes < (size); ++ctr_dump_bytes) \
            printf("0x%02x ", ((uint8_t *)(buf))[ctr_dump_bytes]); \
        printf("\n"); \
    } while (0)
 

/* ################################ ========================================= */
/* A simple encode & decode test. */
/* ################################ ========================================= */
void rs_test1(correct_reed_solomon *ctx)
{
    const uint8_t data[DATA_LENGTH]                 = { 0xde, 0xad, 0xbe, 0xef };
    const uint8_t expected_payload[PAYLOAD_LENGTH]  = { 0xde, 0xad, 0xbe, 0xef, 0x83, 0x86, 0xc9, 0xee }; 
    uint8_t encoded[PAYLOAD_LENGTH]                 = { 0x00 };
    uint8_t decoded[PAYLOAD_LENGTH]                 = { 0x00 };
    ssize_t result; 

    fprintf(stdout, "Running %s...\n", __FUNCTION__); 
    
    dump_bytes("Encoded bytes:", encoded, PAYLOAD_LENGTH);
    /* Compare */
    result = correct_reed_solomon_encode(ctx, data, DATA_LENGTH, encoded);
    /* 255 is returned by the library */
    assert(255 == result);
    
    /* Compare the expected output with encoded buffer.  */
    result = memcmp(expected_payload, encoded, PAYLOAD_LENGTH);
    dump_bytes("Encoded bytes:", encoded, PAYLOAD_LENGTH);
    assert(0 == result);

    /* Decode the encoded buffer. */
    result = correct_reed_solomon_decode(ctx, encoded, PAYLOAD_LENGTH, decoded);
    /* See if the remaining bytes are still zero. */
    dump_bytes("Decoded bytes:", decoded, PAYLOAD_LENGTH);
    assert(DATA_LENGTH == result);

    /* Compare the decoded buffer with the original data. */
    result = memcmp(data, decoded, DATA_LENGTH);
    assert(result == 0);

    fprintf(stdout, "###################################\n");
    fprintf(stdout, "%s passed!\n", __FUNCTION__); 
    fprintf(stdout, "###################################\n");
}

/* ################################ ========================================= */
/* Some of the payloads includes errors, but all should be able to be recovered. */
/* ################################ ========================================= */

void rs_test2(correct_reed_solomon *ctx)
{
    uint8_t recoverable_payload[SAMPLE_COUNT][PAYLOAD_LENGTH] = { 
                                                                   { 0x11, 0x11, 0x11, 0x11, 0x6a, 0xec, 0x1b, 0x9d },
                                                                   { 0x56, 0xd4, 0xaa, 0xe3, 0x19, 0x90, 0xac, 0xee },
                                                                   { 0xff, 0xff, 0xff, 0xff, 0x1c, 0x8d, 0x99, 0x60 },
                                                                   { 0xaa, 0x00, 0xaa, 0xaa, 0xa3, 0xf6, 0x00, 0xbb },
                                                                   { 0x24, 0x00, 0x38, 0x90, 0x8b, 0x71, 0xff, 0x76 }
                                                                };
    int failure = 0;
    int i;

    fprintf(stdout, "Running %s...\n", __FUNCTION__); 
    
    for (i = 0; i < SAMPLE_COUNT; ++i) {
        uint8_t buf[DATA_LENGTH] = { 0x00 };
        ssize_t result = correct_reed_solomon_decode(ctx, recoverable_payload[i], PAYLOAD_LENGTH, buf);

        failure += (DATA_LENGTH != result);
        fprintf(stdout, "Decoding result for distorted input (idx: %d): %s\n", i, ((DATA_LENGTH == result) ? "SUCCESS" : "FAILURE")) ;
    }    

    fprintf(stdout, "###################################\n");
    /* If no failures has been detected so far, then the test passed! */
    if (0 == failure)
        fprintf(stdout, "%s passed!\n", __FUNCTION__);
    else
        fprintf(stdout, "%s FAILED!\n", __FUNCTION__);
    fprintf(stdout, "###################################\n");
}

/* ################################ ========================================= */
/* The last four bytes of all payloads distorted intentionally. All of the 
 * decoding attempts are expected to fail. */
/* ################################ ========================================= */
void rs_test3(correct_reed_solomon *ctx)
{

    uint8_t sample_data[SAMPLE_COUNT][DATA_LENGTH] = { 
                                                        { 0xaa, 0xaa, 0xaa, 0xaa }, 
                                                        { 0xff, 0xff, 0xff, 0xff },
                                                        { 0x4f, 0xf3, 0x89, 0x18 },
                                                        { 0x12, 0x34, 0x56, 0x78 },
                                                        { 0x24, 0xff, 0x38, 0x90 }
                                                     };

    uint8_t expected_payload[SAMPLE_COUNT][PAYLOAD_LENGTH] = {
                                                                { 0xaa, 0xaa, 0xaa, 0xaa, 0xa3, 0xf6, 0xee, 0xbb },
                                                                { 0xff, 0xff, 0xff, 0xff, 0x7c, 0x8d, 0x99, 0x68 },
                                                                { 0x4f, 0xf3, 0x89, 0x18, 0x31, 0x23, 0x07, 0x38 },
                                                                { 0x12, 0x34, 0x56, 0x78, 0x54, 0x56, 0x20, 0x2a },
                                                                { 0x24, 0xff, 0x38, 0x90, 0x8b, 0x71, 0xff, 0x76 }
                                                            };
 

    uint8_t distorted_ecc[SAMPLE_COUNT][ECC_LENGTH] = {
                                                        { 0x00, 0x00, 0x00, 0x00 },
                                                        { 0xff, 0xff, 0xff, 0xff },
                                                        { 0xb7, 0x1f, 0xff, 0x75 },
                                                        { 0xff, 0xff, 0xff, 0xff },
                                                        { 0x8b, 0x71, 0xff, 0x76 }
                                                     };

    int failure = 0;

    uint8_t buf[PAYLOAD_LENGTH];
    int i;


    fprintf(stdout, "Running %s...\n", __FUNCTION__); 
    
    for (i = 0; i < SAMPLE_COUNT; ++i) {
        /* Clean the contents */
        memset(buf, 0x00, sizeof(buf));
        /* Encode sample_data[i] */

        ssize_t result = correct_reed_solomon_encode(ctx, sample_data[i], DATA_LENGTH, buf);
    
        assert(255 == result);

        fprintf(stdout, "Checking encoded data integrity (%d)...\n", i);
        dump_bytes("Encoded value:", buf, PAYLOAD_LENGTH);
        
        if (memcmp(expected_payload[i], buf, PAYLOAD_LENGTH)) {
            dump_bytes("Expected payload:", expected_payload[i], PAYLOAD_LENGTH);
            fprintf(stdout, "\n Encoding failed!\n");
            abort();
        } else {
            fprintf(stdout, " OK!\n");
        }
    }

    for (i = 0; i < SAMPLE_COUNT; ++i) {
       uint8_t output[PAYLOAD_LENGTH] = { 0x00 };
       ssize_t result = 0;

       /* Copy data */
       memcpy(buf, sample_data[i], DATA_LENGTH);
       /* Intentionally distort ecc values completely */
       memcpy(buf + DATA_LENGTH, distorted_ecc[i], ECC_LENGTH);
       /* Print modified payload */ 
       dump_bytes("Data with distorted ECC:", buf, PAYLOAD_LENGTH);
       /* Decode modified payload. The function is EXPECTED to fail! */
       result = correct_reed_solomon_decode(ctx, buf, PAYLOAD_LENGTH, output);

       fprintf(stdout, "Decoding result for distorted input (idx: %d): %s\n", i, ((DATA_LENGTH == result) ? "DECODING SUCCESS (False Positive!)" : "DECODING FAILURE")) ;
       failure += (DATA_LENGTH == result);
    }

    fprintf(stdout, "###################################\n");
    /* If no failures has been detected so far, then the test passed! */
    if (0 == failure)
        fprintf(stdout, "%s passed!\n", __FUNCTION__); 
    else
        fprintf(stdout, "%s FAILED!\n", __FUNCTION__); 
    fprintf(stdout, "###################################\n");
}

/* ################################ ========================================= */

int main(void)
{
    const uint16_t primitive_polynomial   = correct_rs_primitive_polynomial_8_4_3_2_0;
    const uint8_t  first_consecutive_root = 0;
    const uint8_t  generator_root_gap     = 1;
    const uint8_t  num_roots              = 4;

    /* Create reed solomon codec instance */
    correct_reed_solomon *ctx = correct_reed_solomon_create(primitive_polynomial,
                                                            first_consecutive_root,
                                                            generator_root_gap,
                                                            num_roots);
    assert(0 != ctx);

    rs_test1(ctx);
    rs_test2(ctx);
    rs_test3(ctx);

    /* Destroy rs codec instance. */
    correct_reed_solomon_destroy(ctx);
    
    fprintf(stdout, "All tests completed successfully!\n");

    return 0;
}

missing symbols of inline functions

Hi,
Another issue we have found: when compiling without optimization the compiler complains about missing symbols that are defined in metric.h. Shouldn't these be defined in the .c file?

Piotr Szulc

Running 'convolutional-fec.exe'

When running this test program on MSVC/clang (x86), all I got was:
expected to decode 4096 bytes, decoded 0 bytes instead

before it exited. The reason is that error-sim.c and scratch->decode() is expecting a number of bytes decoded.
Correct?

But in fact scratch->decode point to functions returning void! Seems that conv_fec27_decode() returns 0 after all.
But I patched them all:

--- a/include/correct/util/error-sim-fec.h 2021-07-12 18:28:28
+++ b/include/correct/util/error-sim-fec.h 2022-04-07 14:45:51
@@ -2,7 +2,7 @@

 #include <fec.h>

-void conv_fec27_decode(void *conv_v, uint8_t *soft, size_t soft_len, uint8_t *msg);
-void conv_fec29_decode(void *conv_v, uint8_t *soft, size_t soft_len, uint8_t *msg);
-void conv_fec39_decode(void *conv_v, uint8_t *soft, size_t soft_len, uint8_t *msg);
-void conv_fec615_decode(void *conv_v, uint8_t *soft, size_t soft_len, uint8_t *msg);
+size_t conv_fec27_decode(void *conv_v, uint8_t *soft, size_t soft_len, uint8_t *msg);
+size_t conv_fec29_decode(void *conv_v, uint8_t *soft, size_t soft_len, uint8_t *msg);
+size_t conv_fec39_decode(void *conv_v, uint8_t *soft, size_t soft_len, uint8_t *msg);
+size_t conv_fec615_decode(void *conv_v, uint8_t *soft, size_t soft_len, uint8_t *msg);

--- a/util/error-sim-fec.c 2021-07-12 18:28:28
+++ b/util/error-sim-fec.c 2022-04-07 14:46:55
@@ -1,29 +1,33 @@
 #include "correct/util/error-sim-fec.h"

-void conv_fec27_decode(void *conv_v, uint8_t *soft, size_t soft_len, uint8_t *msg) {
+size_t conv_fec27_decode(void *conv_v, uint8_t *soft, size_t soft_len, uint8_t *msg) {
     init_viterbi27(conv_v, 0);
     update_viterbi27_blk(conv_v, soft, soft_len / 2 - 2);
     size_t n_decoded_bits = (soft_len / 2) - 8;
     chainback_viterbi27(conv_v, msg, n_decoded_bits, 0);
+    return n_decoded_bits / 8;
 }

-void conv_fec29_decode(void *conv_v, uint8_t *soft, size_t soft_len, uint8_t *msg) {
+size_t conv_fec29_decode(void *conv_v, uint8_t *soft, size_t soft_len, uint8_t *msg) {
     init_viterbi29(conv_v, 0);
     update_viterbi29_blk(conv_v, soft, soft_len / 2 - 2);
     size_t n_decoded_bits = (soft_len / 2) - 10;
     chainback_viterbi29(conv_v, msg, n_decoded_bits, 0);
+    return n_decoded_bits / 8;
 }

-void conv_fec39_decode(void *conv_v, uint8_t *soft, size_t soft_len, uint8_t *msg) {
+size_t conv_fec39_decode(void *conv_v, uint8_t *soft, size_t soft_len, uint8_t *msg) {
     init_viterbi39(conv_v, 0);
     update_viterbi39_blk(conv_v, soft, soft_len / 3 - 2);
     size_t n_decoded_bits = (soft_len / 3) - 10;
     chainback_viterbi39(conv_v, msg, n_decoded_bits, 0);
+    return n_decoded_bits / 8;
 }

-void conv_fec615_decode(void *conv_v, uint8_t *soft, size_t soft_len, uint8_t *msg) {
+size_t conv_fec615_decode(void *conv_v, uint8_t *soft, size_t soft_len, uint8_t *msg) {
     init_viterbi615(conv_v, 0);
     update_viterbi615_blk(conv_v, soft, soft_len / 6 - 2);
     size_t n_decoded_bits = (soft_len / 6) - 16;
     chainback_viterbi615(conv_v, msg, n_decoded_bits, 0);
+    return n_decoded_bits / 8;
 }

But perhaps static void chainback_viterbi() should return this instead?

So running convolutional-fec.exe now gives something more sensible:

test passed, expected error rate=0.00e+00, observed error rate=0.00e+00 @infdB for rate 2 order 6
test passed, expected error rate=8.00e-06, observed error rate=4.00e-06 @4.5dB for rate 2 order 6
test passed, expected error rate=5.00e-05, observed error rate=2.45e-05 @4.0dB for rate 2 order 6

test passed, expected error rate=0.00e+00, observed error rate=0.00e+00 @infdB for rate 2 order 9
test passed, expected error rate=3.00e-06, observed error rate=0.00e+00 @4.5dB for rate 2 order 9
test passed, expected error rate=8.00e-06, observed error rate=2.75e-06 @4.0dB for rate 2 order 9

test passed, expected error rate=0.00e+00, observed error rate=0.00e+00 @infdB for rate 3 order 9
test passed, expected error rate=3.00e-06, observed error rate=0.00e+00 @4.5dB for rate 3 order 9
test passed, expected error rate=5.00e-06, observed error rate=2.25e-06 @4.0dB for rate 3 order 9

test passed, expected error rate=0.00e+00, observed error rate=0.00e+00 @infdB for rate 6 order 15
test passed, expected error rate=3.00e-06, observed error rate=0.00e+00 @3.0dB for rate 6 order 15
test passed, expected error rate=1.00e-05, observed error rate=0.00e+00 @2.5dB for rate 6 order 15

Takes 2 minutes to complete.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.