mod: --softin from test-branch

pull/27/head
Zilog80 2020-06-14 14:43:47 +02:00
rodzic 2e770cee8b
commit 7b00d3a678
12 zmienionych plików z 1007 dodań i 1804 usunięć

Wyświetl plik

@ -59,4 +59,9 @@ alternative decoders using cross-correlation for better header-synchronization
The difference between hard and soft viterbi becomes only apparent at lower SNR. The inner convolutional
code does most of the error correction. The concatenated outer Reed-Solomon code kicks in only at low SNR.
soft input:<br />
Option `--softin` expects float32 symbols as input, with `s>0` corresponding to `bit=1`.<br />
(remark/caution: often soft bits are defined as `bit=0 -> s=+1` and `bit=1 -> s=-1` such that the identity element `0`
for addition mod 2 corresponds to the identity element `+1` for multiplication.)

Wyświetl plik

@ -24,6 +24,8 @@
/* ------------------------------------------------------------------------------------ */
#ifndef EXT_FSK
static void raw_dft(dft_t *dft, float complex *Z) {
int s, l, l2, i, j, k;
float complex w1, w2, T;
@ -126,7 +128,7 @@ static int dft_window(dft_t *dft, int w) {
dft->win[n] = 0.5 * ( 1.0 - cos(2*M_PI*n/(float)(dft->N2-1)) );
break ;
case 2: // Hamming
dft->win[n] = 25/46.0 + (1.0 - 25/46.0)*cos(2*M_PI*n / (float)(dft->N2-1));
dft->win[n] = 25/46.0 - (1.0 - 25/46.0)*cos(2*M_PI*n / (float)(dft->N2-1));
break ;
case 3: // Blackmann
dft->win[n] = 7938/18608.0
@ -942,6 +944,96 @@ int read_softbit(dsp_t *dsp, hsbit_t *shb, int inv, int ofs, int pos, float l, i
return 0;
}
int read_softbit2p(dsp_t *dsp, hsbit_t *shb, int inv, int ofs, int pos, float l, int spike, hsbit_t *shb1) {
// symlen==2: manchester2 10->0,01->1: 2.bit
float sample, sample1;
float avg;
float ths = 0.5, scale = 0.27;
double sum = 0.0, sum1 = 0.0;
double mid;
//double l = 1.0;
double bg = pos*dsp->symlen*dsp->sps;
double dc = 0.0;
ui8_t bit = 0, bit1 = 0;
if (dsp->opt_dc && dsp->opt_iq < 2) dc = dsp->dc;
if (pos == 0) {
bg = 0;
dsp->sc = 0;
}
if (dsp->symlen == 2) {
mid = bg + (dsp->sps-1)/2.0;
bg += dsp->sps;
do {
if (dsp->buffered > 0) dsp->buffered -= 1;
else if (f32buf_sample(dsp, inv) == EOF) return EOF;
sample = dsp->bufs[(dsp->sample_out-dsp->buffered + ofs + dsp->M) % dsp->M];
sample1 = dsp->bufs[(dsp->sample_out-dsp->buffered + ofs-1 + dsp->M) % dsp->M];
if (spike && fabs(sample - avg) > ths) {
avg = 0.5*(dsp->bufs[(dsp->sample_out-dsp->buffered-1 + ofs + dsp->M) % dsp->M]
+dsp->bufs[(dsp->sample_out-dsp->buffered+1 + ofs + dsp->M) % dsp->M]);
sample = avg + scale*(sample - avg); // spikes
}
sample -= dc;
sample1 -= dc;
if (l < 0 || (mid-l < dsp->sc && dsp->sc < mid+l)) {
sum -= sample;
sum1 -= sample1;
}
dsp->sc++;
} while (dsp->sc < bg); // n < dsp->sps
}
mid = bg + (dsp->sps-1)/2.0;
bg += dsp->sps;
do {
if (dsp->buffered > 0) dsp->buffered -= 1;
else if (f32buf_sample(dsp, inv) == EOF) return EOF;
sample = dsp->bufs[(dsp->sample_out-dsp->buffered + ofs + dsp->M) % dsp->M];
sample1 = dsp->bufs[(dsp->sample_out-dsp->buffered + ofs-1 + dsp->M) % dsp->M];
if (spike && fabs(sample - avg) > ths) {
avg = 0.5*(dsp->bufs[(dsp->sample_out-dsp->buffered-1 + ofs + dsp->M) % dsp->M]
+dsp->bufs[(dsp->sample_out-dsp->buffered+1 + ofs + dsp->M) % dsp->M]);
sample = avg + scale*(sample - avg); // spikes
}
sample -= dc;
sample1 -= dc;
if (l < 0 || (mid-l < dsp->sc && dsp->sc < mid+l)) {
sum += sample;
sum1 += sample1;
}
dsp->sc++;
} while (dsp->sc < bg); // n < dsp->sps
if (sum >= 0) bit = 1;
else bit = 0;
shb->hb = bit;
shb->sb = (float)sum;
if (sum1 >= 0) bit1 = 1;
else bit1 = 0;
shb1->hb = bit1;
shb1->sb = (float)sum1;
return 0;
}
/* -------------------------------------------------------------------------- */
#define IF_SAMPLE_RATE 48000
@ -1275,12 +1367,6 @@ int free_buffers(dsp_t *dsp) {
/* ------------------------------------------------------------------------------------ */
ui32_t get_sample(dsp_t *dsp) {
return dsp->sample_out;
}
/* ------------------------------------------------------------------------------------ */
int find_header(dsp_t *dsp, float thres, int hdmax, int bitofs, int opt_dc) {
ui32_t k = 0;
@ -1345,3 +1431,145 @@ int find_header(dsp_t *dsp, float thres, int hdmax, int bitofs, int opt_dc) {
return EOF;
}
/* ------------------------------------------------------------------------------------ */
#else
// external FSK demod: read float32 soft symbols
float read_wav_header(pcm_t *pcm, FILE *fp) {}
int f32buf_sample(dsp_t *dsp, int inv) {}
int read_slbit(dsp_t *dsp, int *bit, int inv, int ofs, int pos, float l, int spike) {}
int read_softbit(dsp_t *dsp, hsbit_t *shb, int inv, int ofs, int pos, float l, int spike) {}
int read_softbit2p(dsp_t *dsp, hsbit_t *shb, int inv, int ofs, int pos, float l, int spike, hsbit_t *shb1) {}
int init_buffers(dsp_t *dsp) {}
int free_buffers(dsp_t *dsp) {}
int find_header(dsp_t *dsp, float thres, int hdmax, int bitofs, int opt_dc) {}
#endif
static float cmp_hdb(hdb_t *hdb) { // bit-errors?
int i, j;
int headlen = hdb->len;
int berrs1 = 0, berrs2 = 0;
i = 0;
j = hdb->bufpos;
while (i < headlen) {
if (j < 0) j = headlen-1;
if (hdb->buf[j] != hdb->hdr[headlen-1-i]) berrs1 += 1;
j--;
i++;
}
i = 0;
j = hdb->bufpos;
while (i < headlen) {
if (j < 0) j = headlen-1;
if ((hdb->buf[j]^0x01) != hdb->hdr[headlen-1-i]) berrs2 += 1;
j--;
i++;
}
if (berrs2 < berrs1) return (-headlen+berrs2)/(float)headlen;
else return ( headlen-berrs1)/(float)headlen;
return 0;
}
int find_binhead(FILE *fp, hdb_t *hdb, float *score) {
int bit;
int headlen = hdb->len;
float mv;
//*score = 0.0;
while ( (bit = fgetc(fp)) != EOF )
{
bit &= 1;
hdb->bufpos = (hdb->bufpos+1) % headlen;
hdb->buf[hdb->bufpos] = 0x30 | bit; // Ascii
mv = cmp_hdb(hdb);
if ( fabs(mv) > hdb->thb ) {
*score = mv;
return 1;
}
}
return EOF;
}
static float corr_softhdb(hdb_t *hdb) { // max score in window probably not needed
int i, j;
int headlen = hdb->len;
double sum = 0.0;
double normx = 0.0,
normy = 0.0;
float x, y;
i = 0;
j = hdb->bufpos + 1;
while (i < headlen) {
if (j >= headlen) j = 0;
x = hdb->sbuf[j];
y = 2.0*(hdb->hdr[i]&0x1) - 1.0;
sum += y * hdb->sbuf[j];
normx += x*x;
normy += y*y;
j++;
i++;
}
sum /= sqrt(normx*normy);
return sum;
}
int f32soft_read(FILE *fp, float *s) {
unsigned int word = 0;
short *b = (short*)&word;
float *f = (float*)&word;
int bps = 32;
if (fread( &word, bps/8, 1, fp) != 1) return EOF;
if (bps == 32) {
*s = *f;
}
else {
if (bps == 8) { *b -= 128; }
*s = *b/128.0;
if (bps == 16) { *s /= 256.0; }
}
return 0;
}
int find_softbinhead(FILE *fp, hdb_t *hdb, float *score) {
int headlen = hdb->len;
float sbit;
float mv;
//*score = 0.0;
while ( f32soft_read(fp, &sbit) != EOF )
{
hdb->bufpos = (hdb->bufpos+1) % headlen;
hdb->sbuf[hdb->bufpos] = sbit;
mv = corr_softhdb(hdb);
if ( fabs(mv) > hdb->ths ) {
*score = mv;
return 1;
}
}
return EOF;
}

Wyświetl plik

@ -144,16 +144,30 @@ typedef struct {
} hsbit_t;
typedef struct {
char *hdr;
char *buf;
float *sbuf;
int len;
int bufpos;
float thb;
float ths;
} hdb_t;
float read_wav_header(pcm_t *, FILE *);
int f32buf_sample(dsp_t *, int);
int read_slbit(dsp_t *, int*, int, int, int, float, int);
int read_softbit(dsp_t *, hsbit_t *, int, int, int, float, int );
int read_softbit(dsp_t *, hsbit_t *, int, int, int, float, int);
int read_softbit2p(dsp_t *dsp, hsbit_t *shb, int inv, int ofs, int pos, float l, int spike, hsbit_t *shb1);
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 f32soft_read(FILE *fp, float *s);
int find_binhead(FILE *fp, hdb_t *hdb, float *score);
int find_softbinhead(FILE *fp, hdb_t *hdb, float *score);

Wyświetl plik

@ -885,67 +885,6 @@ static int print_frame(gpx_t *gpx) {
/* -------------------------------------------------------------------------- */
// header bit buffer
typedef struct {
char *hdr;
char *buf;
char len;
int bufpos;
float ths;
} hdb_t;
static float cmp_hdb(hdb_t *hdb) { // bit-errors?
int i, j;
int headlen = hdb->len;
int berrs1 = 0, berrs2 = 0;
i = 0;
j = hdb->bufpos;
while (i < headlen) {
if (j < 0) j = headlen-1;
if (hdb->buf[j] != hdb->hdr[headlen-1-i]) berrs1 += 1;
j--;
i++;
}
i = 0;
j = hdb->bufpos;
while (i < headlen) {
if (j < 0) j = headlen-1;
if ((hdb->buf[j]^0x01) != hdb->hdr[headlen-1-i]) berrs2 += 1;
j--;
i++;
}
if (berrs2 < berrs1) return (-headlen+berrs2)/(float)headlen;
else return ( headlen-berrs1)/(float)headlen;
return 0;
}
static int find_binhead(FILE *fp, hdb_t *hdb, float *score) {
int bit;
int headlen = hdb->len;
float mv;
//*score = 0.0;
while ( (bit = fgetc(fp)) != EOF )
{
bit &= 1;
hdb->bufpos = (hdb->bufpos+1) % headlen;
hdb->buf[hdb->bufpos] = 0x30 | bit; // Ascii
mv = cmp_hdb(hdb);
if ( fabs(mv) > hdb->ths ) {
*score = mv;
return 1;
}
}
return EOF;
}
int main(int argc, char **argv) {
@ -961,6 +900,7 @@ int main(int argc, char **argv) {
int option_lp = 0;
int option_dc = 0;
int option_bin = 0;
int option_softin = 0;
int option_json = 0; // JSON blob output (for auto_rx)
int option_pcmraw = 0;
int wavloaded = 0;
@ -1042,12 +982,13 @@ int main(int argc, char **argv) {
else if ( (strcmp(*argv, "--spike") == 0) ) {
spike = 1;
}
else if ( (strcmp(*argv, "--auto") == 0) ) { option_auto = 1; }
else if (strcmp(*argv, "--bin") == 0) { option_bin = 1; } // bit/byte binary input
else if ( (strcmp(*argv, "--dist") == 0) ) { option_dist = 1; option_ecc = 1; }
else if ( (strcmp(*argv, "--json") == 0) ) { option_json = 1; option_ecc = 1; }
else if ( (strcmp(*argv, "--ch2") == 0) ) { sel_wavch = 1; } // right channel (default: 0=left)
else if ( (strcmp(*argv, "--ths") == 0) ) {
else if (strcmp(*argv, "--auto") == 0) { option_auto = 1; }
else if (strcmp(*argv, "--bin") == 0) { option_bin = 1; } // bit/byte binary input
else if (strcmp(*argv, "--softin") == 0) { option_softin = 1; } // float32 soft input
else if (strcmp(*argv, "--dist") == 0) { option_dist = 1; option_ecc = 1; }
else if (strcmp(*argv, "--json") == 0) { option_json = 1; option_ecc = 1; }
else if (strcmp(*argv, "--ch2") == 0) { sel_wavch = 1; } // right channel (default: 0=left)
else if (strcmp(*argv, "--ths") == 0) {
++argv;
if (*argv) {
thres = atof(*argv);
@ -1150,7 +1091,14 @@ int main(int argc, char **argv) {
headerlen = strlen(dfm_rawheader);
if (!option_bin) {
#ifdef EXT_FSK
if (!option_bin && !option_softin) {
option_softin = 1;
fprintf(stderr, "reading float32 soft symbols\n");
}
#endif
if (!option_bin && !option_softin) {
if (option_iq == 0 && option_pcmraw) {
fclose(fp);
@ -1198,38 +1146,48 @@ int main(int argc, char **argv) {
if ( dsp.sps < 8 ) {
fprintf(stderr, "note: sample rate low\n");
}
k = init_buffers(&dsp);
if ( k < 0 ) {
fprintf(stderr, "error: init buffers\n");
return -1;
}
bitofs += shift;
}
else {
if (option_bin && option_softin) option_bin = 0;
// init circular header bit buffer
hdb.hdr = dfm_rawheader;
hdb.len = strlen(dfm_rawheader);
hdb.ths = 1.0 - 2.1/(float)hdb.len; // 1.0-max_bit_errors/hdrlen // max 1.1 !!
hdb.thb = 1.0 - 2.1/(float)hdb.len; // 1.0-max_bit_errors/hdrlen // max 1.1 !!
hdb.bufpos = -1;
hdb.buf = calloc(hdb.len, sizeof(char));
if (hdb.buf == NULL) {
fprintf(stderr, "error: malloc\n");
return -1;
}
hdb.ths = 0.7; // caution/test false positive
hdb.sbuf = calloc(hdb.len, sizeof(float));
if (hdb.sbuf == NULL) {
fprintf(stderr, "error: malloc\n");
return -1;
}
}
k = init_buffers(&dsp);
if ( k < 0 ) {
fprintf(stderr, "error: init buffers\n");
return -1;
};
bitofs += shift;
while ( 1 )
{
if (option_bin) { // aka find_binrawhead()
header_found = find_binhead(fp, &hdb, &_mv); // symbols or bits?
hdrcnt += nfrms;
}
else { // FM-audio:
else if (option_softin) {
header_found = find_softbinhead(fp, &hdb, &_mv);
hdrcnt += nfrms;
}
else { //2 (false positive) // FM-audio:
header_found = find_header(&dsp, thres, 2, bitofs, dsp.opt_dc); // optional 2nd pass: dc=0
_mv = dsp.mv;
}
@ -1251,7 +1209,7 @@ int main(int argc, char **argv) {
frm = 0;
while ( frm < nfrms ) { // nfrms=1,2,4,8
if (option_bin) {
if (option_bin || option_softin) {
gpx._frmcnt = hdrcnt + frm;
}
else {
@ -1271,15 +1229,25 @@ int main(int argc, char **argv) {
hsbit.sb = 2*hsbit.hb - 1;
}
}
else if (option_softin) {
float s1 = 0.0;
float s2 = 0.0;
float s = 0.0;
bitQ = f32soft_read(fp, &s1);
if (bitQ != EOF) {
bitQ = f32soft_read(fp, &s2);
if (bitQ != EOF) {
s = s2-s1; // integrate both symbols // only 2nd Manchester symbol: s2
hsbit.sb = s;
hsbit.hb = (s>=0.0);
}
}
}
else {
if (option_iq >= 2) {
float bl = -1;
if (option_iq > 2) bl = 4.0;
bitQ = read_softbit(&dsp, &hsbit, 0, bitofs, bitpos, bl, 0);
}
else {
bitQ = read_softbit(&dsp, &hsbit, 0, bitofs, bitpos, -1, spike);
}
float bl = -1;
if (option_iq >= 2) spike = 0;
if (option_iq > 2) bl = 4.0;
bitQ = read_softbit(&dsp, &hsbit, 0, bitofs, bitpos, bl, spike); // symlen=2
// optional:
// normalize soft bit s_j by
// rhsbit.sb /= dsp._spb+1; // all samples in [-1,+1]
@ -1309,7 +1277,7 @@ int main(int argc, char **argv) {
}
if (!option_bin) free_buffers(&dsp);
if (!option_bin && !option_softin) free_buffers(&dsp);
else {
if (hdb.buf) { free(hdb.buf); hdb.buf = NULL; }
}

Wyświetl plik

@ -3,6 +3,10 @@
* LMS6
* (403 MHz)
*
* soft decision test:
* IQ-decoding: --vit2 (soft decision) better performance (low dB)
* FM-decoding: --vit1 (hard decision) better than --vit2
*
* sync header: correlation/matched filter
* files: lms6Xmod.c demod_mod.c demod_mod.h bch_ecc_mod.c bch_ecc_mod.h
* compile, either (a) or (b):
@ -16,7 +20,8 @@
*
* usage:
* ./lms6Xmod --vit --ecc <audio.wav>
* ( --vit recommended)
* ./lms6Xmod --vit2 --ecc --IQ 0.0 <iq_data.wav>
* ( --vit/--vit2 recommended)
* author: zilog80
*/
@ -116,12 +121,11 @@ typedef struct {
ui8_t bIn;
ui8_t codeIn;
ui8_t prevState; // 0..M=64
int w; // > 255 : if (w>250): w=250 ?
//float sw;
float w;
} states_t;
typedef struct {
char rawbits[RAWBITFRAME_LEN+OVERLAP*BITS*2 +8];
hsbit_t rawbits[RAWBITFRAME_LEN+OVERLAP*BITS*2 +8];
states_t state[RAWBITFRAME_LEN+OVERLAP +8][M];
states_t d[N];
} VIT_t;
@ -138,7 +142,7 @@ typedef struct {
double lat; double lon; double alt;
double vH; double vD; double vV;
double vE; double vN; double vU;
char blk_rawbits[RAWBITBLOCK_LEN+SYNC_LEN*BITS*2 +9];
hsbit_t blk_rawbits[RAWBITBLOCK_LEN+SYNC_LEN*BITS*2 +9];
ui8_t frame[FRM_LEN]; // = { 0x24, 0x54, 0x00, 0x00}; // dataheader
int frm_pos; // ecc_blk <-> frm_blk
int sf6;
@ -213,12 +217,16 @@ static int vit_initCodes(gpx_t *gpx) {
return 0;
}
static int vit_dist(int c, char *rc) {
return (((c>>1)^rc[0])&1) + ((c^rc[1])&1);
static float vit_dist2(int c, hsbit_t *rc) {
int c0 = 2*((c>>1) & 1)-1; // {0,1} -> {-1,+1}
int c1 = 2*(c & 1)-1;
float d2 = (c0-rc[0].sb)*(c0-rc[0].sb) + (c1-rc[1].sb)*(c1-rc[1].sb);
return d2;
}
static int vit_start(VIT_t *vit, char *rc) {
int t, m, j, c, d;
static int vit_start(VIT_t *vit, hsbit_t *rc) {
int t, m, j, c;
float d;
t = L-1;
m = M;
@ -236,7 +244,7 @@ static int vit_start(VIT_t *vit, char *rc) {
c = vit_code[j];
vit->state[t][j].bIn = j % 2;
vit->state[t][j].codeIn = c;
d = vit_dist( c, rc+2*(t-1) );
d = vit_dist2( c, rc+2*(t-1) );
vit->state[t][j].w = vit->state[t-1][vit->state[t][j].prevState].w + d;
}
m *= 2;
@ -245,7 +253,7 @@ static int vit_start(VIT_t *vit, char *rc) {
return t;
}
static int vit_next(VIT_t *vit, int t, char *rc) {
static int vit_next(VIT_t *vit, int t, hsbit_t *rc) {
int b, nstate;
int j, index;
@ -255,7 +263,7 @@ static int vit_next(VIT_t *vit, int t, char *rc) {
vit->d[nstate].bIn = b;
vit->d[nstate].codeIn = vit_code[nstate];
vit->d[nstate].prevState = j;
vit->d[nstate].w = vit->state[t][j].w + vit_dist( vit->d[nstate].codeIn, rc );
vit->d[nstate].w = vit->state[t][j].w + vit_dist2( vit->d[nstate].codeIn, rc );
}
}
@ -272,11 +280,11 @@ static int vit_next(VIT_t *vit, int t, char *rc) {
static int vit_path(VIT_t *vit, int j, int t) {
int c;
vit->rawbits[2*t] = '\0';
vit->rawbits[2*t].hb = '\0';
while (t > 0) {
c = vit->state[t][j].codeIn;
vit->rawbits[2*t -2] = 0x30 + ((c>>1) & 1);
vit->rawbits[2*t -1] = 0x30 + (c & 1);
vit->rawbits[2*t -2].hb = 0x30 + ((c>>1) & 1);
vit->rawbits[2*t -1].hb = 0x30 + (c & 1);
j = vit->state[t][j].prevState;
t--;
}
@ -284,13 +292,20 @@ static int vit_path(VIT_t *vit, int j, int t) {
return 0;
}
static int viterbi(VIT_t *vit, char *rc) {
static int hbstr_len(hsbit_t *hsbit) {
int len = 0;
while (hsbit[len].hb) len++;
return len;
}
static int viterbi(VIT_t *vit, hsbit_t *rc) {
int t, tmax;
int j, j_min, w_min;
int j, j_min;
float w_min;
vit_start(vit, rc);
tmax = strlen(rc)/2;
tmax = hbstr_len(rc)/2;
for (t = L-1; t < tmax; t++)
{
@ -315,15 +330,15 @@ static int viterbi(VIT_t *vit, char *rc) {
// ------------------------------------------------------------------------
static int deconv(char* rawbits, char *bits) {
static int deconv(hsbit_t *rawbits, char *bits) {
int j, n, bitA, bitB;
char *p;
hsbit_t *p;
int len;
int errors = 0;
int m = L-1;
len = strlen(rawbits);
len = hbstr_len(rawbits);
for (j = 0; j < m; j++) bits[j] = '0';
n = 0;
while ( 2*(m+n) < len ) {
@ -333,10 +348,10 @@ static int deconv(char* rawbits, char *bits) {
bitA ^= (bits[n+j]&1) & (polyA[j]&1);
bitB ^= (bits[n+j]&1) & (polyB[j]&1);
}
if ( (bitA^(p[0]&1))==(polyA[m]&1) && (bitB^(p[1]&1))==(polyB[m]&1) ) bits[n+m] = '1';
else if ( (bitA^(p[0]&1))==0 && (bitB^(p[1]&1))==0 ) bits[n+m] = '0';
if ( (bitA^(p[0].hb&1))==(polyA[m]&1) && (bitB^(p[1].hb&1))==(polyB[m]&1) ) bits[n+m] = '1';
else if ( (bitA^(p[0].hb&1))==0 && (bitB^(p[1].hb&1))==0 ) bits[n+m] = '0';
else {
if ( (bitA^(p[0]&1))!=(polyA[m]&1) && (bitB^(p[1]&1))==(polyB[m]&1) ) bits[n+m] = 0x39;
if ( (bitA^(p[0].hb&1))!=(polyA[m]&1) && (bitB^(p[1].hb&1))==(polyB[m]&1) ) bits[n+m] = 0x39;
else bits[n+m] = 0x38;
errors = n;
break;
@ -795,7 +810,7 @@ static void proc_frame(gpx_t *gpx, int len) {
ui8_t block_bytes[FRAME_LEN+8];
ui8_t rs_cw[rs_N];
char frame_bits[BITFRAME_LEN+OVERLAP*BITS +8]; // init L-1 bits mit 0
char *rawbits = NULL;
hsbit_t *rawbits = NULL;
int i, j;
int err = 0;
int errs = 0;
@ -804,13 +819,17 @@ static void proc_frame(gpx_t *gpx, int len) {
if ((len % 8) > 4) {
while (len % 8) gpx->blk_rawbits[len++] = '0';
while (len % 8) {
gpx->blk_rawbits[len].hb = '0';
gpx->blk_rawbits[len].sb = -1;
len++;
}
}
gpx->blk_rawbits[len] = '\0';
gpx->blk_rawbits[len].hb = '\0';
flen = len / (2*BITS);
if (gpx->option.vit == 1) {
if (gpx->option.vit) {
viterbi(gpx->vit, gpx->blk_rawbits);
rawbits = gpx->vit->rawbits;
}
@ -922,6 +941,8 @@ static void proc_frame(gpx_t *gpx, int len) {
}
/* -------------------------------------------------------------------------- */
int main(int argc, char **argv) {
@ -930,6 +951,7 @@ int main(int argc, char **argv) {
int option_iq = 0;
int option_lp = 0;
int option_dc = 0;
int option_softin = 0;
int option_pcmraw = 0;
int wavloaded = 0;
int sel_wavch = 0; // audio channel: left
@ -940,7 +962,7 @@ int main(int argc, char **argv) {
int k;
int bit, rbit;
hsbit_t hsbit, rhsbit, rhsbit1;
int bitpos = 0;
int bitQ;
int pos;
@ -948,15 +970,17 @@ int main(int argc, char **argv) {
int header_found = 0;
float thres = 0.68;
float thres = 0.65;
float _mv = 0.0;
float lpIQ_bw = 16e3;
int symlen = 1;
int bitofs = 0;
int shift = 0;
int bitofs6 = 1; // +1 .. +2
int bitofsX = 0; // 0 .. +1
int bitofs6 = 0; // -1 .. +2
int bitofsX = 0; // -1 .. +1
unsigned int bc = 0;
@ -966,17 +990,21 @@ int main(int argc, char **argv) {
pcm_t pcm = {0};
dsp_t dsp = {0}; //memset(&dsp, 0, sizeof(dsp));
/*
hdb_t hdb = {0};
/*
// gpx_t _gpx = {0}; gpx_t *gpx = &_gpx; // stack size ...
gpx_t *gpx = NULL;
gpx = calloc(1, sizeof(gpx_t));
//memset(gpx, 0, sizeof(gpx_t));
*/
*/
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);
#endif
@ -1010,7 +1038,9 @@ int main(int argc, char **argv) {
gpx->option.raw = 1; // bytes - rs_ecc_codewords
}
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, "--ecc3") == 0) { gpx->option.ecc = 3; } // RS-ECC
else if (strcmp(*argv, "--vit" ) == 0) { gpx->option.vit = 1; } // viterbi-hard
else if (strcmp(*argv, "--vit2" ) == 0) { gpx->option.vit = 2; } // viterbi-soft
else if ( (strcmp(*argv, "--gpsweek") == 0) ) {
++argv;
if (*argv) {
@ -1022,8 +1052,9 @@ 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, "--ch2") == 0) ) { sel_wavch = 1; } // right channel (default: 0=left)
else if ( (strcmp(*argv, "--ths") == 0) ) {
else if (strcmp(*argv, "--ch2") == 0) { sel_wavch = 1; } // right channel (default: 0=left)
else if (strcmp(*argv, "--softin") == 0) { option_softin = 1; } // float32 soft input
else if (strcmp(*argv, "--ths") == 0) {
++argv;
if (*argv) {
thres = atof(*argv);
@ -1053,6 +1084,14 @@ int main(int argc, char **argv) {
option_iq = 5;
}
else if (strcmp(*argv, "--lp") == 0) { option_lp = 1; } // IQ 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;
}
else if (strcmp(*argv, "--dc") == 0) { option_dc = 1; }
else if (strcmp(*argv, "--min") == 0) {
option_min = 1;
@ -1094,71 +1133,113 @@ int main(int argc, char **argv) {
if (gpx->option.raw == 4) gpx->option.ecc = 1;
// init gpx
memcpy(gpx->blk_rawbits, blk_syncbits, sizeof(blk_syncbits));
memcpy(gpx->frame, frm_sync6, sizeof(frm_sync6));
gpx->frm_pos = 0; // ecc_blk <-> frm_blk
gpx->sf6 = 0;
gpx->sfX = 0;
//memcpy(gpx->blk_rawbits, blk_syncbits, sizeof(blk_syncbits));
for (k = 0; k < strlen(blk_syncbits); k++) { // strlen(blk_syncbits)=BLOCKSTART
int hbit = blk_syncbits[k] & 1;
gpx->blk_rawbits[k].hb = hbit + 0x30;
gpx->blk_rawbits[k].sb = 2*hbit-1;
}
gpx->option.inv = option_inv; // irrelevant
gpx->week = gpsweek;
if (option_iq == 0 && option_pcmraw) {
fclose(fp);
fprintf(stderr, "error: raw data not IQ\n");
return -1;
}
if (option_iq) sel_wavch = 0;
pcm.sel_ch = sel_wavch;
if (option_pcmraw == 0) {
k = read_wav_header(&pcm, fp);
if ( k < 0 ) {
#ifdef EXT_FSK
if (!option_softin) {
option_softin = 1;
fprintf(stderr, "reading float32 soft symbols\n");
}
#endif
if (!option_softin) {
if (option_iq == 0 && option_pcmraw) {
fclose(fp);
fprintf(stderr, "error: wav header\n");
fprintf(stderr, "error: raw data not IQ\n");
return -1;
}
if (option_iq == 0 && gpx->option.vit == 2) { // FM-demodulated data not recommended
gpx->option.vit = 1; // for soft-decoding
fprintf(stderr, "info: soft decoding only for IQ\n");
}
if (option_iq) sel_wavch = 0;
pcm.sel_ch = sel_wavch;
if (option_pcmraw == 0) {
k = read_wav_header(&pcm, fp);
if ( k < 0 ) {
fclose(fp);
fprintf(stderr, "error: wav header\n");
return -1;
}
}
symlen = 1;
// init dsp
//
dsp.fp = fp;
dsp.sr = pcm.sr;
dsp.bps = pcm.bps;
dsp.nch = pcm.nch;
dsp.ch = pcm.sel_ch;
dsp.br = (float)BAUD_RATE6;
dsp.sps = (float)dsp.sr/dsp.br;
dsp.symlen = symlen;
dsp.symhd = 1;
dsp._spb = dsp.sps*symlen;
dsp.hdr = rawheader;
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.opt_iq = option_iq;
dsp.opt_lp = option_lp;
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;
if ( dsp.sps < 8 ) {
fprintf(stderr, "note: sample rate low (%.1f sps)\n", dsp.sps);
}
//headerlen = dsp.hdrlen;
k = init_buffers(&dsp); // baud difference not significant
if ( k < 0 ) {
fprintf(stderr, "error: init buffers\n");
return -1;
}
}
symlen = 1;
// init dsp
//
dsp.fp = fp;
dsp.sr = pcm.sr;
dsp.bps = pcm.bps;
dsp.nch = pcm.nch;
dsp.ch = pcm.sel_ch;
dsp.br = (float)BAUD_RATE6;
dsp.sps = (float)dsp.sr/dsp.br;
dsp.symlen = symlen;
dsp.symhd = 1;
dsp._spb = dsp.sps*symlen;
dsp.hdr = rawheader;
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.opt_iq = option_iq;
dsp.opt_lp = option_lp;
dsp.lpIQ_bw = 8e3; // IF lowpass bandwidth
dsp.lpFM_bw = 6e3; // FM audio lowpass
dsp.opt_dc = option_dc;
dsp.opt_IFmin = option_min;
if ( dsp.sps < 8 ) {
fprintf(stderr, "note: sample rate low (%.1f sps)\n", dsp.sps);
else {
// init circular header bit buffer
hdb.hdr = rawheader;
hdb.len = strlen(rawheader);
//hdb.thb = 1.0 - 3.1/(float)hdb.len; // 1.0-max_bit_errors/hdrlen
hdb.bufpos = -1;
hdb.buf = NULL;
/*
calloc(hdb.len, sizeof(char));
if (hdb.buf == NULL) {
fprintf(stderr, "error: malloc\n");
return -1;
}
*/
hdb.ths = 0.7; // caution/test false positive
hdb.sbuf = calloc(hdb.len, sizeof(float));
if (hdb.sbuf == NULL) {
fprintf(stderr, "error: malloc\n");
return -1;
}
}
//headerlen = dsp.hdrlen;
k = init_buffers(&dsp); // baud difference not significant
if ( k < 0 ) {
fprintf(stderr, "error: init buffers\n");
return -1;
};
if (gpx->option.vit) {
k = vit_initCodes(gpx);
@ -1194,9 +1275,13 @@ int main(int argc, char **argv) {
while ( 1 )
{
// FM-audio:
header_found = find_header(&dsp, thres, 6, bitofs, dsp.opt_dc); // optional 2nd pass: dc=0
_mv = dsp.mv;
if (option_softin) {
header_found = find_softbinhead(fp, &hdb, &_mv);
}
else { // FM-audio:
header_found = find_header(&dsp, thres, 10, bitofs, dsp.opt_dc); // optional 2nd pass: dc=0
_mv = dsp.mv;
}
if (header_found == EOF) break;
@ -1220,19 +1305,49 @@ int main(int argc, char **argv) {
while ( pos < rawbitblock_len ) {
bitQ = read_slbit(&dsp, &rbit, 0, bitofs, bitpos, -1, 0); // symlen=1
if (option_softin) {
float s = 0.0;
bitQ = f32soft_read(fp, &s);
if (bitQ != EOF) {
rhsbit.sb = s;
rhsbit.hb = (s>=0.0);
}
}
else {
//bitQ = read_softbit(&dsp, &rhsbit, 0, bitofs, bitpos, -1, 0); // symlen=1
bitQ = read_softbit2p(&dsp, &rhsbit, 0, bitofs, bitpos, -1, 0, &rhsbit1); // symlen=1
if (gpx->option.ecc == 3) {
if (rhsbit.sb*rhsbit1.sb < 0) {
rhsbit.sb += rhsbit1.sb;
rhsbit.hb = (rhsbit.sb>=0.0);
}
}
}
if (bitQ == EOF) { break; }
bit = rbit ^ (bc%2); // (c0,inv(c1))
gpx->blk_rawbits[pos] = 0x30 + bit;
// optional:
// normalize soft bit s_j by
// rhsbit.sb /= dsp._spb+1; // all samples in [-1,+1]
// or at the end by max|s_j| over all bits in rawframe
// (only if |sj| >> 1 by factor 100)
hsbit.hb = rhsbit.hb ^ (bc%2); // (c0,inv(c1))
int sgn = -2*(((unsigned int)bc)%2)+1;
hsbit.sb = sgn * rhsbit.sb;
if (gpx->option.vit == 1) { // hard decision
hsbit.sb = 2*hsbit.hb -1;
}
gpx->blk_rawbits[pos] = hsbit;
gpx->blk_rawbits[pos].hb += 0x30;
bc++;
pos++;
bitpos += 1;
}
gpx->blk_rawbits[pos] = '\0';
gpx->blk_rawbits[pos].hb = '\0';
time_elapsed_sec = dsp.sample_in / (double)dsp.sr;
proc_frame(gpx, pos);
@ -1276,7 +1391,11 @@ int main(int argc, char **argv) {
}
free_buffers(&dsp);
if (!option_softin) free_buffers(&dsp);
else {
if (hdb.buf) { free(hdb.buf); hdb.buf = NULL; }
}
if (gpx->vit) { free(gpx->vit); gpx->vit = NULL; }
fclose(fp);

Plik diff jest za duży Load Diff

Wyświetl plik

@ -1102,6 +1102,8 @@ static int print_frame(gpx_t *gpx, int pos) {
return (gpx->frame_bytes[0]<<8)|gpx->frame_bytes[1];
}
/* -------------------------------------------------------------------------- */
int main(int argc, char **argv) {
@ -1115,6 +1117,8 @@ int main(int argc, char **argv) {
int option_iq = 0;
int option_lp = 0;
int option_dc = 0;
int option_chk = 0;
int option_softin = 0;
int option_pcmraw = 0;
int wavloaded = 0;
int sel_wavch = 0; // audio channel: left
@ -1129,6 +1133,7 @@ int main(int argc, char **argv) {
int bitpos = 0;
int bitQ;
int pos;
hsbit_t hsbit, hsbit1;
//int headerlen = 0;
@ -1144,6 +1149,8 @@ int main(int argc, char **argv) {
pcm_t pcm = {0};
dsp_t dsp = {0}; //memset(&dsp, 0, sizeof(dsp));
hdb_t hdb = {0};
gpx_t gpx = {0};
@ -1185,8 +1192,10 @@ int main(int argc, char **argv) {
else if ( (strcmp(*argv, "--spike") == 0) ) {
spike = 1;
}
else if ( (strcmp(*argv, "--ch2") == 0) ) { sel_wavch = 1; } // right channel (default: 0=left)
else if ( (strcmp(*argv, "--ths") == 0) ) {
else if (strcmp(*argv, "--chk3") == 0) { option_chk = 3; }
else if (strcmp(*argv, "--ch2") == 0) { sel_wavch = 1; } // right channel (default: 0=left)
else if (strcmp(*argv, "--softin") == 0) { option_softin = 1; } // float32 soft input
else if (strcmp(*argv, "--ths") == 0) {
++argv;
if (*argv) {
thres = atof(*argv);
@ -1250,6 +1259,7 @@ int main(int argc, char **argv) {
if (!wavloaded) fp = stdin;
// init gpx
gpx.option.inv = option_inv; // irrelevant
gpx.option.vbs = option_verbose;
gpx.option.raw = option_raw;
@ -1257,71 +1267,105 @@ int main(int argc, char **argv) {
gpx.option.col = option_color;
// init gpx
if (option_iq == 0 && option_pcmraw) {
fclose(fp);
fprintf(stderr, "error: raw data not IQ\n");
return -1;
#ifdef EXT_FSK
if (!option_softin) {
option_softin = 1;
fprintf(stderr, "reading float32 soft symbols\n");
}
if (option_iq) sel_wavch = 0;
#endif
pcm.sel_ch = sel_wavch;
if (option_pcmraw == 0) {
k = read_wav_header(&pcm, fp);
if ( k < 0 ) {
if (!option_softin) {
if (option_iq == 0 && option_pcmraw) {
fclose(fp);
fprintf(stderr, "error: wav header\n");
fprintf(stderr, "error: raw data not IQ\n");
return -1;
}
if (option_iq) sel_wavch = 0;
pcm.sel_ch = sel_wavch;
if (option_pcmraw == 0) {
k = read_wav_header(&pcm, fp);
if ( k < 0 ) {
fclose(fp);
fprintf(stderr, "error: wav header\n");
return -1;
}
}
// m10: BT>1?, h=1.2 ?
symlen = 2;
// init dsp
//
dsp.fp = fp;
dsp.sr = pcm.sr;
dsp.bps = pcm.bps;
dsp.nch = pcm.nch;
dsp.ch = pcm.sel_ch;
dsp.br = (float)BAUD_RATE;
dsp.sps = (float)dsp.sr/dsp.br;
dsp.symlen = symlen;
dsp.symhd = 1; // M10!header
dsp._spb = dsp.sps*symlen;
dsp.hdr = rawheader;
dsp.hdrlen = strlen(rawheader);
dsp.BT = 1.8; // bw/time (ISI) // 1.0..2.0
dsp.h = 0.9; // 1.2 modulation index
dsp.opt_iq = option_iq;
dsp.opt_lp = option_lp;
dsp.lpIQ_bw = 24e3; // IF lowpass bandwidth
dsp.lpFM_bw = 10e3; // FM audio lowpass
dsp.opt_dc = option_dc;
dsp.opt_IFmin = option_min;
if ( dsp.sps < 8 ) {
fprintf(stderr, "note: sample rate low (%.1f sps)\n", dsp.sps);
}
//headerlen = dsp.hdrlen;
k = init_buffers(&dsp);
if ( k < 0 ) {
fprintf(stderr, "error: init buffers\n");
return -1;
}
bitofs += shift;
}
else {
// init circular header bit buffer
hdb.hdr = rawheader;
hdb.len = strlen(rawheader);
//hdb.thb = 1.0 - 3.1/(float)hdb.len; // 1.0-max_bit_errors/hdrlen
hdb.bufpos = -1;
hdb.buf = NULL;
/*
calloc(hdb.len, sizeof(char));
if (hdb.buf == NULL) {
fprintf(stderr, "error: malloc\n");
return -1;
}
*/
hdb.ths = 0.8; // caution 0.7: false positive / offset
hdb.sbuf = calloc(hdb.len, sizeof(float));
if (hdb.sbuf == NULL) {
fprintf(stderr, "error: malloc\n");
return -1;
}
}
// m10: BT>1?, h=1.2 ?
symlen = 2;
// init dsp
//
dsp.fp = fp;
dsp.sr = pcm.sr;
dsp.bps = pcm.bps;
dsp.nch = pcm.nch;
dsp.ch = pcm.sel_ch;
dsp.br = (float)BAUD_RATE;
dsp.sps = (float)dsp.sr/dsp.br;
dsp.symlen = symlen;
dsp.symhd = 1; // M10!header
dsp._spb = dsp.sps*symlen;
dsp.hdr = rawheader;
dsp.hdrlen = strlen(rawheader);
dsp.BT = 1.8; // bw/time (ISI) // 1.0..2.0
dsp.h = 0.9; // 1.2 modulation index
dsp.opt_iq = option_iq;
dsp.opt_lp = option_lp;
dsp.lpIQ_bw = 24e3; // IF lowpass bandwidth
dsp.lpFM_bw = 10e3; // FM audio lowpass
dsp.opt_dc = option_dc;
dsp.opt_IFmin = option_min;
if ( dsp.sps < 8 ) {
fprintf(stderr, "note: sample rate low (%.1f sps)\n", dsp.sps);
}
//headerlen = dsp.hdrlen;
k = init_buffers(&dsp);
if ( k < 0 ) {
fprintf(stderr, "error: init buffers\n");
return -1;
};
bitofs += shift;
while ( 1 )
{
// FM-audio:
header_found = find_header(&dsp, thres, 2, bitofs, dsp.opt_dc); // optional 2nd pass: dc=0
_mv = dsp.mv;
if (option_softin) {
header_found = find_softbinhead(fp, &hdb, &_mv);
}
else { // FM-audio:
header_found = find_header(&dsp, thres, 2, bitofs, dsp.opt_dc); // optional 2nd pass: dc=0
_mv = dsp.mv;
}
if (header_found == EOF) break;
@ -1339,15 +1383,31 @@ int main(int argc, char **argv) {
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);
if (option_softin) {
float s1 = 0.0;
float s2 = 0.0;
float s = 0.0;
bitQ = f32soft_read(fp, &s1);
if (bitQ != EOF) {
bitQ = f32soft_read(fp, &s2);
if (bitQ != EOF) {
s = s2-s1; // integrate both symbols // only 2nd Manchester symbol: s2
bit = (s>=0.0); // no soft decoding
}
}
}
else {
bitQ = read_slbit(&dsp, &bit, 0/*gpx.option.inv*/, bitofs, bitpos, -1, spike); // symlen=2
float bl = -1;
if (option_iq >= 2) spike = 0;
if (option_iq > 2) bl = 4.0;
//bitQ = read_slbit(&dsp, &bit, 0, bitofs, bitpos, bl, spike); // symlen=2
bitQ = read_softbit2p(&dsp, &hsbit, 0, bitofs, bitpos, bl, spike, &hsbit1); // symlen=1
bit = hsbit.hb;
if (option_chk == 3 && option_iq) {
//if (hsbit.sb*hsbit1.sb < 0)
bit = (hsbit.sb+0.25*hsbit1.sb)>=0;
}
}
if ( bitQ == EOF ) { break; }
gpx.frame_bits[pos] = 0x31 ^ (bit0 ^ bit);
@ -1364,7 +1424,13 @@ int main(int argc, char **argv) {
// 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 (option_softin) {
float s = 0.0;
bitQ = f32soft_read(fp, &s);
}
else {
bitQ = read_slbit(&dsp, &bit, 0, bitofs, bitpos, -1, 0); // symlen=2
}
if ( bitQ == EOF) break;
bitpos++;
}
@ -1374,7 +1440,11 @@ int main(int argc, char **argv) {
}
}
free_buffers(&dsp);
if (!option_softin) free_buffers(&dsp);
else {
if (hdb.buf) { free(hdb.buf); hdb.buf = NULL; }
}
fclose(fp);

Wyświetl plik

@ -212,6 +212,7 @@ int main(int argc, char **argv) {
int option_iq = 0;
int option_lp = 0;
int option_dc = 0;
int option_softin = 0;
int option_pcmraw = 0;
int sel_wavch = 0;
int wavloaded = 0;
@ -267,6 +268,8 @@ int main(int argc, char **argv) {
pcm_t pcm = {0};
dsp_t dsp = {0}; //memset(&dsp, 0, sizeof(dsp));
hdb_t hdb = {0};
gpx_t gpx = {0};
@ -308,8 +311,9 @@ int main(int argc, char **argv) {
}
else return -1;
}
else if ( (strcmp(*argv, "--ch2") == 0) ) { sel_wavch = 1; } // right channel (default: 0=left)
else if ( (strcmp(*argv, "--ths") == 0) ) {
else if (strcmp(*argv, "--ch2") == 0) { sel_wavch = 1; } // right channel (default: 0=left)
else if (strcmp(*argv, "--softin") == 0) { option_softin = 1; } // float32 soft input
else if (strcmp(*argv, "--ths") == 0) {
++argv;
if (*argv) {
thres = atof(*argv);
@ -378,63 +382,98 @@ int main(int argc, char **argv) {
if (!wavloaded) fp = stdin;
if (option_iq == 0 && option_pcmraw) {
fclose(fp);
fprintf(stderr, "error: raw data not IQ\n");
return -1;
#ifdef EXT_FSK
if (!option_softin) {
option_softin = 1;
fprintf(stderr, "reading float32 soft symbols\n");
}
if (option_iq) sel_wavch = 0;
#endif
pcm.sel_ch = sel_wavch;
if (option_pcmraw == 0) {
k = read_wav_header(&pcm, fp);
if ( k < 0 ) {
if (!option_softin) {
if (option_iq == 0 && option_pcmraw) {
fclose(fp);
fprintf(stderr, "error: wav header\n");
fprintf(stderr, "error: raw data not IQ\n");
return -1;
}
if (option_iq) sel_wavch = 0;
pcm.sel_ch = sel_wavch;
if (option_pcmraw == 0) {
k = read_wav_header(&pcm, fp);
if ( k < 0 ) {
fclose(fp);
fprintf(stderr, "error: wav header\n");
return -1;
}
}
symlen = 1;
// init dsp
//
dsp.fp = fp;
dsp.sr = pcm.sr;
dsp.bps = pcm.bps;
dsp.nch = pcm.nch;
dsp.ch = pcm.sel_ch;
dsp.br = (float)BAUD_RATE;
dsp.sps = (float)dsp.sr/dsp.br;
dsp.symlen = symlen;
dsp.symhd = 1;
dsp._spb = dsp.sps*symlen;
dsp.hdr = rawheader;
dsp.hdrlen = strlen(rawheader);
dsp.BT = 1.2; // bw/time (ISI) // 1.0..2.0
dsp.h = 2.4; // 2.8
dsp.opt_iq = option_iq;
dsp.opt_lp = option_lp;
dsp.lpIQ_bw = 16e3; // IF lowpass bandwidth
dsp.lpFM_bw = 4e3; // FM audio lowpass
dsp.opt_dc = option_dc;
dsp.opt_IFmin = option_min;
if ( dsp.sps < 8 ) {
fprintf(stderr, "note: sample rate low (%.1f sps)\n", dsp.sps);
}
if (baudrate > 0) {
dsp.br = (float)baudrate;
dsp.sps = (float)dsp.sr/dsp.br;
fprintf(stderr, "sps corr: %.4f\n", dsp.sps);
}
k = init_buffers(&dsp);
if ( k < 0 ) {
fprintf(stderr, "error: init buffers\n");
return -1;
}
bitofs += shift;
}
else {
// init circular header bit buffer
hdb.hdr = rawheader;
hdb.len = strlen(rawheader);
//hdb.thb = 1.0 - 3.1/(float)hdb.len; // 1.0-max_bit_errors/hdrlen
hdb.bufpos = -1;
hdb.buf = NULL;
/*
calloc(hdb.len, sizeof(char));
if (hdb.buf == NULL) {
fprintf(stderr, "error: malloc\n");
return -1;
}
*/
hdb.ths = 0.8; // caution/test false positive
hdb.sbuf = calloc(hdb.len, sizeof(float));
if (hdb.sbuf == NULL) {
fprintf(stderr, "error: malloc\n");
return -1;
}
}
symlen = 1;
// init dsp
//
dsp.fp = fp;
dsp.sr = pcm.sr;
dsp.bps = pcm.bps;
dsp.nch = pcm.nch;
dsp.ch = pcm.sel_ch;
dsp.br = (float)BAUD_RATE;
dsp.sps = (float)dsp.sr/dsp.br;
dsp.symlen = symlen;
dsp.symhd = 1;
dsp._spb = dsp.sps*symlen;
dsp.hdr = rawheader;
dsp.hdrlen = strlen(rawheader);
dsp.BT = 1.2; // bw/time (ISI) // 1.0..2.0
dsp.h = 2.4; // 2.8
dsp.opt_iq = option_iq;
dsp.opt_lp = option_lp;
dsp.lpIQ_bw = 16e3; // IF lowpass bandwidth
dsp.lpFM_bw = 4e3; // FM audio lowpass
dsp.opt_dc = option_dc;
dsp.opt_IFmin = option_min;
if ( dsp.sps < 8 ) {
fprintf(stderr, "note: sample rate low (%.1f sps)\n", dsp.sps);
}
if (baudrate > 0) {
dsp.br = (float)baudrate;
dsp.sps = (float)dsp.sr/dsp.br;
fprintf(stderr, "sps corr: %.4f\n", dsp.sps);
}
k = init_buffers(&dsp);
if ( k < 0 ) {
fprintf(stderr, "error: init buffers\n");
return -1;
};
if (option_ecc) {
rs_init_BCH64(&gpx.RS);
@ -442,14 +481,16 @@ int main(int argc, char **argv) {
gpx.sn = -1;
bitofs += shift;
while ( 1 )
{
// FM-audio:
header_found = find_header(&dsp, thres, 1, bitofs, dsp.opt_dc); // optional 2nd pass: dc=0
_mv = dsp.mv;
if (option_softin) {
header_found = find_softbinhead(fp, &hdb, &_mv);
}
else { // FM-audio:
header_found = find_header(&dsp, thres, 1, bitofs, dsp.opt_dc); // optional 2nd pass: dc=0
_mv = dsp.mv;
}
if (header_found == EOF) break;
@ -462,9 +503,14 @@ int main(int argc, char **argv) {
while (bitpos < RAWBITFRAME_LEN/2-RAWHEADLEN) { // 2*600-48
bitQ = read_slbit(&dsp, &bit, 0, bitofs, bitpos, -1, 0); // symlen=1
if (option_softin) {
float s = 0.0;
bitQ = f32soft_read(fp, &s);
if (bitQ != EOF) bit = (s>=0.0); // no soft decoding
}
else {
bitQ = read_slbit(&dsp, &bit, 0, bitofs, bitpos, -1, 0); // symlen=1
}
if (bitQ == EOF) { break; }
gpx.frame_rawbits[bitpos] = 0x30 + bit;
@ -768,7 +814,11 @@ int main(int argc, char **argv) {
printf("\n");
free_buffers(&dsp);
if (!option_softin) free_buffers(&dsp);
else {
if (hdb.buf) { free(hdb.buf); hdb.buf = NULL; }
}
fclose(fp);

Wyświetl plik

@ -87,6 +87,7 @@ typedef struct {
float T; float RH;
ui32_t crc;
ui8_t frame[FRAME_LEN];
ui8_t dfrm[FRAME_LEN];
ui8_t calibytes[51*16];
ui8_t calfrchk[51];
float ptu_Rf1; // ref-resistor f1 (750 Ohm)
@ -1006,7 +1007,27 @@ static int rs41_ecc(gpx_t *gpx, int frmlen) {
errors2 = rs_decode(&gpx->RS, cw2, err_pos2, err_val2);
if (gpx->option.ecc == 2 && (errors1 < 0 || errors2 < 0))
if (gpx->option.ecc >= 2) // option_softin: mark weak dfrm[]
{ // 2nd pass
if (errors1 < 0) {
for (i = 0; i < frmlen/2; i++) gpx->frame[2*i] ^= gpx->dfrm[2*i];
for (i = 0; i < rs_K; i++) cw1[rs_R+i] = gpx->frame[cfg_rs41.msgpos+2*i ];
errors1 = rs_decode(&gpx->RS, cw1, err_pos1, err_val1);
if (errors1 < 0) {
for (i = 0; i < frmlen/2; i++) gpx->frame[2*i] ^= gpx->dfrm[2*i];
}
}
if (errors2 < 0) {
for (i = 0; i < frmlen/2; i++) gpx->frame[2*i+1] ^= gpx->dfrm[2*i+1];
for (i = 0; i < rs_K; i++) cw2[rs_R+i] = gpx->frame[cfg_rs41.msgpos+2*i+1];
errors2 = rs_decode(&gpx->RS, cw2, err_pos2, err_val2);
if (errors2 < 0) {
for (i = 0; i < frmlen/2; i++) gpx->frame[2*i+1] ^= gpx->dfrm[2*i+1];
}
}
}
if (gpx->option.ecc >= 2 && (errors1 < 0 || errors2 < 0))
{ // 2nd pass
gpx->frame[pos_FRAME] = (pck_FRAME>>8)&0xFF; gpx->frame[pos_FRAME+1] = pck_FRAME&0xFF;
gpx->frame[pos_PTU] = (pck_PTU >>8)&0xFF; gpx->frame[pos_PTU +1] = pck_PTU &0xFF;
@ -1032,6 +1053,14 @@ static int rs41_ecc(gpx_t *gpx, int frmlen) {
errors2 = rs_decode(&gpx->RS, cw2, err_pos2, err_val2);
}
if (gpx->option.ecc >= 3)
{ // 3nd pass: erasures ...
if (errors1 < 0) {
}
if (errors2 < 0) {
}
}
// Wenn Fehler im 00-padding korrigiert wurden,
// war entweder der frame zu kurz, oder
@ -1448,7 +1477,7 @@ static void print_frame(gpx_t *gpx, int len) {
}
if (gpx->option.ecc) {
if (ec >= 0) fprintf(stdout, " [OK]"); else fprintf(stdout, " [NO]");
if (gpx->option.ecc /*== 2*/) {
if (gpx->option.ecc /*>= 2*/) {
if (ec > 0) fprintf(stdout, " (%d)", ec);
if (ec < 0) {
if (ec == -1) fprintf(stdout, " (-+)");
@ -1467,69 +1496,6 @@ static void print_frame(gpx_t *gpx, int len) {
/* -------------------------------------------------------------------------- */
// header bit buffer
typedef struct {
char *hdr;
char *buf;
char len;
int bufpos;
float ths;
} hdb_t;
static float cmp_hdb(hdb_t *hdb) { // bit-errors?
int i, j;
int headlen = hdb->len;
int berrs1 = 0, berrs2 = 0;
i = 0;
j = hdb->bufpos;
while (i < headlen) {
if (j < 0) j = headlen-1;
if (hdb->buf[j] != hdb->hdr[headlen-1-i]) berrs1 += 1;
j--;
i++;
}
i = 0;
j = hdb->bufpos;
while (i < headlen) {
if (j < 0) j = headlen-1;
if ((hdb->buf[j]^0x01) != hdb->hdr[headlen-1-i]) berrs2 += 1;
j--;
i++;
}
if (berrs2 < berrs1) return (-headlen+berrs2)/(float)headlen;
else return ( headlen-berrs1)/(float)headlen;
return 0;
}
static int find_binhead(FILE *fp, hdb_t *hdb, float *score) {
int bit;
int headlen = hdb->len;
float mv;
//*score = 0.0;
while ( (bit = fgetc(fp)) != EOF )
{
bit &= 1;
hdb->bufpos = (hdb->bufpos+1) % headlen;
hdb->buf[hdb->bufpos] = 0x30 | bit; // Ascii
mv = cmp_hdb(hdb);
if ( fabs(mv) > hdb->ths ) {
*score = mv;
return 1;
}
}
return EOF;
}
int main(int argc, char *argv[]) {
//int option_inv = 0; // invertiert Signal
@ -1538,6 +1504,7 @@ int main(int argc, char *argv[]) {
int option_lp = 0;
int option_dc = 0;
int option_bin = 0;
int option_softin = 0;
int option_pcmraw = 0;
int wavloaded = 0;
int sel_wavch = 0; // audio channel: left
@ -1554,12 +1521,16 @@ int main(int argc, char *argv[]) {
byte_count = FRAMESTART;
int bit, byte;
int bitQ;
int difbyte = 0;
hsbit_t hsbit, hsbit1;
int header_found = 0;
float thres = 0.7; // dsp.mv threshold
float _mv = 0.0;
float lpIQ_bw = 7.4e3;
int symlen = 1;
int bitofs = 2; // +0 .. +3
int shift = 0;
@ -1608,12 +1579,14 @@ int main(int argc, char *argv[]) {
}
else if (strcmp(*argv, "--ecc" ) == 0) { gpx.option.ecc = 1; }
else if (strcmp(*argv, "--ecc2") == 0) { gpx.option.ecc = 2; }
else if (strcmp(*argv, "--ecc3") == 0) { gpx.option.ecc = 3; }
else if (strcmp(*argv, "--sat") == 0) { gpx.option.sat = 1; }
else if (strcmp(*argv, "--ptu") == 0) { gpx.option.ptu = 1; }
else if (strcmp(*argv, "--silent") == 0) { gpx.option.slt = 1; }
else if (strcmp(*argv, "--ch2") == 0) { sel_wavch = 1; } // right channel (default: 0=left)
else if (strcmp(*argv, "--auto") == 0) { gpx.option.aut = 1; }
else if (strcmp(*argv, "--bin") == 0) { option_bin = 1; } // bit/byte binary input
else if (strcmp(*argv, "--bin") == 0) { option_bin = 1; } // bit/byte binary input
else if (strcmp(*argv, "--softin") == 0) { option_softin = 1; } // float32 soft input
else if (strcmp(*argv, "--ths") == 0) {
++argv;
if (*argv) {
@ -1644,6 +1617,14 @@ int main(int argc, char *argv[]) {
option_iq = 5;
}
else if (strcmp(*argv, "--lp") == 0) { option_lp = 1; } // IQ 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;
}
else if (strcmp(*argv, "--dc") == 0) { option_dc = 1; }
else if (strcmp(*argv, "--min") == 0) {
option_min = 1;
@ -1694,9 +1675,16 @@ int main(int argc, char *argv[]) {
memcpy(gpx.frame, rs41_header_bytes, sizeof(rs41_header_bytes)); // 8 header bytes
#ifdef EXT_FSK
if (!option_bin && !option_softin) {
option_softin = 1;
fprintf(stderr, "reading float32 soft symbols\n");
}
#endif
if (!rawhex) {
if (!option_bin) {
if (!option_bin && !option_softin) {
if (option_iq == 0 && option_pcmraw) {
fclose(fp);
@ -1736,7 +1724,7 @@ int main(int argc, char *argv[]) {
dsp.h = 0.6; //0.7; // 0.7..0.8? modulation index abzgl. BT
dsp.opt_iq = option_iq;
dsp.opt_lp = option_lp;
dsp.lpIQ_bw = 8e3; // IF lowpass bandwidth
dsp.lpIQ_bw = lpIQ_bw; // 7.4e3 (6e3..8e3) // IF lowpass bandwidth
dsp.lpFM_bw = 6e3; // FM audio lowpass
dsp.opt_dc = option_dc;
dsp.opt_IFmin = option_min;
@ -1744,37 +1732,48 @@ int main(int argc, char *argv[]) {
if ( dsp.sps < 8 ) {
fprintf(stderr, "note: sample rate low (%.1f sps)\n", dsp.sps);
}
k = init_buffers(&dsp); // BT=0.5 (IQ-Int: BT > 0.5 ?)
if ( k < 0 ) {
fprintf(stderr, "error: init buffers\n");
return -1;
}
//if (option_iq >= 2) bitofs += 1; // FM: +1 , IQ: +2
bitofs += shift;
}
else {
if (option_bin && option_softin) option_bin = 0;
// init circular header bit buffer
hdb.hdr = rs41_header;
hdb.len = strlen(rs41_header);
hdb.ths = 1.0 - 3.1/(float)hdb.len; // 1.0-max_bit_errors/hdrlen
hdb.thb = 1.0 - 3.1/(float)hdb.len; // 1.0-max_bit_errors/hdrlen
hdb.bufpos = -1;
hdb.buf = calloc(hdb.len, sizeof(char));
if (hdb.buf == NULL) {
fprintf(stderr, "error: malloc\n");
return -1;
}
hdb.ths = 0.7; // caution/test false positive
hdb.sbuf = calloc(hdb.len, sizeof(float));
if (hdb.sbuf == NULL) {
fprintf(stderr, "error: malloc\n");
return -1;
}
}
k = init_buffers(&dsp); // BT=0.5 (IQ-Int: BT > 0.5 ?)
if ( k < 0 ) {
fprintf(stderr, "error: init buffers\n");
return -1;
};
//if (option_iq >= 2) bitofs += 1; // FM: +1 , IQ: +2
bitofs += shift;
while ( 1 )
{
if (option_bin) {
header_found = find_binhead(fp, &hdb, &_mv);
}
else if (option_softin) {
header_found = find_softbinhead(fp, &hdb, &_mv);
}
else { // FM-audio:
header_found = find_header(&dsp, thres, 3, bitofs, dsp.opt_dc); // optional 2nd pass: dc=0
header_found = find_header(&dsp, thres, 4, bitofs, dsp.opt_dc); // optional 2nd pass: dc=0
_mv = dsp.mv;
}
if (header_found == EOF) break;
@ -1790,6 +1789,7 @@ int main(int argc, char *argv[]) {
byte_count = FRAMESTART;
bitpos = 0; // byte_count*8-HEADLEN
b8pos = 0;
difbyte = 0;
while ( byte_count < FRAME_LEN )
{
@ -1797,14 +1797,21 @@ int main(int argc, char *argv[]) {
bitQ = fgetc(fp);
if (bitQ != EOF) bit = bitQ & 0x1;
}
else if (option_softin) {
float s = 0.0;
bitQ = f32soft_read(fp, &s);
if (bitQ != EOF) bit = (s>=0.0); // no soft decoding
}
else {
if (option_iq >= 2) {
float bl = -1;
if (option_iq > 2) bl = 1.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, 0);
float bl = -1;
if (option_iq > 2) bl = 2.0;
//bitQ = read_slbit(&dsp, &bit, 0, bitofs, bitpos, bl, 0); // symlen=1
bitQ = read_softbit2p(&dsp, &hsbit, 0, bitofs, bitpos, bl, 0, &hsbit1); // symlen=1
bit = hsbit.hb;
if (gpx.option.ecc == 3) bit = (hsbit.sb+hsbit1.sb)>=0;
if (bitpos < FRAME_LEN*BITS && hsbit.sb*hsbit1.sb < 0) {
difbyte |= 1<<b8pos;
}
}
if ( bitQ == EOF ) break; // liest 2x EOF
@ -1818,6 +1825,8 @@ int main(int argc, char *argv[]) {
b8pos = 0;
byte = bits2byte(bitbuf);
gpx.frame[byte_count] = byte ^ mask[byte_count % MASK_LEN];
gpx.dfrm[byte_count] = difbyte;
difbyte = 0;
byte_count++;
}
}
@ -1828,7 +1837,7 @@ int main(int argc, char *argv[]) {
}
}
if (!option_bin) free_buffers(&dsp);
if (!option_bin && !option_softin) free_buffers(&dsp);
else {
if (hdb.buf) { free(hdb.buf); hdb.buf = NULL; }
}

Wyświetl plik

@ -1221,11 +1221,13 @@ static void print_frame(gpx_t *gpx, int len) {
if (ec < 0) fprintf(stdout, " (-)");
}
fprintf(stdout, "\n");
// fprintf(stdout, "\n");
// fprintf(stdout, "\n");
}
else print_position(gpx, ec);
}
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[]) {
@ -1237,6 +1239,7 @@ int main(int argc, char *argv[]) {
int option_iq = 0;
int option_lp = 0;
int option_dc = 0;
int option_softin = 0;
int option_pcmraw = 0;
int sel_wavch = 0; // audio channel: left
int spike = 0;
@ -1265,6 +1268,8 @@ int main(int argc, char *argv[]) {
pcm_t pcm = {0};
dsp_t dsp = {0}; //memset(&dsp, 0, sizeof(dsp));
hdb_t hdb = {0};
gpx_t gpx = {0};
gpx.gps.prn32toggle = 0x1;
@ -1375,18 +1380,19 @@ int main(int argc, char *argv[]) {
}
else return -1;
}
else if (strcmp(*argv, "-g1") == 0) { gpx.gps.opt_vergps = 1; } // verbose1 GPS
else if (strcmp(*argv, "-g2") == 0) { gpx.gps.opt_vergps = 2; } // verbose2 GPS (bancroft)
else if (strcmp(*argv, "-gg") == 0) { gpx.gps.opt_vergps = 8; } // vverbose GPS
else if (strcmp(*argv, "--json") == 0) {
else if (strcmp(*argv, "-g1") == 0) { gpx.gps.opt_vergps = 1; } // verbose1 GPS
else if (strcmp(*argv, "-g2") == 0) { gpx.gps.opt_vergps = 2; } // verbose2 GPS (bancroft)
else if (strcmp(*argv, "-gg") == 0) { gpx.gps.opt_vergps = 8; } // vverbose GPS
else if (strcmp(*argv, "--json") == 0) {
gpx.option.jsn = 1;
gpx.option.ecc = 2;
gpx.option.crc = 1;
gpx.gps.opt_vel = 4;
}
else if (strcmp(*argv, "--spike") == 0) { spike = 1; }
else if (strcmp(*argv, "--ch2") == 0) { sel_wavch = 1; } // right channel (default: 0=left)
else if (strcmp(*argv, "--ths") == 0) {
else if (strcmp(*argv, "--spike") == 0) { spike = 1; }
else if (strcmp(*argv, "--ch2") == 0) { sel_wavch = 1; } // right channel (default: 0=left)
else if (strcmp(*argv, "--softin") == 0) { option_softin = 1; } // float32 soft input
else if (strcmp(*argv, "--ths") == 0) {
++argv;
if (*argv) {
thres = atof(*argv);
@ -1480,70 +1486,112 @@ int main(int argc, char *argv[]) {
// init gpx
memcpy(gpx.frame, rs92_header_bytes, sizeof(rs92_header_bytes)); // 6 header bytes
if (option_iq == 0 && option_pcmraw) {
fclose(fp);
fprintf(stderr, "error: raw data not IQ\n");
return -1;
}
if (option_iq) sel_wavch = 0;
pcm.sel_ch = sel_wavch;
if (option_pcmraw == 0) {
k = read_wav_header(&pcm, fp);
if ( k < 0 ) {
#ifdef EXT_FSK
if (!option_softin) {
option_softin = 1;
fprintf(stderr, "reading float32 soft symbols\n");
}
#endif
if (!option_softin) {
if (option_iq == 0 && option_pcmraw) {
fclose(fp);
fprintf(stderr, "error: wav header\n");
fprintf(stderr, "error: raw data not IQ\n");
return -1;
}
if (option_iq) sel_wavch = 0;
pcm.sel_ch = sel_wavch;
if (option_pcmraw == 0) {
k = read_wav_header(&pcm, fp);
if ( k < 0 ) {
fclose(fp);
fprintf(stderr, "error: wav header\n");
return -1;
}
}
// rs92-sgp: BT=0.5, h=1.0 ?
symlen = 2;
// init dsp
//
dsp.fp = fp;
dsp.sr = pcm.sr;
dsp.bps = pcm.bps;
dsp.nch = pcm.nch;
dsp.ch = pcm.sel_ch;
dsp.br = (float)BAUD_RATE;
dsp.sps = (float)dsp.sr/dsp.br;
dsp.symlen = symlen;
dsp.symhd = symlen;
dsp._spb = dsp.sps*symlen;
dsp.hdr = rs92_rawheader;
dsp.hdrlen = strlen(rs92_rawheader);
dsp.BT = 0.5; // bw/time (ISI) // 0.3..0.5
dsp.h = 0.8; // 1.0 modulation index abzgl. BT
dsp.opt_iq = option_iq;
dsp.opt_lp = option_lp;
dsp.lpIQ_bw = 8e3; // IF lowpass bandwidth
dsp.lpFM_bw = 6e3; // FM audio lowpass
dsp.opt_dc = option_dc;
dsp.opt_IFmin = option_min;
if (gpx.option.ngp) { // L-band rs92-ngp
dsp.h = 3.8; // RS92-NGP: 1680/400=4.2, 4.2*0.9=3.8=4.75*0.8
dsp.lpIQ_bw = 32e3; // IF lowpass bandwidth // 32e3=4.2*7.6e3
}
if ( dsp.sps < 8 ) {
fprintf(stderr, "note: sample rate low (%.1f sps)\n", dsp.sps);
}
k = init_buffers(&dsp); // BT=0.5 (IQ-Int: BT > 0.5 ?)
if ( k < 0 ) {
fprintf(stderr, "error: init buffers\n");
return -1;
};
bitofs += shift;
}
else {
// init circular header bit buffer
hdb.hdr = rs92_rawheader;
hdb.len = strlen(rs92_rawheader);
//hdb.thb = 1.0 - 3.1/(float)hdb.len; // 1.0-max_bit_errors/hdrlen
hdb.bufpos = -1;
hdb.buf = NULL;
/*
calloc(hdb.len, sizeof(char));
if (hdb.buf == NULL) {
fprintf(stderr, "error: malloc\n");
return -1;
}
*/
// caution ths=0.7: -3 byte offset, false positive
// 2A 2A 2A 2A 2A 10|65 10 ..
// header sync could be extended into the frame
hdb.ths = 0.8;
hdb.sbuf = calloc(hdb.len, sizeof(float));
if (hdb.sbuf == NULL) {
fprintf(stderr, "error: malloc\n");
return -1;
}
}
// rs92-sgp: BT=0.5, h=1.0 ?
symlen = 2;
// init dsp
//
dsp.fp = fp;
dsp.sr = pcm.sr;
dsp.bps = pcm.bps;
dsp.nch = pcm.nch;
dsp.ch = pcm.sel_ch;
dsp.br = (float)BAUD_RATE;
dsp.sps = (float)dsp.sr/dsp.br;
dsp.symlen = symlen;
dsp.symhd = symlen;
dsp._spb = dsp.sps*symlen;
dsp.hdr = rs92_rawheader;
dsp.hdrlen = strlen(rs92_rawheader);
dsp.BT = 0.5; // bw/time (ISI) // 0.3..0.5
dsp.h = 0.8; // 1.0 modulation index abzgl. BT
dsp.opt_iq = option_iq;
dsp.opt_lp = option_lp;
dsp.lpIQ_bw = 8e3; // IF lowpass bandwidth
dsp.lpFM_bw = 6e3; // FM audio lowpass
dsp.opt_dc = option_dc;
dsp.opt_IFmin = option_min;
if (gpx.option.ngp) { // L-band rs92-ngp
dsp.h = 3.8; // RS92-NGP: 1680/400=4.2, 4.2*0.9=3.8=4.75*0.8
dsp.lpIQ_bw = 32e3; // IF lowpass bandwidth // 32e3=4.2*7.6e3
}
if ( dsp.sps < 8 ) {
fprintf(stderr, "note: sample rate low (%.1f sps)\n", dsp.sps);
}
k = init_buffers(&dsp); // BT=0.5 (IQ-Int: BT > 0.5 ?)
if ( k < 0 ) {
fprintf(stderr, "error: init buffers\n");
return -1;
};
bitofs += shift;
while ( 1 ) {
header_found = find_header(&dsp, thres, 3, bitofs, dsp.opt_dc);
_mv = dsp.mv;
while ( 1 )
{
if (option_softin) {
for (k = 0; k < hdb.len; k++) hdb.sbuf[k] = 0.0;
header_found = find_softbinhead(fp, &hdb, &_mv);
}
else {
header_found = find_header(&dsp, thres, 3, bitofs, dsp.opt_dc);
_mv = dsp.mv;
}
if (header_found == EOF) break;
@ -1560,9 +1608,25 @@ int main(int argc, char *argv[]) {
b8pos = 0;
while ( byte_count < FRAME_LEN ) {
float bl = -1;
if (option_iq > 2) bl = 4.0;
bitQ = read_slbit(&dsp, &bit, 0/*gpx.option.inv*/, bitofs, bitpos, bl, spike);
if (option_softin) {
float s1 = 0.0;
float s2 = 0.0;
float s = 0.0;
bitQ = f32soft_read(fp, &s1);
if (bitQ != EOF) {
bitQ = f32soft_read(fp, &s2);
if (bitQ != EOF) {
s = s2-s1; // integrate both symbols // only 2nd Manchester symbol: s2
bit = (s>=0.0); // no soft decoding
}
}
}
else {
float bl = -1;
if (option_iq > 2) bl = 4.0;
bitQ = read_slbit(&dsp, &bit, 0, bitofs, bitpos, bl, spike); // symlen=2
}
if ( bitQ == EOF) break;
if (gpx.option.inv) bit ^= 1;
@ -1586,9 +1650,13 @@ int main(int argc, char *argv[]) {
}
free_buffers(&dsp);
if (!option_softin) free_buffers(&dsp);
else {
if (hdb.buf) { free(hdb.buf); hdb.buf = NULL; }
}
if (gpx.gps.ephs) free(gpx.gps.ephs);
fclose(fp);
return 0;

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.