From 23592d046bfd44324072140a7509a965e9f763ac Mon Sep 17 00:00:00 2001 From: Mark Jessop Date: Sat, 21 Sep 2019 18:02:13 +0930 Subject: [PATCH] Rebase to latest upstream decoders. --- auto_rx/build.sh | 10 ++-- demod/mod/demod_mod.c | 54 ++++++++++++++---- demod/mod/demod_mod.h | 8 +++ demod/mod/dfm09mod.c | 16 +++++- demod/mod/lms6Xmod.c | 32 ++++++++--- demod/mod/lms6mod.c | 84 ++++++++++++++++++++++++++-- demod/mod/m10mod.c | 117 ++++++++++++++++++++++----------------- demod/mod/meisei100mod.c | 4 ++ demod/mod/rs41mod.c | 32 +++++++++-- 9 files changed, 273 insertions(+), 84 deletions(-) mode change 100755 => 100644 demod/mod/meisei100mod.c diff --git a/auto_rx/build.sh b/auto_rx/build.sh index eb239f1..65ea2a4 100755 --- a/auto_rx/build.sh +++ b/auto_rx/build.sh @@ -10,11 +10,11 @@ echo "Building dft_detect" cd ../scan/ gcc dft_detect.c -lm -o dft_detect -DNOC34C50 -echo "Building RS92/RS41/DFM Demodulators" -cd ../demod/ -gcc -c demod.c -gcc -c demod_dft.c -gcc dfm09dm_dft.c demod_dft.o -lm -o dfm09ecc +echo "Building RS92/RS41/DFM/LMS6/iMS Demodulators" +#cd ../demod/ +#gcc -c demod.c +#gcc -c demod_dft.c +#gcc dfm09dm_dft.c demod_dft.o -lm -o dfm09ecc # New demodulators cd ../demod/mod/ diff --git a/demod/mod/demod_mod.c b/demod/mod/demod_mod.c index 136d9f8..9123e46 100644 --- a/demod/mod/demod_mod.c +++ b/demod/mod/demod_mod.c @@ -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; } diff --git a/demod/mod/demod_mod.h b/demod/mod/demod_mod.h index bd3cf8d..6e457f2 100644 --- a/demod/mod/demod_mod.h +++ b/demod/mod/demod_mod.h @@ -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; diff --git a/demod/mod/dfm09mod.c b/demod/mod/dfm09mod.c index 6ce6899..d179703 100644 --- a/demod/mod/dfm09mod.c +++ b/demod/mod/dfm09mod.c @@ -452,7 +452,7 @@ static int conf_out(gpx_t *gpx, ui8_t *conf_bits, int ec) { gpx->snc.max_ch = conf_id; } - if (conf_id > 4 && conf_id > gpx->snc.max_ch && ec == 0) { // mind. 5 Kanaele + if (conf_id > 5 && conf_id > gpx->snc.max_ch && ec == 0) { // mind. 6 Kanaele if (bits2val(conf_bits+4, 4) == 0xC) { // 0xsCaaaab gpx->snc.max_ch = conf_id; // reset? } @@ -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; @@ -940,6 +941,17 @@ int main(int argc, char **argv) { else if (strcmp(*argv, "--iq0") == 0) { option_iq = 1; } // differential/FM-demod else if (strcmp(*argv, "--iq2") == 0) { option_iq = 2; } else if (strcmp(*argv, "--iq3") == 0) { option_iq = 3; } // iq2==iq3 + else if (strcmp(*argv, "--IQ") == 0) { // fq baseband -> IF (rotate from and decimate) + double fq = 0.0; // --IQ , -0.5 < fq < 0.5 + ++argv; + if (*argv) fq = atof(*argv); + else return -1; + if (fq < -0.5) fq = -0.5; + if (fq > 0.5) fq = 0.5; + 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"); @@ -1000,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"); diff --git a/demod/mod/lms6Xmod.c b/demod/mod/lms6Xmod.c index 00a91e4..204c22f 100644 --- a/demod/mod/lms6Xmod.c +++ b/demod/mod/lms6Xmod.c @@ -146,6 +146,7 @@ typedef struct { int typ; float frm_rate; int auto_detect; + int reset_dsp; option_t option; RS_t RS; VIT_t *vit; @@ -840,7 +841,7 @@ static void proc_frame(gpx_t *gpx, int len) { if (gpx->sf6 < 4) { frmsync_X(gpx, block_bytes); // pos(frm_syncX[]) < 46: different baud not significant if (gpx->sfX == 4) { - if (gpx->auto_detect) gpx->typ = 10; + if (gpx->auto_detect) { gpx->typ = 10; gpx->reset_dsp = 1; } break; } } @@ -881,7 +882,7 @@ static void proc_frame(gpx_t *gpx, int len) { for (j = 0; j < 4; j++) gpx->sf6 += (block_bytes[blk_pos+j] == frm_sync6[j]); if (gpx->sf6 == 4) { gpx->frm_pos = 0; - if (gpx->auto_detect) gpx->typ = 6; + if (gpx->auto_detect) { gpx->typ = 6; gpx->reset_dsp = 1; } break; } blk_pos++; @@ -891,7 +892,7 @@ static void proc_frame(gpx_t *gpx, int len) { // LMS6: frm_rate = 4800.0 * FRAME_LEN/BLOCK_LEN = 4800*300/260 = 5538 // LMSX: delta_mp = 4797.8 (longer timesync-frames possible) if (gpx->frm_rate > 5000.0 || gpx->frm_rate < 4000.0) { // lms6-blocklen = 260/300 sr, sync wird ueberlesen ... - if (gpx->auto_detect) gpx->typ = 6; + if (gpx->auto_detect) { gpx->typ = 6; gpx->reset_dsp = 1; } } } else @@ -923,6 +924,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 @@ -968,7 +970,7 @@ int main(int argc, char **argv) { gpx_t _gpx = {0}; gpx_t *gpx = &_gpx; gpx->auto_detect = 1; - + gpx->reset_dsp = 0; #ifdef CYGWIN _setmode(fileno(stdin), _O_BINARY); // _setmode(_fileno(stdin), _O_BINARY); @@ -1015,9 +1017,6 @@ int main(int argc, char **argv) { else if ( (strcmp(*argv, "-i") == 0) || (strcmp(*argv, "--invert") == 0) ) { option_inv = 1; // nicht noetig } - else if ( (strcmp(*argv, "--dc") == 0) ) { - option_dc = 1; - } else if ( (strcmp(*argv, "--ch2") == 0) ) { sel_wavch = 1; } // right channel (default: 0=left) else if ( (strcmp(*argv, "--ths") == 0) ) { ++argv; @@ -1048,6 +1047,8 @@ 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) { gpx->option.jsn = 1; gpx->option.ecc = 1; @@ -1108,7 +1109,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); @@ -1205,12 +1208,18 @@ int main(int argc, char **argv) { pos = BLOCKSTART; header_found = 0; - if ( gpx->auto_detect ) { + if ( gpx->auto_detect && gpx->reset_dsp ) { if (gpx->typ == 10) { // set lmsX rawbitblock_len = RAWBITBLOCK_LEN;//_X; dsp.br = (float)BAUD_RATEX; dsp.sps = (float)dsp.sr/dsp.br; + + // reset F1sum, F2sum + for (k = 0; k < dsp.N_IQBUF; k++) dsp.rot_iqbuf[k] = 0; + dsp.F1sum = 0; + dsp.F2sum = 0; + bitofs = bitofsX + shift; } if (gpx->typ == 6) { @@ -1218,8 +1227,15 @@ int main(int argc, char **argv) { rawbitblock_len = RAWBITBLOCK_LEN_6; dsp.br = (float)BAUD_RATE6; dsp.sps = (float)dsp.sr/dsp.br; + + // reset F1sum, F2sum + for (k = 0; k < dsp.N_IQBUF; k++) dsp.rot_iqbuf[k] = 0; + dsp.F1sum = 0; + dsp.F2sum = 0; + bitofs = bitofs6 + shift; } + gpx->reset_dsp = 0; } } diff --git a/demod/mod/lms6mod.c b/demod/mod/lms6mod.c index 67e0f0c..a0d11df 100644 --- a/demod/mod/lms6mod.c +++ b/demod/mod/lms6mod.c @@ -126,7 +126,7 @@ typedef struct { typedef struct { int frnr; int sn; - int week; int gpstow; + int week; int gpstow; int gpssec; int jahr; int monat; int tag; int wday; int std; int min; float sek; @@ -143,6 +143,37 @@ typedef struct { } gpx_t; +/* ------------------------------------------------------------------------------------ */ +static int gpstow_start = -1; +static double time_elapsed_sec = 0.0; + +/* + * Convert GPS Week and Seconds to Modified Julian Day. + * - Adapted from sci.astro FAQ. + * - Ignores UTC leap seconds. + */ +// in : week, gpssec +// out: jahr, monat, tag +static void Gps2Date(gpx_t *gpx) { + long GpsDays, Mjd; + long _J, _C, _Y, _M; + + GpsDays = gpx->week * 7 + (gpx->gpssec / 86400); + Mjd = 44244 + GpsDays; + + _J = Mjd + 2468570; + _C = 4 * _J / 146097; + _J = _J - (146097 * _C + 3) / 4; + _Y = 4000 * (_J + 1) / 1461001; + _J = _J - 1461 * _Y / 4 + 31; + _M = 80 * _J / 2447; + gpx->tag = _J - 2447 * _M / 80; + _J = _M / 11; + gpx->monat = _M + 2 - (12 * _J); + gpx->jahr = 100 * (_C - 49) + _Y + _J; +} +/* ------------------------------------------------------------------------------------ */ + // ------------------------------------------------------------------------ static ui8_t vit_code[N]; @@ -419,7 +450,7 @@ static int get_FrameNb(gpx_t *gpx) { //char weekday[7][3] = { "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"}; static char weekday[7][4] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; -static int get_GPStime(gpx_t *gpx) { +static int get_GPStime(gpx_t *gpx, int crc_err) { int i; unsigned byte; ui8_t gpstime_bytes[4]; @@ -436,10 +467,15 @@ static int get_GPStime(gpx_t *gpx) { gpstime |= gpstime_bytes[i] << (8*(3-i)); } + if (gpstow_start < 0 && !crc_err) { + gpstow_start = gpstime; // time elapsed since start-up? + if (gpx->week > 0 && gpstime/1000.0 < time_elapsed_sec) gpx->week += 1; + } gpx->gpstow = gpstime; ms = gpstime % 1000; gpstime /= 1000; + gpx->gpssec = gpstime; day = gpstime / (24 * 3600); gpstime %= (24*3600); @@ -603,8 +639,16 @@ static void print_frame(gpx_t *gpx, int crc_err, int len) { get_FrameNb(gpx); printf(" (%7d) ", gpx->sn); printf(" [%5d] ", gpx->frnr); - err = get_GPStime(gpx); + err = get_GPStime(gpx, crc_err); if (!err) printf("%s ", weekday[gpx->wday]); + if (gpx->week > 0) { + if (gpx->gpstow < gpstow_start && !crc_err) { + gpx->week += 1; // week roll-over + gpstow_start = gpx->gpstow; + } + Gps2Date(gpx); + fprintf(stdout, "%04d-%02d-%02d ", gpx->jahr, gpx->monat, gpx->tag); + } printf("%02d:%02d:%06.3f ", gpx->std, gpx->min, gpx->sek); // falls Rundung auf 60s: Ueberlauf get_GPSlat(gpx); @@ -628,8 +672,12 @@ static void print_frame(gpx_t *gpx, int crc_err, int len) { // Print JSON output required by auto_rx. if (crc_err==0) { // CRC-OK // UTC oder GPS? - printf("{ \"frame\": %d, \"id\": \"LMS6-%d\", \"datetime\": \"%02d:%02d:%06.3fZ\", \"lat\": %.5f, \"lon\": %.5f, \"alt\": %.5f, \"vel_h\": %.5f, \"heading\": %.5f, \"vel_v\": %.5f }\n", - gpx->frnr, gpx->sn, gpx->std, gpx->min, gpx->sek, gpx->lat, gpx->lon, gpx->alt, gpx->vH, gpx->vD, gpx->vV ); + printf("{ \"frame\": %d, \"id\": \"LMS6-%d\", \"datetime\": \"", gpx->frnr, gpx->sn ); + //if (gpx->week > 0) printf("%04d-%02d-%02dT", gpx->jahr, gpx->monat, gpx->tag ); + printf("%02d:%02d:%06.3fZ\", \"lat\": %.5f, \"lon\": %.5f, \"alt\": %.5f, \"vel_h\": %.5f, \"heading\": %.5f, \"vel_v\": %.5f", + gpx->std, gpx->min, gpx->sek, gpx->lat, gpx->lon, gpx->alt, gpx->vH, gpx->vD, gpx->vV ); + printf(", \"gpstow\": %d", gpx->gpstow ); + printf(" }\n"); printf("\n"); } } @@ -746,9 +794,11 @@ 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 + int gpsweek = 0; FILE *fp = NULL; char *fpname = NULL; @@ -818,6 +868,14 @@ int main(int argc, char **argv) { } else if (strcmp(*argv, "--ecc" ) == 0) { gpx->option.ecc = 1; } // RS-ECC else if (strcmp(*argv, "--vit" ) == 0) { gpx->option.vit = 1; } // viterbi + else if ( (strcmp(*argv, "--gpsweek") == 0) ) { + ++argv; + if (*argv) { + gpsweek = atoi(*argv); + if (gpsweek < 1024 || gpsweek > 3072) gpsweek = 0; + } + else return -1; + } else if ( (strcmp(*argv, "-i") == 0) || (strcmp(*argv, "--invert") == 0) ) { option_inv = 1; // nicht noetig } @@ -844,6 +902,17 @@ int main(int argc, char **argv) { else if (strcmp(*argv, "--iq0") == 0) { option_iq = 1; } // differential/FM-demod else if (strcmp(*argv, "--iq2") == 0) { option_iq = 2; } else if (strcmp(*argv, "--iq3") == 0) { option_iq = 3; } // iq2==iq3 + else if (strcmp(*argv, "--IQ") == 0) { // fq baseband -> IF (rotate from and decimate) + double fq = 0.0; // --IQ , -0.5 < fq < 0.5 + ++argv; + if (*argv) fq = atof(*argv); + else return -1; + if (fq < -0.5) fq = -0.5; + if (fq > 0.5) fq = 0.5; + 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; @@ -872,6 +941,8 @@ int main(int argc, char **argv) { gpx->option.inv = option_inv; // irrelevant + gpx->week = gpsweek; + if (option_iq) sel_wavch = 0; pcm.sel_ch = sel_wavch; @@ -900,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); @@ -963,6 +1036,7 @@ int main(int argc, char **argv) { gpx->blk_rawbits[pos] = '\0'; + time_elapsed_sec = dsp.sample_in / (double)dsp.sr; proc_frame(gpx, pos); if (pos < RAWBITBLOCK_LEN) break; diff --git a/demod/mod/m10mod.c b/demod/mod/m10mod.c index 320aafd..6e50c0b 100644 --- a/demod/mod/m10mod.c +++ b/demod/mod/m10mod.c @@ -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; @@ -974,6 +975,17 @@ int main(int argc, char **argv) { else if (strcmp(*argv, "--iq0") == 0) { option_iq = 1; } // differential/FM-demod else if (strcmp(*argv, "--iq2") == 0) { option_iq = 2; } else if (strcmp(*argv, "--iq3") == 0) { option_iq = 3; } // iq2==iq3 + else if (strcmp(*argv, "--IQ") == 0) { // fq baseband -> IF (rotate from and decimate) + double fq = 0.0; // --IQ , -0.5 < fq < 0.5 + ++argv; + if (*argv) fq = atof(*argv); + else return -1; + if (fq < -0.5) fq = -0.5; + if (fq > 0.5) fq = 0.5; + 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"); @@ -996,6 +1008,7 @@ int main(int argc, char **argv) { // init gpx + pcm.sel_ch = sel_wavch; k = read_wav_header(&pcm, fp); if ( k < 0 ) { @@ -1023,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 = 24e3; 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); @@ -1040,63 +1055,63 @@ int main(int argc, char **argv) { bitofs += shift; - while ( 1 ) - { + while ( 1 ) + { - header_found = find_header(&dsp, thres, 2, bitofs, option_dc); - _mv = dsp.mv; + header_found = find_header(&dsp, thres, 2, bitofs, option_dc); + _mv = dsp.mv; - if (header_found == EOF) break; + if (header_found == EOF) break; - // mv == correlation score - if (_mv*(0.5-gpx.option.inv) < 0) { - gpx.option.inv ^= 0x1; // M10: irrelevant + // mv == correlation score + if (_mv*(0.5-gpx.option.inv) < 0) { + gpx.option.inv ^= 0x1; // M10: irrelevant + } + + + if (header_found) { + + bitpos = 0; + pos = 0; + pos /= 2; + bit0 = '0'; // oder: _mv[j] > 0 + + while ( pos < BITFRAME_LEN+BITAUX_LEN ) { + + if (option_iq >= 2) { + float bl = -1; + if (option_iq > 2) bl = 4.0; + bitQ = read_slbit(&dsp, &bit, 0/*gpx.option.inv*/, bitofs, bitpos, bl, 0); + } + else { + bitQ = read_slbit(&dsp, &bit, 0/*gpx.option.inv*/, bitofs, bitpos, -1, spike); // symlen=2 + } + + if ( bitQ == EOF ) { break; } + + gpx.frame_bits[pos] = 0x31 ^ (bit0 ^ bit); + pos++; + bit0 = bit; + bitpos += 1; + } + gpx.frame_bits[pos] = '\0'; + print_frame(&gpx, pos); + if (pos < BITFRAME_LEN) break; + + header_found = 0; + + // bis Ende der Sekunde vorspulen; allerdings Doppel-Frame alle 10 sek + if (gpx.option.vbs < 3) { // && (regulare frame) // print_frame-return? + while ( bitpos < 5*BITFRAME_LEN ) { + bitQ = read_slbit(&dsp, &bit, 0/*gpx.option.inv*/, bitofs, bitpos, -1, spike); // symlen=2 + if ( bitQ == EOF) break; + bitpos++; + } } - - if (header_found) { - - bitpos = 0; - pos = 0; - pos /= 2; - bit0 = '0'; // oder: _mv[j] > 0 - - while ( pos < BITFRAME_LEN+BITAUX_LEN ) { - - if (option_iq >= 2) { - float bl = -1; - if (option_iq > 2) bl = 4.0; - bitQ = read_slbit(&dsp, &bit, 0/*gpx.option.inv*/, bitofs, bitpos, bl, 0); - } - else { - bitQ = read_slbit(&dsp, &bit, 0/*gpx.option.inv*/, bitofs, bitpos, -1, spike); // symlen=2 - } - - if ( bitQ == EOF ) { break; } - - gpx.frame_bits[pos] = 0x31 ^ (bit0 ^ bit); - pos++; - bit0 = bit; - bitpos += 1; - } - gpx.frame_bits[pos] = '\0'; - print_frame(&gpx, pos); - if (pos < BITFRAME_LEN) break; - - header_found = 0; - - // bis Ende der Sekunde vorspulen; allerdings Doppel-Frame alle 10 sek - if (gpx.option.vbs < 3) { // && (regulare frame) // print_frame-return? - while ( bitpos < 5*BITFRAME_LEN ) { - bitQ = read_slbit(&dsp, &bit, 0/*gpx.option.inv*/, bitofs, bitpos, -1, spike); // symlen=2 - if ( bitQ == EOF) break; - bitpos++; - } - } - - pos = 0; - } + pos = 0; } + } free_buffers(&dsp); diff --git a/demod/mod/meisei100mod.c b/demod/mod/meisei100mod.c old mode 100755 new mode 100644 index d742a98..9310047 --- a/demod/mod/meisei100mod.c +++ b/demod/mod/meisei100mod.c @@ -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); diff --git a/demod/mod/rs41mod.c b/demod/mod/rs41mod.c index 11b258a..30e70d9 100644 --- a/demod/mod/rs41mod.c +++ b/demod/mod/rs41mod.c @@ -518,7 +518,7 @@ static float get_Tc(gpx_t *gpx, ui32_t f, ui32_t f1, ui32_t f2) { } // rel.hum., capacitor -// (data:) ftp://ftp-cdc.dwd.de/pub/CDC/observations_germany/radiosondes/ +// (data:) ftp://ftp-cdc.dwd.de/climate_environment/CDC/observations_germany/radiosondes/ // (diffAlt: Ellipsoid-Geoid) static float get_RH(gpx_t *gpx, ui32_t f, ui32_t f1, ui32_t f2, float T) { float a0 = 7.5; // empirical @@ -955,6 +955,16 @@ static int get_Calconf(gpx_t *gpx, int out, int ofs) { } if (out && gpx->option.vbs) fprintf(stdout, ": %s ", sondetyp); strcpy(gpx->rstyp, sondetyp); + if (out && gpx->option.vbs == 3) { // Stationsdruck QFE + float qfe1 = 0.0, qfe2 = 0.0; + memcpy(&qfe1, gpx->frame+pos_CalData+1, 4); + memcpy(&qfe2, gpx->frame+pos_CalData+5, 4); + if (qfe1 > 0.0 || qfe2 > 0.0) { + fprintf(stdout, " "); + if (qfe1 > 0.0) fprintf(stdout, "QFE1:%.1fhPa ", qfe1); + if (qfe2 > 0.0) fprintf(stdout, "QFE2:%.1fhPa ", qfe2); + } + } } } @@ -1088,8 +1098,8 @@ static int prn_gpspos(gpx_t *gpx) { fprintf(stdout, " lat: %.5f ", gpx->lat); fprintf(stdout, " lon: %.5f ", gpx->lon); fprintf(stdout, " alt: %.2f ", gpx->alt); - fprintf(stdout," vH: %4.1f D: %5.1f vV: %3.1f ", gpx->vH, gpx->vD, gpx->vV); - if (gpx->option.vbs == 3) fprintf(stdout," sats: %02d ", gpx->numSV); + fprintf(stdout, " vH: %4.1f D: %5.1f vV: %3.1f ", gpx->vH, gpx->vD, gpx->vV); + if (gpx->option.vbs == 3) fprintf(stdout, " sats: %02d ", gpx->numSV); return 0; } @@ -1374,7 +1384,7 @@ static int print_position(gpx_t *gpx, int ec) { if (!err1) prn_gpstime(gpx); if (!err3) prn_gpspos(gpx); - if (!err0) prn_ptu(gpx); + if (!err0 && gpx->option.ptu) prn_ptu(gpx); if (0 && !err) get_Calconf(gpx, out, 0); // only if ecc-OK output = ((gpx->crc & out_mask) != out_mask); @@ -1523,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; @@ -1624,6 +1635,17 @@ int main(int argc, char *argv[]) { else if (strcmp(*argv, "--iq0") == 0) { option_iq = 1; } // differential/FM-demod else if (strcmp(*argv, "--iq2") == 0) { option_iq = 2; } else if (strcmp(*argv, "--iq3") == 0) { option_iq = 3; } // iq2==iq3 + else if (strcmp(*argv, "--IQ") == 0) { // fq baseband -> IF (rotate from and decimate) + double fq = 0.0; // --IQ , -0.5 < fq < 0.5 + ++argv; + if (*argv) fq = atof(*argv); + else return -1; + if (fq < -0.5) fq = -0.5; + if (fq > 0.5) fq = 0.5; + 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 @@ -1683,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);