diff --git a/Makefile b/Makefile index 93d2631..2c9c699 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,12 @@ INCLUDES=-I. -CFLAGS= -O3 -Wall $(INCLUDES) +CFLAGS= -g -Wall $(INCLUDES) -OBJS= main.o image.o dsp.o filter.o reg.o fcolor.o +OBJS= main.o input.o image.o dsp.o filter.o reg.o fcolor.o atpdec: $(OBJS) - $(CC) -o $@ $(OBJS) -lm -lsndfile -lpng + $(CC) -o $@ $(OBJS) -lm -lsndfile -lpng -lasound main.o: main.c version.h temppalette.h gvipalette.h offsets.h dsp.o: dsp.c filtercoeff.h filter.h diff --git a/TODO b/TODO deleted file mode 100644 index 53ddd31..0000000 --- a/TODO +++ /dev/null @@ -1,11 +0,0 @@ -ATPDEC TODO List - -- Could be useful to read data directly from /dev/dsp - -- GUI : I'm not a GUI man , but if someone want to do the job .... - -- Optimisation : Don't do anything in order to run fast. There is plenty - room for performance improvement (but on my 1.7GHz celeron , decoding - is already faster than real time...) - - diff --git a/dsp.c b/dsp.c index 3462760..a2f76c1 100755 --- a/dsp.c +++ b/dsp.c @@ -20,152 +20,114 @@ * */ #include +#include #include #include -#ifndef M_PI -#define M_PI 3.14159265358979323846 /* for OS that don't know it */ -#endif /* */ #include "filter.h" #include "filtercoeff.h" -extern int getsample(float *inbuff, int nb); +extern int nbch,nch; +extern int getsample(short *inbuff, int nb); #define Fc 2400.0 -#define DFc 50.0 #define PixelLine 2080 -#define Fp (2*PixelLine) -#define RSMULT 15 -#define Fi (Fp*RSMULT) +#define RSMULT 30 +#define Fi (PixelLine*2*RSMULT) -static double Fe; +double Fe; -static double offset = 0.0; +static double FreqOsc; +static double DPLL_C1,DPLL_C2,AGCK; static double FreqLine = 1.0; -static double FreqOsc; -static double K1,K2; +#define sig 20 +#define RSFilterLen (5*sig+1) +static float rsfilter[RSFilterLen]; -int init_dsp(double F) +int init_dsp(void) { -if(F > Fi) return (1); -if(F < Fp) return (-1); -Fe=F; +int i; -K1=DFc/Fe; -K2=K1*K1/2.0; +/* gausian filter coeff */ + +for(i=0;i=0) { - r = (I - Q) / (I + Q); - angle = 0.25 - 0.25 * r; - } else { - r = (I + Q) / (Q - I); - angle = 0.75 - 0.25 * r; - } - - if(s>0) - return(angle); - else - return(-angle); -} -static double pll(double I, double Q) -{ +#define BLKIN 4096 + static short inbuff[2*BLKIN]; + int n,ns; -/* pll coeff */ static double PhaseOsc = 0.0; - double Io, Qo; - double Ip, Qp; + static double mamp=0.5; + double amp; double DPhi; +#define DFc 50.0 + + ns=getsample(inbuff, nb > BLKIN ? BLKIN : nb); + + for (n = 0; n < ns; n++) { + double in; + + in=((double)inbuff[n*nbch+nch]/32768.0); + + mamp=AGCK*mamp+(1.0-AGCK)*fabs(in); + + amp=2.0*in*cos(PhaseOsc); + ambuff[n] = amp; -/* quadrature oscillator */ - Io = cos(PhaseOsc); - Qo = sin(PhaseOsc); + //fprintf(stderr,"%g %g %g\n",in,cos(PhaseOsc),amp); -/* phase detector */ - Ip = I*Io+Q*Qo; - Qp = Q*Io-I*Qo; - DPhi = Phase(Ip,Qp); +/* delta phase */ + DPhi=-in/(mamp*M_SQRT2)*(sin(PhaseOsc)-sin(3.0*PhaseOsc)); /* loop filter */ - PhaseOsc += 2.0 * M_PI * (K1 * DPhi + FreqOsc); + PhaseOsc += 2.0 * M_PI * (DPLL_C2 * DPhi + FreqOsc); if (PhaseOsc > M_PI) PhaseOsc -= 2.0 * M_PI; if (PhaseOsc <= -M_PI) PhaseOsc += 2.0 * M_PI; - FreqOsc += K2 * DPhi; + FreqOsc += DPLL_C1 * DPhi; if (FreqOsc > ((Fc + DFc) / Fe)) FreqOsc = (Fc + DFc) / Fe; if (FreqOsc < ((Fc - DFc) / Fe)) FreqOsc = (Fc - DFc) / Fe; - return (Ip); -} - -static int getamp(double *ambuff, int nb) -{ - -#define BLKIN 1024 - static float inbuff[BLKIN]; - static int idxin=0; - static int nin=0; - - int n; - - for (n = 0; n < nb; n++) { - double I,Q; - if (nin < IQFilterLen*2+2) { - int res; - memmove(inbuff, &(inbuff[idxin]), nin * sizeof(float)); - idxin = 0; - res = getsample(&(inbuff[nin]), BLKIN - nin); - nin += res; - if (nin < IQFilterLen*2+2) - return (n); - } - - iqfir(&inbuff[idxin],iqfilter,IQFilterLen,&I,&Q); - ambuff[n] = pll(I,Q); - - idxin += 1; - nin -= 1; } - return (n); + return (ns); } int getpixelv(float *pvbuff, int nb) { -#define BLKAMP 1024 + static double offset = 0.0; + +#define BLKAMP 4096 static double ambuff[BLKAMP]; static int nam = 0; static int idxam = 0; int n,m; double mult; + float v; + static float ppv=0,pv=0; mult = (double) Fi/Fe*FreqLine; @@ -184,9 +146,18 @@ int getpixelv(float *pvbuff, int nb) return (n); } - pvbuff[n] = rsfir(&(ambuff[idxam]), rsfilter, RSFilterLen, offset, mult) * mult * 256.0; - -//printf("%g\n",pvbuff[n]); + v = rsfir(&(ambuff[idxam]), rsfilter, RSFilterLen, offset, mult) * mult * 256.0; + if(v<0.0) { + v = 2.0*(pv-ppv); + if (v<0.0) v=0.0; + if (v>=256.0) v=255.0; + pvbuff[n] = v; + ppv=pv; + } else { + if (v>=256.0) v=255.0; + pvbuff[n] = v; + ppv=pv;pv=v; + } shift = ((int) floor((RSMULT - offset) / mult))+1; offset = shift*mult+offset-RSMULT ; diff --git a/filter.c b/filter.c index 327e16a..b87a3b3 100755 --- a/filter.c +++ b/filter.c @@ -34,20 +34,6 @@ float fir(float *buff, const float *coeff, const int len) return r; } -void iqfir(float *buff, const float *coeff, const int len,double *I,double *Q) -{ - int k; - double i,q; - - i=q=0.0; - for (k = 0; k < len; k++) { - q += buff[2*k] * coeff[k]; - i += buff[2*k] ; - } - i= buff[len-1]-i/len; - *I=i,*Q=q; -} - float rsfir(double *buff, const float *coeff, const int len, const double offset, const double delta) { diff --git a/filter.h b/filter.h index 13e4304..9f6cd8d 100755 --- a/filter.h +++ b/filter.h @@ -22,6 +22,5 @@ float fir(float *buff,const float *coeff,const int len); -void iqfir(float *buff,const float *coeff,const int len,double *I,double *Q); float rsfir(double *buff,const float *coeff,const int len ,const double offset ,const double delta); diff --git a/filtercoeff.h b/filtercoeff.h index 062d20b..63de1c7 100755 --- a/filtercoeff.h +++ b/filtercoeff.h @@ -1,6 +1,6 @@ /* * Atpdec - * Copyright (c) 2003 by Thierry Leconte (F4DWV) + * Copyright (c) 2010 by Thierry Leconte (F4DWV) * * $Id$ * @@ -20,14 +20,6 @@ * */ -#define IQFilterLen 32 -const float iqfilter[IQFilterLen] = - { 0.0205361, 0.0219524, 0.0235785, 0.0254648, 0.0276791, 0.0303152, -0.0335063, 0.0374482, 0.0424413, 0.0489708, 0.0578745, 0.0707355, 0.0909457, 0.127324, 0.212207, 0.63662, --0.63662, -0.212207, -0.127324, -0.0909457, -0.0707355, -0.0578745, -0.0489708, -0.0424413, -0.0374482, --0.0335063, -0.0303152, -0.0276791, -0.0254648, -0.0235785, -0.0219524, -0.0205361 -}; - #define SyncFilterLen 32 const float Sync[SyncFilterLen] = @@ -36,71 +28,3 @@ const float Sync[SyncFilterLen] = }; -#define RSFilterLen 437 -const float rsfilter[RSFilterLen] = - { -3.37279e-04, -8.80292e-06, -3.96418e-04, -1.78544e-04, -5.27511e-04, --3.75376e-04, -6.95337e-04, -5.93148e-04, -8.79730e-04, -8.15327e-04, -1.05669e-03, -1.01377e-03, --1.19836e-03, -1.15443e-03, -1.26937e-03, -1.20955e-03, -1.23904e-03, -1.15302e-03, -1.08660e-03, --9.64235e-04, -8.02450e-04, -6.46202e-04, -3.95376e-04, -2.18096e-04, 1.11906e-04, 2.89567e-04, -6.67167e-04, 8.19039e-04, 1.21725e-03, 1.30556e-03, 1.69365e-03, 1.68588e-03, 2.03277e-03, 1.90159e-03, -2.18455e-03, 1.90833e-03, 2.12100e-03, 1.69052e-03, 1.77484e-03, 1.42542e-03, 1.18292e-03, 8.66979e-04, -5.54161e-04, 2.15793e-04, -1.11623e-04, -4.35173e-04, -7.27194e-04, -9.91551e-04, -1.20407e-03, --1.37032e-03, -1.46991e-03, -1.51120e-03, -1.48008e-03, -1.39047e-03, -1.23115e-03, -1.02128e-03, --7.60099e-04, -4.68008e-04, -1.46339e-04, 1.80867e-04, 5.11244e-04, 8.19243e-04, 1.09739e-03, 1.32668e-03, -1.50632e-03, 1.61522e-03, 1.66246e-03, 1.62390e-03, 1.52430e-03, 1.34273e-03, 1.10736e-03, 8.10335e-04, -4.76814e-04, 1.13622e-04, -2.64150e-04, -6.26595e-04, -9.95436e-04, -1.27846e-03, -1.54080e-03, --1.74292e-03, -1.86141e-03, -1.89318e-03, -1.83969e-03, -1.69770e-03, -1.47938e-03, -1.18696e-03, --8.37003e-04, -4.39507e-04, -1.56907e-05, 4.19904e-04, 8.43172e-04, 1.23827e-03, 1.58411e-03, -1.86382e-03, 2.06312e-03, 2.17177e-03, 2.18121e-03, 2.08906e-03, 1.89772e-03, 1.61153e-03, -1.24507e-03, 8.13976e-04, 3.29944e-04, -1.74591e-04, -6.83619e-04, -1.17826e-03, -1.61659e-03, --2.00403e-03, -2.29070e-03, -2.49179e-03, -2.56546e-03, -2.53448e-03, -2.37032e-03, -2.10060e-03, --1.72140e-03, -1.24542e-03, -7.15425e-04, -1.24964e-04, 4.83736e-04, 1.08328e-03, 1.64530e-03, -2.14503e-03, 2.55400e-03, 2.85589e-03, 3.02785e-03, 3.06271e-03, 2.95067e-03, 2.69770e-03, -2.30599e-03, 1.79763e-03, 1.18587e-03, 5.04003e-04, -2.23591e-04, -9.57591e-04, -1.66939e-03, --2.31717e-03, -2.87636e-03, -3.31209e-03, -3.60506e-03, -3.73609e-03, -3.69208e-03, -3.44913e-03, --3.06572e-03, -2.50229e-03, -1.80630e-03, -1.00532e-03, -1.22305e-04, 7.83910e-04, 1.69402e-03, -2.53826e-03, 3.30312e-03, 3.91841e-03, 4.38017e-03, 4.63546e-03, 4.68091e-03, 4.50037e-03, -4.09614e-03, 3.47811e-03, 2.67306e-03, 1.70418e-03, 6.20542e-04, -5.36994e-04, -1.70981e-03, --2.84712e-03, -3.88827e-03, -4.78659e-03, -5.48593e-03, -5.95049e-03, -6.14483e-03, -6.05118e-03, --5.65829e-03, -4.97525e-03, -4.01796e-03, -2.82224e-03, -1.43003e-03, 1.00410e-04, 1.71169e-03, -3.31983e-03, 4.87796e-03, 6.23237e-03, 7.31013e-03, 8.20642e-03, 8.67374e-03, 8.77681e-03, -8.43444e-03, 7.66794e-03, 6.46827e-03, 4.87294e-03, 2.92923e-03, 6.98913e-04, -1.72126e-03, --4.24785e-03, -6.75380e-03, -9.13309e-03, -1.12532e-02, -1.30038e-02, -1.42633e-02, -1.49338e-02, --1.49145e-02, -1.41484e-02, -1.25761e-02, -1.01870e-02, -6.97432e-03, -2.97910e-03, 1.75386e-03, -7.11899e-03, 1.30225e-02, 1.93173e-02, 2.58685e-02, 3.24965e-02, 3.90469e-02, 4.53316e-02, -5.11931e-02, 5.64604e-02, 6.09924e-02, 6.46584e-02, 6.73547e-02, 6.90049e-02, 6.97096e-02, -6.90049e-02, 6.73547e-02, 6.46584e-02, 6.09924e-02, 5.64604e-02, 5.11931e-02, 4.53316e-02, -3.90469e-02, 3.24965e-02, 2.58685e-02, 1.93173e-02, 1.30225e-02, 7.11899e-03, 1.75386e-03, --2.97910e-03, -6.97432e-03, -1.01870e-02, -1.25761e-02, -1.41484e-02, -1.49145e-02, -1.49338e-02, --1.42633e-02, -1.30038e-02, -1.12532e-02, -9.13309e-03, -6.75380e-03, -4.24785e-03, -1.72126e-03, -6.98913e-04, 2.92923e-03, 4.87294e-03, 6.46827e-03, 7.66794e-03, 8.43444e-03, 8.77681e-03, -8.67374e-03, 8.20642e-03, 7.31013e-03, 6.23237e-03, 4.87796e-03, 3.31983e-03, 1.71169e-03, -1.00410e-04, -1.43003e-03, -2.82224e-03, -4.01796e-03, -4.97525e-03, -5.65829e-03, -6.05118e-03, --6.14483e-03, -5.95049e-03, -5.48593e-03, -4.78659e-03, -3.88827e-03, -2.84712e-03, -1.70981e-03, --5.36994e-04, 6.20542e-04, 1.70418e-03, 2.67306e-03, 3.47811e-03, 4.09614e-03, 4.50037e-03, -4.68091e-03, 4.63546e-03, 4.38017e-03, 3.91841e-03, 3.30312e-03, 2.53826e-03, 1.69402e-03, -7.83910e-04, -1.22305e-04, -1.00532e-03, -1.80630e-03, -2.50229e-03, -3.06572e-03, -3.44913e-03, --3.69208e-03, -3.73609e-03, -3.60506e-03, -3.31209e-03, -2.87636e-03, -2.31717e-03, -1.66939e-03, --9.57591e-04, -2.23591e-04, 5.04003e-04, 1.18587e-03, 1.79763e-03, 2.30599e-03, 2.69770e-03, -2.95067e-03, 3.06271e-03, 3.02785e-03, 2.85589e-03, 2.55400e-03, 2.14503e-03, 1.64530e-03, -1.08328e-03, 4.83736e-04, -1.24964e-04, -7.15425e-04, -1.24542e-03, -1.72140e-03, -2.10060e-03, --2.37032e-03, -2.53448e-03, -2.56546e-03, -2.49179e-03, -2.29070e-03, -2.00403e-03, -1.61659e-03, --1.17826e-03, -6.83619e-04, -1.74591e-04, 3.29944e-04, 8.13976e-04, 1.24507e-03, 1.61153e-03, -1.89772e-03, 2.08906e-03, 2.18121e-03, 2.17177e-03, 2.06312e-03, 1.86382e-03, 1.58411e-03, -1.23827e-03, 8.43172e-04, 4.19904e-04, -1.56907e-05, -4.39507e-04, -8.37003e-04, -1.18696e-03, --1.47938e-03, -1.69770e-03, -1.83969e-03, -1.89318e-03, -1.86141e-03, -1.74292e-03, -1.54080e-03, --1.27846e-03, -9.95436e-04, -6.26595e-04, -2.64150e-04, 1.13622e-04, 4.76814e-04, 8.10335e-04, -1.10736e-03, 1.34273e-03, 1.52430e-03, 1.62390e-03, 1.66246e-03, 1.61522e-03, 1.50632e-03, -1.32668e-03, 1.09739e-03, 8.19243e-04, 5.11244e-04, 1.80867e-04, -1.46339e-04, -4.68008e-04, --7.60099e-04, -1.02128e-03, -1.23115e-03, -1.39047e-03, -1.48008e-03, -1.51120e-03, -1.46991e-03, --1.37032e-03, -1.20407e-03, -9.91551e-04, -7.27194e-04, -4.35173e-04, -1.11623e-04, 2.15793e-04, -5.54161e-04, 8.66979e-04, 1.18292e-03, 1.42542e-03, 1.77484e-03, 1.69052e-03, 2.12100e-03, -1.90833e-03, 2.18455e-03, 1.90159e-03, 2.03277e-03, 1.68588e-03, 1.69365e-03, 1.30556e-03, -1.21725e-03, 8.19039e-04, 6.67167e-04, 2.89567e-04, 1.11906e-04, -2.18096e-04, -3.95376e-04, --6.46202e-04, -8.02450e-04, -9.64235e-04, -1.08660e-03, -1.15302e-03, -1.23904e-03, -1.20955e-03, --1.26937e-03, -1.15443e-03, -1.19836e-03, -1.01377e-03, -1.05669e-03, -8.15327e-04, -8.79730e-04, --5.93148e-04, -6.95337e-04, -3.75376e-04, -5.27511e-04, -1.78544e-04, -3.96418e-04, -8.80292e-06, --3.37279e-04 -}; - - diff --git a/main.c b/main.c index 487a524..1d6f288 100644 --- a/main.c +++ b/main.c @@ -40,46 +40,9 @@ #include "gvipalette.h" extern int getpixelrow(float *pixelv); -extern int init_dsp(double F);; +extern int init_dsp(void);; -static SNDFILE *inwav; -static int initsnd(char *filename) -{ - SF_INFO infwav; - int res; - -/* open wav input file */ - infwav.format = 0; - inwav = sf_open(filename, SFM_READ, &infwav); - if (inwav == NULL) { - fprintf(stderr, "could not open %s\n", filename); - return (1); - } - - res=init_dsp(infwav.samplerate); - if(res<0) { - fprintf(stderr, "Sample rate too low : %d\n", infwav.samplerate); - return (1); - } - if(res>0) { - fprintf(stderr, "Sample rate too hight : %d\n", infwav.samplerate); - return (1); - } - fprintf(stderr, "Sample rate : %d\n", infwav.samplerate); - - if (infwav.channels != 1) { - fprintf(stderr, "Too many channels in input file : %d\n", infwav.channels); - return (1); - } - - return (0); -} - -int getsample(float *sample, int nb) -{ - return (sf_read_float(inwav, sample, nb)); -} static png_text text_ptr[] = { {PNG_TEXT_COMPRESSION_NONE, "Software", version, sizeof(version)} @@ -280,10 +243,12 @@ extern void readfconf(char *file); extern int optind, opterr; extern char *optarg; int satnum = 4; +int nch=0; static void usage(void) { - fprintf(stderr, "atpdec [options] soundfiles ...\n"); + fprintf(stderr, version); + fprintf(stderr, "atpdec [options]\n"); fprintf(stderr, "options:\n-d \tDestination directory\n-i [r|a|b|c|t]\tOutput image type\n\t\t\tr: Raw\n\t\t\ta: A chan.\n\t\t\tb: B chan.\n\t\t\tc: False color\n\t\t\tt: Temperature\n-c \tFalse color config file\n-s [15|16|17|18|19]\tSatellite number (for temperature and false color generation)\n"); exit(1); @@ -294,6 +259,7 @@ int main(int argc, char **argv) char pngfilename[1024]; char name[1024]; char pngdirname[1024] = ""; + char imgopt[20] = "ac"; float *prow[3000]; char *chid[] = { "?", "1", "2", "3A", "4", "5", "3B" }; @@ -301,10 +267,8 @@ int main(int argc, char **argv) int chA,chB; int c; - printf("%s\n", version); - opterr = 0; - while ((c = getopt(argc, argv, "c:d:i:s:")) != EOF) { + while ((c = getopt(argc, argv, "a:f:c:d:i:s:LR")) != EOF) { switch (c) { case 'd': strcpy(pngdirname, optarg); @@ -322,32 +286,44 @@ int main(int argc, char **argv) exit(1); } break; + case 'f': + strcpy(name, basename(optarg)); + strtok(name, "."); + if(initsnd(optarg)) + exit(1); + break; + case 'a': + strcpy(name,"audioin"); + if(initalsa(optarg)) + exit(1); + break; + case 'L': + nch=0; + break; + case 'R': + nch=0; + break; default: usage(); } } - for (nrow = 0; nrow < 3000; nrow++) + for (nrow = 0; nrow < 3000; nrow++) prow[nrow] = NULL; - for (; optind < argc; optind++) { - chA=chB=0; - strcpy(pngfilename, argv[optind]); - strcpy(name, basename(pngfilename)); - strtok(name, "."); if (pngdirname[0] == '\0') { - strcpy(pngfilename, argv[optind]); - strcpy(pngdirname, dirname(pngfilename)); + strcpy(pngdirname,"."); } -/* open snd input */ - if (initsnd(argv[optind])) - exit(1); + +/* init dsp */ + if(init_dsp()) + exit(2); /* main loop */ - printf("Decoding: %s \n", argv[optind]); + printf("Decoding: %s \n", name); for (nrow = 0; nrow < 3000; nrow++) { if (prow[nrow] == NULL) prow[nrow] = (float *) malloc(sizeof(float) * 2150); @@ -357,7 +333,7 @@ int main(int argc, char **argv) fflush(stdout); } printf("\nDone\n"); - sf_close(inwav); + endsample(); /* raw image */ @@ -418,6 +394,7 @@ int main(int argc, char **argv) sprintf(pngfilename, "%s/%s-c.png", pngdirname, name); ImageOut(pngfilename, "GVI", prow, nrow, CH_WIDTH, CHB_OFFSET, (png_color*)GviPalette); } - } + + exit(0); } diff --git a/version.h b/version.h index 63a5cd8..d8f9745 100644 --- a/version.h +++ b/version.h @@ -1,2 +1,2 @@ -char version[]="Atpdec CVS version (c) 2004-2005 Thierry Leconte F4DWV"; +char version[]="Atpdec CVS version (c) 2004-2010 Thierry Leconte F4DWV";