multi decode: rs41, dfm

pull/18/head
Zilog80 2019-08-22 20:22:59 +02:00
rodzic af57f03752
commit bd9831b64c
7 zmienionych plików z 5270 dodań i 0 usunięć

Plik diff jest za duży Load Diff

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

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