pull/18/head
Zilog80 2019-09-12 23:41:46 +02:00
rodzic f6d1705d13
commit de2c25cc1e
15 zmienionych plików z 141 dodań i 21 usunięć

Wyświetl plik

@ -404,6 +404,7 @@ static int get_SNR(dsp_t *dsp) {
}
// decimate lowpass
static float *ws_dec;
static double sinc(double x) {
@ -413,10 +414,11 @@ static double sinc(double x) {
return y;
}
static int decimate_init(int taps, float f) {
static int lowpass_init(float f, int taps, float **pws) {
double *h, *w;
double norm = 0;
int n;
float *ws = NULL;
if (taps % 2 == 0) taps++; // odd/symmetric
@ -424,17 +426,18 @@ static int decimate_init(int taps, float f) {
h = (double*)calloc( taps+1, sizeof(double)); if (h == NULL) return -1;
w = (double*)calloc( taps+1, sizeof(double)); if (w == NULL) return -1;
ws_dec = (float*)calloc( taps+1, sizeof(float)); if (ws_dec == NULL) return -1;
ws = (float*)calloc( taps+1, sizeof(float)); if (ws == NULL) return -1;
for (n = 0; n < taps; n++) {
w[n] = 7938/18608.0 - 9240/18608.0*cos(2*M_PI*n/(taps-1)) + 1430/18608.0*cos(4*M_PI*n/(taps-1)); // Blackmann
h[n] = 2*f*sinc(2*f*(n-(taps-1)/2));
ws_dec[n] = w[n]*h[n];
norm += ws_dec[n];
ws[n] = w[n]*h[n];
norm += ws[n]; // 1-norm
}
for (n = 0; n < taps; n++) {
ws_dec[n] /= norm;
ws[n] /= norm; // 1-norm
}
*pws = ws;
free(h); h = NULL;
free(w); w = NULL;
@ -442,15 +445,16 @@ static int decimate_init(int taps, float f) {
return taps;
}
static float complex lowpass(float complex buffer[], ui32_t sample, ui32_t M) {
static float complex lowpass(float complex buffer[], ui32_t sample, ui32_t taps, float *ws) {
ui32_t n;
double complex w = 0;
for (n = 0; n < M; n++) {
w += buffer[(sample+n+1)%M]*ws_dec[M-1-n];
for (n = 0; n < taps; n++) {
w += buffer[(sample+n+1)%taps]*ws[taps-1-n];
}
return (float complex)w;
}
int f32buf_sample(dsp_t *dsp, int inv) {
float s = 0.0;
float xneu, xalt;
@ -471,10 +475,17 @@ int f32buf_sample(dsp_t *dsp, int inv) {
dsp->sample_dec += 1;
if (dsp->sample_dec == s_reset) dsp->sample_dec = 0;
}
z = lowpass(dsp->decXbuffer, dsp->sample_dec, dsp->dectaps);
z = lowpass(dsp->decXbuffer, dsp->sample_dec, dsp->dectaps, ws_dec);
}
else if ( f32read_csample(dsp, &z) == EOF ) return EOF;
// IF-lowpass
if (dsp->opt_lp) {
dsp->lpIQ_buf[dsp->sample_in % dsp->lpIQtaps] = z;
z = lowpass(dsp->lpIQ_buf, dsp->sample_in, dsp->lpIQtaps, dsp->ws_lpIQ);
}
dsp->raw_iqbuf[dsp->sample_in % dsp->N_IQBUF] = z;
//z *= cexp(-t*2*M_PI*dsp->df*I);
@ -798,7 +809,7 @@ int init_buffers(dsp_t *dsp) {
t_bw /= sr_base;
taps = 4.0/t_bw; if (taps%2==0) taps++;
taps = decimate_init(taps, f_lp);
taps = lowpass_init(f_lp, taps, &ws_dec); // decimate lowpass
if (taps < 0) return -1;
dsp->dectaps = (ui32_t)taps;
@ -854,6 +865,23 @@ int init_buffers(dsp_t *dsp) {
if (dsp->decMbuf == NULL) return -1;
}
if (dsp->opt_iq && dsp->opt_lp)
{
float f_lp; // lowpass_bw
int taps; // lowpass taps: 4*sr/transition_bw
// IF lowpass
taps = 4*dsp->sr/4e3; if (taps%2==0) taps++; // 4kHz transition
f_lp = dsp->lpIQ_bw/(float)dsp->sr/2.0;
taps = lowpass_init(f_lp, taps, &dsp->ws_lpIQ); if (taps < 0) return -1;
dsp->lpIQtaps = taps;
dsp->lpIQ_buf = calloc( dsp->lpIQtaps+3, sizeof(float complex));
if (dsp->lpIQ_buf == NULL) return -1;
// dc-offset: if not centered, (aquisition) lowpass bw = lpIQ_bw + 4kHz
}
L = dsp->hdrlen * dsp->sps + 0.5;
M = 3*L;
@ -996,6 +1024,12 @@ int free_buffers(dsp_t *dsp) {
if (ws_dec) { free(ws_dec); ws_dec = NULL; }
}
if (dsp->opt_iq && dsp->opt_lp)
{
if (dsp->ws_lpIQ) { free(dsp->ws_lpIQ); dsp->ws_lpIQ = NULL; }
if (dsp->lpIQ_buf) { free(dsp->lpIQ_buf); dsp->lpIQ_buf = NULL; }
}
return 0;
}

Wyświetl plik

@ -92,6 +92,7 @@ typedef struct {
double V_signal;
double SNRdB;
// decimate
int decM;
ui32_t sr_base;
ui32_t dectaps;
@ -102,6 +103,13 @@ typedef struct {
float complex *ex; // exp_lut
double xlt_fq;
// IF: lowpass
int opt_lp;
int lpIQ_bw;
int lpIQtaps; // ui32_t
float *ws_lpIQ;
float complex *lpIQ_buf;
} dsp_t;

Wyświetl plik

@ -836,6 +836,7 @@ int main(int argc, char **argv) {
int option_dist = 0; // continuous pcks 0..8
int option_auto = 0;
int option_iq = 0;
int option_lp = 0;
int option_bin = 0;
int option_json = 0; // JSON blob output (for auto_rx)
int wavloaded = 0;
@ -950,6 +951,7 @@ int main(int argc, char **argv) {
dsp.xlt_fq = -fq; // S(t) -> S(t)*exp(-f*2pi*I*t)
option_iq = 5;
}
else if (strcmp(*argv, "--lp") == 0) { option_lp = 1; } // IQ lowpass
else if (strcmp(*argv, "--dbg") == 0) { gpx.option.dbg = 1; }
else {
fp = fopen(*argv, "rb");
@ -1010,7 +1012,9 @@ int main(int argc, char **argv) {
dsp.hdrlen = strlen(dfm_rawheader);
dsp.BT = 0.5; // bw/time (ISI) // 0.3..0.5
dsp.h = 1.8; // 2.4 modulation index abzgl. BT
dsp.lpIQ_bw = 12e3;
dsp.opt_iq = option_iq;
dsp.opt_lp = option_lp;
if ( dsp.sps < 8 ) {
fprintf(stderr, "note: sample rate low\n");

Wyświetl plik

@ -923,6 +923,7 @@ int main(int argc, char **argv) {
int option_inv = 0; // invertiert Signal
int option_iq = 0;
int option_lp = 0;
int option_dc = 0;
int wavloaded = 0;
int sel_wavch = 0; // audio channel: left
@ -1048,6 +1049,7 @@ int main(int argc, char **argv) {
dsp.xlt_fq = -fq; // S(t) -> S(t)*exp(-f*2pi*I*t)
option_iq = 5;
}
else if (strcmp(*argv, "--lp") == 0) { option_lp = 1; } // IQ lowpass
else if (strcmp(*argv, "--json") == 0) {
gpx->option.jsn = 1;
gpx->option.ecc = 1;
@ -1108,7 +1110,9 @@ int main(int argc, char **argv) {
dsp.hdrlen = strlen(rawheader);
dsp.BT = 1.2; // bw/time (ISI) // 1.0..2.0 // BT(lmsX) < BT(lms6) ? -> init_buffers()
dsp.h = 0.9; // 0.95 modulation index
dsp.lpIQ_bw = 8e3;
dsp.opt_iq = option_iq;
dsp.opt_lp = option_lp;
if ( dsp.sps < 8 ) {
fprintf(stderr, "note: sample rate low (%.1f sps)\n", dsp.sps);

Wyświetl plik

@ -794,6 +794,7 @@ int main(int argc, char **argv) {
int option_inv = 0; // invertiert Signal
int option_iq = 0;
int option_lp = 0;
int option_dc = 0;
int wavloaded = 0;
int sel_wavch = 0; // audio channel: left
@ -911,6 +912,7 @@ int main(int argc, char **argv) {
dsp.xlt_fq = -fq; // S(t) -> S(t)*exp(-f*2pi*I*t)
option_iq = 5;
}
else if (strcmp(*argv, "--lp") == 0) { option_lp = 1; } // IQ lowpass
else if (strcmp(*argv, "--json") == 0) {
gpx->option.jsn = 1;
gpx->option.ecc = 1;
@ -969,7 +971,9 @@ int main(int argc, char **argv) {
dsp.hdrlen = strlen(rawheader);
dsp.BT = 1.5; // bw/time (ISI) // 1.0..2.0
dsp.h = 0.9; // 1.0 modulation index
dsp.lpIQ_bw = 8e3;
dsp.opt_iq = option_iq;
dsp.opt_lp = option_lp;
if ( dsp.sps < 8 ) {
fprintf(stderr, "note: sample rate low (%.1f sps)\n", dsp.sps);

Wyświetl plik

@ -882,6 +882,7 @@ int main(int argc, char **argv) {
int option_ptu = 0;
int option_dc = 0;
int option_iq = 0;
int option_lp = 0;
int wavloaded = 0;
int sel_wavch = 0; // audio channel: left
int spike = 0;
@ -984,6 +985,7 @@ int main(int argc, char **argv) {
dsp.xlt_fq = -fq; // S(t) -> S(t)*exp(-f*2pi*I*t)
option_iq = 5;
}
else if (strcmp(*argv, "--lp") == 0) { option_lp = 1; } // IQ lowpass
else if (strcmp(*argv, "--json") == 0) { gpx.option.jsn = 1; }
else {
fp = fopen(*argv, "rb");
@ -1034,7 +1036,9 @@ int main(int argc, char **argv) {
dsp.hdrlen = strlen(rawheader);
dsp.BT = 1.8; // bw/time (ISI) // 1.0..2.0
dsp.h = 0.9; // 1.2 modulation index
dsp.lpIQ_bw = 20e3;
dsp.opt_iq = option_iq;
dsp.opt_lp = option_lp;
if ( dsp.sps < 8 ) {
fprintf(stderr, "note: sample rate low (%.1f sps)\n", dsp.sps);

Wyświetl plik

@ -210,6 +210,7 @@ int main(int argc, char **argv) {
option_jsn = 0; // JSON output (auto_rx)
int wavloaded = 0;
int option_iq = 0;
int option_lp = 0;
int option_dc = 0;
int sel_wavch = 0;
@ -334,6 +335,7 @@ int main(int argc, char **argv) {
dsp.xlt_fq = -fq; // S(t) -> S(t)*exp(-f*2pi*I*t)
option_iq = 5;
}
else if (strcmp(*argv, "--lp") == 0) { option_lp = 1; } // IQ lowpass
// else if ( (strcmp(*argv, "--dc") == 0) ) { option_dc = 1; }
else if (strcmp(*argv, "--json") == 0) {
option_jsn = 1;
@ -380,7 +382,9 @@ int main(int argc, char **argv) {
dsp.hdrlen = strlen(rawheader);
dsp.BT = 1.2; // bw/time (ISI) // 1.0..2.0
dsp.h = 2.4; // 2.8
dsp.lpIQ_bw = 16e3;
dsp.opt_iq = option_iq;
dsp.opt_lp = option_lp;
if ( dsp.sps < 8 ) {
fprintf(stderr, "note: sample rate low (%.1f sps)\n", dsp.sps);

Wyświetl plik

@ -1533,6 +1533,7 @@ int main(int argc, char *argv[]) {
//int option_inv = 0; // invertiert Signal
int option_iq = 0;
int option_lp = 0;
int option_ofs = 0;
int option_bin = 0;
int wavloaded = 0;
@ -1644,6 +1645,7 @@ int main(int argc, char *argv[]) {
dsp.xlt_fq = -fq; // S(t) -> S(t)*exp(-f*2pi*I*t)
option_iq = 5;
}
else if (strcmp(*argv, "--lp") == 0) { option_lp = 1; } // IQ lowpass
else if (strcmp(*argv, "--ofs") == 0) { option_ofs = 1; }
else if (strcmp(*argv, "--rawhex") == 0) { rawhex = 2; } // raw hex input
else if (strcmp(*argv, "--xorhex") == 0) { rawhex = 2; xorhex = 1; } // raw xor input
@ -1703,7 +1705,9 @@ int main(int argc, char *argv[]) {
dsp.hdrlen = strlen(rs41_header);
dsp.BT = 0.5; // bw/time (ISI) // 0.3..0.5
dsp.h = 0.6; //0.7; // 0.7..0.8? modulation index abzgl. BT
dsp.lpIQ_bw = 8e3;
dsp.opt_iq = option_iq;
dsp.opt_lp = option_lp;
if ( dsp.sps < 8 ) {
fprintf(stderr, "note: sample rate low (%.1f sps)\n", dsp.sps);

Wyświetl plik

@ -481,6 +481,7 @@ static int get_SNR(dsp_t *dsp) {
}
// decimate lowpass
static float *ws_dec;
static double sinc(double x) {
@ -490,10 +491,11 @@ static double sinc(double x) {
return y;
}
int decimate_init(int taps, float f) {
static int lowpass_init(float f, int taps, float **pws) {
double *h, *w;
double norm = 0;
int n;
float *ws = NULL;
if (taps % 2 == 0) taps++; // odd/symmetric
@ -501,17 +503,18 @@ int decimate_init(int taps, float f) {
h = (double*)calloc( taps+1, sizeof(double)); if (h == NULL) return -1;
w = (double*)calloc( taps+1, sizeof(double)); if (w == NULL) return -1;
ws_dec = (float*)calloc( taps+1, sizeof(float)); if (ws_dec == NULL) return -1;
ws = (float*)calloc( taps+1, sizeof(float)); if (ws == NULL) return -1;
for (n = 0; n < taps; n++) {
w[n] = 7938/18608.0 - 9240/18608.0*cos(2*M_PI*n/(taps-1)) + 1430/18608.0*cos(4*M_PI*n/(taps-1)); // Blackmann
h[n] = 2*f*sinc(2*f*(n-(taps-1)/2));
ws_dec[n] = w[n]*h[n];
norm += ws_dec[n];
ws[n] = w[n]*h[n];
norm += ws[n]; // 1-norm
}
for (n = 0; n < taps; n++) {
ws_dec[n] /= norm;
ws[n] /= norm; // 1-norm
}
*pws = ws;
free(h); h = NULL;
free(w); w = NULL;
@ -519,6 +522,10 @@ int decimate_init(int taps, float f) {
return taps;
}
int decimate_init(float f, int taps) {
return lowpass_init(f, taps, &ws_dec);
}
int decimate_free() {
if (ws_dec) { free(ws_dec); ws_dec = NULL; }
@ -527,11 +534,11 @@ int decimate_free() {
}
static float complex lowpass(float complex buffer[], ui32_t sample, ui32_t M) {
static float complex lowpass(float complex buffer[], ui32_t sample, ui32_t taps, float *ws) {
ui32_t n;
double complex w = 0;
for (n = 0; n < M; n++) {
w += buffer[(sample+n+1)%M]*ws_dec[M-1-n];
for (n = 0; n < taps; n++) {
w += buffer[(sample+n+1)%taps]*ws[taps-1-n];
}
return (float complex)w;
}
@ -556,10 +563,16 @@ int f32buf_sample(dsp_t *dsp, int inv) {
dsp->sample_dec += 1;
if (dsp->sample_dec == s_reset) dsp->sample_dec = 0;
}
z = lowpass(dsp->decXbuffer, dsp->sample_dec, dsp->dectaps);
z = lowpass(dsp->decXbuffer, dsp->sample_dec, dsp->dectaps, ws_dec);
}
else if ( f32read_csample(dsp, &z) == EOF ) return EOF;
// IF-lowpass
if (dsp->opt_lp) {
dsp->lpIQ_buf[dsp->sample_in % dsp->lpIQtaps] = z;
z = lowpass(dsp->lpIQ_buf, dsp->sample_in, dsp->lpIQtaps, dsp->ws_lpIQ);
}
dsp->raw_iqbuf[dsp->sample_in % dsp->N_IQBUF] = z;
//z *= cexp(-t*2*M_PI*dsp->df*I);
@ -905,6 +918,23 @@ int init_buffers(dsp_t *dsp) {
if (dsp->decMbuf == NULL) return -1;
}
if (dsp->opt_iq && dsp->opt_lp)
{
float f_lp; // lowpass_bw
int taps; // lowpass taps: 4*sr/transition_bw
// IF lowpass
taps = 4*dsp->sr/4e3; if (taps%2==0) taps++; // 4kHz transition
f_lp = dsp->lpIQ_bw/(float)dsp->sr/2.0;
taps = lowpass_init(f_lp, taps, &dsp->ws_lpIQ); if (taps < 0) return -1;
dsp->lpIQtaps = taps;
dsp->lpIQ_buf = calloc( dsp->lpIQtaps+3, sizeof(float complex));
if (dsp->lpIQ_buf == NULL) return -1;
// dc-offset: if not centered, (aquisition) lowpass bw = lpIQ_bw + 4kHz
}
L = dsp->hdrlen * dsp->sps + 0.5;
M = 3*L;
@ -1047,6 +1077,13 @@ int free_buffers(dsp_t *dsp) {
if (dsp->ex) { free(dsp->ex); dsp->ex = NULL; }
}
// IF lowpass
if (dsp->opt_iq && dsp->opt_lp)
{
if (dsp->ws_lpIQ) { free(dsp->ws_lpIQ); dsp->ws_lpIQ = NULL; }
if (dsp->lpIQ_buf) { free(dsp->lpIQ_buf); dsp->lpIQ_buf = NULL; }
}
return 0;
}

Wyświetl plik

@ -112,6 +112,7 @@ typedef struct {
double V_signal;
double SNRdB;
// decimate
int decM;
int blk_cnt;
ui32_t sr_base;
@ -121,6 +122,14 @@ typedef struct {
float complex *decXbuffer;
float complex *decMbuf;
float complex *ex; // exp_lut
// IF: lowpass
int opt_lp;
int lpIQ_bw;
int lpIQtaps; // ui32_t
float *ws_lpIQ;
float complex *lpIQ_buf;
thd_t thd;
} dsp_t;
@ -162,6 +171,6 @@ ui32_t get_sample(dsp_t *);
int find_header(dsp_t *, float, int, int, int);
int decimate_init(int taps, float f);
int decimate_init(float f, int taps);
int decimate_free(void);

Wyświetl plik

@ -863,7 +863,9 @@ void *thd_dfm09(void *targs) {
dsp.hdrlen = strlen(dfm_rawheader);
dsp.BT = 0.5; // bw/time (ISI) // 0.3..0.5
dsp.h = 1.8; // 2.4 modulation index abzgl. BT
dsp.lpIQ_bw = 12e3;
dsp.opt_iq = option_iq;
dsp.opt_lp = 1;
if ( dsp.sps < 8 ) {
fprintf(stderr, "note: sample rate low\n");

Wyświetl plik

@ -1026,7 +1026,9 @@ void *thd_lms6X(void *targs) { // pcm_t *pcm, double xlt_fq
dsp.hdrlen = strlen(rawheader);
dsp.BT = 1.2; // bw/time (ISI) // 1.0..2.0 // BT(lmsX) < BT(lms6) ? -> init_buffers()
dsp.h = 0.9; // 0.95 modulation index
dsp.lpIQ_bw = 8e3;
dsp.opt_iq = option_iq;
dsp.opt_lp = 1;
if ( dsp.sps < 8 ) {
fprintf(stderr, "note: sample rate low (%.1f sps)\n", dsp.sps);

Wyświetl plik

@ -957,7 +957,9 @@ void *thd_m10(void *targs) { // pcm_t *pcm, double xlt_fq
dsp.hdrlen = strlen(rawheader);
dsp.BT = 1.8; // bw/time (ISI) // 1.0..2.0
dsp.h = 0.9; // 1.2 modulation index
dsp.lpIQ_bw = 20e3;
dsp.opt_iq = option_iq;
dsp.opt_lp = 1;
if ( dsp.sps < 8 ) {
fprintf(stderr, "note: sample rate low (%.1f sps)\n", dsp.sps);

Wyświetl plik

@ -1550,7 +1550,9 @@ void *thd_rs41(void *targs) { // pcm_t *pcm, double xlt_fq
dsp.hdrlen = strlen(rs41_header);
dsp.BT = 0.5; // bw/time (ISI) // 0.3..0.5
dsp.h = 0.6; //0.7; // 0.7..0.8? modulation index abzgl. BT
dsp.lpIQ_bw = 8e3;
dsp.opt_iq = option_iq;
dsp.opt_lp = 1;
if ( dsp.sps < 8 ) {
fprintf(stderr, "note: sample rate low (%.1f sps)\n", dsp.sps);

Wyświetl plik

@ -59,7 +59,7 @@ static int pcm_dec_init(pcm_t *p) {
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);
taps = decimate_init(f_lp, taps);
if (taps < 0) return -1;
p->dectaps = (ui32_t)taps;