mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-25 13:48:42 -05: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
f7fd69cf5d
commit
6951499db3
@ -2,8 +2,7 @@ CC = gcc
|
||||
#CC = clang
|
||||
FC = gfortran
|
||||
|
||||
FFLAGS = -O2 -Wall -Wno-conversion
|
||||
CFLAGS= -g -I/usr/include -Wall -Wno-missing-braces -O2
|
||||
CFLAGS= -I/usr/include -Wall -Wno-missing-braces -O3 -ffast-math
|
||||
LDFLAGS = -L/usr/lib
|
||||
LIBS = -lfftw3 -lm
|
||||
|
||||
@ -21,8 +20,8 @@ LIBS = -lfftw3 -lm
|
||||
|
||||
all: wsprd wsprsim wsprd_exp
|
||||
|
||||
DEPS = wsprsim_utils.h wsprd_utils.h fano.h
|
||||
OBJS1 = wsprd.o wsprd_utils.o wsprsim_utils.o tab.o fano.o nhash.o
|
||||
DEPS = wsprsim_utils.h wsprd_utils.h fano.h jelinek.h nhash.h
|
||||
OBJS1 = wsprd.o wsprsim_utils.o wsprd_utils.o tab.o fano.o jelinek.o nhash.o
|
||||
wsprd: $(OBJS1)
|
||||
$(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)
|
||||
$(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)
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) $(LIBS)
|
||||
clean:
|
||||
|
@ -51,23 +51,6 @@ struct node {
|
||||
#define POLY2 0xe4613c47
|
||||
#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
|
||||
* high bit first and the encoded packet is written into 'symbols',
|
||||
* one symbol per byte. The first symbol is generated from POLY1,
|
||||
@ -171,8 +154,8 @@ int fano(
|
||||
for(i=1;i <= maxcycles;i++) {
|
||||
if((int)(np-nodes) > (int)*maxnp) *maxnp=(int)(np-nodes);
|
||||
#ifdef debug
|
||||
printf("k=%ld, g=%ld, t=%d, m[%d]=%d, maxnp=%d\n",
|
||||
np-nodes,np->gamma,t,np->i,np->tm[np->i],*maxnp);
|
||||
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->encstate);
|
||||
#endif
|
||||
// Look forward */
|
||||
ngamma = np->gamma + np->tm[np->i];
|
||||
@ -249,6 +232,7 @@ int fano(
|
||||
np += 8;
|
||||
}
|
||||
*cycles = i+1;
|
||||
|
||||
free(nodes);
|
||||
if(i >= maxcycles) return -1; // Decoder timed out
|
||||
return 0; // Successful completion
|
||||
|
@ -20,4 +20,20 @@ int encode(unsigned char *symbols,unsigned char *data,unsigned int nbytes);
|
||||
|
||||
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
|
||||
|
@ -599,8 +599,10 @@ int main(int argc, char *argv[])
|
||||
unsigned int cycles; int jitter; };
|
||||
struct result decodes[50];
|
||||
|
||||
char hashtab[32768][13];
|
||||
char *hashtab;
|
||||
hashtab=malloc(sizeof(char)*32768*13);
|
||||
memset(hashtab,0,sizeof(char)*32768*13);
|
||||
|
||||
int nh;
|
||||
symbols=malloc(sizeof(char)*nbits*2);
|
||||
decdata=malloc((nbits+7)/8);
|
||||
@ -773,7 +775,7 @@ int main(int argc, char *argv[])
|
||||
if( (fhash=fopen(hash_fname,"r+")) ) {
|
||||
while (fgets(line, sizeof(line), fhash) != NULL) {
|
||||
sscanf(line,"%d %s",&nh,hcall);
|
||||
strcpy(*hashtab+nh*13,hcall);
|
||||
strcpy(hashtab+nh*13,hcall);
|
||||
}
|
||||
} else {
|
||||
fhash=fopen(hash_fname,"w+");
|
||||
@ -1080,7 +1082,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
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);
|
||||
} else {
|
||||
break;
|
||||
@ -1211,8 +1213,8 @@ int main(int argc, char *argv[])
|
||||
if( usehashtable ) {
|
||||
fhash=fopen(hash_fname,"w");
|
||||
for (i=0; i<32768; i++) {
|
||||
if( strncmp(hashtab[i],"\0",1) != 0 ) {
|
||||
fprintf(fhash,"%5d %s\n",i,*hashtab+i*13);
|
||||
if( strncmp(hashtab+i*13,"\0",1) != 0 ) {
|
||||
fprintf(fhash,"%5d %s\n",i,hashtab+i*13);
|
||||
}
|
||||
}
|
||||
fclose(fhash);
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <fftw3.h>
|
||||
|
||||
#include "fano.h"
|
||||
#include "jelinek.h"
|
||||
#include "nhash.h"
|
||||
#include "wsprd_utils.h"
|
||||
#include "wsprsim_utils.h"
|
||||
@ -66,12 +67,15 @@ int printdata=0;
|
||||
unsigned long readc2file(char *ptr_to_infile, double *idat, double *qdat,
|
||||
double *freq, int *wspr_type)
|
||||
{
|
||||
float buffer[2*65536];
|
||||
float *buffer;
|
||||
double dfreq;
|
||||
int i,ntrmin;
|
||||
char *c2file[15];
|
||||
FILE* fp;
|
||||
|
||||
buffer=malloc(sizeof(float)*2*65536);
|
||||
memset(buffer,0,sizeof(float)*2*65536);
|
||||
|
||||
fp = fopen(ptr_to_infile,"rb");
|
||||
if (fp == NULL) {
|
||||
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,
|
||||
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,
|
||||
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. *
|
||||
@ -191,18 +195,18 @@ void sync_and_demodulate(double *id, double *qd, long np,
|
||||
* symbols using passed frequency and shift. *
|
||||
************************************************************************/
|
||||
|
||||
float dt=1.0/375.0, df=375.0/256.0, fbest=0.0;
|
||||
int i, j, k;
|
||||
double pi=4.*atan(1.0),twopidt;
|
||||
float f0=0.0,fp,ss;
|
||||
int lag;
|
||||
static float fplast=-10000.0;
|
||||
static double fplast=-10000.0;
|
||||
static double dt=1.0/375.0, df=375.0/256.0;
|
||||
static double pi=3.14159265358979323846;
|
||||
double twopidt, df15=df*1.5, df05=df*0.5;
|
||||
|
||||
int i, j, k, lag;
|
||||
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 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,
|
||||
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;
|
||||
|
||||
syncmax=-1e30;
|
||||
@ -217,21 +221,21 @@ void sync_and_demodulate(double *id, double *qd, long np,
|
||||
ss=0.0;
|
||||
totp=0.0;
|
||||
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
|
||||
dphi0=twopidt*(fp-1.5*df);
|
||||
dphi0=twopidt*(fp-df15);
|
||||
cdphi0=cos(dphi0);
|
||||
sdphi0=sin(dphi0);
|
||||
|
||||
dphi1=twopidt*(fp-0.5*df);
|
||||
dphi1=twopidt*(fp-df05);
|
||||
cdphi1=cos(dphi1);
|
||||
sdphi1=sin(dphi1);
|
||||
|
||||
dphi2=twopidt*(fp+0.5*df);
|
||||
dphi2=twopidt*(fp+df05);
|
||||
cdphi2=cos(dphi2);
|
||||
sdphi2=sin(dphi2);
|
||||
|
||||
dphi3=twopidt*(fp+1.5*df);
|
||||
dphi3=twopidt*(fp+df15);
|
||||
cdphi3=cos(dphi3);
|
||||
sdphi3=sin(dphi3);
|
||||
|
||||
@ -260,7 +264,7 @@ void sync_and_demodulate(double *id, double *qd, long np,
|
||||
|
||||
for (j=0; j<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];
|
||||
q0[i]=q0[i] - id[k]*s0[j] + qd[k]*c0[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;
|
||||
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(pr3[i]) {
|
||||
if(pr3[i]==1) {
|
||||
fsymb[i]=p3-p1;
|
||||
} else {
|
||||
fsymb[i]=p2-p0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( ss/totp > syncmax ) { //Save best parameters
|
||||
syncmax=ss/totp;
|
||||
ss=ss/totp;
|
||||
if( ss > syncmax ) { //Save best parameters
|
||||
syncmax=ss;
|
||||
best_shift=lag;
|
||||
fbest=f0;
|
||||
}
|
||||
@ -329,9 +333,9 @@ void sync_and_demodulate(double *id, double *qd, long np,
|
||||
symbol-by-symbol signal subtraction
|
||||
****************************************************************************/
|
||||
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;
|
||||
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;
|
||||
|
||||
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);
|
||||
sdphi=sin(dphi);
|
||||
|
||||
@ -385,7 +389,7 @@ void subtract_signal(double *id, double *qd, long np,
|
||||
Fully coherent signal subtraction
|
||||
*******************************************************************************/
|
||||
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 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*
|
||||
(
|
||||
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
|
||||
);
|
||||
|
||||
for ( j=0; j<nspersym; j++ ) {
|
||||
ii=nspersym*i+j;
|
||||
refi[ii]=refi[ii]+cos(phi); //cannot precompute sin/cos because dphi is changing
|
||||
refq[ii]=refq[ii]+sin(phi);
|
||||
refi[ii]=cos(phi); //cannot precompute sin/cos because dphi is changing
|
||||
refq[ii]=sin(phi);
|
||||
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
|
||||
for (i=0; i<nsym*nspersym; 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];
|
||||
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];
|
||||
memset(partialsum,0,sizeof(double)*nfilt);
|
||||
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];
|
||||
}
|
||||
for (i=0; i<nfilt; i++) {
|
||||
@ -489,7 +493,7 @@ void subtract_signal2(double *id, double *qd, long np,
|
||||
}
|
||||
k=shift0+i;
|
||||
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;
|
||||
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)
|
||||
{
|
||||
int i;
|
||||
float *buffer;
|
||||
buffer=malloc(sizeof(float)*2*45000);
|
||||
memset(buffer,0,sizeof(float)*2*45000);
|
||||
double *buffer;
|
||||
buffer=malloc(sizeof(double)*2*45000);
|
||||
memset(buffer,0,sizeof(double)*2*45000);
|
||||
|
||||
FILE *fp;
|
||||
|
||||
@ -530,7 +534,7 @@ unsigned long writec2file(char *c2filename, int trmin, double freq
|
||||
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 ) {
|
||||
return nwrite;
|
||||
} else {
|
||||
@ -548,10 +552,12 @@ void usage(void)
|
||||
printf("Options:\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(" -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(" -f x (x is transceiver dial frequency in MHz)\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(" -q quick mode - doesn't dig deep for weak signals\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 int optind;
|
||||
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};
|
||||
char *callsign, *call_loc_pow;
|
||||
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 timer_fname[200],hash_fname[200];
|
||||
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 writec2=0, npasses=2, subtraction=1;
|
||||
int shift1, lagmin, lagmax, lagstep, ifmin, ifmax, worth_a_try, not_decoded;
|
||||
unsigned int nbits=81;
|
||||
unsigned int npoints, metric, maxcycles, cycles, maxnp;
|
||||
float df=375.0/256.0/2;
|
||||
float freq0[200],snr0[200],drift0[200],sync0[200];
|
||||
unsigned int nbits=81, stacksize=200000;
|
||||
unsigned int npoints, metric, cycles, maxnp;
|
||||
double df=375.0/256.0/2;
|
||||
double freq0[200],snr0[200],drift0[200],sync0[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;
|
||||
float dialfreq_error=0.0;
|
||||
float fmin=-110, fmax=110;
|
||||
float f1, fstep, sync1, drift1;
|
||||
float psavg[512];
|
||||
double dialfreq_error=0.0;
|
||||
double fmin=-110, fmax=110;
|
||||
double f1, fstep, sync1, drift1;
|
||||
double psavg[512];
|
||||
double *idat, *qdat;
|
||||
clock_t t0,t00;
|
||||
double tfano=0.0,treadwav=0.0,tcandidates=0.0,tsync0=0.0;
|
||||
double tsync1=0.0,tsync2=0.0,ttotal=0.0;
|
||||
|
||||
struct result { char date[7]; char time[5]; float sync; float snr;
|
||||
float dt; double freq; char message[23]; float drift;
|
||||
struct result { char date[7]; char time[5]; double sync; double snr;
|
||||
double dt; double freq; char message[23]; double drift;
|
||||
unsigned int cycles; int jitter; };
|
||||
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);
|
||||
int nh;
|
||||
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);
|
||||
call_loc_pow=malloc(sizeof(char)*23);
|
||||
float allfreqs[100];
|
||||
double allfreqs[100];
|
||||
char allcalls[100][13];
|
||||
memset(allfreqs,0,sizeof(float)*100);
|
||||
memset(allfreqs,0,sizeof(double)*100);
|
||||
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:
|
||||
maxcycles=10000; //Fano timeout limit
|
||||
unsigned int maxcycles=10000; //Decoder timeout limit
|
||||
double minsync1=0.10; //First sync limit
|
||||
double minsync2=0.12; //Second sync limit
|
||||
int iifac=8; //Step size in final DT peakup
|
||||
@ -622,18 +633,18 @@ int main(int argc, char *argv[])
|
||||
int maxdrift=4; //Maximum (+/-) drift
|
||||
double minrms=52.0 * (symfac/64.0); //Final test for plausible decoding
|
||||
delta=60; //Fano threshold step
|
||||
double bias=0.42; //Fano metric bias (used for both Fano and stack algorithms)
|
||||
|
||||
t00=clock();
|
||||
fftw_complex *fftin, *fftout;
|
||||
#include "./metric_tables.c"
|
||||
|
||||
int mettab[2][256];
|
||||
float bias=0.42;
|
||||
|
||||
idat=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) {
|
||||
case 'a':
|
||||
data_dir = optarg;
|
||||
@ -641,12 +652,14 @@ int main(int argc, char *argv[])
|
||||
case 'c':
|
||||
writec2=1;
|
||||
break;
|
||||
case 'C':
|
||||
maxcycles=(unsigned int) strtoul(optarg,NULL,10);
|
||||
break;
|
||||
case 'd':
|
||||
more_candidates=1;
|
||||
iifac=4;
|
||||
break;
|
||||
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
|
||||
break;
|
||||
case 'f':
|
||||
@ -655,14 +668,17 @@ int main(int argc, char *argv[])
|
||||
case 'H':
|
||||
usehashtable = 0;
|
||||
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;
|
||||
break;
|
||||
case 'q':
|
||||
case 'q': //no shift jittering
|
||||
quickmode = 1;
|
||||
break;
|
||||
case 's':
|
||||
subtraction = 0; //single pass mode (same as original wsprd)
|
||||
case 's': //single pass mode (same as original wsprd)
|
||||
subtraction = 0;
|
||||
npasses = 1;
|
||||
break;
|
||||
case 'v':
|
||||
@ -673,7 +689,7 @@ int main(int argc, char *argv[])
|
||||
fmax=150.0;
|
||||
break;
|
||||
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;
|
||||
case '?':
|
||||
usage();
|
||||
@ -681,6 +697,10 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
if( stackdecoder ) {
|
||||
stack=malloc(stacksize*sizeof(struct node));
|
||||
}
|
||||
|
||||
if( optind+1 > argc) {
|
||||
usage();
|
||||
return 1;
|
||||
@ -766,8 +786,8 @@ int main(int argc, char *argv[])
|
||||
fftout=(fftw_complex*) fftw_malloc(sizeof(fftw_complex)*512);
|
||||
PLAN3 = fftw_plan_dft_1d(512, fftin, fftout, FFTW_FORWARD, PATIENCE);
|
||||
|
||||
float ps[512][nffts];
|
||||
float w[512];
|
||||
double ps[512][nffts];
|
||||
double w[512];
|
||||
for(i=0; i<512; i++) {
|
||||
w[i]=sin(0.006147931*i);
|
||||
}
|
||||
@ -777,7 +797,7 @@ int main(int argc, char *argv[])
|
||||
if( (fhash=fopen(hash_fname,"r+")) ) {
|
||||
while (fgets(line, sizeof(line), fhash) != NULL) {
|
||||
sscanf(line,"%d %s",&nh,hcall);
|
||||
strcpy(*hashtab+nh*13,hcall);
|
||||
strcpy(hashtab+nh*13,hcall);
|
||||
}
|
||||
} else {
|
||||
fhash=fopen(hash_fname,"w+");
|
||||
@ -788,9 +808,10 @@ int main(int argc, char *argv[])
|
||||
//*************** main loop starts here *****************
|
||||
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(j=0; j<512; j++ ) {
|
||||
k=i*128+j;
|
||||
@ -807,7 +828,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
// Compute average spectrum
|
||||
memset(psavg,0.0, sizeof(float)*512);
|
||||
memset(psavg,0.0, sizeof(double)*512);
|
||||
for (i=0; i<nffts; i++) {
|
||||
for (j=0; j<512; j++) {
|
||||
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
|
||||
int window[7]={1,1,1,1,1,1,1};
|
||||
float smspec[411];
|
||||
double smspec[411];
|
||||
for (i=0; i<411; i++) {
|
||||
smspec[i]=0.0;
|
||||
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
|
||||
float tmpsort[411];
|
||||
double tmpsort[411];
|
||||
for (j=0; j<411; 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
|
||||
float noise_level = tmpsort[122];
|
||||
double noise_level = tmpsort[122];
|
||||
|
||||
/* Renormalize spectrum so that (large) peaks represent an estimate of snr.
|
||||
* We know from experience that threshold snr is near -7dB in wspr 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. */
|
||||
|
||||
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
|
||||
if( wspr_type == 2 ) {
|
||||
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
|
||||
int pass;
|
||||
float tmp;
|
||||
double tmp;
|
||||
for (pass = 1; pass <= npk - 1; pass++) {
|
||||
for (k = 0; k < npk - pass ; k++) {
|
||||
if (snr0[k] < snr0[k+1]) {
|
||||
@ -918,6 +939,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
t0=clock();
|
||||
|
||||
/* Make coarse estimates of shift (DT), freq, and drift
|
||||
|
||||
* 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 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...
|
||||
smax=-1e30;
|
||||
if0=freq0[j]/df+256;
|
||||
@ -950,7 +972,7 @@ int main(int argc, char *argv[])
|
||||
ss=0.0;
|
||||
pow=0.0;
|
||||
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;
|
||||
if( kindex < nffts ) {
|
||||
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));
|
||||
pow=pow+p0+p1+p2+p3;
|
||||
sync1=ss/pow;
|
||||
}
|
||||
}
|
||||
sync1=ss/pow;
|
||||
if( sync1 > smax ) { //Save coarse parameters
|
||||
smax=sync1;
|
||||
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.
|
||||
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].
|
||||
|
||||
Function sync_and_demodulate has three modes of operation
|
||||
@ -1025,7 +1047,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
// refine drift estimate
|
||||
fstep=0.0; ifmin=0; ifmax=0;
|
||||
float driftp,driftm,syncp,syncm;
|
||||
double driftp,driftm,syncp,syncm;
|
||||
driftp=drift1+0.5;
|
||||
sync_and_demodulate(idat, qdat, npoints, symbols, &f1, ifmin, ifmax, fstep, &shift1,
|
||||
lagmin, lagmax, lagstep, &driftp, symfac, &syncp, 1);
|
||||
@ -1093,22 +1115,23 @@ int main(int argc, char *argv[])
|
||||
deinterleave(symbols);
|
||||
t0 = clock();
|
||||
|
||||
not_decoded = fano(&metric,&cycles,&maxnp,decdata,symbols,nbits,
|
||||
mettab,delta,maxcycles);
|
||||
if ( stackdecoder ) {
|
||||
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;
|
||||
|
||||
/* ### 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++;
|
||||
if( quickmode ) break;
|
||||
}
|
||||
|
||||
if( worth_a_try && !not_decoded ) {
|
||||
ndecodes_pass++;
|
||||
|
||||
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).
|
||||
noprint=unpk_(message,hashtab,call_loc_pow,callsign);
|
||||
|
||||
if( subtraction && (ipass < (npasses-1) ) && !noprint ) {
|
||||
|
||||
unsigned char channel_symbols[162];
|
||||
|
||||
if( get_wspr_channel_symbols(call_loc_pow, channel_symbols) ) {
|
||||
// subtract even on last pass
|
||||
if( subtraction && (ipass < npasses ) && !noprint ) {
|
||||
if( get_wspr_channel_symbols(call_loc_pow, hashtab, channel_symbols) ) {
|
||||
subtract_signal2(idat, qdat, npoints, f1, shift1, drift1, channel_symbols);
|
||||
} else {
|
||||
break;
|
||||
@ -1169,15 +1190,6 @@ int main(int argc, char *argv[])
|
||||
decodes[uniques-1].drift=drift1;
|
||||
decodes[uniques-1].cycles=cycles;
|
||||
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(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,"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,"Total %7.2f %7.2f\n",ttotal,1.0);
|
||||
|
||||
@ -1260,13 +1272,17 @@ int main(int argc, char *argv[])
|
||||
if( usehashtable ) {
|
||||
fhash=fopen(hash_fname,"w");
|
||||
for (i=0; i<32768; i++) {
|
||||
if( strncmp(hashtab[i],"\0",1) != 0 ) {
|
||||
fprintf(fhash,"%5d %s\n",i,*hashtab+i*13);
|
||||
if( strncmp(hashtab+i*13,"\0",1) != 0 ) {
|
||||
fprintf(fhash,"%5d %s\n",i,hashtab+i*13);
|
||||
}
|
||||
}
|
||||
fclose(fhash);
|
||||
}
|
||||
|
||||
if( stackdecoder ) {
|
||||
free(stack);
|
||||
}
|
||||
|
||||
if(writenoise == 999) return -1; //Silence compiler warning
|
||||
return 0;
|
||||
}
|
||||
|
@ -225,6 +225,13 @@ void deinterleave(unsigned char *sym)
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
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,"\0",1);
|
||||
ihash=nhash(callsign,strlen(callsign),(uint32_t)146);
|
||||
strcpy(*hashtab+ihash*13,callsign);
|
||||
strcpy(hashtab+ihash*13,callsign);
|
||||
} else {
|
||||
nadd=nu;
|
||||
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;
|
||||
if( nu == 0 || nu == 3 || nu == 7 || nu == 10 ) { //make sure power is OK
|
||||
ihash=nhash(callsign,strlen(callsign),(uint32_t)146);
|
||||
strcpy(*hashtab+ihash*13,callsign);
|
||||
strcpy(hashtab+ihash*13,callsign);
|
||||
} else noprint=1;
|
||||
}
|
||||
} 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...
|
||||
// isalpha(grid6[4]) && isalpha(grid6[5]) ) ) {
|
||||
ihash=nhash(callsign,strlen(callsign),(uint32_t)146);
|
||||
strcpy(*hashtab+ihash*13,callsign);
|
||||
strcpy(hashtab+ihash*13,callsign);
|
||||
} else noprint=1;
|
||||
|
||||
ihash=(n2-ntype-64)/128;
|
||||
if( strncmp(hashtab[ihash],"\0",1) != 0 ) {
|
||||
sprintf(callsign,"<%s>",hashtab[ihash]);
|
||||
if( strncmp(hashtab+ihash*13,"\0",1) != 0 ) {
|
||||
sprintf(callsign,"<%s>",hashtab+ihash*13);
|
||||
} else {
|
||||
sprintf(callsign,"%5s","<...>");
|
||||
}
|
||||
|
@ -21,8 +21,9 @@ int unpackpfx( int32_t nprefix, char *call);
|
||||
void deinterleave(unsigned char *sym);
|
||||
|
||||
// used by qsort
|
||||
int doublecomp(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
|
||||
|
@ -126,13 +126,18 @@ int main(int argc, char *argv[])
|
||||
extern int optind;
|
||||
int i, c, printchannel=0, writec2=0;
|
||||
float snr=50.0;
|
||||
char *message, *c2filename;
|
||||
char *message, *c2filename, *hashtab;
|
||||
c2filename=malloc(sizeof(char)*15);
|
||||
hashtab=malloc(sizeof(char)*32768*13);
|
||||
memset(hashtab,0,sizeof(char)*32768*13);
|
||||
|
||||
// message length is 22 characters
|
||||
message=malloc(sizeof(char)*23);
|
||||
|
||||
strcpy(c2filename,"000000_0001.c2");
|
||||
|
||||
srand(getpid());
|
||||
|
||||
while ( (c = getopt(argc, argv, "cdo:s:")) !=-1 ) {
|
||||
switch (c) {
|
||||
case 'c':
|
||||
@ -159,7 +164,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
unsigned char channel_symbols[162];
|
||||
get_wspr_channel_symbols(message, channel_symbols);
|
||||
get_wspr_channel_symbols(message, hashtab, channel_symbols);
|
||||
|
||||
if( printchannel ) {
|
||||
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 i, j, ihash;
|
||||
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
|
||||
// unpack it with the routine that the decoder will use and display
|
||||
// the result. let the operator decide whether it worked.
|
||||
char hashtab[32768][13];
|
||||
memset(hashtab,0,sizeof(char)*32768*13);
|
||||
// char hashtab[32768][13];
|
||||
// memset(hashtab,0,sizeof(char)*32768*13);
|
||||
|
||||
char *check_call_loc_pow, *check_callsign;
|
||||
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);
|
||||
|
||||
int get_wspr_channel_symbols(char* message, unsigned char* symbols);
|
||||
int get_wspr_channel_symbols(char* message, char* hashtab, unsigned char* symbols);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user