mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2025-05-24 10:22:26 -04:00
Move hashtab onto the heap. Add new wsprd_exp with stack decoder option (jelinek.c)
git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@5721 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
parent
46b2deb3c1
commit
88a7ab5f95
@ -2,8 +2,7 @@ CC = gcc
|
|||||||
#CC = clang
|
#CC = clang
|
||||||
FC = gfortran
|
FC = gfortran
|
||||||
|
|
||||||
FFLAGS = -O2 -Wall -Wno-conversion
|
CFLAGS= -I/usr/include -Wall -Wno-missing-braces -O3 -ffast-math
|
||||||
CFLAGS= -g -I/usr/include -Wall -Wno-missing-braces -O2
|
|
||||||
LDFLAGS = -L/usr/lib
|
LDFLAGS = -L/usr/lib
|
||||||
LIBS = -lfftw3 -lm
|
LIBS = -lfftw3 -lm
|
||||||
|
|
||||||
@ -21,8 +20,8 @@ LIBS = -lfftw3 -lm
|
|||||||
|
|
||||||
all: wsprd wsprsim wsprd_exp
|
all: wsprd wsprsim wsprd_exp
|
||||||
|
|
||||||
DEPS = wsprsim_utils.h wsprd_utils.h fano.h
|
DEPS = wsprsim_utils.h wsprd_utils.h fano.h jelinek.h nhash.h
|
||||||
OBJS1 = wsprd.o wsprd_utils.o wsprsim_utils.o tab.o fano.o nhash.o
|
OBJS1 = wsprd.o wsprsim_utils.o wsprd_utils.o tab.o fano.o jelinek.o nhash.o
|
||||||
wsprd: $(OBJS1)
|
wsprd: $(OBJS1)
|
||||||
$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) $(LIBS)
|
$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) $(LIBS)
|
||||||
|
|
||||||
@ -30,7 +29,7 @@ OBJS2 = wsprsim.o wsprsim_utils.o wsprd_utils.o tab.o fano.o nhash.o
|
|||||||
wsprsim: $(OBJS2)
|
wsprsim: $(OBJS2)
|
||||||
$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) $(LIBS)
|
$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) $(LIBS)
|
||||||
|
|
||||||
OBJS3 = wsprd_exp.o wsprsim_utils.o wsprd_utils.o tab.o fano.o nhash.o
|
OBJS3 = wsprd_exp.o wsprsim_utils.o wsprd_utils.o tab.o fano.o jelinek.o nhash.o
|
||||||
wsprd_exp: $(OBJS3)
|
wsprd_exp: $(OBJS3)
|
||||||
$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) $(LIBS)
|
$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) $(LIBS)
|
||||||
clean:
|
clean:
|
||||||
|
@ -51,23 +51,6 @@ struct node {
|
|||||||
#define POLY2 0xe4613c47
|
#define POLY2 0xe4613c47
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Convolutional encoder macro. Takes the encoder state, generates
|
|
||||||
* a rate 1/2 symbol pair and stores it in 'sym'. The symbol generated from
|
|
||||||
* POLY1 goes into the 2-bit of sym, and the symbol generated from POLY2
|
|
||||||
* goes into the 1-bit.
|
|
||||||
*/
|
|
||||||
#define ENCODE(sym,encstate) {\
|
|
||||||
unsigned long _tmp;\
|
|
||||||
\
|
|
||||||
_tmp = (encstate) & POLY1;\
|
|
||||||
_tmp ^= _tmp >> 16;\
|
|
||||||
(sym) = Partab[(_tmp ^ (_tmp >> 8)) & 0xff] << 1;\
|
|
||||||
_tmp = (encstate) & POLY2;\
|
|
||||||
_tmp ^= _tmp >> 16;\
|
|
||||||
(sym) |= Partab[(_tmp ^ (_tmp >> 8)) & 0xff];\
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Convolutionally encode a packet. The input data bytes are read
|
/* Convolutionally encode a packet. The input data bytes are read
|
||||||
* high bit first and the encoded packet is written into 'symbols',
|
* high bit first and the encoded packet is written into 'symbols',
|
||||||
* one symbol per byte. The first symbol is generated from POLY1,
|
* one symbol per byte. The first symbol is generated from POLY1,
|
||||||
@ -171,8 +154,8 @@ int fano(
|
|||||||
for(i=1;i <= maxcycles;i++) {
|
for(i=1;i <= maxcycles;i++) {
|
||||||
if((int)(np-nodes) > (int)*maxnp) *maxnp=(int)(np-nodes);
|
if((int)(np-nodes) > (int)*maxnp) *maxnp=(int)(np-nodes);
|
||||||
#ifdef debug
|
#ifdef debug
|
||||||
printf("k=%ld, g=%ld, t=%d, m[%d]=%d, maxnp=%d\n",
|
printf("k=%ld, g=%ld, t=%d, m[%d]=%d, maxnp=%d, encstate=%lx\n",
|
||||||
np-nodes,np->gamma,t,np->i,np->tm[np->i],*maxnp);
|
np-nodes,np->gamma,t,np->i,np->tm[np->i],*maxnp,np->encstate);
|
||||||
#endif
|
#endif
|
||||||
// Look forward */
|
// Look forward */
|
||||||
ngamma = np->gamma + np->tm[np->i];
|
ngamma = np->gamma + np->tm[np->i];
|
||||||
@ -249,6 +232,7 @@ int fano(
|
|||||||
np += 8;
|
np += 8;
|
||||||
}
|
}
|
||||||
*cycles = i+1;
|
*cycles = i+1;
|
||||||
|
|
||||||
free(nodes);
|
free(nodes);
|
||||||
if(i >= maxcycles) return -1; // Decoder timed out
|
if(i >= maxcycles) return -1; // Decoder timed out
|
||||||
return 0; // Successful completion
|
return 0; // Successful completion
|
||||||
|
@ -20,4 +20,20 @@ int encode(unsigned char *symbols,unsigned char *data,unsigned int nbytes);
|
|||||||
|
|
||||||
extern unsigned char Partab[];
|
extern unsigned char Partab[];
|
||||||
|
|
||||||
|
/* Convolutional encoder macro. Takes the encoder state, generates
|
||||||
|
* a rate 1/2 symbol pair and stores it in 'sym'. The symbol generated from
|
||||||
|
* POLY1 goes into the 2-bit of sym, and the symbol generated from POLY2
|
||||||
|
* goes into the 1-bit.
|
||||||
|
*/
|
||||||
|
#define ENCODE(sym,encstate){\
|
||||||
|
unsigned long _tmp;\
|
||||||
|
\
|
||||||
|
_tmp = (encstate) & POLY1;\
|
||||||
|
_tmp ^= _tmp >> 16;\
|
||||||
|
(sym) = Partab[(_tmp ^ (_tmp >> 8)) & 0xff] << 1;\
|
||||||
|
_tmp = (encstate) & POLY2;\
|
||||||
|
_tmp ^= _tmp >> 16;\
|
||||||
|
(sym) |= Partab[(_tmp ^ (_tmp >> 8)) & 0xff];\
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -599,8 +599,10 @@ int main(int argc, char *argv[])
|
|||||||
unsigned int cycles; int jitter; };
|
unsigned int cycles; int jitter; };
|
||||||
struct result decodes[50];
|
struct result decodes[50];
|
||||||
|
|
||||||
char hashtab[32768][13];
|
char *hashtab;
|
||||||
|
hashtab=malloc(sizeof(char)*32768*13);
|
||||||
memset(hashtab,0,sizeof(char)*32768*13);
|
memset(hashtab,0,sizeof(char)*32768*13);
|
||||||
|
|
||||||
int nh;
|
int nh;
|
||||||
symbols=malloc(sizeof(char)*nbits*2);
|
symbols=malloc(sizeof(char)*nbits*2);
|
||||||
decdata=malloc((nbits+7)/8);
|
decdata=malloc((nbits+7)/8);
|
||||||
@ -773,7 +775,7 @@ int main(int argc, char *argv[])
|
|||||||
if( (fhash=fopen(hash_fname,"r+")) ) {
|
if( (fhash=fopen(hash_fname,"r+")) ) {
|
||||||
while (fgets(line, sizeof(line), fhash) != NULL) {
|
while (fgets(line, sizeof(line), fhash) != NULL) {
|
||||||
sscanf(line,"%d %s",&nh,hcall);
|
sscanf(line,"%d %s",&nh,hcall);
|
||||||
strcpy(*hashtab+nh*13,hcall);
|
strcpy(hashtab+nh*13,hcall);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fhash=fopen(hash_fname,"w+");
|
fhash=fopen(hash_fname,"w+");
|
||||||
@ -1080,7 +1082,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
unsigned char channel_symbols[162];
|
unsigned char channel_symbols[162];
|
||||||
|
|
||||||
if( get_wspr_channel_symbols(call_loc_pow, channel_symbols) ) {
|
if( get_wspr_channel_symbols(call_loc_pow, hashtab, channel_symbols) ) {
|
||||||
subtract_signal2(idat, qdat, npoints, f1, shift1, drift1, channel_symbols);
|
subtract_signal2(idat, qdat, npoints, f1, shift1, drift1, channel_symbols);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
@ -1211,8 +1213,8 @@ int main(int argc, char *argv[])
|
|||||||
if( usehashtable ) {
|
if( usehashtable ) {
|
||||||
fhash=fopen(hash_fname,"w");
|
fhash=fopen(hash_fname,"w");
|
||||||
for (i=0; i<32768; i++) {
|
for (i=0; i<32768; i++) {
|
||||||
if( strncmp(hashtab[i],"\0",1) != 0 ) {
|
if( strncmp(hashtab+i*13,"\0",1) != 0 ) {
|
||||||
fprintf(fhash,"%5d %s\n",i,*hashtab+i*13);
|
fprintf(fhash,"%5d %s\n",i,hashtab+i*13);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(fhash);
|
fclose(fhash);
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include <fftw3.h>
|
#include <fftw3.h>
|
||||||
|
|
||||||
#include "fano.h"
|
#include "fano.h"
|
||||||
|
#include "jelinek.h"
|
||||||
#include "nhash.h"
|
#include "nhash.h"
|
||||||
#include "wsprd_utils.h"
|
#include "wsprd_utils.h"
|
||||||
#include "wsprsim_utils.h"
|
#include "wsprsim_utils.h"
|
||||||
@ -66,12 +67,15 @@ int printdata=0;
|
|||||||
unsigned long readc2file(char *ptr_to_infile, double *idat, double *qdat,
|
unsigned long readc2file(char *ptr_to_infile, double *idat, double *qdat,
|
||||||
double *freq, int *wspr_type)
|
double *freq, int *wspr_type)
|
||||||
{
|
{
|
||||||
float buffer[2*65536];
|
float *buffer;
|
||||||
double dfreq;
|
double dfreq;
|
||||||
int i,ntrmin;
|
int i,ntrmin;
|
||||||
char *c2file[15];
|
char *c2file[15];
|
||||||
FILE* fp;
|
FILE* fp;
|
||||||
|
|
||||||
|
buffer=malloc(sizeof(float)*2*65536);
|
||||||
|
memset(buffer,0,sizeof(float)*2*65536);
|
||||||
|
|
||||||
fp = fopen(ptr_to_infile,"rb");
|
fp = fopen(ptr_to_infile,"rb");
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
fprintf(stderr, "Cannot open data file '%s'\n", ptr_to_infile);
|
fprintf(stderr, "Cannot open data file '%s'\n", ptr_to_infile);
|
||||||
@ -180,9 +184,9 @@ unsigned long readwavfile(char *ptr_to_infile, int ntrmin, double *idat, double
|
|||||||
|
|
||||||
//***************************************************************************
|
//***************************************************************************
|
||||||
void sync_and_demodulate(double *id, double *qd, long np,
|
void sync_and_demodulate(double *id, double *qd, long np,
|
||||||
unsigned char *symbols, float *f1, int ifmin, int ifmax, float fstep,
|
unsigned char *symbols, double *f1, int ifmin, int ifmax, double fstep,
|
||||||
int *shift1, int lagmin, int lagmax, int lagstep,
|
int *shift1, int lagmin, int lagmax, int lagstep,
|
||||||
float *drift1, int symfac, float *sync, int mode)
|
double *drift1, int symfac, double *sync, int mode)
|
||||||
{
|
{
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* mode = 0: no frequency or drift search. find best time lag. *
|
* mode = 0: no frequency or drift search. find best time lag. *
|
||||||
@ -191,18 +195,18 @@ void sync_and_demodulate(double *id, double *qd, long np,
|
|||||||
* symbols using passed frequency and shift. *
|
* symbols using passed frequency and shift. *
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
float dt=1.0/375.0, df=375.0/256.0, fbest=0.0;
|
static double fplast=-10000.0;
|
||||||
int i, j, k;
|
static double dt=1.0/375.0, df=375.0/256.0;
|
||||||
double pi=4.*atan(1.0),twopidt;
|
static double pi=3.14159265358979323846;
|
||||||
float f0=0.0,fp,ss;
|
double twopidt, df15=df*1.5, df05=df*0.5;
|
||||||
int lag;
|
|
||||||
static float fplast=-10000.0;
|
int i, j, k, lag;
|
||||||
double i0[162],q0[162],i1[162],q1[162],i2[162],q2[162],i3[162],q3[162];
|
double i0[162],q0[162],i1[162],q1[162],i2[162],q2[162],i3[162],q3[162];
|
||||||
double p0,p1,p2,p3,cmet,totp,syncmax,fac;
|
double p0,p1,p2,p3,cmet,totp,syncmax,fac;
|
||||||
double c0[256],s0[256],c1[256],s1[256],c2[256],s2[256],c3[256],s3[256];
|
double c0[256],s0[256],c1[256],s1[256],c2[256],s2[256],c3[256],s3[256];
|
||||||
double dphi0, cdphi0, sdphi0, dphi1, cdphi1, sdphi1, dphi2, cdphi2, sdphi2,
|
double dphi0, cdphi0, sdphi0, dphi1, cdphi1, sdphi1, dphi2, cdphi2, sdphi2,
|
||||||
dphi3, cdphi3, sdphi3;
|
dphi3, cdphi3, sdphi3;
|
||||||
float fsum=0.0, f2sum=0.0, fsymb[162];
|
double f0=0.0, fp, ss, fbest=0.0, fsum=0.0, f2sum=0.0, fsymb[162];
|
||||||
int best_shift = 0, ifreq;
|
int best_shift = 0, ifreq;
|
||||||
|
|
||||||
syncmax=-1e30;
|
syncmax=-1e30;
|
||||||
@ -217,21 +221,21 @@ void sync_and_demodulate(double *id, double *qd, long np,
|
|||||||
ss=0.0;
|
ss=0.0;
|
||||||
totp=0.0;
|
totp=0.0;
|
||||||
for (i=0; i<162; i++) {
|
for (i=0; i<162; i++) {
|
||||||
fp = f0 + ((float)*drift1/2.0)*((float)i-81.0)/81.0;
|
fp = f0 + (*drift1/2.0)*((double)i-81.0)/81.0;
|
||||||
if( i==0 || (fp != fplast) ) { // only calculate sin/cos if necessary
|
if( i==0 || (fp != fplast) ) { // only calculate sin/cos if necessary
|
||||||
dphi0=twopidt*(fp-1.5*df);
|
dphi0=twopidt*(fp-df15);
|
||||||
cdphi0=cos(dphi0);
|
cdphi0=cos(dphi0);
|
||||||
sdphi0=sin(dphi0);
|
sdphi0=sin(dphi0);
|
||||||
|
|
||||||
dphi1=twopidt*(fp-0.5*df);
|
dphi1=twopidt*(fp-df05);
|
||||||
cdphi1=cos(dphi1);
|
cdphi1=cos(dphi1);
|
||||||
sdphi1=sin(dphi1);
|
sdphi1=sin(dphi1);
|
||||||
|
|
||||||
dphi2=twopidt*(fp+0.5*df);
|
dphi2=twopidt*(fp+df05);
|
||||||
cdphi2=cos(dphi2);
|
cdphi2=cos(dphi2);
|
||||||
sdphi2=sin(dphi2);
|
sdphi2=sin(dphi2);
|
||||||
|
|
||||||
dphi3=twopidt*(fp+1.5*df);
|
dphi3=twopidt*(fp+df15);
|
||||||
cdphi3=cos(dphi3);
|
cdphi3=cos(dphi3);
|
||||||
sdphi3=sin(dphi3);
|
sdphi3=sin(dphi3);
|
||||||
|
|
||||||
@ -260,7 +264,7 @@ void sync_and_demodulate(double *id, double *qd, long np,
|
|||||||
|
|
||||||
for (j=0; j<256; j++) {
|
for (j=0; j<256; j++) {
|
||||||
k=lag+i*256+j;
|
k=lag+i*256+j;
|
||||||
if( (k>0) & (k<np) ) {
|
if( (k>0) && (k<np) ) {
|
||||||
i0[i]=i0[i] + id[k]*c0[j] + qd[k]*s0[j];
|
i0[i]=i0[i] + id[k]*c0[j] + qd[k]*s0[j];
|
||||||
q0[i]=q0[i] - id[k]*s0[j] + qd[k]*c0[j];
|
q0[i]=q0[i] - id[k]*s0[j] + qd[k]*c0[j];
|
||||||
i1[i]=i1[i] + id[k]*c1[j] + qd[k]*s1[j];
|
i1[i]=i1[i] + id[k]*c1[j] + qd[k]*s1[j];
|
||||||
@ -283,18 +287,18 @@ void sync_and_demodulate(double *id, double *qd, long np,
|
|||||||
|
|
||||||
totp=totp+p0+p1+p2+p3;
|
totp=totp+p0+p1+p2+p3;
|
||||||
cmet=(p1+p3)-(p0+p2);
|
cmet=(p1+p3)-(p0+p2);
|
||||||
ss=ss+cmet*(2*pr3[i]-1);
|
ss = (pr3[i] == 1) ? ss+cmet : ss-cmet;
|
||||||
if( mode == 2) { //Compute soft symbols
|
if( mode == 2) { //Compute soft symbols
|
||||||
if(pr3[i]) {
|
if(pr3[i]==1) {
|
||||||
fsymb[i]=p3-p1;
|
fsymb[i]=p3-p1;
|
||||||
} else {
|
} else {
|
||||||
fsymb[i]=p2-p0;
|
fsymb[i]=p2-p0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ss=ss/totp;
|
||||||
if( ss/totp > syncmax ) { //Save best parameters
|
if( ss > syncmax ) { //Save best parameters
|
||||||
syncmax=ss/totp;
|
syncmax=ss;
|
||||||
best_shift=lag;
|
best_shift=lag;
|
||||||
fbest=f0;
|
fbest=f0;
|
||||||
}
|
}
|
||||||
@ -329,9 +333,9 @@ void sync_and_demodulate(double *id, double *qd, long np,
|
|||||||
symbol-by-symbol signal subtraction
|
symbol-by-symbol signal subtraction
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void subtract_signal(double *id, double *qd, long np,
|
void subtract_signal(double *id, double *qd, long np,
|
||||||
float f0, int shift0, float drift0, unsigned char* channel_symbols)
|
double f0, int shift0, double drift0, unsigned char* channel_symbols)
|
||||||
{
|
{
|
||||||
float dt=1.0/375.0, df=375.0/256.0;
|
double dt=1.0/375.0, df=375.0/256.0;
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
double pi=4.*atan(1.0),twopidt, fp;
|
double pi=4.*atan(1.0),twopidt, fp;
|
||||||
|
|
||||||
@ -342,9 +346,9 @@ void subtract_signal(double *id, double *qd, long np,
|
|||||||
twopidt=2*pi*dt;
|
twopidt=2*pi*dt;
|
||||||
|
|
||||||
for (i=0; i<162; i++) {
|
for (i=0; i<162; i++) {
|
||||||
fp = f0 + ((float)drift0/2.0)*((float)i-81.0)/81.0;
|
fp = f0 + ((double)drift0/2.0)*((double)i-81.0)/81.0;
|
||||||
|
|
||||||
dphi=twopidt*(fp+((float)channel_symbols[i]-1.5)*df);
|
dphi=twopidt*(fp+((double)channel_symbols[i]-1.5)*df);
|
||||||
cdphi=cos(dphi);
|
cdphi=cos(dphi);
|
||||||
sdphi=sin(dphi);
|
sdphi=sin(dphi);
|
||||||
|
|
||||||
@ -385,7 +389,7 @@ void subtract_signal(double *id, double *qd, long np,
|
|||||||
Fully coherent signal subtraction
|
Fully coherent signal subtraction
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
void subtract_signal2(double *id, double *qd, long np,
|
void subtract_signal2(double *id, double *qd, long np,
|
||||||
float f0, int shift0, float drift0, unsigned char* channel_symbols)
|
double f0, int shift0, double drift0, unsigned char* channel_symbols)
|
||||||
{
|
{
|
||||||
double dt=1.0/375.0, df=375.0/256.0;
|
double dt=1.0/375.0, df=375.0/256.0;
|
||||||
double pi=4.*atan(1.0), twopidt, phi=0, dphi, cs;
|
double pi=4.*atan(1.0), twopidt, phi=0, dphi, cs;
|
||||||
@ -427,14 +431,14 @@ void subtract_signal2(double *id, double *qd, long np,
|
|||||||
|
|
||||||
dphi=twopidt*
|
dphi=twopidt*
|
||||||
(
|
(
|
||||||
f0 + ((float)drift0/2.0)*((float)i-(float)nsym/2.0)/((float)nsym/2.0)
|
f0 + (drift0/2.0)*((double)i-(double)nsym/2.0)/((double)nsym/2.0)
|
||||||
+ (cs-1.5)*df
|
+ (cs-1.5)*df
|
||||||
);
|
);
|
||||||
|
|
||||||
for ( j=0; j<nspersym; j++ ) {
|
for ( j=0; j<nspersym; j++ ) {
|
||||||
ii=nspersym*i+j;
|
ii=nspersym*i+j;
|
||||||
refi[ii]=refi[ii]+cos(phi); //cannot precompute sin/cos because dphi is changing
|
refi[ii]=cos(phi); //cannot precompute sin/cos because dphi is changing
|
||||||
refq[ii]=refq[ii]+sin(phi);
|
refq[ii]=sin(phi);
|
||||||
phi=phi+dphi;
|
phi=phi+dphi;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -446,7 +450,7 @@ void subtract_signal2(double *id, double *qd, long np,
|
|||||||
// leave nfilt zeros as a pad at the beginning of the unfiltered reference signal
|
// leave nfilt zeros as a pad at the beginning of the unfiltered reference signal
|
||||||
for (i=0; i<nsym*nspersym; i++) {
|
for (i=0; i<nsym*nspersym; i++) {
|
||||||
k=shift0+i;
|
k=shift0+i;
|
||||||
if( (k>0) & (k<np) ) {
|
if( (k>0) && (k<np) ) {
|
||||||
ci[i+nfilt] = id[k]*refi[i] + qd[k]*refq[i];
|
ci[i+nfilt] = id[k]*refi[i] + qd[k]*refq[i];
|
||||||
cq[i+nfilt] = qd[k]*refi[i] - id[k]*refq[i];
|
cq[i+nfilt] = qd[k]*refi[i] - id[k]*refq[i];
|
||||||
}
|
}
|
||||||
@ -456,7 +460,7 @@ void subtract_signal2(double *id, double *qd, long np,
|
|||||||
double w[nfilt], norm=0, partialsum[nfilt];
|
double w[nfilt], norm=0, partialsum[nfilt];
|
||||||
memset(partialsum,0,sizeof(double)*nfilt);
|
memset(partialsum,0,sizeof(double)*nfilt);
|
||||||
for (i=0; i<nfilt; i++) {
|
for (i=0; i<nfilt; i++) {
|
||||||
w[i]=sin(pi*(float)i/(float)(nfilt-1));
|
w[i]=sin(pi*(double)i/(double)(nfilt-1));
|
||||||
norm=norm+w[i];
|
norm=norm+w[i];
|
||||||
}
|
}
|
||||||
for (i=0; i<nfilt; i++) {
|
for (i=0; i<nfilt; i++) {
|
||||||
@ -489,7 +493,7 @@ void subtract_signal2(double *id, double *qd, long np,
|
|||||||
}
|
}
|
||||||
k=shift0+i;
|
k=shift0+i;
|
||||||
j=i+nfilt;
|
j=i+nfilt;
|
||||||
if( (k>0) & (k<np) ) {
|
if( (k>0) && (k<np) ) {
|
||||||
id[k]=id[k] - (cfi[j]*refi[i]-cfq[j]*refq[i])/norm;
|
id[k]=id[k] - (cfi[j]*refi[i]-cfq[j]*refq[i])/norm;
|
||||||
qd[k]=qd[k] - (cfi[j]*refq[i]+cfq[j]*refi[i])/norm;
|
qd[k]=qd[k] - (cfi[j]*refq[i]+cfq[j]*refi[i])/norm;
|
||||||
}
|
}
|
||||||
@ -509,9 +513,9 @@ unsigned long writec2file(char *c2filename, int trmin, double freq
|
|||||||
, double *idat, double *qdat)
|
, double *idat, double *qdat)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
float *buffer;
|
double *buffer;
|
||||||
buffer=malloc(sizeof(float)*2*45000);
|
buffer=malloc(sizeof(double)*2*45000);
|
||||||
memset(buffer,0,sizeof(float)*2*45000);
|
memset(buffer,0,sizeof(double)*2*45000);
|
||||||
|
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
@ -530,7 +534,7 @@ unsigned long writec2file(char *c2filename, int trmin, double freq
|
|||||||
buffer[2*i+1]=-qdat[i];
|
buffer[2*i+1]=-qdat[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
nwrite = fwrite(buffer, sizeof(float), 2*45000, fp);
|
nwrite = fwrite(buffer, sizeof(double), 2*45000, fp);
|
||||||
if( nwrite == 2*45000 ) {
|
if( nwrite == 2*45000 ) {
|
||||||
return nwrite;
|
return nwrite;
|
||||||
} else {
|
} else {
|
||||||
@ -548,10 +552,12 @@ void usage(void)
|
|||||||
printf("Options:\n");
|
printf("Options:\n");
|
||||||
printf(" -a <path> path to writeable data files, default=\".\"\n");
|
printf(" -a <path> path to writeable data files, default=\".\"\n");
|
||||||
printf(" -c write .c2 file at the end of the first pass\n");
|
printf(" -c write .c2 file at the end of the first pass\n");
|
||||||
printf(" -d deeper search. Much slower, a few more decodes\n");
|
printf(" -C maximum number of decoder cycles per bit, default 10000\n");
|
||||||
|
printf(" -d deeper search. Slower, a few more decodes\n");
|
||||||
printf(" -e x (x is transceiver dial frequency error in Hz)\n");
|
printf(" -e x (x is transceiver dial frequency error in Hz)\n");
|
||||||
printf(" -f x (x is transceiver dial frequency in MHz)\n");
|
printf(" -f x (x is transceiver dial frequency in MHz)\n");
|
||||||
printf(" -H do not use (or update) the hash table\n");
|
printf(" -H do not use (or update) the hash table\n");
|
||||||
|
printf(" -J use the stack decoder instead of Fano decoder\n");
|
||||||
printf(" -m decode wspr-15 .wav file\n");
|
printf(" -m decode wspr-15 .wav file\n");
|
||||||
printf(" -q quick mode - doesn't dig deep for weak signals\n");
|
printf(" -q quick mode - doesn't dig deep for weak signals\n");
|
||||||
printf(" -s single pass mode, no subtraction (same as original wsprd)\n");
|
printf(" -s single pass mode, no subtraction (same as original wsprd)\n");
|
||||||
@ -566,7 +572,7 @@ int main(int argc, char *argv[])
|
|||||||
extern char *optarg;
|
extern char *optarg;
|
||||||
extern int optind;
|
extern int optind;
|
||||||
int i,j,k;
|
int i,j,k;
|
||||||
unsigned char *symbols, *decdata;
|
unsigned char *symbols, *decdata, *channel_symbols;
|
||||||
signed char message[]={-9,13,-35,123,57,-39,64,0,0,0,0};
|
signed char message[]={-9,13,-35,123,57,-39,64,0,0,0,0};
|
||||||
char *callsign, *call_loc_pow;
|
char *callsign, *call_loc_pow;
|
||||||
char *ptr_to_infile,*ptr_to_infile_suffix;
|
char *ptr_to_infile,*ptr_to_infile_suffix;
|
||||||
@ -574,47 +580,52 @@ int main(int argc, char *argv[])
|
|||||||
char wisdom_fname[200],all_fname[200],spots_fname[200];
|
char wisdom_fname[200],all_fname[200],spots_fname[200];
|
||||||
char timer_fname[200],hash_fname[200];
|
char timer_fname[200],hash_fname[200];
|
||||||
char uttime[5],date[7];
|
char uttime[5],date[7];
|
||||||
int c,delta,maxpts=65536,verbose=0,quickmode=0,more_candidates=0;
|
int c,delta,maxpts=65536,verbose=0,quickmode=0,more_candidates=0, stackdecoder=0;
|
||||||
int writenoise=0,usehashtable=1,wspr_type=2, ipass;
|
int writenoise=0,usehashtable=1,wspr_type=2, ipass;
|
||||||
int writec2=0, npasses=2, subtraction=1;
|
int writec2=0, npasses=2, subtraction=1;
|
||||||
int shift1, lagmin, lagmax, lagstep, ifmin, ifmax, worth_a_try, not_decoded;
|
int shift1, lagmin, lagmax, lagstep, ifmin, ifmax, worth_a_try, not_decoded;
|
||||||
unsigned int nbits=81;
|
unsigned int nbits=81, stacksize=200000;
|
||||||
unsigned int npoints, metric, maxcycles, cycles, maxnp;
|
unsigned int npoints, metric, cycles, maxnp;
|
||||||
float df=375.0/256.0/2;
|
double df=375.0/256.0/2;
|
||||||
float freq0[200],snr0[200],drift0[200],sync0[200];
|
double freq0[200],snr0[200],drift0[200],sync0[200];
|
||||||
int shift0[200];
|
int shift0[200];
|
||||||
float dt=1.0/375.0, dt_print;
|
double dt=1.0/375.0, dt_print;
|
||||||
double dialfreq_cmdline=0.0, dialfreq, freq_print;
|
double dialfreq_cmdline=0.0, dialfreq, freq_print;
|
||||||
float dialfreq_error=0.0;
|
double dialfreq_error=0.0;
|
||||||
float fmin=-110, fmax=110;
|
double fmin=-110, fmax=110;
|
||||||
float f1, fstep, sync1, drift1;
|
double f1, fstep, sync1, drift1;
|
||||||
float psavg[512];
|
double psavg[512];
|
||||||
double *idat, *qdat;
|
double *idat, *qdat;
|
||||||
clock_t t0,t00;
|
clock_t t0,t00;
|
||||||
double tfano=0.0,treadwav=0.0,tcandidates=0.0,tsync0=0.0;
|
double tfano=0.0,treadwav=0.0,tcandidates=0.0,tsync0=0.0;
|
||||||
double tsync1=0.0,tsync2=0.0,ttotal=0.0;
|
double tsync1=0.0,tsync2=0.0,ttotal=0.0;
|
||||||
|
|
||||||
struct result { char date[7]; char time[5]; float sync; float snr;
|
struct result { char date[7]; char time[5]; double sync; double snr;
|
||||||
float dt; double freq; char message[23]; float drift;
|
double dt; double freq; char message[23]; double drift;
|
||||||
unsigned int cycles; int jitter; };
|
unsigned int cycles; int jitter; };
|
||||||
struct result decodes[50];
|
struct result decodes[50];
|
||||||
|
|
||||||
char hashtab[32768][13];
|
// char hashtab[32768][13];
|
||||||
|
char *hashtab;
|
||||||
|
hashtab=malloc(sizeof(char)*32768*13);
|
||||||
memset(hashtab,0,sizeof(char)*32768*13);
|
memset(hashtab,0,sizeof(char)*32768*13);
|
||||||
int nh;
|
int nh;
|
||||||
symbols=malloc(sizeof(char)*nbits*2);
|
symbols=malloc(sizeof(char)*nbits*2);
|
||||||
decdata=malloc((nbits+7)/8);
|
decdata=malloc(sizeof(char)*11);
|
||||||
|
channel_symbols=malloc(sizeof(char)*nbits*2);
|
||||||
|
// unsigned char channel_symbols[162];
|
||||||
|
|
||||||
callsign=malloc(sizeof(char)*13);
|
callsign=malloc(sizeof(char)*13);
|
||||||
call_loc_pow=malloc(sizeof(char)*23);
|
call_loc_pow=malloc(sizeof(char)*23);
|
||||||
float allfreqs[100];
|
double allfreqs[100];
|
||||||
char allcalls[100][13];
|
char allcalls[100][13];
|
||||||
memset(allfreqs,0,sizeof(float)*100);
|
memset(allfreqs,0,sizeof(double)*100);
|
||||||
memset(allcalls,0,sizeof(char)*100*13);
|
memset(allcalls,0,sizeof(char)*100*13);
|
||||||
|
|
||||||
int uniques=0, noprint=0;
|
int uniques=0, noprint=0, ndecodes_pass=0;
|
||||||
|
|
||||||
// Parameters used for performance-tuning:
|
// Parameters used for performance-tuning:
|
||||||
maxcycles=10000; //Fano timeout limit
|
unsigned int maxcycles=10000; //Decoder timeout limit
|
||||||
double minsync1=0.10; //First sync limit
|
double minsync1=0.10; //First sync limit
|
||||||
double minsync2=0.12; //Second sync limit
|
double minsync2=0.12; //Second sync limit
|
||||||
int iifac=8; //Step size in final DT peakup
|
int iifac=8; //Step size in final DT peakup
|
||||||
@ -622,18 +633,18 @@ int main(int argc, char *argv[])
|
|||||||
int maxdrift=4; //Maximum (+/-) drift
|
int maxdrift=4; //Maximum (+/-) drift
|
||||||
double minrms=52.0 * (symfac/64.0); //Final test for plausible decoding
|
double minrms=52.0 * (symfac/64.0); //Final test for plausible decoding
|
||||||
delta=60; //Fano threshold step
|
delta=60; //Fano threshold step
|
||||||
|
double bias=0.42; //Fano metric bias (used for both Fano and stack algorithms)
|
||||||
|
|
||||||
t00=clock();
|
t00=clock();
|
||||||
fftw_complex *fftin, *fftout;
|
fftw_complex *fftin, *fftout;
|
||||||
#include "./metric_tables.c"
|
#include "./metric_tables.c"
|
||||||
|
|
||||||
int mettab[2][256];
|
int mettab[2][256];
|
||||||
float bias=0.42;
|
|
||||||
|
|
||||||
idat=malloc(sizeof(double)*maxpts);
|
idat=malloc(sizeof(double)*maxpts);
|
||||||
qdat=malloc(sizeof(double)*maxpts);
|
qdat=malloc(sizeof(double)*maxpts);
|
||||||
|
|
||||||
while ( (c = getopt(argc, argv, "a:cde:f:Hmqstwvz:")) !=-1 ) {
|
while ( (c = getopt(argc, argv, "a:cC:de:f:HJmqstwvz:")) !=-1 ) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'a':
|
case 'a':
|
||||||
data_dir = optarg;
|
data_dir = optarg;
|
||||||
@ -641,12 +652,14 @@ int main(int argc, char *argv[])
|
|||||||
case 'c':
|
case 'c':
|
||||||
writec2=1;
|
writec2=1;
|
||||||
break;
|
break;
|
||||||
|
case 'C':
|
||||||
|
maxcycles=(unsigned int) strtoul(optarg,NULL,10);
|
||||||
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
more_candidates=1;
|
more_candidates=1;
|
||||||
iifac=4;
|
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
dialfreq_error = strtof(optarg,NULL); // units of Hz
|
dialfreq_error = strtod(optarg,NULL); // units of Hz
|
||||||
// dialfreq_error = dial reading - actual, correct frequency
|
// dialfreq_error = dial reading - actual, correct frequency
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
@ -655,14 +668,17 @@ int main(int argc, char *argv[])
|
|||||||
case 'H':
|
case 'H':
|
||||||
usehashtable = 0;
|
usehashtable = 0;
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'J': //Stack (Jelinek) decoder, Fano decoder is the default
|
||||||
|
stackdecoder = 1;
|
||||||
|
break;
|
||||||
|
case 'm': //15-minute wspr mode
|
||||||
wspr_type = 15;
|
wspr_type = 15;
|
||||||
break;
|
break;
|
||||||
case 'q':
|
case 'q': //no shift jittering
|
||||||
quickmode = 1;
|
quickmode = 1;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's': //single pass mode (same as original wsprd)
|
||||||
subtraction = 0; //single pass mode (same as original wsprd)
|
subtraction = 0;
|
||||||
npasses = 1;
|
npasses = 1;
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
@ -673,7 +689,7 @@ int main(int argc, char *argv[])
|
|||||||
fmax=150.0;
|
fmax=150.0;
|
||||||
break;
|
break;
|
||||||
case 'z':
|
case 'z':
|
||||||
bias=strtof(optarg,NULL); //fano metric bias (default is 0.42)
|
bias=strtod(optarg,NULL); //fano metric bias (default is 0.42)
|
||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
usage();
|
usage();
|
||||||
@ -681,6 +697,10 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( stackdecoder ) {
|
||||||
|
stack=malloc(stacksize*sizeof(struct node));
|
||||||
|
}
|
||||||
|
|
||||||
if( optind+1 > argc) {
|
if( optind+1 > argc) {
|
||||||
usage();
|
usage();
|
||||||
return 1;
|
return 1;
|
||||||
@ -766,8 +786,8 @@ int main(int argc, char *argv[])
|
|||||||
fftout=(fftw_complex*) fftw_malloc(sizeof(fftw_complex)*512);
|
fftout=(fftw_complex*) fftw_malloc(sizeof(fftw_complex)*512);
|
||||||
PLAN3 = fftw_plan_dft_1d(512, fftin, fftout, FFTW_FORWARD, PATIENCE);
|
PLAN3 = fftw_plan_dft_1d(512, fftin, fftout, FFTW_FORWARD, PATIENCE);
|
||||||
|
|
||||||
float ps[512][nffts];
|
double ps[512][nffts];
|
||||||
float w[512];
|
double w[512];
|
||||||
for(i=0; i<512; i++) {
|
for(i=0; i<512; i++) {
|
||||||
w[i]=sin(0.006147931*i);
|
w[i]=sin(0.006147931*i);
|
||||||
}
|
}
|
||||||
@ -777,7 +797,7 @@ int main(int argc, char *argv[])
|
|||||||
if( (fhash=fopen(hash_fname,"r+")) ) {
|
if( (fhash=fopen(hash_fname,"r+")) ) {
|
||||||
while (fgets(line, sizeof(line), fhash) != NULL) {
|
while (fgets(line, sizeof(line), fhash) != NULL) {
|
||||||
sscanf(line,"%d %s",&nh,hcall);
|
sscanf(line,"%d %s",&nh,hcall);
|
||||||
strcpy(*hashtab+nh*13,hcall);
|
strcpy(hashtab+nh*13,hcall);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fhash=fopen(hash_fname,"w+");
|
fhash=fopen(hash_fname,"w+");
|
||||||
@ -788,9 +808,10 @@ int main(int argc, char *argv[])
|
|||||||
//*************** main loop starts here *****************
|
//*************** main loop starts here *****************
|
||||||
for (ipass=0; ipass<npasses; ipass++) {
|
for (ipass=0; ipass<npasses; ipass++) {
|
||||||
|
|
||||||
if( ipass > 0 && uniques == 0 ) break;
|
if( ipass > 0 && ndecodes_pass == 0 ) break;
|
||||||
|
ndecodes_pass=0;
|
||||||
|
|
||||||
memset(ps,0.0, sizeof(float)*512*nffts);
|
memset(ps,0.0, sizeof(double)*512*nffts);
|
||||||
for (i=0; i<nffts; i++) {
|
for (i=0; i<nffts; i++) {
|
||||||
for(j=0; j<512; j++ ) {
|
for(j=0; j<512; j++ ) {
|
||||||
k=i*128+j;
|
k=i*128+j;
|
||||||
@ -807,7 +828,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Compute average spectrum
|
// Compute average spectrum
|
||||||
memset(psavg,0.0, sizeof(float)*512);
|
memset(psavg,0.0, sizeof(double)*512);
|
||||||
for (i=0; i<nffts; i++) {
|
for (i=0; i<nffts; i++) {
|
||||||
for (j=0; j<512; j++) {
|
for (j=0; j<512; j++) {
|
||||||
psavg[j]=psavg[j]+ps[j][i];
|
psavg[j]=psavg[j]+ps[j][i];
|
||||||
@ -816,7 +837,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
// Smooth with 7-point window and limit spectrum to +/-150 Hz
|
// Smooth with 7-point window and limit spectrum to +/-150 Hz
|
||||||
int window[7]={1,1,1,1,1,1,1};
|
int window[7]={1,1,1,1,1,1,1};
|
||||||
float smspec[411];
|
double smspec[411];
|
||||||
for (i=0; i<411; i++) {
|
for (i=0; i<411; i++) {
|
||||||
smspec[i]=0.0;
|
smspec[i]=0.0;
|
||||||
for(j=-3; j<=3; j++) {
|
for(j=-3; j<=3; j++) {
|
||||||
@ -826,21 +847,21 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sort spectrum values, then pick off noise level as a percentile
|
// Sort spectrum values, then pick off noise level as a percentile
|
||||||
float tmpsort[411];
|
double tmpsort[411];
|
||||||
for (j=0; j<411; j++) {
|
for (j=0; j<411; j++) {
|
||||||
tmpsort[j]=smspec[j];
|
tmpsort[j]=smspec[j];
|
||||||
}
|
}
|
||||||
qsort(tmpsort, 411, sizeof(float), floatcomp);
|
qsort(tmpsort, 411, sizeof(double), doublecomp);
|
||||||
|
|
||||||
// Noise level of spectrum is estimated as 123/411= 30'th percentile
|
// Noise level of spectrum is estimated as 123/411= 30'th percentile
|
||||||
float noise_level = tmpsort[122];
|
double noise_level = tmpsort[122];
|
||||||
|
|
||||||
/* Renormalize spectrum so that (large) peaks represent an estimate of snr.
|
/* Renormalize spectrum so that (large) peaks represent an estimate of snr.
|
||||||
* We know from experience that threshold snr is near -7dB in wspr bandwidth,
|
* We know from experience that threshold snr is near -7dB in wspr bandwidth,
|
||||||
* corresponding to -7-26.3=-33.3dB in 2500 Hz bandwidth.
|
* corresponding to -7-26.3=-33.3dB in 2500 Hz bandwidth.
|
||||||
* The corresponding threshold is -42.3 dB in 2500 Hz bandwidth for WSPR-15. */
|
* The corresponding threshold is -42.3 dB in 2500 Hz bandwidth for WSPR-15. */
|
||||||
|
|
||||||
float min_snr, snr_scaling_factor;
|
double min_snr, snr_scaling_factor;
|
||||||
min_snr = pow(10.0,-7.0/10.0); //this is min snr in wspr bw
|
min_snr = pow(10.0,-7.0/10.0); //this is min snr in wspr bw
|
||||||
if( wspr_type == 2 ) {
|
if( wspr_type == 2 ) {
|
||||||
snr_scaling_factor=26.3;
|
snr_scaling_factor=26.3;
|
||||||
@ -903,7 +924,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
// bubble sort on snr, bringing freq along for the ride
|
// bubble sort on snr, bringing freq along for the ride
|
||||||
int pass;
|
int pass;
|
||||||
float tmp;
|
double tmp;
|
||||||
for (pass = 1; pass <= npk - 1; pass++) {
|
for (pass = 1; pass <= npk - 1; pass++) {
|
||||||
for (k = 0; k < npk - pass ; k++) {
|
for (k = 0; k < npk - pass ; k++) {
|
||||||
if (snr0[k] < snr0[k+1]) {
|
if (snr0[k] < snr0[k+1]) {
|
||||||
@ -918,6 +939,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
t0=clock();
|
t0=clock();
|
||||||
|
|
||||||
/* Make coarse estimates of shift (DT), freq, and drift
|
/* Make coarse estimates of shift (DT), freq, and drift
|
||||||
|
|
||||||
* Look for time offsets up to +/- 8 symbols (about +/- 5.4 s) relative
|
* Look for time offsets up to +/- 8 symbols (about +/- 5.4 s) relative
|
||||||
@ -940,7 +962,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
int idrift,ifr,if0,ifd,k0;
|
int idrift,ifr,if0,ifd,k0;
|
||||||
int kindex;
|
int kindex;
|
||||||
float smax,ss,pow,p0,p1,p2,p3;
|
double smax,ss,pow,p0,p1,p2,p3;
|
||||||
for(j=0; j<npk; j++) { //For each candidate...
|
for(j=0; j<npk; j++) { //For each candidate...
|
||||||
smax=-1e30;
|
smax=-1e30;
|
||||||
if0=freq0[j]/df+256;
|
if0=freq0[j]/df+256;
|
||||||
@ -950,7 +972,7 @@ int main(int argc, char *argv[])
|
|||||||
ss=0.0;
|
ss=0.0;
|
||||||
pow=0.0;
|
pow=0.0;
|
||||||
for (k=0; k<162; k++) { //Sum over symbols
|
for (k=0; k<162; k++) { //Sum over symbols
|
||||||
ifd=ifr+((float)k-81.0)/81.0*( (float)idrift )/(2.0*df);
|
ifd=ifr+((double)k-81.0)/81.0*( (double)idrift )/(2.0*df);
|
||||||
kindex=k0+2*k;
|
kindex=k0+2*k;
|
||||||
if( kindex < nffts ) {
|
if( kindex < nffts ) {
|
||||||
p0=ps[ifd-3][kindex];
|
p0=ps[ifd-3][kindex];
|
||||||
@ -965,9 +987,9 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
ss=ss+(2*pr3[k]-1)*((p1+p3)-(p0+p2));
|
ss=ss+(2*pr3[k]-1)*((p1+p3)-(p0+p2));
|
||||||
pow=pow+p0+p1+p2+p3;
|
pow=pow+p0+p1+p2+p3;
|
||||||
sync1=ss/pow;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sync1=ss/pow;
|
||||||
if( sync1 > smax ) { //Save coarse parameters
|
if( sync1 > smax ) { //Save coarse parameters
|
||||||
smax=sync1;
|
smax=sync1;
|
||||||
shift0[j]=128*(k0+1);
|
shift0[j]=128*(k0+1);
|
||||||
@ -983,7 +1005,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Refine the estimates of freq, shift using sync as a metric.
|
Refine the estimates of freq, shift using sync as a metric.
|
||||||
Sync is calculated such that it is a float taking values in the range
|
Sync is calculated such that it is a double taking values in the range
|
||||||
[0.0,1.0].
|
[0.0,1.0].
|
||||||
|
|
||||||
Function sync_and_demodulate has three modes of operation
|
Function sync_and_demodulate has three modes of operation
|
||||||
@ -1025,7 +1047,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
// refine drift estimate
|
// refine drift estimate
|
||||||
fstep=0.0; ifmin=0; ifmax=0;
|
fstep=0.0; ifmin=0; ifmax=0;
|
||||||
float driftp,driftm,syncp,syncm;
|
double driftp,driftm,syncp,syncm;
|
||||||
driftp=drift1+0.5;
|
driftp=drift1+0.5;
|
||||||
sync_and_demodulate(idat, qdat, npoints, symbols, &f1, ifmin, ifmax, fstep, &shift1,
|
sync_and_demodulate(idat, qdat, npoints, symbols, &f1, ifmin, ifmax, fstep, &shift1,
|
||||||
lagmin, lagmax, lagstep, &driftp, symfac, &syncp, 1);
|
lagmin, lagmax, lagstep, &driftp, symfac, &syncp, 1);
|
||||||
@ -1093,22 +1115,23 @@ int main(int argc, char *argv[])
|
|||||||
deinterleave(symbols);
|
deinterleave(symbols);
|
||||||
t0 = clock();
|
t0 = clock();
|
||||||
|
|
||||||
not_decoded = fano(&metric,&cycles,&maxnp,decdata,symbols,nbits,
|
if ( stackdecoder ) {
|
||||||
mettab,delta,maxcycles);
|
not_decoded = jelinek(&metric, &cycles, decdata, symbols, nbits,
|
||||||
|
stacksize, stack, mettab,maxcycles);
|
||||||
|
} else {
|
||||||
|
not_decoded = fano(&metric,&cycles,&maxnp,decdata,symbols,nbits,
|
||||||
|
mettab,delta,maxcycles);
|
||||||
|
}
|
||||||
|
|
||||||
tfano += (double)(clock()-t0)/CLOCKS_PER_SEC;
|
tfano += (double)(clock()-t0)/CLOCKS_PER_SEC;
|
||||||
|
|
||||||
/* ### Used for timing tests:
|
|
||||||
if(not_decoded) fprintf(fdiag,
|
|
||||||
"%6s %4s %4.1f %3.0f %4.1f %10.7f %-18s %2d %5u %4d %6.1f %2d\n",
|
|
||||||
date,uttime,sync1*10,snr0[j], shift1*dt-2.0, dialfreq+(1500+f1)/1e6,
|
|
||||||
"@ ", (int)drift1, cycles/81, ii, rms, maxnp);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
idt++;
|
idt++;
|
||||||
if( quickmode ) break;
|
if( quickmode ) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( worth_a_try && !not_decoded ) {
|
if( worth_a_try && !not_decoded ) {
|
||||||
|
ndecodes_pass++;
|
||||||
|
|
||||||
for(i=0; i<11; i++) {
|
for(i=0; i<11; i++) {
|
||||||
|
|
||||||
@ -1125,11 +1148,9 @@ int main(int argc, char *argv[])
|
|||||||
// call_loc_pow string and also callsign (for de-duping).
|
// call_loc_pow string and also callsign (for de-duping).
|
||||||
noprint=unpk_(message,hashtab,call_loc_pow,callsign);
|
noprint=unpk_(message,hashtab,call_loc_pow,callsign);
|
||||||
|
|
||||||
if( subtraction && (ipass < (npasses-1) ) && !noprint ) {
|
// subtract even on last pass
|
||||||
|
if( subtraction && (ipass < npasses ) && !noprint ) {
|
||||||
unsigned char channel_symbols[162];
|
if( get_wspr_channel_symbols(call_loc_pow, hashtab, channel_symbols) ) {
|
||||||
|
|
||||||
if( get_wspr_channel_symbols(call_loc_pow, channel_symbols) ) {
|
|
||||||
subtract_signal2(idat, qdat, npoints, f1, shift1, drift1, channel_symbols);
|
subtract_signal2(idat, qdat, npoints, f1, shift1, drift1, channel_symbols);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
@ -1169,15 +1190,6 @@ int main(int argc, char *argv[])
|
|||||||
decodes[uniques-1].drift=drift1;
|
decodes[uniques-1].drift=drift1;
|
||||||
decodes[uniques-1].cycles=cycles;
|
decodes[uniques-1].cycles=cycles;
|
||||||
decodes[uniques-1].jitter=ii;
|
decodes[uniques-1].jitter=ii;
|
||||||
|
|
||||||
/* For timing tests
|
|
||||||
|
|
||||||
fprintf(fdiag,
|
|
||||||
"%6s %4s %4.1f %3.0f %4.1f %10.7f %-18s %2d %5u %4d %6.1f\n",
|
|
||||||
date,uttime,sync1*10,snr0[j],
|
|
||||||
shift1*dt-2.0, dialfreq+(1500+f1)/1e6,
|
|
||||||
call_loc_pow, (int)drift1, cycles/81, ii, rms);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1245,7 +1257,7 @@ int main(int argc, char *argv[])
|
|||||||
fprintf(ftimer,"sync_and_demod(0) %7.2f %7.2f\n",tsync0,tsync0/ttotal);
|
fprintf(ftimer,"sync_and_demod(0) %7.2f %7.2f\n",tsync0,tsync0/ttotal);
|
||||||
fprintf(ftimer,"sync_and_demod(1) %7.2f %7.2f\n",tsync1,tsync1/ttotal);
|
fprintf(ftimer,"sync_and_demod(1) %7.2f %7.2f\n",tsync1,tsync1/ttotal);
|
||||||
fprintf(ftimer,"sync_and_demod(2) %7.2f %7.2f\n",tsync2,tsync2/ttotal);
|
fprintf(ftimer,"sync_and_demod(2) %7.2f %7.2f\n",tsync2,tsync2/ttotal);
|
||||||
fprintf(ftimer,"Fano decoder %7.2f %7.2f\n",tfano,tfano/ttotal);
|
fprintf(ftimer,"Stack/Fano decoder %7.2f %7.2f\n",tfano,tfano/ttotal);
|
||||||
fprintf(ftimer,"-----------------------------------\n");
|
fprintf(ftimer,"-----------------------------------\n");
|
||||||
fprintf(ftimer,"Total %7.2f %7.2f\n",ttotal,1.0);
|
fprintf(ftimer,"Total %7.2f %7.2f\n",ttotal,1.0);
|
||||||
|
|
||||||
@ -1260,13 +1272,17 @@ int main(int argc, char *argv[])
|
|||||||
if( usehashtable ) {
|
if( usehashtable ) {
|
||||||
fhash=fopen(hash_fname,"w");
|
fhash=fopen(hash_fname,"w");
|
||||||
for (i=0; i<32768; i++) {
|
for (i=0; i<32768; i++) {
|
||||||
if( strncmp(hashtab[i],"\0",1) != 0 ) {
|
if( strncmp(hashtab+i*13,"\0",1) != 0 ) {
|
||||||
fprintf(fhash,"%5d %s\n",i,*hashtab+i*13);
|
fprintf(fhash,"%5d %s\n",i,hashtab+i*13);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(fhash);
|
fclose(fhash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( stackdecoder ) {
|
||||||
|
free(stack);
|
||||||
|
}
|
||||||
|
|
||||||
if(writenoise == 999) return -1; //Silence compiler warning
|
if(writenoise == 999) return -1; //Silence compiler warning
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -225,6 +225,13 @@ void deinterleave(unsigned char *sym)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// used by qsort
|
// used by qsort
|
||||||
|
int doublecomp(const void* elem1, const void* elem2)
|
||||||
|
{
|
||||||
|
if(*(const double*)elem1 < *(const double*)elem2)
|
||||||
|
return -1;
|
||||||
|
return *(const double*)elem1 > *(const double*)elem2;
|
||||||
|
}
|
||||||
|
|
||||||
int floatcomp(const void* elem1, const void* elem2)
|
int floatcomp(const void* elem1, const void* elem2)
|
||||||
{
|
{
|
||||||
if(*(const float*)elem1 < *(const float*)elem2)
|
if(*(const float*)elem1 < *(const float*)elem2)
|
||||||
@ -232,7 +239,7 @@ int floatcomp(const void* elem1, const void* elem2)
|
|||||||
return *(const float*)elem1 > *(const float*)elem2;
|
return *(const float*)elem1 > *(const float*)elem2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int unpk_(signed char *message, char hashtab[32768][13], char *call_loc_pow, char *callsign)
|
int unpk_(signed char *message, char *hashtab, char *call_loc_pow, char *callsign)
|
||||||
{
|
{
|
||||||
int n1,n2,n3,ndbm,ihash,nadd,noprint=0;
|
int n1,n2,n3,ndbm,ihash,nadd,noprint=0;
|
||||||
char grid[5],grid6[7],cdbm[3];
|
char grid[5],grid6[7],cdbm[3];
|
||||||
@ -270,7 +277,7 @@ int unpk_(signed char *message, char hashtab[32768][13], char *call_loc_pow, cha
|
|||||||
strncat(call_loc_pow,cdbm,2);
|
strncat(call_loc_pow,cdbm,2);
|
||||||
strncat(call_loc_pow,"\0",1);
|
strncat(call_loc_pow,"\0",1);
|
||||||
ihash=nhash(callsign,strlen(callsign),(uint32_t)146);
|
ihash=nhash(callsign,strlen(callsign),(uint32_t)146);
|
||||||
strcpy(*hashtab+ihash*13,callsign);
|
strcpy(hashtab+ihash*13,callsign);
|
||||||
} else {
|
} else {
|
||||||
nadd=nu;
|
nadd=nu;
|
||||||
if( nu > 3 ) nadd=nu-3;
|
if( nu > 3 ) nadd=nu-3;
|
||||||
@ -287,7 +294,7 @@ int unpk_(signed char *message, char hashtab[32768][13], char *call_loc_pow, cha
|
|||||||
int nu=ndbm%10;
|
int nu=ndbm%10;
|
||||||
if( nu == 0 || nu == 3 || nu == 7 || nu == 10 ) { //make sure power is OK
|
if( nu == 0 || nu == 3 || nu == 7 || nu == 10 ) { //make sure power is OK
|
||||||
ihash=nhash(callsign,strlen(callsign),(uint32_t)146);
|
ihash=nhash(callsign,strlen(callsign),(uint32_t)146);
|
||||||
strcpy(*hashtab+ihash*13,callsign);
|
strcpy(hashtab+ihash*13,callsign);
|
||||||
} else noprint=1;
|
} else noprint=1;
|
||||||
}
|
}
|
||||||
} else if ( ntype < 0 ) {
|
} else if ( ntype < 0 ) {
|
||||||
@ -303,12 +310,12 @@ int unpk_(signed char *message, char hashtab[32768][13], char *call_loc_pow, cha
|
|||||||
// grid is only 4 chars even though this is a hashed callsign...
|
// grid is only 4 chars even though this is a hashed callsign...
|
||||||
// isalpha(grid6[4]) && isalpha(grid6[5]) ) ) {
|
// isalpha(grid6[4]) && isalpha(grid6[5]) ) ) {
|
||||||
ihash=nhash(callsign,strlen(callsign),(uint32_t)146);
|
ihash=nhash(callsign,strlen(callsign),(uint32_t)146);
|
||||||
strcpy(*hashtab+ihash*13,callsign);
|
strcpy(hashtab+ihash*13,callsign);
|
||||||
} else noprint=1;
|
} else noprint=1;
|
||||||
|
|
||||||
ihash=(n2-ntype-64)/128;
|
ihash=(n2-ntype-64)/128;
|
||||||
if( strncmp(hashtab[ihash],"\0",1) != 0 ) {
|
if( strncmp(hashtab+ihash*13,"\0",1) != 0 ) {
|
||||||
sprintf(callsign,"<%s>",hashtab[ihash]);
|
sprintf(callsign,"<%s>",hashtab+ihash*13);
|
||||||
} else {
|
} else {
|
||||||
sprintf(callsign,"%5s","<...>");
|
sprintf(callsign,"%5s","<...>");
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,9 @@ int unpackpfx( int32_t nprefix, char *call);
|
|||||||
void deinterleave(unsigned char *sym);
|
void deinterleave(unsigned char *sym);
|
||||||
|
|
||||||
// used by qsort
|
// used by qsort
|
||||||
|
int doublecomp(const void* elem1, const void* elem2);
|
||||||
int floatcomp(const void* elem1, const void* elem2);
|
int floatcomp(const void* elem1, const void* elem2);
|
||||||
|
|
||||||
int unpk_( signed char *message, char hashtab[32768][13], char *call_loc_pow, char *callsign);
|
int unpk_( signed char *message, char* hashtab, char *call_loc_pow, char *callsign);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -126,13 +126,18 @@ int main(int argc, char *argv[])
|
|||||||
extern int optind;
|
extern int optind;
|
||||||
int i, c, printchannel=0, writec2=0;
|
int i, c, printchannel=0, writec2=0;
|
||||||
float snr=50.0;
|
float snr=50.0;
|
||||||
char *message, *c2filename;
|
char *message, *c2filename, *hashtab;
|
||||||
c2filename=malloc(sizeof(char)*15);
|
c2filename=malloc(sizeof(char)*15);
|
||||||
|
hashtab=malloc(sizeof(char)*32768*13);
|
||||||
|
memset(hashtab,0,sizeof(char)*32768*13);
|
||||||
|
|
||||||
// message length is 22 characters
|
// message length is 22 characters
|
||||||
message=malloc(sizeof(char)*23);
|
message=malloc(sizeof(char)*23);
|
||||||
|
|
||||||
strcpy(c2filename,"000000_0001.c2");
|
strcpy(c2filename,"000000_0001.c2");
|
||||||
|
|
||||||
|
srand(getpid());
|
||||||
|
|
||||||
while ( (c = getopt(argc, argv, "cdo:s:")) !=-1 ) {
|
while ( (c = getopt(argc, argv, "cdo:s:")) !=-1 ) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'c':
|
case 'c':
|
||||||
@ -159,7 +164,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned char channel_symbols[162];
|
unsigned char channel_symbols[162];
|
||||||
get_wspr_channel_symbols(message, channel_symbols);
|
get_wspr_channel_symbols(message, hashtab, channel_symbols);
|
||||||
|
|
||||||
if( printchannel ) {
|
if( printchannel ) {
|
||||||
printf("Channel symbols:\n");
|
printf("Channel symbols:\n");
|
||||||
|
@ -163,7 +163,7 @@ void interleave(unsigned char *sym)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_wspr_channel_symbols(char* rawmessage, unsigned char* symbols) {
|
int get_wspr_channel_symbols(char* rawmessage, char* hashtab, unsigned char* symbols) {
|
||||||
int m=0, n=0, ntype=0;
|
int m=0, n=0, ntype=0;
|
||||||
int i, j, ihash;
|
int i, j, ihash;
|
||||||
unsigned char pr3[162]=
|
unsigned char pr3[162]=
|
||||||
@ -285,8 +285,8 @@ int get_wspr_channel_symbols(char* rawmessage, unsigned char* symbols) {
|
|||||||
// make sure that the 11-byte data vector is unpackable
|
// make sure that the 11-byte data vector is unpackable
|
||||||
// unpack it with the routine that the decoder will use and display
|
// unpack it with the routine that the decoder will use and display
|
||||||
// the result. let the operator decide whether it worked.
|
// the result. let the operator decide whether it worked.
|
||||||
char hashtab[32768][13];
|
// char hashtab[32768][13];
|
||||||
memset(hashtab,0,sizeof(char)*32768*13);
|
// memset(hashtab,0,sizeof(char)*32768*13);
|
||||||
|
|
||||||
char *check_call_loc_pow, *check_callsign;
|
char *check_call_loc_pow, *check_callsign;
|
||||||
check_call_loc_pow=malloc(sizeof(char)*23);
|
check_call_loc_pow=malloc(sizeof(char)*23);
|
||||||
|
@ -23,6 +23,6 @@ void pack_prefix(char *callsign, int32_t *n, int32_t *m, int32_t *nadd );
|
|||||||
|
|
||||||
void interleave(unsigned char *sym);
|
void interleave(unsigned char *sym);
|
||||||
|
|
||||||
int get_wspr_channel_symbols(char* message, unsigned char* symbols);
|
int get_wspr_channel_symbols(char* message, char* hashtab, unsigned char* symbols);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user