mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2025-05-29 04:42:28 -04:00
Remove more old stuff.
git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@6529 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
parent
31bcf0a783
commit
4a4af7b24f
@ -1,24 +0,0 @@
|
|||||||
srcdir = .
|
|
||||||
prefix = /usr/local
|
|
||||||
exec_prefix=${prefix}
|
|
||||||
CC=gcc
|
|
||||||
|
|
||||||
CFLAGS=-I/usr/local/include -Wall -O3
|
|
||||||
|
|
||||||
all: sfrsd
|
|
||||||
|
|
||||||
encode_rs_int.o: encode_rs.c
|
|
||||||
gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^
|
|
||||||
|
|
||||||
decode_rs_int.o: decode_rs.c
|
|
||||||
gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^
|
|
||||||
|
|
||||||
init_rs_int.o: init_rs.c
|
|
||||||
gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^
|
|
||||||
|
|
||||||
sfrsd: sfrsd.o encode_rs_int.o decode_rs_int.o init_rs_int.o
|
|
||||||
gcc -g -o $@ $^
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f *.o *.a sfrsd
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
|||||||
srcdir = .
|
|
||||||
prefix = /usr/local
|
|
||||||
exec_prefix=${prefix}
|
|
||||||
CC=gcc
|
|
||||||
|
|
||||||
CFLAGS=-I/usr/local/include -Wall -O3
|
|
||||||
|
|
||||||
all: sfrsd.exe
|
|
||||||
|
|
||||||
encode_rs_int.o: encode_rs.c
|
|
||||||
gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^
|
|
||||||
|
|
||||||
decode_rs_int.o: decode_rs.c
|
|
||||||
gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^
|
|
||||||
|
|
||||||
init_rs_int.o: init_rs.c
|
|
||||||
gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^
|
|
||||||
|
|
||||||
sfrsd.exe: sfrsd.o encode_rs_int.o decode_rs_int.o init_rs_int.o
|
|
||||||
gcc -g -DWIN32 -o $@ $^
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f *.o *.a sfrsd.exe
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
|||||||
/* Include file to configure the RS codec for character symbols
|
|
||||||
*
|
|
||||||
* Copyright 2002, Phil Karn, KA9Q
|
|
||||||
* May be used under the terms of the GNU General Public License (GPL)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define DTYPE unsigned char
|
|
||||||
|
|
||||||
/* Reed-Solomon codec control block */
|
|
||||||
struct rs {
|
|
||||||
unsigned int mm; /* Bits per symbol */
|
|
||||||
unsigned int nn; /* Symbols per block (= (1<<mm)-1) */
|
|
||||||
unsigned char *alpha_to; /* log lookup table */
|
|
||||||
unsigned char *index_of; /* Antilog lookup table */
|
|
||||||
unsigned char *genpoly; /* Generator polynomial */
|
|
||||||
unsigned int nroots; /* Number of generator roots = number of parity symbols */
|
|
||||||
unsigned char fcr; /* First consecutive root, index form */
|
|
||||||
unsigned char prim; /* Primitive element, index form */
|
|
||||||
unsigned char iprim; /* prim-th root of 1, index form */
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline int modnn(struct rs *rs,int x){
|
|
||||||
while (x >= rs->nn) {
|
|
||||||
x -= rs->nn;
|
|
||||||
x = (x >> rs->mm) + (x & rs->nn);
|
|
||||||
}
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
#define MODNN(x) modnn(rs,x)
|
|
||||||
|
|
||||||
#define MM (rs->mm)
|
|
||||||
#define NN (rs->nn)
|
|
||||||
#define ALPHA_TO (rs->alpha_to)
|
|
||||||
#define INDEX_OF (rs->index_of)
|
|
||||||
#define GENPOLY (rs->genpoly)
|
|
||||||
#define NROOTS (rs->nroots)
|
|
||||||
#define FCR (rs->fcr)
|
|
||||||
#define PRIM (rs->prim)
|
|
||||||
#define IPRIM (rs->iprim)
|
|
||||||
#define A0 (NN)
|
|
||||||
|
|
||||||
#define ENCODE_RS encode_rs_char
|
|
||||||
#define DECODE_RS decode_rs_char
|
|
||||||
#define INIT_RS init_rs_char
|
|
||||||
#define FREE_RS free_rs_char
|
|
||||||
|
|
||||||
void ENCODE_RS(void *p,DTYPE *data,DTYPE *parity);
|
|
||||||
int DECODE_RS(void *p,DTYPE *data,int *eras_pos,int no_eras);
|
|
||||||
void *INIT_RS(unsigned int symsize,unsigned int gfpoly,unsigned int fcr,
|
|
||||||
unsigned int prim,unsigned int nroots);
|
|
||||||
void FREE_RS(void *p);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,268 +0,0 @@
|
|||||||
/* Reed-Solomon decoder
|
|
||||||
* Copyright 2002 Phil Karn, KA9Q
|
|
||||||
* May be used under the terms of the GNU General Public License (GPL)
|
|
||||||
* Modified by Steve Franke, K9AN, for use in a soft-symbol RS decoder
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
#include <stdio.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define NULL ((void *)0)
|
|
||||||
#define min(a,b) ((a) < (b) ? (a) : (b))
|
|
||||||
|
|
||||||
#ifdef FIXED
|
|
||||||
#include "fixed.h"
|
|
||||||
#elif defined(BIGSYM)
|
|
||||||
#include "int.h"
|
|
||||||
#else
|
|
||||||
#include "char.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int DECODE_RS(
|
|
||||||
#ifndef FIXED
|
|
||||||
void *p,
|
|
||||||
#endif
|
|
||||||
DTYPE *data, int *eras_pos, int no_eras, int calc_syn){
|
|
||||||
|
|
||||||
#ifndef FIXED
|
|
||||||
struct rs *rs = (struct rs *)p;
|
|
||||||
#endif
|
|
||||||
int deg_lambda, el, deg_omega;
|
|
||||||
int i, j, r,k;
|
|
||||||
DTYPE u,q,tmp,num1,num2,den,discr_r;
|
|
||||||
DTYPE lambda[NROOTS+1]; // Err+Eras Locator poly
|
|
||||||
static DTYPE s[51]; // and syndrome poly
|
|
||||||
DTYPE b[NROOTS+1], t[NROOTS+1], omega[NROOTS+1];
|
|
||||||
DTYPE root[NROOTS], reg[NROOTS+1], loc[NROOTS];
|
|
||||||
int syn_error, count;
|
|
||||||
|
|
||||||
if( calc_syn ) {
|
|
||||||
/* form the syndromes; i.e., evaluate data(x) at roots of g(x) */
|
|
||||||
for(i=0;i<NROOTS;i++)
|
|
||||||
s[i] = data[0];
|
|
||||||
|
|
||||||
for(j=1;j<NN;j++){
|
|
||||||
for(i=0;i<NROOTS;i++){
|
|
||||||
if(s[i] == 0){
|
|
||||||
s[i] = data[j];
|
|
||||||
} else {
|
|
||||||
s[i] = data[j] ^ ALPHA_TO[MODNN(INDEX_OF[s[i]] + (FCR+i)*PRIM)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert syndromes to index form, checking for nonzero condition */
|
|
||||||
syn_error = 0;
|
|
||||||
for(i=0;i<NROOTS;i++){
|
|
||||||
syn_error |= s[i];
|
|
||||||
s[i] = INDEX_OF[s[i]];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!syn_error) {
|
|
||||||
/* if syndrome is zero, data[] is a codeword and there are no
|
|
||||||
* errors to correct. So return data[] unmodified
|
|
||||||
*/
|
|
||||||
count = 0;
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&lambda[1],0,NROOTS*sizeof(lambda[0]));
|
|
||||||
lambda[0] = 1;
|
|
||||||
|
|
||||||
if (no_eras > 0) {
|
|
||||||
/* Init lambda to be the erasure locator polynomial */
|
|
||||||
lambda[1] = ALPHA_TO[MODNN(PRIM*(NN-1-eras_pos[0]))];
|
|
||||||
for (i = 1; i < no_eras; i++) {
|
|
||||||
u = MODNN(PRIM*(NN-1-eras_pos[i]));
|
|
||||||
for (j = i+1; j > 0; j--) {
|
|
||||||
tmp = INDEX_OF[lambda[j - 1]];
|
|
||||||
if(tmp != A0)
|
|
||||||
lambda[j] ^= ALPHA_TO[MODNN(u + tmp)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG >= 1
|
|
||||||
/* Test code that verifies the erasure locator polynomial just constructed
|
|
||||||
Needed only for decoder debugging. */
|
|
||||||
|
|
||||||
/* find roots of the erasure location polynomial */
|
|
||||||
for(i=1;i<=no_eras;i++)
|
|
||||||
reg[i] = INDEX_OF[lambda[i]];
|
|
||||||
|
|
||||||
count = 0;
|
|
||||||
for (i = 1,k=IPRIM-1; i <= NN; i++,k = MODNN(k+IPRIM)) {
|
|
||||||
q = 1;
|
|
||||||
for (j = 1; j <= no_eras; j++)
|
|
||||||
if (reg[j] != A0) {
|
|
||||||
reg[j] = MODNN(reg[j] + j);
|
|
||||||
q ^= ALPHA_TO[reg[j]];
|
|
||||||
}
|
|
||||||
if (q != 0)
|
|
||||||
continue;
|
|
||||||
/* store root and error location number indices */
|
|
||||||
root[count] = i;
|
|
||||||
loc[count] = k;
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
if (count != no_eras) {
|
|
||||||
printf("count = %d no_eras = %d\n lambda(x) is WRONG\n",count,no_eras);
|
|
||||||
count = -1;
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
#if DEBUG >= 2
|
|
||||||
printf("\n Erasure positions as determined by roots of Eras Loc Poly:\n");
|
|
||||||
for (i = 0; i < count; i++)
|
|
||||||
printf("%d ", loc[i]);
|
|
||||||
printf("\n");
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
for(i=0;i<NROOTS+1;i++)
|
|
||||||
b[i] = INDEX_OF[lambda[i]];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Begin Berlekamp-Massey algorithm to determine error+erasure
|
|
||||||
* locator polynomial
|
|
||||||
*/
|
|
||||||
r = no_eras;
|
|
||||||
el = no_eras;
|
|
||||||
while (++r <= NROOTS) { /* r is the step number */
|
|
||||||
/* Compute discrepancy at the r-th step in poly-form */
|
|
||||||
discr_r = 0;
|
|
||||||
for (i = 0; i < r; i++){
|
|
||||||
if ((lambda[i] != 0) && (s[r-i-1] != A0)) {
|
|
||||||
discr_r ^= ALPHA_TO[MODNN(INDEX_OF[lambda[i]] + s[r-i-1])];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
discr_r = INDEX_OF[discr_r]; /* Index form */
|
|
||||||
if (discr_r == A0) {
|
|
||||||
/* 2 lines below: B(x) <-- x*B(x) */
|
|
||||||
memmove(&b[1],b,NROOTS*sizeof(b[0]));
|
|
||||||
b[0] = A0;
|
|
||||||
} else {
|
|
||||||
/* 7 lines below: T(x) <-- lambda(x) - discr_r*x*b(x) */
|
|
||||||
t[0] = lambda[0];
|
|
||||||
for (i = 0 ; i < NROOTS; i++) {
|
|
||||||
if(b[i] != A0)
|
|
||||||
t[i+1] = lambda[i+1] ^ ALPHA_TO[MODNN(discr_r + b[i])];
|
|
||||||
else
|
|
||||||
t[i+1] = lambda[i+1];
|
|
||||||
}
|
|
||||||
if (2 * el <= r + no_eras - 1) {
|
|
||||||
el = r + no_eras - el;
|
|
||||||
/*
|
|
||||||
* 2 lines below: B(x) <-- inv(discr_r) *
|
|
||||||
* lambda(x)
|
|
||||||
*/
|
|
||||||
for (i = 0; i <= NROOTS; i++)
|
|
||||||
b[i] = (lambda[i] == 0) ? A0 : MODNN(INDEX_OF[lambda[i]] - discr_r + NN);
|
|
||||||
} else {
|
|
||||||
/* 2 lines below: B(x) <-- x*B(x) */
|
|
||||||
memmove(&b[1],b,NROOTS*sizeof(b[0]));
|
|
||||||
b[0] = A0;
|
|
||||||
}
|
|
||||||
memcpy(lambda,t,(NROOTS+1)*sizeof(t[0]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert lambda to index form and compute deg(lambda(x)) */
|
|
||||||
deg_lambda = 0;
|
|
||||||
for(i=0;i<NROOTS+1;i++){
|
|
||||||
lambda[i] = INDEX_OF[lambda[i]];
|
|
||||||
if(lambda[i] != A0)
|
|
||||||
deg_lambda = i;
|
|
||||||
}
|
|
||||||
/* Find roots of the error+erasure locator polynomial by Chien search */
|
|
||||||
memcpy(®[1],&lambda[1],NROOTS*sizeof(reg[0]));
|
|
||||||
count = 0; /* Number of roots of lambda(x) */
|
|
||||||
for (i = 1,k=IPRIM-1; i <= NN; i++,k = MODNN(k+IPRIM)) {
|
|
||||||
q = 1; /* lambda[0] is always 0 */
|
|
||||||
for (j = deg_lambda; j > 0; j--){
|
|
||||||
if (reg[j] != A0) {
|
|
||||||
reg[j] = MODNN(reg[j] + j);
|
|
||||||
q ^= ALPHA_TO[reg[j]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (q != 0)
|
|
||||||
continue; /* Not a root */
|
|
||||||
/* store root (index-form) and error location number */
|
|
||||||
#if DEBUG>=2
|
|
||||||
printf("count %d root %d loc %d\n",count,i,k);
|
|
||||||
#endif
|
|
||||||
root[count] = i;
|
|
||||||
loc[count] = k;
|
|
||||||
/* If we've already found max possible roots,
|
|
||||||
* abort the search to save time
|
|
||||||
*/
|
|
||||||
if(++count == deg_lambda)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (deg_lambda != count) {
|
|
||||||
/*
|
|
||||||
* deg(lambda) unequal to number of roots => uncorrectable
|
|
||||||
* error detected
|
|
||||||
*/
|
|
||||||
count = -1;
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Compute err+eras evaluator poly omega(x) = s(x)*lambda(x) (modulo
|
|
||||||
* x**NROOTS). in index form. Also find deg(omega).
|
|
||||||
*/
|
|
||||||
deg_omega = 0;
|
|
||||||
for (i = 0; i < NROOTS;i++){
|
|
||||||
tmp = 0;
|
|
||||||
j = (deg_lambda < i) ? deg_lambda : i;
|
|
||||||
for(;j >= 0; j--){
|
|
||||||
if ((s[i - j] != A0) && (lambda[j] != A0))
|
|
||||||
tmp ^= ALPHA_TO[MODNN(s[i - j] + lambda[j])];
|
|
||||||
}
|
|
||||||
if(tmp != 0)
|
|
||||||
deg_omega = i;
|
|
||||||
omega[i] = INDEX_OF[tmp];
|
|
||||||
}
|
|
||||||
omega[NROOTS] = A0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Compute error values in poly-form. num1 = omega(inv(X(l))), num2 =
|
|
||||||
* inv(X(l))**(FCR-1) and den = lambda_pr(inv(X(l))) all in poly-form
|
|
||||||
*/
|
|
||||||
for (j = count-1; j >=0; j--) {
|
|
||||||
num1 = 0;
|
|
||||||
for (i = deg_omega; i >= 0; i--) {
|
|
||||||
if (omega[i] != A0)
|
|
||||||
num1 ^= ALPHA_TO[MODNN(omega[i] + i * root[j])];
|
|
||||||
}
|
|
||||||
num2 = ALPHA_TO[MODNN(root[j] * (FCR - 1) + NN)];
|
|
||||||
den = 0;
|
|
||||||
|
|
||||||
/* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */
|
|
||||||
for (i = min(deg_lambda,NROOTS-1) & ~1; i >= 0; i -=2) {
|
|
||||||
if(lambda[i+1] != A0)
|
|
||||||
den ^= ALPHA_TO[MODNN(lambda[i+1] + i * root[j])];
|
|
||||||
}
|
|
||||||
if (den == 0) {
|
|
||||||
#if DEBUG >= 1
|
|
||||||
printf("\n ERROR: denominator = 0\n");
|
|
||||||
#endif
|
|
||||||
count = -1;
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
/* Apply error to data */
|
|
||||||
if (num1 != 0) {
|
|
||||||
data[loc[j]] ^= ALPHA_TO[MODNN(INDEX_OF[num1] + INDEX_OF[num2] + NN - INDEX_OF[den])];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finish:
|
|
||||||
if(eras_pos != NULL){
|
|
||||||
for(i=0;i<count;i++)
|
|
||||||
eras_pos[i] = loc[i];
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
/* Reed-Solomon encoder
|
|
||||||
* Copyright 2002, Phil Karn, KA9Q
|
|
||||||
* May be used under the terms of the GNU General Public License (GPL)
|
|
||||||
*/
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#ifdef FIXED
|
|
||||||
#include "fixed.h"
|
|
||||||
#elif defined(BIGSYM)
|
|
||||||
#include "int.h"
|
|
||||||
#else
|
|
||||||
#include "char.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void ENCODE_RS(
|
|
||||||
#ifndef FIXED
|
|
||||||
void *p,
|
|
||||||
#endif
|
|
||||||
DTYPE *data, DTYPE *bb){
|
|
||||||
#ifndef FIXED
|
|
||||||
struct rs *rs = (struct rs *)p;
|
|
||||||
#endif
|
|
||||||
int i, j;
|
|
||||||
DTYPE feedback;
|
|
||||||
|
|
||||||
memset(bb,0,NROOTS*sizeof(DTYPE));
|
|
||||||
|
|
||||||
for(i=0;i<NN-NROOTS;i++){
|
|
||||||
feedback = INDEX_OF[data[i] ^ bb[0]];
|
|
||||||
if(feedback != A0){ /* feedback term is non-zero */
|
|
||||||
#ifdef UNNORMALIZED
|
|
||||||
/* This line is unnecessary when GENPOLY[NROOTS] is unity, as it must
|
|
||||||
* always be for the polynomials constructed by init_rs()
|
|
||||||
*/
|
|
||||||
feedback = MODNN(NN - GENPOLY[NROOTS] + feedback);
|
|
||||||
#endif
|
|
||||||
for(j=1;j<NROOTS;j++)
|
|
||||||
bb[j] ^= ALPHA_TO[MODNN(feedback + GENPOLY[NROOTS-j])];
|
|
||||||
}
|
|
||||||
/* Shift */
|
|
||||||
memmove(&bb[0],&bb[1],sizeof(DTYPE)*(NROOTS-1));
|
|
||||||
if(feedback != A0)
|
|
||||||
bb[NROOTS-1] = ALPHA_TO[MODNN(feedback + GENPOLY[0])];
|
|
||||||
else
|
|
||||||
bb[NROOTS-1] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
/* Configure the RS codec with fixed parameters for CCSDS standard
|
|
||||||
* (255,223) code over GF(256). Note: the conventional basis is still
|
|
||||||
* used; the dual-basis mappings are performed in [en|de]code_rs_ccsds.c
|
|
||||||
*
|
|
||||||
* Copyright 2002 Phil Karn, KA9Q
|
|
||||||
* May be used under the terms of the GNU General Public License (GPL)
|
|
||||||
*/
|
|
||||||
#define DTYPE unsigned char
|
|
||||||
|
|
||||||
static inline int mod255(int x){
|
|
||||||
while (x >= 255) {
|
|
||||||
x -= 255;
|
|
||||||
x = (x >> 8) + (x & 255);
|
|
||||||
}
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
#define MODNN(x) mod255(x)
|
|
||||||
|
|
||||||
extern unsigned char CCSDS_alpha_to[];
|
|
||||||
extern unsigned char CCSDS_index_of[];
|
|
||||||
extern unsigned char CCSDS_poly[];
|
|
||||||
|
|
||||||
#define MM 8
|
|
||||||
#define NN 255
|
|
||||||
#define ALPHA_TO CCSDS_alpha_to
|
|
||||||
#define INDEX_OF CCSDS_index_of
|
|
||||||
#define GENPOLY CCSDS_poly
|
|
||||||
#define NROOTS 32
|
|
||||||
#define FCR 112
|
|
||||||
#define PRIM 11
|
|
||||||
#define IPRIM 116
|
|
||||||
#define A0 (NN)
|
|
||||||
|
|
||||||
#define ENCODE_RS encode_rs_8
|
|
||||||
#define DECODE_RS decode_rs_8
|
|
||||||
|
|
||||||
void ENCODE_RS(DTYPE *data,DTYPE *parity);
|
|
||||||
int DECODE_RS(DTYPE *data, int *eras_pos, int no_eras);
|
|
@ -1,121 +0,0 @@
|
|||||||
/* Initialize a RS codec
|
|
||||||
*
|
|
||||||
* Copyright 2002 Phil Karn, KA9Q
|
|
||||||
* May be used under the terms of the GNU General Public License (GPL)
|
|
||||||
*/
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#ifdef CCSDS
|
|
||||||
#include "ccsds.h"
|
|
||||||
#elif defined(BIGSYM)
|
|
||||||
#include "int.h"
|
|
||||||
#else
|
|
||||||
#include "char.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define NULL ((void *)0)
|
|
||||||
|
|
||||||
void FREE_RS(void *p){
|
|
||||||
struct rs *rs = (struct rs *)p;
|
|
||||||
|
|
||||||
free(rs->alpha_to);
|
|
||||||
free(rs->index_of);
|
|
||||||
free(rs->genpoly);
|
|
||||||
free(rs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize a Reed-Solomon codec
|
|
||||||
* symsize = symbol size, bits (1-8)
|
|
||||||
* gfpoly = Field generator polynomial coefficients
|
|
||||||
* fcr = first root of RS code generator polynomial, index form
|
|
||||||
* prim = primitive element to generate polynomial roots
|
|
||||||
* nroots = RS code generator polynomial degree (number of roots)
|
|
||||||
*/
|
|
||||||
void *INIT_RS(unsigned int symsize,unsigned int gfpoly,unsigned fcr,unsigned prim,
|
|
||||||
unsigned int nroots){
|
|
||||||
struct rs *rs;
|
|
||||||
int i, j, sr,root,iprim;
|
|
||||||
|
|
||||||
if(symsize > 8*sizeof(DTYPE))
|
|
||||||
return NULL; /* Need version with ints rather than chars */
|
|
||||||
|
|
||||||
if(fcr >= (1<<symsize))
|
|
||||||
return NULL;
|
|
||||||
if(prim == 0 || prim >= (1<<symsize))
|
|
||||||
return NULL;
|
|
||||||
if(nroots >= (1<<symsize))
|
|
||||||
return NULL; /* Can't have more roots than symbol values! */
|
|
||||||
|
|
||||||
rs = (struct rs *)calloc(1,sizeof(struct rs));
|
|
||||||
rs->mm = symsize;
|
|
||||||
rs->nn = (1<<symsize)-1;
|
|
||||||
|
|
||||||
rs->alpha_to = (DTYPE *)malloc(sizeof(DTYPE)*(rs->nn+1));
|
|
||||||
if(rs->alpha_to == NULL){
|
|
||||||
free(rs);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
rs->index_of = (DTYPE *)malloc(sizeof(DTYPE)*(rs->nn+1));
|
|
||||||
if(rs->index_of == NULL){
|
|
||||||
free(rs->alpha_to);
|
|
||||||
free(rs);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Generate Galois field lookup tables */
|
|
||||||
rs->index_of[0] = A0; /* log(zero) = -inf */
|
|
||||||
rs->alpha_to[A0] = 0; /* alpha**-inf = 0 */
|
|
||||||
sr = 1;
|
|
||||||
for(i=0;i<rs->nn;i++){
|
|
||||||
rs->index_of[sr] = i;
|
|
||||||
rs->alpha_to[i] = sr;
|
|
||||||
sr <<= 1;
|
|
||||||
if(sr & (1<<symsize))
|
|
||||||
sr ^= gfpoly;
|
|
||||||
sr &= rs->nn;
|
|
||||||
}
|
|
||||||
if(sr != 1){
|
|
||||||
/* field generator polynomial is not primitive! */
|
|
||||||
free(rs->alpha_to);
|
|
||||||
free(rs->index_of);
|
|
||||||
free(rs);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Form RS code generator polynomial from its roots */
|
|
||||||
rs->genpoly = (DTYPE *)malloc(sizeof(DTYPE)*(nroots+1));
|
|
||||||
if(rs->genpoly == NULL){
|
|
||||||
free(rs->alpha_to);
|
|
||||||
free(rs->index_of);
|
|
||||||
free(rs);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
rs->fcr = fcr;
|
|
||||||
rs->prim = prim;
|
|
||||||
rs->nroots = nroots;
|
|
||||||
|
|
||||||
/* Find prim-th root of 1, used in decoding */
|
|
||||||
for(iprim=1;(iprim % prim) != 0;iprim += rs->nn)
|
|
||||||
;
|
|
||||||
rs->iprim = iprim / prim;
|
|
||||||
|
|
||||||
rs->genpoly[0] = 1;
|
|
||||||
for (i = 0,root=fcr*prim; i < nroots; i++,root += prim) {
|
|
||||||
rs->genpoly[i+1] = 1;
|
|
||||||
|
|
||||||
/* Multiply rs->genpoly[] by @**(root + x) */
|
|
||||||
for (j = i; j > 0; j--){
|
|
||||||
if (rs->genpoly[j] != 0)
|
|
||||||
rs->genpoly[j] = rs->genpoly[j-1] ^ rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[j]] + root)];
|
|
||||||
else
|
|
||||||
rs->genpoly[j] = rs->genpoly[j-1];
|
|
||||||
}
|
|
||||||
/* rs->genpoly[0] can never be zero */
|
|
||||||
rs->genpoly[0] = rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[0]] + root)];
|
|
||||||
}
|
|
||||||
/* convert rs->genpoly[] to index form for quicker encoding */
|
|
||||||
for (i = 0; i <= nroots; i++)
|
|
||||||
rs->genpoly[i] = rs->index_of[rs->genpoly[i]];
|
|
||||||
|
|
||||||
return rs;
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
/* Include file to configure the RS codec for integer symbols
|
|
||||||
*
|
|
||||||
* Copyright 2002, Phil Karn, KA9Q
|
|
||||||
* May be used under the terms of the GNU General Public License (GPL)
|
|
||||||
*/
|
|
||||||
#define DTYPE int
|
|
||||||
|
|
||||||
/* Reed-Solomon codec control block */
|
|
||||||
struct rs {
|
|
||||||
unsigned int mm; /* Bits per symbol */
|
|
||||||
unsigned int nn; /* Symbols per block (= (1<<mm)-1) */
|
|
||||||
int *alpha_to; /* log lookup table */
|
|
||||||
int *index_of; /* Antilog lookup table */
|
|
||||||
int *genpoly; /* Generator polynomial */
|
|
||||||
unsigned int nroots; /* Number of generator roots = number of parity symbols */
|
|
||||||
unsigned int fcr; /* First consecutive root, index form */
|
|
||||||
unsigned int prim; /* Primitive element, index form */
|
|
||||||
unsigned int iprim; /* prim-th root of 1, index form */
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline int modnn(struct rs *rs,int x){
|
|
||||||
while (x >= rs->nn) {
|
|
||||||
x -= rs->nn;
|
|
||||||
x = (x >> rs->mm) + (x & rs->nn);
|
|
||||||
}
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
#define MODNN(x) modnn(rs,x)
|
|
||||||
|
|
||||||
#define MM (rs->mm)
|
|
||||||
#define NN (rs->nn)
|
|
||||||
#define ALPHA_TO (rs->alpha_to)
|
|
||||||
#define INDEX_OF (rs->index_of)
|
|
||||||
#define GENPOLY (rs->genpoly)
|
|
||||||
#define NROOTS (rs->nroots)
|
|
||||||
#define FCR (rs->fcr)
|
|
||||||
#define PRIM (rs->prim)
|
|
||||||
#define IPRIM (rs->iprim)
|
|
||||||
#define A0 (NN)
|
|
||||||
|
|
||||||
#define ENCODE_RS encode_rs_int
|
|
||||||
#define DECODE_RS decode_rs_int
|
|
||||||
#define INIT_RS init_rs_int
|
|
||||||
#define FREE_RS free_rs_int
|
|
||||||
|
|
||||||
void ENCODE_RS(void *p,DTYPE *data,DTYPE *parity);
|
|
||||||
int DECODE_RS(void *p,DTYPE *data,int *eras_pos,int no_eras, int calc_syn);
|
|
||||||
void *INIT_RS(unsigned int symsize,unsigned int gfpoly,unsigned int fcr,
|
|
||||||
unsigned int prim,unsigned int nroots);
|
|
||||||
void FREE_RS(void *p);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,16 +0,0 @@
|
|||||||
/* User include file for the Reed-Solomon codec
|
|
||||||
* Copyright 2002, Phil Karn KA9Q
|
|
||||||
* May be used under the terms of the GNU General Public License (GPL)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* General purpose RS codec, integer symbols */
|
|
||||||
void encode_rs_int(void *rs,int *data,int *parity);
|
|
||||||
int decode_rs_int(void *rs,int *data,int *eras_pos,int no_eras, int calc_syn);
|
|
||||||
void *init_rs_int(int symsize,int gfpoly,int fcr,
|
|
||||||
int prim,int nroots,int pad);
|
|
||||||
void free_rs_int(void *rs);
|
|
||||||
|
|
||||||
/* Tables to map from conventional->dual (Taltab) and
|
|
||||||
* dual->conventional (Tal1tab) bases
|
|
||||||
*/
|
|
||||||
extern unsigned char Taltab[],Tal1tab[];
|
|
@ -1,133 +0,0 @@
|
|||||||
/*
|
|
||||||
./jt65code "Hi there"
|
|
||||||
Message Decoded Err? Type
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
1. HI THERE HI THERE 6: Free text
|
|
||||||
|
|
||||||
Packed message, 6-bit symbols 25 57 1 8 29 22 61 14 46 15 56 28
|
|
||||||
|
|
||||||
Information-carrying channel symbols
|
|
||||||
34 27 12 48 28 59 12 38 25 47 21 40 46 9 12 24 36 7 4 15 49
|
|
||||||
50 6 49 56 2 19 15 7 59 22 7 5 14 20 3 29 56 2 9 17 14
|
|
||||||
45 26 43 31 17 10 50 31 2 25 57 1 8 29 22 61 14 46 15 56 28
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "rs.h"
|
|
||||||
#include "init_random_seed.h"
|
|
||||||
|
|
||||||
static void *rs;
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
int hi_there[]={25,57,1,8,29,22,61,14,46,15,56,28};
|
|
||||||
int data[12], revdat[12];
|
|
||||||
int parity[51];
|
|
||||||
int rxdat[63], errlocs[63];
|
|
||||||
int era_pos[51];
|
|
||||||
int i, numera, nerr, nn=63;
|
|
||||||
|
|
||||||
FILE *datfile;
|
|
||||||
//nsec,xlambda,maxe,nads,mrsym,mrprob,mr2sym,mr2prob
|
|
||||||
int nsec, maxe, nads;
|
|
||||||
float xlambda;
|
|
||||||
int mrsym[63],mrprob[63],mr2sym[63],mr2prob[63];
|
|
||||||
int nsec2,ncount,dat4[12];
|
|
||||||
|
|
||||||
init_random_seed();
|
|
||||||
|
|
||||||
datfile=fopen("kvasd.dat","rb");
|
|
||||||
if( !datfile ) {
|
|
||||||
printf("Unable to open kvasd.dat\n");
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
fread(&nsec,sizeof(int),1,datfile);
|
|
||||||
fread(&xlambda,sizeof(float),1,datfile);
|
|
||||||
fread(&maxe,sizeof(int),1,datfile);
|
|
||||||
fread(&nads,sizeof(int),1,datfile);
|
|
||||||
fread(&mrsym,sizeof(int),63,datfile);
|
|
||||||
fread(&mrprob,sizeof(int),63,datfile);
|
|
||||||
fread(&mr2sym,sizeof(int),63,datfile);
|
|
||||||
fread(&mr2prob,sizeof(int),63,datfile);
|
|
||||||
fread(&nsec2,sizeof(int),1,datfile);
|
|
||||||
fread(&ncount,sizeof(int),1,datfile);
|
|
||||||
fread(&dat4,sizeof(int),12,datfile);
|
|
||||||
fclose(datfile);
|
|
||||||
printf("%d %f %d %d \n",nsec,xlambda,maxe,nads);
|
|
||||||
for (i=0; i<63; i++) printf("%d ",mrsym[i]);
|
|
||||||
printf("\n");
|
|
||||||
// for (i=0; i<63; i++) printf("%d ",mrprob[i]);
|
|
||||||
// printf("\n");
|
|
||||||
// for (i=0; i<63; i++) printf("%d ",mr2sym[i]);
|
|
||||||
// printf("\n");
|
|
||||||
// for (i=0; i<63; i++) printf("%d ",mr2prob[i]);
|
|
||||||
// printf("\n");
|
|
||||||
// printf("%d %d \n",nsec2,ncount);
|
|
||||||
printf("kv decode: ");
|
|
||||||
for (i=0; i<12; i++) printf("%d ",dat4[i]);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialize the ka9q reed solomon encoder/decoder
|
|
||||||
unsigned int symsize=6, gfpoly=0x43, fcr=3, prim=1, nroots=51;
|
|
||||||
rs=init_rs_int(symsize, gfpoly, fcr, prim, nroots, 0);
|
|
||||||
|
|
||||||
// copy the 'hi there' message to the data vector
|
|
||||||
// memcpy(data,hi_there,sizeof(hi_there));
|
|
||||||
// memcpy(data,dat4,sizeof(dat4));
|
|
||||||
|
|
||||||
// printf("data symbols\n");
|
|
||||||
// for( i=0; i<12; i++) {
|
|
||||||
// revdat[i]=data[11-i];
|
|
||||||
// printf("%d ",data[i]);
|
|
||||||
// }
|
|
||||||
// printf("\n");
|
|
||||||
|
|
||||||
// encode_rs_int(rs,revdat,parity);
|
|
||||||
|
|
||||||
//set up the received symbol vector
|
|
||||||
// for( i=0; i<63; i++ ) {
|
|
||||||
// if( i < 12 ) rxdat[i]=revdat[i];
|
|
||||||
// if( i >=12 ) rxdat[i]=parity[i-12];
|
|
||||||
// }
|
|
||||||
|
|
||||||
/*
|
|
||||||
int errval, errloc;
|
|
||||||
int num_errors=0;
|
|
||||||
printf("num_errors = %d\n",num_errors);
|
|
||||||
for( i=0; i<num_errors; i++) {
|
|
||||||
do {
|
|
||||||
errval = rand() & nn;
|
|
||||||
} while(errval == 0); //generate random
|
|
||||||
|
|
||||||
do {
|
|
||||||
errloc = rand() % nn;
|
|
||||||
} while(errlocs[errloc]!=0);
|
|
||||||
|
|
||||||
errlocs[errloc] = errval;
|
|
||||||
rxdat[errloc] ^= errval;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
numera=0;
|
|
||||||
printf("channel symbols\n");
|
|
||||||
for( i=0; i<63; i++ ) {
|
|
||||||
rxdat[i]=mrsym[i];
|
|
||||||
printf("%d ",rxdat[i]);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
nerr=decode_rs_int(rs,rxdat,era_pos,numera);
|
|
||||||
|
|
||||||
printf("nerr %d\n",nerr);
|
|
||||||
|
|
||||||
printf("decoded data\n");
|
|
||||||
for(i=0; i<63; i++) printf("%d ",rxdat[i]);
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,338 +0,0 @@
|
|||||||
/*
|
|
||||||
sfrsd.c
|
|
||||||
|
|
||||||
A soft-decision decoder for the JT65 (63,12) Reed-Solomon code.
|
|
||||||
|
|
||||||
This decoding scheme is built around Phil Karn's Berlekamp-Massey
|
|
||||||
errors and erasures decoder. The approach is inspired by a number of
|
|
||||||
publications, including the stochastic Chase decoder described
|
|
||||||
in "Stochastic Chase Decoding of Reed-Solomon Codes", by Leroux et al.,
|
|
||||||
IEEE Communications Letters, Vol. 14, No. 9, September 2010 and
|
|
||||||
"Soft-Decision Decoding of Reed-Solomon Codes Using Successive Error-
|
|
||||||
and-Erasure Decoding," by Soo-Woong Lee and B. V. K. Vijaya Kumar.
|
|
||||||
|
|
||||||
Steve Franke K9AN, Urbana IL, September 2015
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "rs.h"
|
|
||||||
#include "init_random_seed.h"
|
|
||||||
|
|
||||||
static void *rs;
|
|
||||||
|
|
||||||
//***************************************************************************
|
|
||||||
void usage(void)
|
|
||||||
{
|
|
||||||
printf("Usage: sfrsd [options...] <path to kvasd.dat>\n");
|
|
||||||
printf(" input file should be in kvasd format\n");
|
|
||||||
printf("\n");
|
|
||||||
printf("Options:\n");
|
|
||||||
printf(" -n number of random erasure vectors to try\n");
|
|
||||||
printf(" -v verbose\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]){
|
|
||||||
|
|
||||||
extern char *optarg;
|
|
||||||
extern int optind;
|
|
||||||
|
|
||||||
int rxdat[63], rxprob[63], rxdat2[63], rxprob2[63];
|
|
||||||
int workdat[63], correct[63];
|
|
||||||
int era_pos[51];
|
|
||||||
int c, i, numera, nerr, nn=63, kk=12;
|
|
||||||
char *infile;
|
|
||||||
|
|
||||||
FILE *datfile, *logfile;
|
|
||||||
int nsec, maxe, nads;
|
|
||||||
float xlambda;
|
|
||||||
int mrsym[63],mrprob[63],mr2sym[63],mr2prob[63];
|
|
||||||
int nsec2,ncount,dat4[12],bestdat[12];
|
|
||||||
int ntrials=10000;
|
|
||||||
int verbose=0;
|
|
||||||
int nhard=0,nhard_min=32768,nsoft=0,nsoft_min=32768, ncandidates;
|
|
||||||
|
|
||||||
while ( (c = getopt(argc, argv, "n:qv")) !=-1 ) {
|
|
||||||
switch (c) {
|
|
||||||
case 'n':
|
|
||||||
ntrials=(int)strtof(optarg,NULL);
|
|
||||||
printf("ntrials set to %d\n",ntrials);
|
|
||||||
break;
|
|
||||||
case 'v':
|
|
||||||
verbose=1;
|
|
||||||
break;
|
|
||||||
case 'q': //accept (and ignore) -q option for WSJT10 compatibility
|
|
||||||
break;
|
|
||||||
case '?':
|
|
||||||
usage();
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( optind+1 > argc) {
|
|
||||||
// usage();
|
|
||||||
// exit(1);
|
|
||||||
infile="kvasd.dat";
|
|
||||||
} else {
|
|
||||||
infile=argv[optind];
|
|
||||||
}
|
|
||||||
|
|
||||||
logfile=fopen("/tmp/sfrsd.log","a");
|
|
||||||
if( !logfile ) {
|
|
||||||
printf("Unable to open sfrsd.log\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
datfile=fopen(infile,"rb");
|
|
||||||
if( !datfile ) {
|
|
||||||
printf("Unable to open kvasd.dat\n");
|
|
||||||
exit(1);
|
|
||||||
} else {
|
|
||||||
fread(&nsec,sizeof(int),1,datfile);
|
|
||||||
fread(&xlambda,sizeof(float),1,datfile);
|
|
||||||
fread(&maxe,sizeof(int),1,datfile);
|
|
||||||
fread(&nads,sizeof(int),1,datfile);
|
|
||||||
fread(&mrsym,sizeof(int),63,datfile);
|
|
||||||
fread(&mrprob,sizeof(int),63,datfile);
|
|
||||||
fread(&mr2sym,sizeof(int),63,datfile);
|
|
||||||
fread(&mr2prob,sizeof(int),63,datfile);
|
|
||||||
fread(&nsec2,sizeof(int),1,datfile);
|
|
||||||
fread(&ncount,sizeof(int),1,datfile);
|
|
||||||
// printf("ncount %d\n",ncount);
|
|
||||||
fread(&dat4,sizeof(int),12,datfile);
|
|
||||||
fclose(datfile);
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialize the ka9q reed solomon encoder/decoder
|
|
||||||
unsigned int symsize=6, gfpoly=0x43, fcr=3, prim=1, nroots=51;
|
|
||||||
rs=init_rs_int(symsize, gfpoly, fcr, prim, nroots, 0);
|
|
||||||
|
|
||||||
/* // debug
|
|
||||||
int revdat[12], parity[51], correct[63];
|
|
||||||
for (i=0; i<12; i++) {
|
|
||||||
revdat[i]=dat4[11-i];
|
|
||||||
printf("%d ",revdat[i]);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
encode_rs_int(rs,revdat,parity);
|
|
||||||
for (i=0; i<63; i++) {
|
|
||||||
if( i<12 ) {
|
|
||||||
correct[i]=revdat[i];
|
|
||||||
printf("%d ",parity[i]);
|
|
||||||
} else {
|
|
||||||
correct[i]=parity[i-12];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
*/
|
|
||||||
|
|
||||||
// reverse the received symbol vector for bm decoder
|
|
||||||
for (i=0; i<63; i++) {
|
|
||||||
rxdat[i]=mrsym[62-i];
|
|
||||||
rxprob[i]=mrprob[62-i];
|
|
||||||
rxdat2[i]=mr2sym[62-i];
|
|
||||||
rxprob2[i]=mr2prob[62-i];
|
|
||||||
}
|
|
||||||
|
|
||||||
// sort the mrsym probabilities to find the least reliable symbols
|
|
||||||
int k, pass, tmp, nsym=63;
|
|
||||||
int probs[63], indexes[63];
|
|
||||||
for (i=0; i<63; i++) {
|
|
||||||
indexes[i]=i;
|
|
||||||
probs[i]=rxprob[i]; // must un-comment sfrsd metrics in demod64a
|
|
||||||
|
|
||||||
}
|
|
||||||
for (pass = 1; pass <= nsym-1; pass++) {
|
|
||||||
for (k = 0; k < nsym - pass; k++) {
|
|
||||||
if( probs[k] < probs[k+1] ) {
|
|
||||||
tmp = probs[k];
|
|
||||||
probs[k] = probs[k+1];
|
|
||||||
probs[k+1] = tmp;
|
|
||||||
tmp = indexes[k];
|
|
||||||
indexes[k] = indexes[k+1];
|
|
||||||
indexes[k+1] = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// see if we can decode using BM HDD (and calculate the syndrome vector)
|
|
||||||
memset(era_pos,0,51*sizeof(int));
|
|
||||||
numera=0;
|
|
||||||
memcpy(workdat,rxdat,sizeof(rxdat));
|
|
||||||
nerr=decode_rs_int(rs,workdat,era_pos,numera,1);
|
|
||||||
if( nerr >= 0 ) {
|
|
||||||
fprintf(logfile," BM decode nerrors= %3d : ",nerr);
|
|
||||||
for(i=0; i<12; i++) printf("%2d ",workdat[11-i]);
|
|
||||||
fprintf(logfile,"\n");
|
|
||||||
fclose(logfile);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate random erasure-locator vectors and see if any of them
|
|
||||||
// decode. This will generate a list of potential codewords. The
|
|
||||||
// "soft" distance between each codeword and the received word is
|
|
||||||
// used to decide which codeword is "best".
|
|
||||||
//
|
|
||||||
|
|
||||||
init_random_seed();
|
|
||||||
|
|
||||||
float p_erase;
|
|
||||||
int thresh, nsum;
|
|
||||||
ncandidates=0;
|
|
||||||
|
|
||||||
|
|
||||||
for( k=0; k<ntrials; k++) {
|
|
||||||
memset(era_pos,0,51*sizeof(int));
|
|
||||||
memcpy(workdat,rxdat,sizeof(rxdat));
|
|
||||||
|
|
||||||
// mark a subset of the symbols as erasures
|
|
||||||
numera=0;
|
|
||||||
for (i=0; i<nn; i++) {
|
|
||||||
p_erase=0.0;
|
|
||||||
if( probs[62-i] >= 255 ) {
|
|
||||||
p_erase = 0.5;
|
|
||||||
} else if ( probs[62-i] >= 196 ) {
|
|
||||||
p_erase = 0.6;
|
|
||||||
} else if ( probs[62-i] >= 128 ) {
|
|
||||||
p_erase = 0.6;
|
|
||||||
} else if ( probs[62-i] >= 32 ) {
|
|
||||||
p_erase = 0.6;
|
|
||||||
} else {
|
|
||||||
p_erase = 0.8;
|
|
||||||
}
|
|
||||||
thresh = p_erase*100;
|
|
||||||
long int ir;
|
|
||||||
ir=rand();
|
|
||||||
if( ((ir % 100) < thresh ) && numera < 51 ) {
|
|
||||||
era_pos[numera]=indexes[62-i];
|
|
||||||
numera=numera+1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nerr=decode_rs_int(rs,workdat,era_pos,numera,0);
|
|
||||||
|
|
||||||
if( nerr >= 0 ) {
|
|
||||||
ncandidates=ncandidates+1;
|
|
||||||
for(i=0; i<12; i++) dat4[i]=workdat[11-i];
|
|
||||||
// fprintf(logfile,"loop1 decode nerr= %3d : ",nerr);
|
|
||||||
// for(i=0; i<12; i++) fprintf(logfile, "%2d ",dat4[i]);
|
|
||||||
// fprintf(logfile,"\n");
|
|
||||||
nhard=0;
|
|
||||||
nsoft=0;
|
|
||||||
nsum=0;
|
|
||||||
for (i=0; i<63; i++) {
|
|
||||||
nsum=nsum+rxprob[i];
|
|
||||||
if( workdat[i] != rxdat[i] ) {
|
|
||||||
nhard=nhard+1;
|
|
||||||
nsoft=nsoft+rxprob[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( nsum != 0 ) {
|
|
||||||
nsoft=63*nsoft/nsum;
|
|
||||||
if( (nsoft < nsoft_min) ) {
|
|
||||||
nsoft_min=nsoft;
|
|
||||||
nhard_min=nhard;
|
|
||||||
memcpy(bestdat,dat4,12*sizeof(int));
|
|
||||||
memcpy(correct,workdat,63*sizeof(int));
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
fprintf(logfile,"error - nsum %d nsoft %d nhard %d\n",nsum,nsoft,nhard);
|
|
||||||
}
|
|
||||||
// if( ncandidates >= 5000 ) {
|
|
||||||
if( ncandidates >= ntrials/2 ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(logfile,"%d candidates after stochastic loop\n",ncandidates);
|
|
||||||
|
|
||||||
// do Forney Generalized Minimum Distance pattern
|
|
||||||
for (k=0; k<25; k++) {
|
|
||||||
memset(era_pos,0,51*sizeof(int));
|
|
||||||
numera=2*k;
|
|
||||||
for (i=0; i<numera; i++) {
|
|
||||||
era_pos[i]=indexes[62-i];
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(workdat,rxdat,sizeof(rxdat));
|
|
||||||
nerr=decode_rs_int(rs,workdat,era_pos,numera,0);
|
|
||||||
|
|
||||||
if( nerr >= 0 ) {
|
|
||||||
ncandidates=ncandidates+1;
|
|
||||||
for(i=0; i<12; i++) dat4[i]=workdat[11-i];
|
|
||||||
// fprintf(logfile,"GMD decode nerr= %3d : ",nerr);
|
|
||||||
// for(i=0; i<12; i++) fprintf(logfile, "%2d ",dat4[i]);
|
|
||||||
// fprintf(logfile,"\n");
|
|
||||||
nhard=0;
|
|
||||||
nsoft=0;
|
|
||||||
nsum=0;
|
|
||||||
for (i=0; i<63; i++) {
|
|
||||||
nsum=nsum+rxprob[i];
|
|
||||||
if( workdat[i] != rxdat[i] ) {
|
|
||||||
nhard=nhard+1;
|
|
||||||
nsoft=nsoft+rxprob[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( nsum != 0 ) {
|
|
||||||
nsoft=63*nsoft/nsum;
|
|
||||||
if( (nsoft < nsoft_min) ) {
|
|
||||||
nsoft_min=nsoft;
|
|
||||||
nhard_min=nhard;
|
|
||||||
memcpy(bestdat,dat4,12*sizeof(int));
|
|
||||||
memcpy(correct,workdat,63*sizeof(int));
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
fprintf(logfile,"error - nsum %d nsoft %d nhard %d\n",nsum,nsoft,nhard);
|
|
||||||
}
|
|
||||||
// if( ncandidates >=5000 ) {
|
|
||||||
if( ncandidates >= ntrials/2 ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(logfile,"%d candidates after GMD\n",ncandidates);
|
|
||||||
|
|
||||||
if( (ncandidates >= 0) && (nsoft_min < 36) && (nhard_min < 44) ) {
|
|
||||||
for (i=0; i<63; i++) {
|
|
||||||
fprintf(logfile,"%3d %3d %3d %3d %3d %3d\n",i,correct[i],rxdat[i],rxprob[i],rxdat2[i],rxprob2[i]);
|
|
||||||
// fprintf(logfile,"%3d %3d %3d %3d %3d\n",i,workdat[i],rxdat[i],rxprob[i],rxdat2[i],rxprob2[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(logfile,"**** ncandidates %d nhard %d nsoft %d nsum %d\n",ncandidates,nhard_min,nsoft_min,nsum);
|
|
||||||
} else {
|
|
||||||
nhard_min=-1;
|
|
||||||
memset(bestdat,0,12*sizeof(int));
|
|
||||||
}
|
|
||||||
datfile=fopen(infile,"wb");
|
|
||||||
if( !datfile ) {
|
|
||||||
printf("Unable to open kvasd.dat\n");
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
fwrite(&nsec,sizeof(int),1,datfile);
|
|
||||||
fwrite(&xlambda,sizeof(float),1,datfile);
|
|
||||||
fwrite(&maxe,sizeof(int),1,datfile);
|
|
||||||
fwrite(&nads,sizeof(int),1,datfile);
|
|
||||||
fwrite(&mrsym,sizeof(int),63,datfile);
|
|
||||||
fwrite(&mrprob,sizeof(int),63,datfile);
|
|
||||||
fwrite(&mr2sym,sizeof(int),63,datfile);
|
|
||||||
fwrite(&mr2prob,sizeof(int),63,datfile);
|
|
||||||
fwrite(&nsec2,sizeof(int),1,datfile);
|
|
||||||
fwrite(&nhard_min,sizeof(int),1,datfile);
|
|
||||||
fwrite(&bestdat,sizeof(int),12,datfile);
|
|
||||||
fclose(datfile);
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(logfile,"exiting sfrsd\n");
|
|
||||||
fflush(logfile);
|
|
||||||
fclose(logfile);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user