kopia lustrzana https://github.com/rs1729/RS
multi decode: rs41, dfm
rodzic
af57f03752
commit
bd9831b64c
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,97 @@
|
|||
|
||||
/*
|
||||
* BCH / Reed-Solomon
|
||||
* encoder()
|
||||
* decoder() (Euklid. Alg.)
|
||||
*
|
||||
*
|
||||
* author: zilog80
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef INCLUDESTATIC
|
||||
#define INCSTAT static
|
||||
#else
|
||||
typedef unsigned char ui8_t;
|
||||
typedef unsigned int ui32_t;
|
||||
#define INCSTAT
|
||||
#endif
|
||||
|
||||
|
||||
#define MAX_DEG 254 // max N-1
|
||||
|
||||
|
||||
typedef struct {
|
||||
ui32_t f;
|
||||
ui32_t ord;
|
||||
ui8_t alpha;
|
||||
ui8_t exp_a[256];
|
||||
ui8_t log_a[256];
|
||||
} GF_t;
|
||||
|
||||
typedef struct {
|
||||
ui8_t N;
|
||||
ui8_t t;
|
||||
ui8_t R; // RS: R=2t, BCH: R<=mt
|
||||
ui8_t K; // K=N-R
|
||||
ui8_t b;
|
||||
ui8_t p; ui8_t ip; // p*ip = 1 mod N
|
||||
ui8_t g[MAX_DEG+1]; // ohne g[] eventuell als init_return
|
||||
GF_t GF;
|
||||
} RS_t;
|
||||
|
||||
|
||||
static GF_t GF256RS = { f : 0x11D, // RS-GF(2^8): X^8 + X^4 + X^3 + X^2 + 1 : 0x11D
|
||||
ord : 256, // 2^8
|
||||
alpha: 0x02, // generator: alpha = X
|
||||
exp_a: {0},
|
||||
log_a: {0} };
|
||||
|
||||
static GF_t GF256RSccsds = { f : 0x187, // RS-GF(2^8): X^8 + X^7 + X^2 + X + 1 : 0x187
|
||||
ord : 256, // 2^8
|
||||
alpha: 0x02, // generator: alpha = X
|
||||
exp_a: {0},
|
||||
log_a: {0} };
|
||||
|
||||
static GF_t GF64BCH = { f : 0x43, // BCH-GF(2^6): X^6 + X + 1 : 0x43
|
||||
ord : 64, // 2^6
|
||||
alpha: 0x02, // generator: alpha = X
|
||||
exp_a: {0},
|
||||
log_a: {0} };
|
||||
|
||||
static GF_t GF16RS = { f : 0x13, // RS-GF(2^4): X^4 + X + 1 : 0x13
|
||||
ord : 16, // 2^4
|
||||
alpha: 0x02, // generator: alpha = X
|
||||
exp_a: {0},
|
||||
log_a: {0} };
|
||||
|
||||
static GF_t GF256AES = { f : 0x11B, // AES-GF(2^8): X^8 + X^4 + X^3 + X + 1 : 0x11B
|
||||
ord : 256, // 2^8
|
||||
alpha: 0x03, // generator: alpha = X+1
|
||||
exp_a: {0},
|
||||
log_a: {0} };
|
||||
|
||||
|
||||
static RS_t RS256 = { 255, 12, 24, 231, 0, 1, 1, {0}, {0} };
|
||||
static RS_t RS256ccsds = { 255, 16, 32, 223, 112, 11, 116, {0}, {0} };
|
||||
static RS_t BCH64 = { 63, 2, 12, 51, 1, 1, 1, {0}, {0} };
|
||||
|
||||
// static RS_t RS16_0 = { 15, 3, 6, 9, 0, 1, 1, {0}, {0} };
|
||||
static RS_t RS16ccsds = { 15, 2, 4, 11, 6, 1, 1, {0}, {0} };
|
||||
|
||||
|
||||
#ifndef INCLUDESTATIC
|
||||
|
||||
int rs_init_RS255(RS_t *RS);
|
||||
int rs_init_RS255ccsds(RS_t *RS);
|
||||
int rs_init_RS15ccsds(RS_t *RS);
|
||||
int rs_init_BCH64(RS_t *RS);
|
||||
|
||||
int rs_encode(RS_t *RS, ui8_t cw[]);
|
||||
int rs_decode(RS_t *RS, ui8_t cw[], ui8_t *err_pos, ui8_t *err_val);
|
||||
int rs_decode_ErrEra(RS_t *RS, ui8_t cw[], int nera, ui8_t era_pos[], ui8_t *err_pos, ui8_t *err_val);
|
||||
int rs_decode_bch_gf2t2(RS_t *RS, ui8_t cw[], ui8_t *err_pos, ui8_t *err_val);
|
||||
|
||||
#endif
|
||||
|
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,165 @@
|
|||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <complex.h>
|
||||
#include <pthread.h>
|
||||
|
||||
typedef unsigned char ui8_t;
|
||||
typedef unsigned short ui16_t;
|
||||
typedef unsigned int ui32_t;
|
||||
typedef char i8_t;
|
||||
typedef short i16_t;
|
||||
typedef int i32_t;
|
||||
|
||||
|
||||
#define MAX_FQ 5
|
||||
static int blk_sz = 32; // const
|
||||
|
||||
|
||||
typedef struct {
|
||||
int tn;
|
||||
int tn_bit;
|
||||
pthread_t tid;
|
||||
pthread_mutex_t *mutex;
|
||||
pthread_cond_t *cond;
|
||||
//pthread_rwlock_t *lock;
|
||||
int max_fq;
|
||||
double xlt_fq;
|
||||
float complex *blk;
|
||||
} thd_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
int sr; // sample_rate
|
||||
int LOG2N;
|
||||
int N;
|
||||
int N2;
|
||||
float *xn;
|
||||
float complex *ew;
|
||||
float complex *Fm;
|
||||
float complex *X;
|
||||
float complex *Z;
|
||||
float complex *cx;
|
||||
float complex *win; // float real
|
||||
} dft_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
FILE *fp;
|
||||
//
|
||||
int sr; // sample_rate
|
||||
int bps; // bits/sample
|
||||
int nch; // channels
|
||||
int ch; // select channel
|
||||
//
|
||||
int symlen;
|
||||
int symhd;
|
||||
float sps; // samples per symbol
|
||||
float _spb; // samples per bit
|
||||
float br; // baud rate
|
||||
//
|
||||
ui32_t sample_in;
|
||||
ui32_t sample_out;
|
||||
ui32_t delay;
|
||||
ui32_t sc;
|
||||
int buffered;
|
||||
int L;
|
||||
int M;
|
||||
int K;
|
||||
float *match;
|
||||
float *bufs;
|
||||
float dc_ofs;
|
||||
float dc;
|
||||
float mv;
|
||||
ui32_t mv_pos;
|
||||
//
|
||||
int N_norm;
|
||||
int Nvar;
|
||||
float xsum;
|
||||
float qsum;
|
||||
float *xs;
|
||||
float *qs;
|
||||
|
||||
// IQ-data
|
||||
int opt_iq;
|
||||
int N_IQBUF;
|
||||
float complex *raw_iqbuf;
|
||||
float complex *rot_iqbuf;
|
||||
float complex F1sum;
|
||||
float complex F2sum;
|
||||
|
||||
//
|
||||
char *rawbits;
|
||||
char *hdr;
|
||||
int hdrlen;
|
||||
|
||||
//
|
||||
float BT; // bw/time (ISI)
|
||||
float h; // modulation index
|
||||
|
||||
// DFT
|
||||
dft_t DFT;
|
||||
|
||||
double df;
|
||||
int len_sq;
|
||||
|
||||
ui32_t sample_posframe;
|
||||
ui32_t sample_posnoise;
|
||||
|
||||
double V_noise;
|
||||
double V_signal;
|
||||
double SNRdB;
|
||||
|
||||
int sr_base;
|
||||
int decM;
|
||||
int dectaps;
|
||||
int blk_cnt;
|
||||
ui32_t sample_dec;
|
||||
float complex *decXbuffer;
|
||||
float complex *decMbuf;
|
||||
float complex *ex; // exp_lut
|
||||
thd_t thd;
|
||||
} dsp_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
int sr; // sample_rate
|
||||
int bps; // bits_sample bits/sample
|
||||
int nch; // channels
|
||||
int sel_ch; // select wav channel
|
||||
//
|
||||
int sr_base;
|
||||
int decM;
|
||||
int dectaps;
|
||||
FILE *fp;
|
||||
} pcm_t;
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
pcm_t pcm;
|
||||
thd_t thd;
|
||||
} thargs_t;
|
||||
|
||||
|
||||
|
||||
float read_wav_header(pcm_t *);
|
||||
int f32buf_sample(dsp_t *, int);
|
||||
int read_slbit(dsp_t *, int*, int, int, int, float, int);
|
||||
|
||||
int get_fqofs_rs41(dsp_t *, ui32_t, float *, float *);
|
||||
float get_bufvar(dsp_t *, int);
|
||||
float get_bufmu(dsp_t *, int);
|
||||
|
||||
int init_buffers(dsp_t *);
|
||||
int free_buffers(dsp_t *);
|
||||
|
||||
ui32_t get_sample(dsp_t *);
|
||||
|
||||
int find_header(dsp_t *, float, int, int, int);
|
||||
|
||||
int decimate_init(int taps, float f);
|
||||
int decimate_free(void);
|
||||
|
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,206 @@
|
|||
|
||||
/*
|
||||
gcc -O2 -c demod_base.c
|
||||
gcc -O2 -c bch_ecc_mod.c
|
||||
gcc -O2 -c rs41base.c
|
||||
gcc -O2 -c dfm09base.c
|
||||
gcc -O2 rs_multi.c demod_base.o bch_ecc_mod.o rs41base.o dfm09base.o -lm -pthread
|
||||
|
||||
./a.out --rs41 <fq0> [--dfm <fq1> ..] baseband_IQ.wav
|
||||
-0.5 < fq < 0.5
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef CYGWIN
|
||||
#include <fcntl.h> // cygwin: _setmode()
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#include "demod_base.h"
|
||||
|
||||
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
|
||||
//static pthread_rwlock_t lock = PTHREAD_RWLOCK_INITIALIZER;
|
||||
|
||||
static float complex *block_decMB;
|
||||
|
||||
int rbf1; // extern in demod_base.c
|
||||
|
||||
|
||||
void *thd_rs41(void *);
|
||||
void *thd_dfm09(void *);
|
||||
|
||||
|
||||
#define IF_SAMPLE_RATE 48000
|
||||
|
||||
static int pcm_dec_init(pcm_t *p) {
|
||||
|
||||
int IF_sr = IF_SAMPLE_RATE; // designated IF sample rate
|
||||
int decM = 1; // decimate M:1
|
||||
int sr_base = p->sr;
|
||||
float f_lp; // dec_lowpass: lowpass_bandwidth/2
|
||||
float tbw; // dec_lowpass: transition_bandwidth/Hz
|
||||
int taps; // dec_lowpass: taps
|
||||
|
||||
if (IF_sr > sr_base) IF_sr = sr_base;
|
||||
if (IF_sr < sr_base) {
|
||||
while (sr_base % IF_sr) IF_sr += 1;
|
||||
decM = sr_base / IF_sr;
|
||||
}
|
||||
|
||||
f_lp = (IF_sr+20e3)/(4.0*sr_base);
|
||||
tbw = (IF_sr-20e3)/*/2.0*/; if (tbw < 0) tbw = 8e3;
|
||||
taps = sr_base*4.0/tbw; if (taps%2==0) taps++;
|
||||
|
||||
taps = decimate_init(taps, f_lp);
|
||||
|
||||
p->dectaps = taps;
|
||||
p->sr_base = sr_base;
|
||||
p->sr = IF_sr; // sr_base/decM
|
||||
p->decM = decM;
|
||||
|
||||
|
||||
fprintf(stderr, "IF: %d\n", IF_sr);
|
||||
fprintf(stderr, "dec: %d\n", decM);
|
||||
|
||||
fprintf(stderr, "taps: %d\n", taps);
|
||||
fprintf(stderr, "transBW: %.4f = %.1f Hz\n", tbw/sr_base, tbw);
|
||||
fprintf(stderr, "f: +/-%.4f = +/-%.1f Hz\n", f_lp, f_lp*sr_base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
FILE *fp;
|
||||
int wavloaded = 0;
|
||||
int k;
|
||||
int xlt_cnt = 0;
|
||||
double base_fqs[MAX_FQ];
|
||||
void *rstype[MAX_FQ];
|
||||
int option_pcmraw = 0;
|
||||
|
||||
#ifdef CYGWIN
|
||||
_setmode(fileno(stdin), _O_BINARY); // _fileno(stdin)
|
||||
#endif
|
||||
setbuf(stdout, NULL);
|
||||
|
||||
|
||||
pcm_t pcm = {0};
|
||||
|
||||
for (k = 0; k < MAX_FQ; k++) base_fqs[k] = 0.0;
|
||||
|
||||
++argv;
|
||||
while ((*argv) && (!wavloaded)) {
|
||||
if (strcmp(*argv, "--rs41") == 0) {
|
||||
double fq = 0.0;
|
||||
++argv;
|
||||
if (*argv) fq = atof(*argv);
|
||||
else return -1;
|
||||
if (fq < -0.5) fq = -0.5;
|
||||
if (fq > 0.5) fq = 0.5;
|
||||
if (xlt_cnt < MAX_FQ) {
|
||||
base_fqs[xlt_cnt] = fq;
|
||||
rstype[xlt_cnt] = thd_rs41;
|
||||
xlt_cnt++;
|
||||
}
|
||||
}
|
||||
else if (strcmp(*argv, "--dfm") == 0) {
|
||||
double fq = 0.0;
|
||||
++argv;
|
||||
if (*argv) fq = atof(*argv);
|
||||
else return -1;
|
||||
if (fq < -0.5) fq = -0.5;
|
||||
if (fq > 0.5) fq = 0.5;
|
||||
if (xlt_cnt < MAX_FQ) {
|
||||
base_fqs[xlt_cnt] = fq;
|
||||
rstype[xlt_cnt] = thd_dfm09;
|
||||
xlt_cnt++;
|
||||
}
|
||||
}
|
||||
else if (strcmp(*argv, "-") == 0) {
|
||||
int sample_rate = 0, bits_sample = 0, channels = 0;
|
||||
++argv;
|
||||
if (*argv) sample_rate = atoi(*argv); else return -1;
|
||||
++argv;
|
||||
if (*argv) bits_sample = atoi(*argv); else return -1;
|
||||
channels = 2;
|
||||
if (sample_rate < 1 || (bits_sample != 8 && bits_sample != 16 /*&&bits_sample!=32*/)) {
|
||||
fprintf(stderr, "- <sr> <bs>\n");
|
||||
return -1;
|
||||
}
|
||||
pcm.sr = sample_rate;
|
||||
pcm.bps = bits_sample;
|
||||
pcm.nch = channels;
|
||||
option_pcmraw = 1;
|
||||
}
|
||||
else {
|
||||
fp = fopen(*argv, "rb");
|
||||
if (fp == NULL) {
|
||||
fprintf(stderr, "%s konnte nicht geoeffnet werden\n", *argv);
|
||||
return -1;
|
||||
}
|
||||
wavloaded = 1;
|
||||
}
|
||||
++argv;
|
||||
}
|
||||
if (!wavloaded) fp = stdin;
|
||||
|
||||
pcm.fp = fp;
|
||||
if (option_pcmraw == 0) {
|
||||
k = read_wav_header( &pcm );
|
||||
if ( k < 0 ) {
|
||||
fclose(fp);
|
||||
fprintf(stderr, "error: wav header\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (pcm.nch < 2) {
|
||||
fprintf(stderr, "error: iq channels < 2\n");
|
||||
return -50;
|
||||
}
|
||||
|
||||
pcm_dec_init( &pcm );
|
||||
|
||||
|
||||
block_decMB = calloc(pcm.decM*blk_sz+1, sizeof(float complex)); if (block_decMB == NULL) return -1;
|
||||
|
||||
|
||||
thargs_t tharg[xlt_cnt];
|
||||
|
||||
for (k = 0; k < xlt_cnt; k++) {
|
||||
tharg[k].thd.tn = k;
|
||||
tharg[k].thd.tn_bit = (1<<k);
|
||||
tharg[k].thd.mutex = &mutex;
|
||||
tharg[k].thd.cond = &cond;
|
||||
//tharg[k].thd.lock = &lock;
|
||||
tharg[k].thd.blk = block_decMB;
|
||||
tharg[k].thd.max_fq = xlt_cnt;
|
||||
tharg[k].thd.xlt_fq = -base_fqs[k]; // S(t)*exp(-f*2pi*I*t): fq baseband -> IF (rotate from and decimate)
|
||||
tharg[k].pcm = pcm;
|
||||
|
||||
rbf1 |= tharg[k].thd.tn_bit;
|
||||
}
|
||||
|
||||
for (k = 0; k < xlt_cnt; k++) {
|
||||
pthread_create(&tharg[k].thd.tid, NULL, rstype[k], &tharg[k]);
|
||||
}
|
||||
|
||||
|
||||
for (k = 0; k < xlt_cnt; k++) {
|
||||
pthread_join(tharg[k].thd.tid, NULL);
|
||||
}
|
||||
|
||||
|
||||
if (block_decMB) { free(block_decMB); block_decMB = NULL; }
|
||||
decimate_free();
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Ładowanie…
Reference in New Issue