diff --git a/demod/mod/Makefile b/demod/mod/Makefile index 3657002..2961a69 100644 --- a/demod/mod/Makefile +++ b/demod/mod/Makefile @@ -3,7 +3,7 @@ CC = gcc COPTS = -O3 .PHONY: all -all: rs41mod rs92mod lms6Xmod meisei100mod dfm09mod m10mod mXXmod imet54mod +all: rs41mod rs92mod lms6Xmod meisei100mod dfm09mod m10mod mXXmod imet54mod mp3h1mod rs41mod: rs41mod.c demod_mod.o bch_ecc_mod.o $(CC) $(COPTS) -o rs41mod rs41mod.c demod_mod.o bch_ecc_mod.o -lm @@ -29,6 +29,9 @@ meisei100mod: meisei100mod.c demod_mod.o bch_ecc_mod.o rs92mod: rs92mod.c demod_mod.o bch_ecc_mod.o nav_gps_vel.c $(CC) $(COPTS) -o rs92mod rs92mod.c demod_mod.o bch_ecc_mod.o -lm +mp3h1mod: mp3h1mod.c demod_mod.o + $(CC) $(COPTS) -o mp3h1mod mp3h1mod.c demod_mod.o -lm + demod_mod.o: demod_mod.c demod_mod.h $(CC) -Ofast -c demod_mod.c @@ -37,7 +40,7 @@ bch_ecc_mod.o: bch_ecc_mod.c bch_ecc_mod.h .PHONY: clean clean: - rm -f rs41mod rs92mod lms6Xmod meisei100mod dfm09mod m10mod mXXmod imet54mod + rm -f rs41mod rs92mod lms6Xmod meisei100mod dfm09mod m10mod mXXmod imet54mod mp3h1mod rm -f demod_mod.o rm -f bch_ecc_mod.o diff --git a/demod/mod/README.md b/demod/mod/README.md index 9c74762..e59d417 100644 --- a/demod/mod/README.md +++ b/demod/mod/README.md @@ -6,7 +6,7 @@ alternative decoders using cross-correlation for better header-synchronization #### Files * `demod_mod.c`, `demod_mod.h`,
- `rs41mod.c`, `rs92mod.c`, `dfm09mod.c`, `m10mod.c`, `lms6mod.c`, `lms6Xmod.c`, `meisei100mod.c`, `imet54mod.c`,
+ `rs41mod.c`, `rs92mod.c`, `dfm09mod.c`, `m10mod.c`, `lms6mod.c`, `lms6Xmod.c`, `meisei100mod.c`, `imet54mod.c`, `mp3h1mod.c`,
`bch_ecc_mod.c`, `bch_ecc_mod.h` #### Compile @@ -18,7 +18,8 @@ alternative decoders using cross-correlation for better header-synchronization `gcc imet54mod.c demod_mod.o -lm -o imet54mod`
`gcc lms6Xmod.c demod_mod.o bch_ecc_mod.o -lm -o lms6Xmod`
`gcc meisei100mod.c demod_mod.o bch_ecc_mod.o -lm -o meisei100mod`
- `gcc rs92mod.c demod_mod.o bch_ecc_mod.o -lm -o rs92mod` (needs `RS/rs92/nav_gps_vel.c`) + `gcc rs92mod.c demod_mod.o bch_ecc_mod.o -lm -o rs92mod` (needs `RS/rs92/nav_gps_vel.c`)
+ `gcc mp3h1mod.c demod_mod.o -lm -o mp3h1mod` #### Usage/Examples `./rs41mod --ecc2 -vx --ptu `
@@ -30,9 +31,9 @@ alternative decoders using cross-correlation for better header-synchronization If the IQ data is downsampled and centered (IF band), use
`./rs41mod --iq2 `
or with lowpass filter
- `./rs41mod --iq2 --lp `
+ `./rs41mod --iq2 --lpIQ `
For baseband IQ data, use - `./rs41mod --IQ --lp `
+ `./rs41mod --IQ --lpIQ `
where `` is the relative frequency in `-0.5 .. 0.5`; e.g. if the receiver is tuned to 403MHz and the (complex) sample rate is 2MHz, a signal at 402.5MHz would be -0.5MHz off, i.e. ` = -0.5/2 = -0.25`.
diff --git a/demod/mod/demod_mod.c b/demod/mod/demod_mod.c index 51e3538..48b2f42 100644 --- a/demod/mod/demod_mod.c +++ b/demod/mod/demod_mod.c @@ -155,9 +155,8 @@ static int getCorrDFT(dsp_t *dsp) { ui32_t mpos = 0; ui32_t pos = dsp->sample_out; - double dc = 0.0; - int mp_ofs = 0; float *sbuf = dsp->bufs; + float *dcbuf = dsp->fm_buffer; dsp->mv = 0.0; dsp->dc = 0.0; @@ -166,13 +165,6 @@ static int getCorrDFT(dsp_t *dsp) { if (dsp->sample_out < dsp->L) return -2; - if (dsp->opt_iq > 1 && dsp->opt_dc) { - mp_ofs = (dsp->sps-1)/2; - sbuf = dsp->fm_buffer; - } - else { - sbuf = dsp->bufs; - } for (i = 0; i < dsp->K + dsp->L; i++) (dsp->DFT).xn[i] = sbuf[(pos+dsp->M -(dsp->K + dsp->L-1) + i) % dsp->M]; while (i < dsp->DFT.N) (dsp->DFT).xn[i++] = 0.0; @@ -181,13 +173,21 @@ static int getCorrDFT(dsp_t *dsp) { if (dsp->opt_dc) { + if (dsp->opt_iq >= 2 && !dsp->locked) { + for (i = 0; i < dsp->K + dsp->L; i++) (dsp->DFT).xn[i] = sbuf[(pos+dsp->M -(dsp->K + dsp->L-1) + i) % dsp->M]; + while (i < dsp->DFT.N) (dsp->DFT).xn[i++] = 0.0; + + } + /* //X[0] = 0; // nicht ueber gesamte Laenge ... M10 // // L < K ? // only last 2L samples (avoid M10 carrier offset) - dc = 0.0; + double dc = 0.0; for (i = dsp->K - dsp->L; i < dsp->K + dsp->L; i++) dc += (dsp->DFT).xn[i]; dc /= 2.0*(float)dsp->L; dsp->DFT.X[0] -= dsp->DFT.N * dc ;//* 0.95; + */ + dsp->DFT.X[0] = 0; Nidft(&dsp->DFT, dsp->DFT.X, (dsp->DFT).cx); for (i = 0; i < dsp->DFT.N; i++) (dsp->DFT).xn[i] = creal((dsp->DFT).cx[i])/(float)dsp->DFT.N; } @@ -196,8 +196,6 @@ static int getCorrDFT(dsp_t *dsp) { Nidft(&dsp->DFT, dsp->DFT.Z, dsp->DFT.cx); - if (fabs(dc) < 0.5) dsp->dc = dc; - // relativ Peak - Normierung erst zum Schluss; // dann jedoch nicht zwingend corr-Max wenn FM-Amplitude bzw. norm(x) nicht konstant @@ -225,16 +223,85 @@ static int getCorrDFT(dsp_t *dsp) { mx /= xnorm*(dsp->DFT).N; - if (dsp->opt_iq > 1 && dsp->opt_dc) mpos += mp_ofs; - dsp->mv = mx; dsp->mv_pos = mpos; if (pos == dsp->sample_out) dsp->buffered = dsp->sample_out - mpos; -// FM: s = gain * carg(w)/M_PI = gain * dphi / PI // gain=0.8 -// FM audio gain? dc relative to FM-envelope?! -// + + dsp->mv2 = 0.0f; + dsp->mv2_pos = 0; + if (dsp->opt_dc) { + if (dsp->opt_iq >= 2 && !dsp->locked) { + mx = 0.0f; + mpos = 0; + + for (i = 0; i < dsp->K + dsp->L; i++) (dsp->DFT).xn[i] = dcbuf[(pos+dsp->M -(dsp->K + dsp->L-1) + i) % dsp->M]; + while (i < dsp->DFT.N) (dsp->DFT).xn[i++] = 0.0; + rdft(&dsp->DFT, dsp->DFT.xn, dsp->DFT.X); + + /* + //X[0] = 0; // nicht ueber gesamte Laenge ... M10 + // + // L < K ? // only last 2L samples (avoid M10 carrier offset) + double dc = 0.0; + for (i = dsp->K - dsp->L; i < dsp->K + dsp->L; i++) dc += (dsp->DFT).xn[i]; + dc /= 2.0*(float)dsp->L; + dsp->DFT.X[0] -= dsp->DFT.N * dc ;//* 0.95; + */ + dsp->DFT.X[0] = 0; + Nidft(&dsp->DFT, dsp->DFT.X, (dsp->DFT).cx); + for (i = 0; i < dsp->DFT.N; i++) (dsp->DFT).xn[i] = creal((dsp->DFT).cx[i])/(float)dsp->DFT.N; + + for (i = 0; i < dsp->DFT.N; i++) dsp->DFT.Z[i] = dsp->DFT.X[i]*dsp->DFT.Fm[i]; + + Nidft(&dsp->DFT, dsp->DFT.Z, dsp->DFT.cx); + + mx2 = 0.0; // t = L-1 + for (i = dsp->L-1; i < dsp->K + dsp->L; i++) { // i=t .. i=t+K < t+1+K + re_cx = creal(dsp->DFT.cx[i]); // imag(cx)=0 + if (re_cx*re_cx > mx2) { + mx = re_cx; + mx2 = mx*mx; + mp = i; + } + } + if (mp == dsp->L-1 || mp == dsp->K + dsp->L-1) return -4; // Randwert + // mp == t mp == K+t + + mpos = pos - (dsp->K + dsp->L-1) + mp; // t = L-1 + + //xnorm = sqrt(dsp->qs[(mpos + 2*dsp->M) % dsp->M]); // Nvar = L + xnorm = 0.0; + for (i = 0; i < dsp->L; i++) xnorm += (dsp->DFT).xn[mp-i]*(dsp->DFT).xn[mp-i]; + xnorm = sqrt(xnorm); + + mx /= xnorm*(dsp->DFT).N; + + + dsp->mv2 = mx; + dsp->mv2_pos = mpos; + } + } + + + if (dsp->opt_dc) + { + double dc = 0.0; + int mp_ofs = 0; + if (dsp->opt_iq >= 2) { + mp_ofs = (dsp->lpFMtaps - (dsp->sps-1))/2; + } + dc = 0.0; // rs41 without preamble? + for (i = 0; i < dsp->L; i++) dc += dcbuf[(mp_ofs + mpos - i + dsp->M) % dsp->M]; + dc /= (float)dsp->L; + dsp->dc = dc; + } + + + // FM: s = gain * carg(w)/M_PI = gain * dphi / PI // gain=0.8 + // FM audio gain? dc relative to FM-envelope?! + // dsp->dDf = dsp->sr * dsp->dc / (2.0*FM_GAIN); // remaining freq offset return mp; @@ -597,6 +664,7 @@ static float re_lowpass(float buffer[], ui32_t sample, ui32_t taps, float *ws) { int f32buf_sample(dsp_t *dsp, int inv) { float s = 0.0; + float s_fm = s; float xneu, xalt; float complex z, w, z0; @@ -604,25 +672,41 @@ int f32buf_sample(dsp_t *dsp, int inv) { double t = dsp->sample_in / (double)dsp->sr; - if (dsp->opt_iq) { - + if (dsp->opt_iq) + { if (dsp->opt_iq == 5) { ui32_t s_reset = dsp->dectaps*dsp->lut_len; int j; if ( f32read_cblock(dsp) < dsp->decM ) return EOF; for (j = 0; j < dsp->decM; j++) { - dsp->decXbuffer[dsp->sample_dec % dsp->dectaps] = dsp->decMbuf[j] * dsp->ex[dsp->sample_dec % dsp->lut_len]; + if (dsp->opt_nolut) { + double _s_base = (double)(dsp->sample_in*dsp->decM+j); // dsp->sample_dec + double f0 = dsp->xlt_fq*_s_base - dsp->Df*_s_base/(double)dsp->sr_base; + z = dsp->decMbuf[j] * cexp(f0*2*M_PI*I); + } + else { + z = dsp->decMbuf[j] * dsp->ex[dsp->sample_dec % dsp->lut_len]; + } + + dsp->decXbuffer[dsp->sample_dec % dsp->dectaps] = z; dsp->sample_dec += 1; if (dsp->sample_dec == s_reset) dsp->sample_dec = 0; } - z = lowpass(dsp->decXbuffer, dsp->sample_dec, dsp->dectaps, ws_dec); + if (dsp->decM > 1) + { + z = lowpass(dsp->decXbuffer, dsp->sample_dec, dsp->dectaps, ws_dec); + } } else if ( f32read_csample(dsp, &z) == EOF ) return EOF; - z *= cexp(-t*2*M_PI*dsp->Df*I); + if (dsp->opt_dc && !dsp->opt_nolut) + { + z *= cexp(-t*2*M_PI*dsp->Df*I); + } + // IF-lowpass - if (dsp->opt_lp) { + if (dsp->opt_lp & LP_IQ) { dsp->lpIQ_buf[dsp->sample_in % dsp->lpIQtaps] = z; z = lowpass(dsp->lpIQ_buf, dsp->sample_in, dsp->lpIQtaps, dsp->ws_lpIQ); } @@ -630,82 +714,88 @@ int f32buf_sample(dsp_t *dsp, int inv) { z0 = dsp->rot_iqbuf[(dsp->sample_in-1 + dsp->N_IQBUF) % dsp->N_IQBUF]; w = z * conj(z0); - s = gain * carg(w)/M_PI; + s_fm = gain * carg(w)/M_PI; dsp->rot_iqbuf[dsp->sample_in % dsp->N_IQBUF] = z; - // FM-lowpass - if (dsp->opt_lp) { - dsp->lpFM_buf[dsp->sample_in % dsp->lpFMtaps] = s; - s = re_lowpass(dsp->lpFM_buf, dsp->sample_in, dsp->lpFMtaps, dsp->ws_lpFM); - } - - dsp->fm_buffer[(dsp->sample_in - dsp->lpFMtaps/2 + dsp->M) % dsp->M] = s; - - if (dsp->opt_iq >= 2) { - double xbit = 0.0; - //float complex xi = cexp(+I*M_PI*dsp->h/dsp->sps); - double f1 = -dsp->h*dsp->sr/(2*dsp->sps); - double f2 = -f1; + if (dsp->opt_iq >= 2) { + double xbit = 0.0; + //float complex xi = cexp(+I*M_PI*dsp->h/dsp->sps); + double f1 = -dsp->h*dsp->sr/(2.0*dsp->sps); + double f2 = -f1; - float complex X0 = 0; - float complex X = 0; + float complex X0 = 0; + float complex X = 0; - int n = dsp->sps; - double tn = (dsp->sample_in-n) / (double)dsp->sr; - //t = dsp->sample_in / (double)dsp->sr; - //z = dsp->rot_iqbuf[dsp->sample_in % dsp->N_IQBUF]; - z0 = dsp->rot_iqbuf[(dsp->sample_in-n + dsp->N_IQBUF) % dsp->N_IQBUF]; + int n = dsp->sps; + double tn = (dsp->sample_in-n) / (double)dsp->sr; + //t = dsp->sample_in / (double)dsp->sr; + //z = dsp->rot_iqbuf[dsp->sample_in % dsp->N_IQBUF]; + z0 = dsp->rot_iqbuf[(dsp->sample_in-n + dsp->N_IQBUF) % dsp->N_IQBUF]; - // f1 - X0 = z0 * cexp(-tn*2*M_PI*f1*I); // alt - X = z * cexp(-t *2*M_PI*f1*I); // neu - dsp->F1sum += X - X0; + // f1 + X0 = z0 * cexp(-tn*2*M_PI*f1*I); // alt + X = z * cexp(-t *2*M_PI*f1*I); // neu + dsp->F1sum += X - X0; - // f2 - X0 = z0 * cexp(-tn*2*M_PI*f2*I); // alt - X = z * cexp(-t *2*M_PI*f2*I); // neu - dsp->F2sum += X - X0; + // f2 + X0 = z0 * cexp(-tn*2*M_PI*f2*I); // alt + X = z * cexp(-t *2*M_PI*f2*I); // neu + dsp->F2sum += X - X0; - xbit = cabs(dsp->F2sum) - cabs(dsp->F1sum); + xbit = cabs(dsp->F2sum) - cabs(dsp->F1sum); - s = xbit / dsp->sps; - } - else if (0 && dsp->opt_iq >= 4) - { - double xbit = 0.0; - //float complex xi = cexp(+I*M_PI*dsp->h/dsp->sps); - double f1 = -dsp->h*dsp->sr/(2*dsp->sps); - double f2 = -f1; - - float complex X1 = 0; - float complex X2 = 0; - - int n = dsp->sps; - - while (n > 0) { - n--; - t = -n / (double)dsp->sr; - z = dsp->rot_iqbuf[(dsp->sample_in - n + dsp->N_IQBUF) % dsp->N_IQBUF]; // +1 - X1 += z*cexp(-t*2*M_PI*f1*I); - X2 += z*cexp(-t*2*M_PI*f2*I); + s = xbit / dsp->sps; } + else if (0 && dsp->opt_iq == 4) { + double xbit = 0.0; + //float complex xi = cexp(+I*M_PI*dsp->h/dsp->sps); + double f1 = -dsp->h*dsp->sr/(2*dsp->sps); + double f2 = -f1; - xbit = cabs(X2) - cabs(X1); + float complex X1 = 0; + float complex X2 = 0; - s = xbit / dsp->sps; + int n = dsp->sps; + + while (n > 0) { + n--; + t = -n / (double)dsp->sr; + z = dsp->rot_iqbuf[(dsp->sample_in - n + dsp->N_IQBUF) % dsp->N_IQBUF]; // +1 + X1 += z*cexp(-t*2*M_PI*f1*I); + X2 += z*cexp(-t*2*M_PI*f2*I); + } + + xbit = cabs(X2) - cabs(X1); + + s = xbit / dsp->sps; + } + } + else { + s = s_fm; } } else { if (f32read_sample(dsp, &s) == EOF) return EOF; + s_fm = s; } + // FM-lowpass + if (dsp->opt_lp & LP_FM) { + dsp->lpFM_buf[dsp->sample_in % dsp->lpFMtaps] = s_fm; + s_fm = re_lowpass(dsp->lpFM_buf, dsp->sample_in, dsp->lpFMtaps, dsp->ws_lpFM); + if (dsp->opt_iq < 2) s = s_fm; + } + + dsp->fm_buffer[dsp->sample_in % dsp->M] = s_fm; + if (inv) s = -s; dsp->bufs[dsp->sample_in % dsp->M] = s; + xneu = dsp->bufs[(dsp->sample_in ) % dsp->M]; xalt = dsp->bufs[(dsp->sample_in+dsp->M - dsp->Nvar) % dsp->M]; dsp->xsum += xneu - xalt; // + xneu - xalt @@ -728,20 +818,23 @@ static int read_bufbit(dsp_t *dsp, int symlen, char *bits, ui32_t mvp, int pos) ui32_t rcount = ceil(rbitgrenze);//+0.99; // dfm? double sum = 0.0; + double dc = 0.0; + + if (dsp->opt_dc && dsp->opt_iq < 2) dc = dsp->dc; // bei symlen=2 (Manchester) kein dc noetig: -dc+dc=0 ; // allerdings M10-header mit symlen=1 rbitgrenze += dsp->sps; do { - sum += dsp->bufs[(rcount + mvp + dsp->M) % dsp->M] - dsp->dc; + sum += dsp->bufs[(rcount + mvp + dsp->M) % dsp->M] - dc; rcount++; } while (rcount < rbitgrenze); // n < dsp->sps if (symlen == 2) { rbitgrenze += dsp->sps; do { - sum -= dsp->bufs[(rcount + mvp + dsp->M) % dsp->M] - dsp->dc; + sum -= dsp->bufs[(rcount + mvp + dsp->M) % dsp->M] - dc; rcount++; } while (rcount < rbitgrenze); // n < dsp->sps } @@ -767,7 +860,7 @@ static int headcmp(dsp_t *dsp, int opt_dc) { int len = dsp->hdrlen/dsp->symhd; int inv = dsp->mv < 0; - if (opt_dc == 0 || dsp->opt_iq > 1) dsp->dc = 0; // reset? e.g. 2nd pass + //if (opt_dc == 0 || dsp->opt_iq > 1) dsp->dc = 0; if (dsp->symhd != 1) step = 2; if (inv) sign=1; @@ -1067,6 +1160,7 @@ int init_buffers(dsp_t *dsp) { float *m = NULL; + // decimate if (dsp->opt_iq == 5) { int IF_sr = IF_SAMPLE_RATE; // designated IF sample rate @@ -1107,40 +1201,42 @@ int init_buffers(dsp_t *dsp) { } if (dsp->opt_iq == 5) { - // look up table, exp-rotation - int W = 2*8; // 16 Hz window - int d = 1; // 1..W , groesster Teiler d <= W von sr_base - int freq = (int)( dsp->xlt_fq * (double)dsp->sr_base + 0.5); - int freq0 = freq; // init - double f0 = freq0 / (double)dsp->sr_base; // init + if (!dsp->opt_nolut) + { + // look up table, exp-rotation + int W = 2*8; // 16 Hz window + int d = 1; // 1..W , groesster Teiler d <= W von sr_base + int freq = (int)( dsp->xlt_fq * (double)dsp->sr_base + 0.5); + int freq0 = freq; // init + double f0 = freq0 / (double)dsp->sr_base; // init - for (d = W; d > 0; d--) { // groesster Teiler d <= W von sr - if (dsp->sr_base % d == 0) break; - } - if (d == 0) d = 1; // d >= 1 ? - - for (k = 0; k < W/2; k++) { - if ((freq+k) % d == 0) { - freq0 = freq + k; - break; + for (d = W; d > 0; d--) { // groesster Teiler d <= W von sr + if (dsp->sr_base % d == 0) break; } - if ((freq-k) % d == 0) { - freq0 = freq - k; - break; + if (d == 0) d = 1; // d >= 1 ? + + for (k = 0; k < W/2; k++) { + if ((freq+k) % d == 0) { + freq0 = freq + k; + break; + } + if ((freq-k) % d == 0) { + freq0 = freq - k; + break; + } + } + + dsp->lut_len = dsp->sr_base / d; + f0 = freq0 / (double)dsp->sr_base; + + dsp->ex = calloc(dsp->lut_len+1, sizeof(float complex)); + if (dsp->ex == NULL) return -1; + for (n = 0; n < dsp->lut_len; n++) { + t = f0*(double)n; + dsp->ex[n] = cexp(t*2*M_PI*I); } } - dsp->lut_len = dsp->sr_base / d; - f0 = freq0 / (double)dsp->sr_base; - - dsp->ex = calloc(dsp->lut_len+1, sizeof(float complex)); - if (dsp->ex == NULL) return -1; - for (n = 0; n < dsp->lut_len; n++) { - t = f0*(double)n; - dsp->ex[n] = cexp(t*2*M_PI*I); - } - - dsp->decXbuffer = calloc( dsp->dectaps+1, sizeof(float complex)); if (dsp->decXbuffer == NULL) return -1; @@ -1148,13 +1244,13 @@ int init_buffers(dsp_t *dsp) { if (dsp->decMbuf == NULL) return -1; } - if (dsp->opt_iq && dsp->opt_lp) + // IF lowpass + if (dsp->opt_iq && (dsp->opt_lp & LP_IQ)) { float f_lp; // lowpass_bw int taps; // lowpass taps: 4*sr/transition_bw - // IF lowpass - f_lp = 24e3; // default + f_lp = 24e3/(float)dsp->sr/2.0; // default if (dsp->lpIQ_bw) f_lp = dsp->lpIQ_bw/(float)dsp->sr/2.0; taps = 4*dsp->sr/IF_TRANSITION_BW; if (taps%2==0) taps++; taps = lowpass_init(1.5*f_lp, taps, &dsp->ws_lpIQ0); if (taps < 0) return -1; @@ -1175,10 +1271,15 @@ int init_buffers(dsp_t *dsp) { } // locked: //taps = lowpass_update(dsp->lpIQ_fbw, dsp->lpIQtaps, dsp->ws_lpIQ); if (taps < 0) return -1; + } + // FM lowpass + if (dsp->opt_lp & LP_FM) + { + float f_lp; // lowpass_bw + int taps; // lowpass taps: 4*sr/transition_bw - // FM lowpass - f_lp = 10e3; // default + f_lp = 10e3/(float)dsp->sr; // default if (dsp->lpFM_bw > 0) f_lp = dsp->lpFM_bw/(float)dsp->sr; taps = 4*dsp->sr/FM_TRANSITION_BW; if (taps%2==0) taps++; taps = lowpass_init(f_lp, taps, &dsp->ws_lpFM); if (taps < 0) return -1; @@ -1188,6 +1289,7 @@ int init_buffers(dsp_t *dsp) { if (dsp->lpFM_buf == NULL) return -1; } + memset(&IQdc, 0, sizeof(IQdc)); IQdc.maxlim = dsp->sr; IQdc.maxcnt = IQdc.maxlim/32; // 32,16,8,4,2,1 @@ -1333,18 +1435,23 @@ int free_buffers(dsp_t *dsp) { { if (dsp->decXbuffer) { free(dsp->decXbuffer); dsp->decXbuffer = NULL; } if (dsp->decMbuf) { free(dsp->decMbuf); dsp->decMbuf = NULL; } - if (dsp->ex) { free(dsp->ex); dsp->ex = NULL; } + if (!dsp->opt_nolut) { + if (dsp->ex) { free(dsp->ex); dsp->ex = NULL; } + } if (ws_dec) { free(ws_dec); ws_dec = NULL; } } // IF lowpass - if (dsp->opt_iq && dsp->opt_lp) + if (dsp->opt_iq && (dsp->opt_lp & LP_IQ)) { if (dsp->ws_lpIQ0) { free(dsp->ws_lpIQ0); dsp->ws_lpIQ0 = NULL; } if (dsp->ws_lpIQ1) { free(dsp->ws_lpIQ1); dsp->ws_lpIQ1 = NULL; } if (dsp->lpIQ_buf) { free(dsp->lpIQ_buf); dsp->lpIQ_buf = NULL; } - + } + // FM lowpass + if (dsp->opt_lp & LP_FM) + { if (dsp->ws_lpFM) { free(dsp->ws_lpFM); dsp->ws_lpFM = NULL; } if (dsp->lpFM_buf) { free(dsp->lpFM_buf); dsp->lpFM_buf = NULL; } } @@ -1378,17 +1485,41 @@ int find_header(dsp_t *dsp, float thres, int hdmax, int bitofs, int opt_dc) { continue; } - if (dsp->mv > thres || dsp->mv < -thres) { - - if (dsp->opt_dc) { // Problem: FM-gain - if (dsp->opt_iq < 2) dsp->Df += dsp->dDf*0.4; - else { - double ofs = fabs(dsp->dDf); // (iq-decode controls FM-gain) - if (ofs > 200.0) + if (dsp->mv > thres || dsp->mv < -thres + || dsp->mv2 > thres || dsp->mv2 < -thres) + { + if (dsp->opt_dc) + { + if (dsp->opt_iq) { + if (fabs(dsp->dDf) > 50.0) { - dsp->Df += dsp->dDf * 2/3.0; + double diffDf = dsp->dDf*0.6; //0.4 + if (dsp->opt_iq >= 2) { + // update rot_iqbuf, F1sum, F2sum + double f1 = -dsp->h*dsp->sr/(2*dsp->sps); + double f2 = -f1; + float complex X1 = 0; + float complex X2 = 0; + float complex _z = 0; + int _n = dsp->sps; + while ( _n > 0 ) + { + // update rot_iqbuf + double _tn = (dsp->sample_in - _n) / (double)dsp->sr; + dsp->rot_iqbuf[(dsp->sample_in - _n + dsp->N_IQBUF) % dsp->N_IQBUF] *= cexp(-_tn*2*M_PI*diffDf*I); + // + //update/reset F1sum, F2sum + _z = dsp->rot_iqbuf[(dsp->sample_in - _n + dsp->N_IQBUF) % dsp->N_IQBUF]; + X1 += _z*cexp(-_tn*2*M_PI*f1*I); + X2 += _z*cexp(-_tn*2*M_PI*f2*I); + _n--; + } + dsp->F1sum = X1; + dsp->F2sum = X2; + } + dsp->Df += diffDf; } - if (ofs > 1000.0) { //dsp->opt_lp + if (fabs(dsp->dDf) > 1e3) { if (dsp->locked) { dsp->locked = 0; dsp->ws_lpIQ = dsp->ws_lpIQ0; diff --git a/demod/mod/demod_mod.h b/demod/mod/demod_mod.h index 777e063..8225156 100644 --- a/demod/mod/demod_mod.h +++ b/demod/mod/demod_mod.h @@ -7,6 +7,10 @@ #define M_PI (3.1415926535897932384626433832795) #endif +#define LP_IQ 1 +#define LP_FM 2 +#define LP_IQFM 4 + #ifndef INTTYPES #define INTTYPES @@ -61,6 +65,9 @@ typedef struct { float mv; ui32_t mv_pos; // + float mv2; + ui32_t mv2_pos; + // int N_norm; int Nvar; float xsum; @@ -94,6 +101,7 @@ typedef struct { double dc; double Df; double dDf; + // ui32_t sample_posframe; ui32_t sample_posnoise; @@ -103,6 +111,7 @@ typedef struct { double SNRdB; // decimate + int opt_nolut; // default: LUT int opt_IFmin; int decM; ui32_t sr_base; @@ -129,7 +138,7 @@ typedef struct { int lpFMtaps; // ui32_t float *ws_lpFM; float *lpFM_buf; - float *fm_buffer; + float *fm_buffer; } dsp_t; diff --git a/demod/mod/dfm09mod.c b/demod/mod/dfm09mod.c index 1779534..951c0b3 100644 --- a/demod/mod/dfm09mod.c +++ b/demod/mod/dfm09mod.c @@ -731,8 +731,9 @@ static void print_gpx(gpx_t *gpx) { for (i = 0; i < 9; i++) { for (j = 0; j < 13; j++) gpx->dat_str[i][j] = ' '; } + printf("\n"); } - else { + else if (!gpx->option.raw) { if (gpx->option.aut && gpx->option.vbs >= 2) printf("<%c> ", gpx->option.inv?'-':'+'); printf("[%3d] ", gpx->frnr); printf("%4d-%02d-%02d ", gpx->jahr, gpx->monat, gpx->tag); @@ -776,17 +777,17 @@ static void print_gpx(gpx_t *gpx) { gpx->sonde_typ ^= SNbit; } } - } - printf("\n"); - - if (gpx->option.sat) { - printf(" "); - printf(" dMSL: %+.2f", gpx->gps.dMSL); // MSL = alt + gps.dMSL - printf(" sats: %d", gpx->gps.nSV); - printf(" ("); - for (j = 0; j < 32; j++) { if ((gpx->gps.prn >> j)&1) printf(" %02d", j+1); } - printf(" )"); printf("\n"); + + if (gpx->option.sat) { + printf(" "); + printf(" dMSL: %+.2f", gpx->gps.dMSL); // MSL = alt + gps.dMSL + printf(" sats: %d", gpx->gps.nSV); + printf(" ("); + for (j = 0; j < 32; j++) { if ((gpx->gps.prn >> j)&1) printf(" %02d", j+1); } + printf(" )"); + printf("\n"); + } } if (gpx->option.jsn && jsonout && gpx->sek < 60.0) @@ -902,29 +903,32 @@ static int print_frame(gpx_t *gpx) { printf("\n"); } - else if (gpx->option.ecc) { + if ( gpx->option.raw != 1 || gpx->option.jsn ) + { + if (gpx->option.ecc) { + + if (ret0 == 0 || ret0 > 0 || gpx->option.ecc == 2) { + conf_out(gpx, block_conf, ret0); + } + if (ret1 == 0 || ret1 > 0 || gpx->option.ecc == 2) { + frid = dat_out(gpx, block_dat1, ret1); + if (frid == 8) print_gpx(gpx); + } + if (ret2 == 0 || ret2 > 0 || gpx->option.ecc == 2) { + frid = dat_out(gpx, block_dat2, ret2); + if (frid == 8) print_gpx(gpx); + } - if (ret0 == 0 || ret0 > 0 || gpx->option.ecc == 2) { - conf_out(gpx, block_conf, ret0); } - if (ret1 == 0 || ret1 > 0 || gpx->option.ecc == 2) { + else { + + conf_out(gpx, block_conf, ret0); frid = dat_out(gpx, block_dat1, ret1); if (frid == 8) print_gpx(gpx); - } - if (ret2 == 0 || ret2 > 0 || gpx->option.ecc == 2) { frid = dat_out(gpx, block_dat2, ret2); if (frid == 8) print_gpx(gpx); + } - - } - else { - - conf_out(gpx, block_conf, ret0); - frid = dat_out(gpx, block_dat1, ret1); - if (frid == 8) print_gpx(gpx); - frid = dat_out(gpx, block_dat2, ret2); - if (frid == 8) print_gpx(gpx); - } return ret; @@ -947,6 +951,7 @@ int main(int argc, char **argv) { int option_iqdc = 0; int option_lp = 0; int option_dc = 0; + int option_noLUT = 0; int option_bin = 0; int option_softin = 0; int option_json = 0; // JSON blob output (for auto_rx) @@ -1076,20 +1081,22 @@ 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, "--min") == 0) { - option_min = 1; - } - else if (strcmp(*argv, "--dbg") == 0) { gpx.option.dbg = 1; } + else if (strcmp(*argv, "--lpIQ") == 0) { option_lp |= LP_IQ; } // IQ/IF lowpass else if (strcmp(*argv, "--lpbw") == 0) { // IQ lowpass BW / kHz double bw = 0.0; ++argv; if (*argv) bw = atof(*argv); else return -1; if (bw > 4.6 && bw < 24.0) lpIQ_bw = bw*1e3; - option_lp = 1; + option_lp |= LP_IQ; } + else if (strcmp(*argv, "--lpFM") == 0) { option_lp |= LP_FM; } // FM lowpass + else if (strcmp(*argv, "--dc") == 0) { option_dc = 1; } + else if (strcmp(*argv, "--noLUT") == 0) { option_noLUT = 1; } + else if (strcmp(*argv, "--min") == 0) { + option_min = 1; + } + else if (strcmp(*argv, "--dbg") == 0) { gpx.option.dbg = 1; } else if (strcmp(*argv, "--sat") == 0) { gpx.option.sat = 1; } else if (strcmp(*argv, "-") == 0) { int sample_rate = 0, bits_sample = 0, channels = 0; @@ -1119,6 +1126,14 @@ int main(int argc, char **argv) { } if (!wavloaded) fp = stdin; + if (option_iq == 5 && option_dc) option_lp |= LP_FM; + + // LUT faster for decM, however frequency correction after decimation + // LUT recommonded if decM > 2 + // + if (option_noLUT && option_iq == 5) dsp.opt_nolut = 1; else dsp.opt_nolut = 0; + + // ecc2-soft_decision accepts also 2-error words, // so the probability for 3 errors is high and will // produce wrong codewords. hence ecc2 is not recommended diff --git a/demod/mod/imet54mod.c b/demod/mod/imet54mod.c index 0ef0fc8..f66abcd 100644 --- a/demod/mod/imet54mod.c +++ b/demod/mod/imet54mod.c @@ -645,6 +645,7 @@ int main(int argc, char *argv[]) { int option_iqdc = 0; int option_lp = 0; int option_dc = 0; + int option_noLUT = 0; int option_softin = 0; int option_pcmraw = 0; int wavloaded = 0; @@ -761,16 +762,18 @@ 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, "--lpIQ") == 0) { option_lp |= LP_IQ; } // IQ/IF lowpass else if (strcmp(*argv, "--lpbw") == 0) { // IQ lowpass BW / kHz double bw = 0.0; ++argv; if (*argv) bw = atof(*argv); else return -1; if (bw > 4.6 && bw < 24.0) lpIQ_bw = bw*1e3; - option_lp = 1; + option_lp |= LP_IQ; } + else if (strcmp(*argv, "--lpFM") == 0) { option_lp |= LP_FM; } // FM lowpass else if (strcmp(*argv, "--dc") == 0) { option_dc = 1; } + else if (strcmp(*argv, "--noLUT") == 0) { option_noLUT = 1; } else if (strcmp(*argv, "--min") == 0) { option_min = 1; } @@ -814,6 +817,13 @@ int main(int argc, char *argv[]) { } if (!wavloaded) fp = stdin; + if (option_iq == 5 && option_dc) option_lp |= LP_FM; + + // LUT faster for decM, however frequency correction after decimation + // LUT recommonded if decM > 2 + // + if (option_noLUT && option_iq == 5) dsp.opt_nolut = 1; else dsp.opt_nolut = 0; + if (gpx.option.raw && gpx.option.jsn) gpx.option.slt = 1; diff --git a/demod/mod/lms6Xmod.c b/demod/mod/lms6Xmod.c index 8a592f6..80071d3 100644 --- a/demod/mod/lms6Xmod.c +++ b/demod/mod/lms6Xmod.c @@ -994,6 +994,7 @@ int main(int argc, char **argv) { int option_iqdc = 0; int option_lp = 0; int option_dc = 0; + int option_noLUT = 0; int option_softin = 0; int option_pcmraw = 0; int wavloaded = 0; @@ -1128,16 +1129,18 @@ 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, "--lpIQ") == 0) { option_lp |= LP_IQ; } // IQ/IF lowpass else if (strcmp(*argv, "--lpbw") == 0) { // IQ lowpass BW / kHz double bw = 0.0; ++argv; if (*argv) bw = atof(*argv); else return -1; if (bw > 4.6 && bw < 24.0) lpIQ_bw = bw*1e3; - option_lp = 1; + option_lp |= LP_IQ; } + else if (strcmp(*argv, "--lpFM") == 0) { option_lp |= LP_FM; } // FM lowpass else if (strcmp(*argv, "--dc") == 0) { option_dc = 1; } + else if (strcmp(*argv, "--noLUT") == 0) { option_noLUT = 1; } else if (strcmp(*argv, "--min") == 0) { option_min = 1; } @@ -1181,6 +1184,13 @@ int main(int argc, char **argv) { } if (!wavloaded) fp = stdin; + if (option_iq == 5 && option_dc) option_lp |= LP_FM; + + // LUT faster for decM, however frequency correction after decimation + // LUT recommonded if decM > 2 + // + if (option_noLUT && option_iq == 5) dsp.opt_nolut = 1; else dsp.opt_nolut = 0; + if (gpx->option.raw == 4) gpx->option.ecc = 1; @@ -1260,7 +1270,7 @@ int main(int argc, char **argv) { dsp.opt_iq = option_iq; dsp.opt_iqdc = option_iqdc; dsp.opt_lp = option_lp; - dsp.lpIQ_bw = lpIQ_bw; // 16e3; // IF lowpass bandwidth // soft decoding? + dsp.lpIQ_bw = lpIQ_bw; //16e3; // IF lowpass bandwidth // soft decoding? dsp.lpFM_bw = 6e3; // FM audio lowpass dsp.opt_dc = option_dc; dsp.opt_IFmin = option_min; diff --git a/demod/mod/m10mod.c b/demod/mod/m10mod.c index d8b8e83..8564aff 100644 --- a/demod/mod/m10mod.c +++ b/demod/mod/m10mod.c @@ -1143,6 +1143,7 @@ int main(int argc, char **argv) { int option_iqdc = 0; int option_lp = 0; int option_dc = 0; + int option_noLUT = 0; int option_chk = 0; int option_softin = 0; int option_pcmraw = 0; @@ -1170,6 +1171,8 @@ int main(int argc, char **argv) { float thres = 0.76; float _mv = 0.0; + float lpIQ_bw = 24e3; + int symlen = 2; int bitofs = 0; // 0 .. +2 int shift = 0; @@ -1254,8 +1257,18 @@ 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, "--lpIQ") == 0) { option_lp |= LP_IQ; } // IQ/IF lowpass + else if (strcmp(*argv, "--lpbw") == 0) { // IQ lowpass BW / kHz + double bw = 0.0; + ++argv; + if (*argv) bw = atof(*argv); + else return -1; + if (bw > 4.6 && bw < 48.0) lpIQ_bw = bw*1e3; + option_lp |= LP_IQ; + } + else if (strcmp(*argv, "--lpFM") == 0) { option_lp |= LP_FM; } // FM lowpass else if (strcmp(*argv, "--dc") == 0) { option_dc = 1; } + else if (strcmp(*argv, "--noLUT") == 0) { option_noLUT = 1; } else if (strcmp(*argv, "--min") == 0) { option_min = 1; } @@ -1296,6 +1309,13 @@ int main(int argc, char **argv) { } if (!wavloaded) fp = stdin; + if (option_iq == 5 && option_dc) option_lp |= LP_FM; + + // LUT faster for decM, however frequency correction after decimation + // LUT recommonded if decM > 2 + // + if (option_noLUT && option_iq == 5) dsp.opt_nolut = 1; else dsp.opt_nolut = 0; + if (gpx.option.raw && gpx.option.jsn) gpx.option.slt = 1; @@ -1356,7 +1376,7 @@ int main(int argc, char **argv) { dsp.opt_iq = option_iq; dsp.opt_iqdc = option_iqdc; dsp.opt_lp = option_lp; - dsp.lpIQ_bw = 24e3; // IF lowpass bandwidth + dsp.lpIQ_bw = lpIQ_bw; //24e3; // IF lowpass bandwidth dsp.lpFM_bw = 10e3; // FM audio lowpass dsp.opt_dc = option_dc; dsp.opt_IFmin = option_min; diff --git a/demod/mod/mXXmod.c b/demod/mod/mXXmod.c index 0d7239d..dc27b70 100644 --- a/demod/mod/mXXmod.c +++ b/demod/mod/mXXmod.c @@ -803,6 +803,7 @@ int main(int argc, char **argv) { int option_iqdc = 0; int option_lp = 0; int option_dc = 0; + int option_noLUT = 0; int option_softin = 0; int option_pcmraw = 0; int wavloaded = 0; @@ -831,6 +832,8 @@ int main(int argc, char **argv) { float thres = 0.76; float _mv = 0.0; + float lpIQ_bw = 24e3; + int symlen = 2; int bitofs = 0; // 0 .. +2 int shift = 0; @@ -922,8 +925,18 @@ 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, "--lpIQ") == 0) { option_lp |= LP_IQ; } // IQ/IF lowpass + else if (strcmp(*argv, "--lpbw") == 0) { // IQ lowpass BW / kHz + double bw = 0.0; + ++argv; + if (*argv) bw = atof(*argv); + else return -1; + if (bw > 4.6 && bw < 48.0) lpIQ_bw = bw*1e3; + option_lp |= LP_IQ; + } + else if (strcmp(*argv, "--lpFM") == 0) { option_lp |= LP_FM; } // FM lowpass else if (strcmp(*argv, "--dc") == 0) { option_dc = 1; } + else if (strcmp(*argv, "--noLUT") == 0) { option_noLUT = 1; } else if (strcmp(*argv, "--min") == 0) { option_min = 1; } @@ -964,6 +977,13 @@ int main(int argc, char **argv) { } if (!wavloaded) fp = stdin; + if (option_iq == 5 && option_dc) option_lp |= LP_FM; + + // LUT faster for decM, however frequency correction after decimation + // LUT recommonded if decM > 2 + // + if (option_noLUT && option_iq == 5) dsp.opt_nolut = 1; else dsp.opt_nolut = 0; + if (gpx.option.raw && gpx.option.jsn) gpx.option.slt = 1; @@ -1024,7 +1044,7 @@ int main(int argc, char **argv) { dsp.opt_iq = option_iq; dsp.opt_iqdc = option_iqdc; dsp.opt_lp = option_lp; - dsp.lpIQ_bw = 24e3; // IF lowpass bandwidth + dsp.lpIQ_bw = lpIQ_bw; //24e3; // IF lowpass bandwidth dsp.lpFM_bw = 10e3; // FM audio lowpass dsp.opt_dc = option_dc; dsp.opt_IFmin = option_min; diff --git a/demod/mod/meisei100mod.c b/demod/mod/meisei100mod.c index 0e190ce..ad480a7 100644 --- a/demod/mod/meisei100mod.c +++ b/demod/mod/meisei100mod.c @@ -254,6 +254,7 @@ int main(int argc, char **argv) { int option_iqdc = 0; int option_lp = 0; int option_dc = 0; + int option_noLUT = 0; int option_softin = 0; int option_pcmraw = 0; int sel_wavch = 0; @@ -305,6 +306,8 @@ int main(int argc, char **argv) { float thres = 0.7; float _mv = 0.0; + float lpIQ_bw = 16e3; + int symlen = 1; int bitofs = 0; // 0..+1 int shift = 0; @@ -389,8 +392,18 @@ 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, "--lpIQ") == 0) { option_lp |= LP_IQ; } // IQ/IF lowpass + else if (strcmp(*argv, "--lpbw") == 0) { // IQ lowpass BW / kHz + double bw = 0.0; + ++argv; + if (*argv) bw = atof(*argv); + else return -1; + if (bw > 4.6 && bw < 32.0) lpIQ_bw = bw*1e3; + option_lp |= LP_IQ; + } + else if (strcmp(*argv, "--lpFM") == 0) { option_lp |= LP_FM; } // FM lowpass + else if (strcmp(*argv, "--dc") == 0) { option_dc = 1; } + else if (strcmp(*argv, "--noLUT") == 0) { option_noLUT = 1; } else if (strcmp(*argv, "--min") == 0) { option_min = 1; } @@ -435,6 +448,13 @@ int main(int argc, char **argv) { } if (!wavloaded) fp = stdin; + if (option_iq == 5 && option_dc) option_lp |= LP_FM; + + // LUT faster for decM, however frequency correction after decimation + // LUT recommonded if decM > 2 + // + if (option_noLUT && option_iq == 5) dsp.opt_nolut = 1; else dsp.opt_nolut = 0; + if (cfreq > 0) gpx.jsn_freq = (cfreq+500)/1000; @@ -490,7 +510,7 @@ int main(int argc, char **argv) { dsp.opt_iq = option_iq; dsp.opt_iqdc = option_iqdc; dsp.opt_lp = option_lp; - dsp.lpIQ_bw = 16e3; // IF lowpass bandwidth + dsp.lpIQ_bw = lpIQ_bw; //16e3; // IF lowpass bandwidth dsp.lpFM_bw = 4e3; // FM audio lowpass dsp.opt_dc = option_dc; dsp.opt_IFmin = option_min; diff --git a/demod/mod/mp3h1mod.c b/demod/mod/mp3h1mod.c index d52bc22..96a9fdd 100644 --- a/demod/mod/mp3h1mod.c +++ b/demod/mod/mp3h1mod.c @@ -772,6 +772,7 @@ int main(int argc, char **argv) { int option_iqdc = 0; int option_lp = 0; int option_dc = 0; + int option_noLUT = 0; int option_softin = 0; int option_pcmraw = 0; int wavloaded = 0; @@ -883,16 +884,18 @@ 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, "--lpIQ") == 0) { option_lp |= LP_IQ; } // IQ/IF lowpass else if (strcmp(*argv, "--lpbw") == 0) { // IQ lowpass BW / kHz double bw = 0.0; ++argv; if (*argv) bw = atof(*argv); else return -1; - if (bw > 4.6 && bw < 24.0) lpIQ_bw = bw*1e3; - option_lp = 1; + if (bw > 4.6 && bw < 32.0) lpIQ_bw = bw*1e3; + option_lp |= LP_IQ; } + else if (strcmp(*argv, "--lpFM") == 0) { option_lp |= LP_FM; } // FM lowpass else if (strcmp(*argv, "--dc") == 0) { option_dc = 1; } + else if (strcmp(*argv, "--noLUT") == 0) { option_noLUT = 1; } else if (strcmp(*argv, "--min") == 0) { option_min = 1; } @@ -935,6 +938,14 @@ int main(int argc, char **argv) { } if (!wavloaded) fp = stdin; + if (option_iq == 5 && option_dc) option_lp |= LP_FM; + + // LUT faster for decM, however frequency correction after decimation + // LUT recommonded if decM > 2 + // + if (option_noLUT && option_iq == 5) dsp.opt_nolut = 1; else dsp.opt_nolut = 0; + + gpx.jsn_freq = 0; if (cfreq > 0) gpx.jsn_freq = (cfreq+500)/1000; diff --git a/demod/mod/rs41mod.c b/demod/mod/rs41mod.c index 8cd09c7..94ac1ca 100644 --- a/demod/mod/rs41mod.c +++ b/demod/mod/rs41mod.c @@ -2028,6 +2028,7 @@ int main(int argc, char *argv[]) { int option_iqdc = 0; int option_lp = 0; int option_dc = 0; + int option_noLUT = 0; int option_bin = 0; int option_softin = 0; int option_pcmraw = 0; @@ -2147,16 +2148,18 @@ 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, "--lpIQ") == 0) { option_lp |= LP_IQ; } // IQ/IF lowpass else if (strcmp(*argv, "--lpbw") == 0) { // IQ lowpass BW / kHz double bw = 0.0; ++argv; if (*argv) bw = atof(*argv); else return -1; if (bw > 4.6 && bw < 24.0) lpIQ_bw = bw*1e3; - option_lp = 1; + option_lp |= LP_IQ; } + else if (strcmp(*argv, "--lpFM") == 0) { option_lp |= LP_FM; } // FM lowpass else if (strcmp(*argv, "--dc") == 0) { option_dc = 1; } + else if (strcmp(*argv, "--noLUT") == 0) { option_noLUT = 1; } else if (strcmp(*argv, "--min") == 0) { option_min = 1; } @@ -2202,6 +2205,13 @@ int main(int argc, char *argv[]) { } if (!wavloaded) fp = stdin; + if (option_iq == 5 && option_dc) option_lp |= LP_FM; + + // LUT faster for decM, however frequency correction after decimation + // LUT recommonded if decM > 2 + // + if (option_noLUT && option_iq == 5) dsp.opt_nolut = 1; else dsp.opt_nolut = 0; + if (gpx.option.raw && gpx.option.jsn) gpx.option.slt = 1; diff --git a/demod/mod/rs92mod.c b/demod/mod/rs92mod.c index e18a929..15a3b80 100644 --- a/demod/mod/rs92mod.c +++ b/demod/mod/rs92mod.c @@ -1584,6 +1584,7 @@ int main(int argc, char *argv[]) { int option_iqdc = 0; int option_lp = 0; int option_dc = 0; + int option_noLUT = 0; int option_softin = 0; int option_pcmraw = 0; int sel_wavch = 0; // audio channel: left @@ -1779,16 +1780,18 @@ 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, "--lpIQ") == 0) { option_lp |= LP_IQ; } // IQ/IF lowpass else if (strcmp(*argv, "--lpbw") == 0) { // IQ lowpass BW / kHz - float bw = 0.0; + double bw = 0.0; ++argv; if (*argv) bw = atof(*argv); else return -1; - if (bw > 4.6f && bw < 48.0f) set_lpIQbw = bw*1e3f; - option_lp = 1; + if (bw > 4.6 && bw < 48.0) set_lpIQbw = bw*1e3; + option_lp |= LP_IQ; } + else if (strcmp(*argv, "--lpFM") == 0) { option_lp |= LP_FM; } // FM lowpass else if (strcmp(*argv, "--dc") == 0) { option_dc = 1; } + else if (strcmp(*argv, "--noLUT") == 0) { option_noLUT = 1; } else if (strcmp(*argv, "--min") == 0) { option_min = 1; } @@ -1846,6 +1849,13 @@ int main(int argc, char *argv[]) { if (!option_der) gpx.gps.d_err = 1000; } + if (option_iq == 5 && option_dc) option_lp |= LP_FM; + + // LUT faster for decM, however frequency correction after decimation + // LUT recommonded if decM > 2 + // + if (option_noLUT && option_iq == 5) dsp.opt_nolut = 1; else dsp.opt_nolut = 0; + gpx.option.crc = 1; if (gpx.option.ecc < 2) gpx.option.ecc = 1; // turn off for ber-measurement