kopia lustrzana https://github.com/rs1729/RS
				
				
				
			rs41, rs92, dfm09/06: sync match header
							rodzic
							
								
									12564c4cbc
								
							
						
					
					
						commit
						f4d592a58f
					
				|  | @ -0,0 +1,429 @@ | |||
| 
 | ||||
| /*
 | ||||
|  *  sync header: correlation/matched filter | ||||
|  *  compile: | ||||
|  *      gcc -c demod.c | ||||
|  * | ||||
|  *  author: zilog80 | ||||
|  */ | ||||
| 
 | ||||
| /* ------------------------------------------------------------------------------------ */ | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <math.h> | ||||
| 
 | ||||
| 
 | ||||
| typedef unsigned char  ui8_t; | ||||
| typedef unsigned short ui16_t; | ||||
| typedef unsigned int   ui32_t; | ||||
| typedef short i16_t; | ||||
| typedef int   i32_t; | ||||
| 
 | ||||
| //#include "demod.h"
 | ||||
| 
 | ||||
| /* ------------------------------------------------------------------------------------ */ | ||||
| 
 | ||||
| 
 | ||||
| static int sample_rate = 0, bits_sample = 0, channels = 0; | ||||
| static float samples_per_bit = 0; | ||||
| 
 | ||||
| static int findstr(char *buff, char *str, int pos) { | ||||
|     int i; | ||||
|     for (i = 0; i < 4; i++) { | ||||
|         if (buff[(pos+i)%4] != str[i]) break; | ||||
|     } | ||||
|     return i; | ||||
| } | ||||
| 
 | ||||
| int read_wav_header(FILE *fp, float baudrate) { | ||||
|     char txt[4+1] = "\0\0\0\0"; | ||||
|     unsigned char dat[4]; | ||||
|     int byte, p=0; | ||||
| 
 | ||||
|     if (fread(txt, 1, 4, fp) < 4) return -1; | ||||
|     if (strncmp(txt, "RIFF", 4)) return -1; | ||||
|     if (fread(txt, 1, 4, fp) < 4) return -1; | ||||
|     // pos_WAVE = 8L
 | ||||
|     if (fread(txt, 1, 4, fp) < 4) return -1; | ||||
|     if (strncmp(txt, "WAVE", 4)) return -1; | ||||
|     // pos_fmt = 12L
 | ||||
|     for ( ; ; ) { | ||||
|         if ( (byte=fgetc(fp)) == EOF ) return -1; | ||||
|         txt[p % 4] = byte; | ||||
|         p++; if (p==4) p=0; | ||||
|         if (findstr(txt, "fmt ", p) == 4) break; | ||||
|     } | ||||
|     if (fread(dat, 1, 4, fp) < 4) return -1; | ||||
|     if (fread(dat, 1, 2, fp) < 2) return -1; | ||||
| 
 | ||||
|     if (fread(dat, 1, 2, fp) < 2) return -1; | ||||
|     channels = dat[0] + (dat[1] << 8); | ||||
| 
 | ||||
|     if (fread(dat, 1, 4, fp) < 4) return -1; | ||||
|     memcpy(&sample_rate, dat, 4); //sample_rate = dat[0]|(dat[1]<<8)|(dat[2]<<16)|(dat[3]<<24);
 | ||||
| 
 | ||||
|     if (fread(dat, 1, 4, fp) < 4) return -1; | ||||
|     if (fread(dat, 1, 2, fp) < 2) return -1; | ||||
|     //byte = dat[0] + (dat[1] << 8);
 | ||||
| 
 | ||||
|     if (fread(dat, 1, 2, fp) < 2) return -1; | ||||
|     bits_sample = dat[0] + (dat[1] << 8); | ||||
| 
 | ||||
|     // pos_dat = 36L + info
 | ||||
|     for ( ; ; ) { | ||||
|         if ( (byte=fgetc(fp)) == EOF ) return -1; | ||||
|         txt[p % 4] = byte; | ||||
|         p++; if (p==4) p=0; | ||||
|         if (findstr(txt, "data", p) == 4) break; | ||||
|     } | ||||
|     if (fread(dat, 1, 4, fp) < 4) return -1; | ||||
| 
 | ||||
| 
 | ||||
|     fprintf(stderr, "sample_rate: %d\n", sample_rate); | ||||
|     fprintf(stderr, "bits       : %d\n", bits_sample); | ||||
|     fprintf(stderr, "channels   : %d\n", channels); | ||||
| 
 | ||||
|     if ((bits_sample != 8) && (bits_sample != 16)) return -1; | ||||
| 
 | ||||
|     samples_per_bit = sample_rate/baudrate; | ||||
| 
 | ||||
|     fprintf(stderr, "samples/bit: %.2f\n", samples_per_bit); | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static int f32read_sample(FILE *fp, float *s) { | ||||
|     int i; | ||||
|     short b = 0; | ||||
| 
 | ||||
|     for (i = 0; i < channels; i++) { | ||||
| 
 | ||||
|         if (fread( &b, bits_sample/8, 1, fp) != 1) return EOF; | ||||
| 
 | ||||
|         if (i == 0) {  // i = 0: links bzw. mono
 | ||||
|             //if (bits_sample ==  8)  sint = b-128;   // 8bit: 00..FF, centerpoint 0x80=128
 | ||||
|             //if (bits_sample == 16)  sint = (short)b;
 | ||||
| 
 | ||||
|             if (bits_sample ==  8) { b -= 128; } | ||||
|             *s = b/128.0; | ||||
|             if (bits_sample == 16) { *s /= 256.0; } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static unsigned int sample_in, sample_out, delay; | ||||
| 
 | ||||
| static int N, M; | ||||
| 
 | ||||
| static float *match = NULL, | ||||
|              *bufs  = NULL, | ||||
|              *corrbuf = NULL; | ||||
| 
 | ||||
| static char *rawbits = NULL; | ||||
| 
 | ||||
| static int Nvar = 0; // < M
 | ||||
| static double xsum=0, samples_mu=0, | ||||
|               qsum=0, samples_var=0; | ||||
| 
 | ||||
| float get_var() { | ||||
|     return (float)samples_var; | ||||
| } | ||||
| 
 | ||||
| int getmaxCorr(float *maxv, unsigned int *maxvpos, int len) { | ||||
| // In: current Max: maxv at maxvpos
 | ||||
| // Out: Max
 | ||||
| // Maximum im Intervall [sample_out-slen, sample_out-1]
 | ||||
| // Randwerte zaehlen nicht als Extremwerte;
 | ||||
| // nur neu berechnen, wenn neue Werte groesser als altes Max
 | ||||
|     int slen, pos, mpos; | ||||
|     float m, s0, s, s1; | ||||
| 
 | ||||
|     int posIn = 0; // -1..0..1; // rs41:0
 | ||||
|     float S_neu = corrbuf[(sample_out+M+posIn) % M]; | ||||
|     float S_vor = corrbuf[(sample_out+M+posIn-1) % M]; | ||||
| 
 | ||||
|     if (sample_in < delay) return 0; | ||||
| 
 | ||||
|     slen = len*samples_per_bit; | ||||
| 
 | ||||
|     if (slen > M) slen = M; | ||||
| 
 | ||||
|     if ( (sample_out - *maxvpos >= slen-4) || | ||||
|          (sample_out - *maxvpos < slen  &&  *maxv <= S_vor && S_vor >= S_neu) ) | ||||
|     { | ||||
|         m = -1.0; | ||||
|         for (pos = 1; pos < slen+posIn; pos++) { | ||||
|             s0 = corrbuf[(sample_out + 2*M - slen + pos-1) % M]; | ||||
|             s  = corrbuf[(sample_out + 2*M - slen + pos  ) % M]; | ||||
|             s1 = corrbuf[(sample_out + 2*M - slen + pos+1) % M]; | ||||
|             if (s > m && s>=s0 && s>=s1) { | ||||
|                 m = s; | ||||
|                 mpos = sample_out - slen + pos; | ||||
|             } | ||||
|         } | ||||
|         *maxv = m; | ||||
|         *maxvpos = mpos; | ||||
|     } | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| int f32buf_sample(FILE *fp, int inv, int cm) { | ||||
|     static unsigned int sample_in0; | ||||
|     int i; | ||||
|     float s = 0.0; | ||||
|     float x, xneu, xalt, | ||||
|           corr = 0.0, | ||||
|           norm = 0.0; | ||||
| 
 | ||||
| 
 | ||||
|     if (f32read_sample(fp, &s) == EOF) return EOF; | ||||
| 
 | ||||
|     if (inv) s = -s; | ||||
|     bufs[sample_in % M] = s; | ||||
| 
 | ||||
|     sample_out = sample_in - delay; | ||||
| 
 | ||||
| 	if (cm) { | ||||
| 	    if (sample_in > sample_in0+1 || sample_in <= sample_in0) { | ||||
| 	        for (i = 0; i < M; i++) corrbuf[i] = 0.0; | ||||
| 	    } | ||||
| 		norm = 0.0; | ||||
| 	//	for (i = 0; i < N; i++) {
 | ||||
| 	    for (i = 1; i < N-1; i++) { | ||||
| 		    x = bufs[(sample_in+M -(N-1) + i) % M]; | ||||
| 		    corr += match[i]*x; | ||||
| 		    norm += x*x; | ||||
| 		} | ||||
| 		corr = corr/sqrt(norm); | ||||
| 		corrbuf[sample_in % M] = corr; | ||||
| 		sample_in0 = sample_in; | ||||
|     } | ||||
| 
 | ||||
|     xneu = bufs[(sample_out+M +1) % M]; | ||||
|     xalt = bufs[(sample_out+M -Nvar-1) % M]; | ||||
|     xsum = xsum - xalt + xneu; | ||||
|     qsum = qsum - xalt*xalt + xneu*xneu; | ||||
|     samples_mu  = xsum/Nvar; | ||||
|     samples_var = qsum/Nvar - samples_mu*samples_mu; | ||||
| 
 | ||||
|     sample_in += 1; | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| static int read_bufbit(int symlen, char *bits, int ofs, int reset) { | ||||
| // symlen==2: manchester2 0->10,1->01->1: 2.bit
 | ||||
| 
 | ||||
|     static unsigned int rcount; | ||||
|     static float rbitgrenze; | ||||
| 
 | ||||
|     double sum = 0.0; | ||||
| 
 | ||||
|     if (reset) { | ||||
|         rcount = 0;     // eigentlich scount = 1
 | ||||
|         rbitgrenze = 0; //   oder bitgrenze = -1
 | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     rbitgrenze += samples_per_bit; | ||||
|     do { | ||||
|         sum += bufs[(sample_out+rcount + 2*M +ofs) % M]; | ||||
|         rcount++; | ||||
|     } while (rcount < rbitgrenze);  // n < samples_per_bit
 | ||||
| 
 | ||||
|     if (symlen == 2) { | ||||
|         rbitgrenze += samples_per_bit; | ||||
|         do { | ||||
|             sum -= bufs[(sample_out+rcount + 2*M +ofs) % M]; | ||||
|             rcount++; | ||||
|         } while (rcount < rbitgrenze);  // n < samples_per_bit
 | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     if (symlen != 2) { | ||||
|         if (sum >= 0) *bits = '1'; | ||||
|         else          *bits = '0'; | ||||
|     } | ||||
|     else { | ||||
|         if (sum >= 0) strncpy(bits, "10", 2); | ||||
|         else          strncpy(bits, "01", 2); | ||||
|     } | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| int headcmp(int symlen, char *hdr, int len, int ofs) { | ||||
|     int errs = 0; | ||||
|     int pos; | ||||
|     int step = 1; | ||||
|     if (symlen != 1) step = 2; | ||||
| 
 | ||||
|     for (pos = 0; pos < len; pos += step) { | ||||
|         read_bufbit(symlen, rawbits+pos, len*samples_per_bit+ofs, pos==0); | ||||
|     } | ||||
|     rawbits[pos] = '\0'; | ||||
| 
 | ||||
|     while (len > 0) { | ||||
|         if (rawbits[len-1] != hdr[len-1]) errs += 1; | ||||
|         len--; | ||||
|     } | ||||
| 
 | ||||
|     return errs; | ||||
| } | ||||
| 
 | ||||
| /* -------------------------------------------------------------------------- */ | ||||
| 
 | ||||
| int read_sbit(FILE *fp, int symlen, int *bit, int inv, int ofs, int reset, int cm) { | ||||
| // symlen==2: manchester2 10->0,01->1: 2.bit
 | ||||
| 
 | ||||
|     static double bitgrenze; | ||||
|     static unsigned long scount; | ||||
| 
 | ||||
|     float sample, sample0; | ||||
|     int pars; | ||||
| 
 | ||||
|     double sum = 0.0; | ||||
| 
 | ||||
|     sample0 = 0; | ||||
|     pars = 0; | ||||
| 
 | ||||
|     if (reset) { | ||||
|         scount = 0; | ||||
|         bitgrenze = 0; | ||||
|     } | ||||
| 
 | ||||
|     if (symlen == 2) { | ||||
|         bitgrenze += samples_per_bit; | ||||
|         do { | ||||
|             if (f32buf_sample(fp, inv, cm) == EOF) return EOF; | ||||
|             sample = bufs[(sample_out+ofs + M) % M]; | ||||
|             sum -= sample; | ||||
| 
 | ||||
|             if (sample * sample0 < 0) pars++;   // wenn sample[0..n-1]=0 ...
 | ||||
|             sample0 = sample; | ||||
| 
 | ||||
|             scount++; | ||||
|         } while (scount < bitgrenze);  // n < samples_per_bit
 | ||||
|     } | ||||
| 
 | ||||
|     bitgrenze += samples_per_bit; | ||||
|     do { | ||||
|         if (f32buf_sample(fp, inv, cm) == EOF) return EOF; | ||||
|         sample = bufs[(sample_out+ofs + M) % M]; | ||||
|         sum += sample; | ||||
| 
 | ||||
|         if (sample * sample0 < 0) pars++;   // wenn sample[0..n-1]=0 ...
 | ||||
|         sample0 = sample; | ||||
| 
 | ||||
|         scount++; | ||||
|     } while (scount < bitgrenze);  // n < samples_per_bit
 | ||||
| 
 | ||||
|     if (sum >= 0) *bit = 1; | ||||
|     else          *bit = 0; | ||||
| 
 | ||||
|     return pars; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* -------------------------------------------------------------------------- */ | ||||
| 
 | ||||
| static double norm2_match() { | ||||
|     int i; | ||||
|     double x, y = 0.0; | ||||
|     for (i = 0; i < N; i++) { | ||||
|         x = match[i]; | ||||
|         y += x*x; | ||||
|     } | ||||
|     return y; | ||||
| } | ||||
| 
 | ||||
| int init_buffers(char hdr[], int hLen, int bitofs, int shape) { | ||||
|     //hLen = strlen(header) = HEADLEN;
 | ||||
| 
 | ||||
|     int i, pos; | ||||
|     float b, x; | ||||
|     float normMatch; | ||||
| 
 | ||||
|     float alpha, sqalp, a = 1.0; | ||||
| 
 | ||||
| 
 | ||||
|     N = hLen * samples_per_bit; | ||||
|     M = 2*N; // >= N
 | ||||
|     Nvar = 32 * samples_per_bit; | ||||
| 
 | ||||
|     bufs  = (float *)calloc( M+1, sizeof(float)); if (bufs  == NULL) return -100; | ||||
|     match = (float *)calloc( N+1, sizeof(float)); if (match == NULL) return -100; | ||||
|     corrbuf = (float *)calloc( M+1, sizeof(float)); if (corrbuf == NULL) return -100; | ||||
| 
 | ||||
|     rawbits = (char *)calloc( N+1, sizeof(char)); if (rawbits == NULL) return -100; | ||||
| 
 | ||||
|     for (i = 0; i < M; i++) bufs[i] = 0.0; | ||||
|     for (i = 0; i < M; i++) corrbuf[i] = 0.0; | ||||
| 
 | ||||
|     alpha = exp(0.8); | ||||
|     sqalp = sqrt(alpha/M_PI); | ||||
|     //a = sqalp;
 | ||||
| 
 | ||||
|     for (i = 0; i < N; i++) { | ||||
|         pos = i/samples_per_bit; | ||||
|         x = (i - pos*samples_per_bit)*2.0/samples_per_bit - 1; | ||||
|         a = sqalp; | ||||
| 
 | ||||
|         if (   ( pos < hLen-1 &&  hdr[pos]!=hdr[pos+1]  &&  x > 0.0 ) | ||||
|             || ( pos >  0     &&  hdr[pos-1]!=hdr[pos]  &&  x < 0.0 ) )  // x=0: a=sqalp
 | ||||
|         { | ||||
|             switch (shape) { | ||||
|                 case  1: if ( fabs(x) > 0.5 ) a *= (1 - fabs(x))/0.5; | ||||
|                          break; | ||||
|                 case  2: a = sqalp * exp(-alpha*x*x); | ||||
|                          break; | ||||
|                 case  3: a = 1 - fabs( x ); | ||||
|                          break; | ||||
|                 default: a = sqalp; | ||||
|                          if (i-pos*samples_per_bit < 2 || | ||||
|                              i-pos*samples_per_bit > samples_per_bit-2) a = 0.9*sqalp; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         b = ((hdr[pos] & 0x1) - 0.5)*2.0; // {-1,+1}
 | ||||
|         b *= a; | ||||
| 
 | ||||
|         match[i] = b; | ||||
|     } | ||||
| 
 | ||||
|     normMatch = sqrt(norm2_match()); | ||||
|     for (i = 0; i < N; i++) { | ||||
|         match[i] /= normMatch; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     delay = N/4; | ||||
|     sample_in = 0; | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int free_buffers() { | ||||
| 
 | ||||
|     if (match) { free(match); match = NULL; } | ||||
|     if (bufs)  { free(bufs);  bufs  = NULL; } | ||||
|     if (corrbuf) { free(corrbuf); corrbuf = NULL; } | ||||
|     if (rawbits) { free(rawbits); rawbits = NULL; } | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| /* ------------------------------------------------------------------------------------ */ | ||||
| 
 | ||||
| unsigned int get_sample() { | ||||
|     return sample_out; | ||||
| } | ||||
| 
 | ||||
|  | @ -0,0 +1,14 @@ | |||
| 
 | ||||
| int read_wav_header(FILE*, float); | ||||
| int f32buf_sample(FILE*, int, int); | ||||
| int read_sbit(FILE*, int, int*, int, int, int, int); | ||||
| 
 | ||||
| int getmaxCorr(float*, unsigned int*, int); | ||||
| int headcmp(int, char*, int, int); | ||||
| float get_var(void); | ||||
| 
 | ||||
| int init_buffers(char*, int, int, int); | ||||
| int free_buffers(void); | ||||
| 
 | ||||
| unsigned int get_sample(void); | ||||
| 
 | ||||
|  | @ -0,0 +1,730 @@ | |||
| 
 | ||||
| /*
 | ||||
|  *  dfm09 (dfm06) | ||||
|  *  sync header: correlation/matched filter | ||||
|  *  files: dfm09dm.c demod.h demod.c | ||||
|  *  compile: | ||||
|  *      gcc -c demod.c | ||||
|  *      gcc dfm09dm.c demod.o -lm -o dfm09dm | ||||
|  * | ||||
|  *  author: zilog80 | ||||
|  */ | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <math.h> | ||||
| 
 | ||||
| #ifdef CYGWIN | ||||
|   #include <fcntl.h>  // cygwin: _setmode() | ||||
|   #include <io.h> | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| typedef unsigned char ui8_t; | ||||
| typedef unsigned int ui32_t; | ||||
| 
 | ||||
| //#include "demod.c"
 | ||||
| #include "demod.h" | ||||
| 
 | ||||
| 
 | ||||
| typedef struct { | ||||
|     int frnr; | ||||
|     int sonde_typ; | ||||
|     ui32_t SN6; | ||||
|     ui32_t SN9; | ||||
|     int week; int gpssec; | ||||
|     int jahr; int monat; int tag; | ||||
|     int std; int min; float sek; | ||||
|     double lat; double lon; double alt; | ||||
|     double dir; double horiV; double vertV; | ||||
|     float meas24[5]; | ||||
|     float status[2]; | ||||
| } gpx_t; | ||||
| 
 | ||||
| gpx_t gpx; | ||||
| 
 | ||||
| char dat_str[9][13+1]; | ||||
| 
 | ||||
| 
 | ||||
| int option_verbose = 0,  // ausfuehrliche Anzeige
 | ||||
|     option_raw = 0,      // rohe Frames
 | ||||
|     option_inv = 0,      // invertiert Signal
 | ||||
|     option_ecc = 0, | ||||
|     option_ptu = 0, | ||||
|     option_ths = 0, | ||||
|     wavloaded = 0; | ||||
| 
 | ||||
| int start = 0; | ||||
| 
 | ||||
| 
 | ||||
| //#define HEADLEN 32
 | ||||
| // DFM09: Manchester2: 01->1,10->0
 | ||||
| char rawheader[] = "10011010100110010101101001010101"; //->"0100010111001111"; // 0x45CF (big endian)
 | ||||
| 
 | ||||
| #define BITFRAME_LEN     280 | ||||
| char frame_bits[BITFRAME_LEN+4] = "0100010111001111"; | ||||
| 
 | ||||
| /* ------------------------------------------------------------------------------------ */ | ||||
| 
 | ||||
| #define BAUD_RATE   2500 | ||||
| 
 | ||||
| /* ------------------------------------------------------------------------------------ */ | ||||
| 
 | ||||
| 
 | ||||
| #define B 8 // codeword: 8 bit
 | ||||
| #define S 4 // davon 4 bit data
 | ||||
| 
 | ||||
| #define HEAD 0        //  16 bit
 | ||||
| #define CONF (16+0)   //  56 bit
 | ||||
| #define DAT1 (16+56)  // 104 bit
 | ||||
| #define DAT2 (16+160) // 104 bit
 | ||||
|                // frame: 280 bit
 | ||||
| 
 | ||||
| ui8_t H[4][8] =  // Parity-Check
 | ||||
|              {{ 0, 1, 1, 1, 1, 0, 0, 0}, | ||||
|               { 1, 0, 1, 1, 0, 1, 0, 0}, | ||||
|               { 1, 1, 0, 1, 0, 0, 1, 0}, | ||||
|               { 1, 1, 1, 0, 0, 0, 0, 1}}; | ||||
| ui8_t He[8] = { 0x7, 0xB, 0xD, 0xE, 0x8, 0x4, 0x2, 0x1}; // Spalten von H:
 | ||||
|                                                          // 1-bit-error-Syndrome
 | ||||
| ui8_t hamming_conf[ 7*B];  //  7*8=56
 | ||||
| ui8_t hamming_dat1[13*B];  // 13*8=104
 | ||||
| ui8_t hamming_dat2[13*B]; | ||||
| 
 | ||||
| ui8_t block_conf[ 7*S];  //  7*4=28
 | ||||
| ui8_t block_dat1[13*S];  // 13*4=52
 | ||||
| ui8_t block_dat2[13*S]; | ||||
| 
 | ||||
| ui32_t bits2val(ui8_t *bits, int len) { // big endian
 | ||||
|     int j; | ||||
|     ui32_t val; | ||||
|     if ((len < 0) || (len > 32)) return -1; // = 0xFFFF
 | ||||
|     val = 0; | ||||
|     for (j = 0; j < len; j++) { | ||||
|         val |= (bits[j] << (len-1-j)); | ||||
|     } | ||||
|     return val; | ||||
| } | ||||
| 
 | ||||
| void deinterleave(char *str, int L, ui8_t *block) { | ||||
|     int i, j; | ||||
|     for (j = 0; j < B; j++) {  // L = 7, 13
 | ||||
|         for (i = 0; i < L; i++) { | ||||
|             if (str[L*j+i] >= 0x30 && str[L*j+i] <= 0x31) { | ||||
|                 block[B*i+j] = str[L*j+i] - 0x30; // ASCII -> bit
 | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| int check(ui8_t code[8]) { | ||||
|     int i, j;               // Bei Demodulierung durch Nulldurchgaenge, wenn durch Fehler ausser Takt,
 | ||||
|     ui32_t synval = 0;      // verschieben sich die bits. Fuer Hamming-Decode waere es besser,
 | ||||
|     ui8_t syndrom[4];       // sync zu Beginn mit Header und dann Takt beibehalten fuer decision.
 | ||||
|     int ret=0; | ||||
| 
 | ||||
|     for (i = 0; i < 4; i++) { // S = 4
 | ||||
|         syndrom[i] = 0; | ||||
|         for (j = 0; j < 8; j++) { // B = 8
 | ||||
|             syndrom[i] ^= H[i][j] & code[j]; | ||||
|         } | ||||
|     } | ||||
|     synval = bits2val(syndrom, 4); | ||||
|     if (synval) { | ||||
|         ret = -1; | ||||
|         for (j = 0; j < 8; j++) {   // 1-bit-error
 | ||||
|             if (synval == He[j]) {  // reicht auf databits zu pruefen, d.h.
 | ||||
|                 ret = j+1;          // (systematischer Code) He[0..3]
 | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     else ret = 0; | ||||
|     if (ret > 0) code[ret-1] ^= 0x1; | ||||
| 
 | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| int hamming(ui8_t *ham, int L, ui8_t *sym) { | ||||
|     int i, j; | ||||
|     int ret = 0;               // L = 7, 13
 | ||||
|     for (i = 0; i < L; i++) {  // L * 2 nibble (data+parity)
 | ||||
|         if (option_ecc) ret |= check(ham+B*i); | ||||
|         for (j = 0; j < S; j++) {  // systematic: bits 0..S-1 data
 | ||||
|             sym[S*i+j] = ham[B*i+j]; | ||||
|         } | ||||
|     } | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| char nib2chr(ui8_t nib) { | ||||
|     char c = '_'; | ||||
|     if (nib < 0x10) { | ||||
|         if (nib < 0xA)  c = 0x30 + nib; | ||||
|         else            c = 0x41 + nib-0xA; | ||||
|     } | ||||
|     return c; | ||||
| } | ||||
| 
 | ||||
| int dat_out(ui8_t *dat_bits) { | ||||
|     int i, ret = 0; | ||||
|     static int fr_id; | ||||
|     // int jahr = 0, monat = 0, tag = 0, std = 0, min = 0;
 | ||||
|     int frnr = 0; | ||||
|     int msek = 0; | ||||
|     int lat = 0, lon = 0, alt = 0; | ||||
|     int nib; | ||||
|     int dvv;  // signed/unsigned 16bit
 | ||||
| 
 | ||||
|     fr_id = bits2val(dat_bits+48, 4); | ||||
| 
 | ||||
| 
 | ||||
|     if (fr_id >= 0  && fr_id <= 8) { | ||||
|         for (i = 0; i < 13; i++) { | ||||
|             nib = bits2val(dat_bits+4*i, 4); | ||||
|             dat_str[fr_id][i] = nib2chr(nib); | ||||
|         } | ||||
|         dat_str[fr_id][13] = '\0'; | ||||
|     } | ||||
| 
 | ||||
|     if (fr_id == 0) { | ||||
|         start = 1; | ||||
|         frnr = bits2val(dat_bits+24, 8); | ||||
|         gpx.frnr = frnr; | ||||
|     } | ||||
| 
 | ||||
|     if (fr_id == 1) { | ||||
|         // 00..31: ? GPS-Sats in Sicht?
 | ||||
|         msek = bits2val(dat_bits+32, 16); | ||||
|         gpx.sek = msek/1000.0; | ||||
|     } | ||||
| 
 | ||||
|     if (fr_id == 2) { | ||||
|         lat = bits2val(dat_bits, 32); | ||||
|         gpx.lat = lat/1e7; | ||||
|         dvv = (short)bits2val(dat_bits+32, 16);  // (short)? zusammen mit dir sollte unsigned sein
 | ||||
|         gpx.horiV = dvv/1e2; | ||||
|     } | ||||
| 
 | ||||
|     if (fr_id == 3) { | ||||
|         lon = bits2val(dat_bits, 32); | ||||
|         gpx.lon = lon/1e7; | ||||
|         dvv = bits2val(dat_bits+32, 16) & 0xFFFF;  // unsigned
 | ||||
|         gpx.dir = dvv/1e2; | ||||
|     } | ||||
| 
 | ||||
|     if (fr_id == 4) { | ||||
|         alt = bits2val(dat_bits, 32); | ||||
|         gpx.alt = alt/1e2; | ||||
|         dvv = (short)bits2val(dat_bits+32, 16);  // signed
 | ||||
|         gpx.vertV = dvv/1e2; | ||||
|     } | ||||
| 
 | ||||
|     if (fr_id == 5) { | ||||
|     } | ||||
| 
 | ||||
|     if (fr_id == 6) { | ||||
|     } | ||||
| 
 | ||||
|     if (fr_id == 7) { | ||||
|     } | ||||
| 
 | ||||
|     if (fr_id == 8) { | ||||
|         gpx.jahr  = bits2val(dat_bits,   12); | ||||
|         gpx.monat = bits2val(dat_bits+12, 4); | ||||
|         gpx.tag   = bits2val(dat_bits+16, 5); | ||||
|         gpx.std   = bits2val(dat_bits+21, 5); | ||||
|         gpx.min   = bits2val(dat_bits+26, 6); | ||||
|     } | ||||
| 
 | ||||
|     ret = fr_id; | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| // DFM-06 (NXP8)
 | ||||
| float fl20(int d) {  // float20
 | ||||
|     int val, p; | ||||
|     float f; | ||||
|     p = (d>>16) & 0xF; | ||||
|     val = d & 0xFFFF; | ||||
|     f = val/(float)(1<<p); | ||||
|     return  f; | ||||
| } | ||||
| /*
 | ||||
| float flo20(int d) { | ||||
|     int m, e; | ||||
|     float f1, f; | ||||
|     m = d & 0xFFFF; | ||||
|     e = (d >> 16) & 0xF; | ||||
|     f =  m / pow(2,e); | ||||
|     return  f; | ||||
| } | ||||
| */ | ||||
| 
 | ||||
| // DFM-09 (STM32)
 | ||||
| float fl24(int d) {  // float24
 | ||||
|     int val, p; | ||||
|     float f; | ||||
|     p = (d>>20) & 0xF; | ||||
|     val = d & 0xFFFFF; | ||||
|     f = val/(float)(1<<p); | ||||
|     return  f; | ||||
| } | ||||
| 
 | ||||
| // temperature approximation
 | ||||
| float get_Temp(float *meas) { // meas[0..4]
 | ||||
| // NTC-Thermistor EPCOS B57540G0502
 | ||||
| // R/T No 8402, R25=Ro=5k
 | ||||
| // B0/100=3450
 | ||||
| // 1/T = 1/To + 1/B log(r) , r=R/Ro
 | ||||
| // GRAW calibration data -80C..+40C on EEPROM ?
 | ||||
| // meas0 = g*(R + Rs)
 | ||||
| // meas3 = g*Rs , Rs: dfm6:10k, dfm9:20k
 | ||||
| // meas4 = g*Rf , Rf=220k
 | ||||
|     float B0 = 3260.0;       // B/Kelvin, fit -55C..+40C
 | ||||
|     float T0 = 25 + 273.15;  // t0=25C
 | ||||
|     float R0 = 5.0e3;        // R0=R25=5k
 | ||||
|     float Rf = 220e3;        // Rf = 220k
 | ||||
|     float g = meas[4]/Rf; | ||||
|     float R = (meas[0]-meas[3]) / g; // meas[0,3,4] > 0 ?
 | ||||
|     float T = 0;                     // T/Kelvin
 | ||||
|     if (meas[0]*meas[3]*meas[4] == 0) R = 0; | ||||
|     if (R > 0)  T = 1/(1/T0 + 1/B0 * log(R/R0)); | ||||
|     return  T - 273.15; // Celsius
 | ||||
| //  DFM-06: meas20 * 16 = meas24
 | ||||
| //      -> (meas24[0]-meas24[3])/meas24[4]=(meas20[0]-meas20[3])/meas20[4]
 | ||||
| } | ||||
| float get_Temp2(float *meas) { // meas[0..4]
 | ||||
| // NTC-Thermistor EPCOS B57540G0502
 | ||||
| // R/T No 8402, R25=Ro=5k
 | ||||
| // B0/100=3450
 | ||||
| // 1/T = 1/To + 1/B log(r) , r=R/Ro
 | ||||
| // GRAW calibration data -80C..+40C on EEPROM ?
 | ||||
| // meas0 = g*(R+Rs)+ofs
 | ||||
| // meas3 = g*Rs+ofs , Rs: dfm6:10k, dfm9:20k
 | ||||
| // meas4 = g*Rf+ofs , Rf=220k
 | ||||
|     float f  = meas[0], | ||||
|           f1 = meas[3], | ||||
|           f2 = meas[4]; | ||||
|     float B0 = 3260.0;      // B/Kelvin, fit -55C..+40C
 | ||||
|     float T0 = 25 + 273.15; // t0=25C
 | ||||
|     float R0 = 5.0e3;       // R0=R25=5k
 | ||||
|     float Rf2 = 220e3;      // Rf2 = Rf = 220k
 | ||||
|     float g_o = f2/Rf2;     // approx gain
 | ||||
|     float Rs_o = f1/g_o;    // = Rf2 * f1/f2;
 | ||||
|     float Rf1 = Rs_o;       // Rf1 = Rs: dfm6:10k, dfm9:20k
 | ||||
|     float g = g_o;          // gain
 | ||||
|     float Rb = 0.0;         // offset
 | ||||
|     float R = 0;            // thermistor
 | ||||
|     float T = 0;            // T/Kelvin
 | ||||
| 
 | ||||
|     if       ( 8e3 < Rs_o && Rs_o < 12e3) Rf1 = 10e3;  // dfm6
 | ||||
|     else if  (18e3 < Rs_o && Rs_o < 22e3) Rf1 = 20e3;  // dfm9
 | ||||
|     g = (f2 - f1) / (Rf2 - Rf1); | ||||
|     Rb = (f1*Rf2-f2*Rf1)/(f2-f1); // ofs/g
 | ||||
| 
 | ||||
|     R = (f-f1)/g;                    // meas[0,3,4] > 0 ?
 | ||||
|     if (R > 0)  T = 1/(1/T0 + 1/B0 * log(R/R0)); | ||||
| 
 | ||||
|     if (option_ptu && option_verbose == 2) { | ||||
|         printf("  (Rso: %.1f , Rb: %.1f)", Rs_o/1e3, Rb/1e3); | ||||
|     } | ||||
| 
 | ||||
|     return  T - 273.15; | ||||
| //  DFM-06: meas20 * 16 = meas24
 | ||||
| } | ||||
| float get_Temp4(float *meas) { // meas[0..4]
 | ||||
| // NTC-Thermistor EPCOS B57540G0502
 | ||||
| // [  T/C  ,   R/R25   , alpha ] :
 | ||||
| // [ -55.0 ,  51.991   ,   6.4 ]
 | ||||
| // [ -50.0 ,  37.989   ,   6.2 ]
 | ||||
| // [ -45.0 ,  28.07    ,   5.9 ]
 | ||||
| // [ -40.0 ,  20.96    ,   5.7 ]
 | ||||
| // [ -35.0 ,  15.809   ,   5.5 ]
 | ||||
| // [ -30.0 ,  12.037   ,   5.4 ]
 | ||||
| // [ -25.0 ,   9.2484  ,   5.2 ]
 | ||||
| // [ -20.0 ,   7.1668  ,   5.0 ]
 | ||||
| // [ -15.0 ,   5.5993  ,   4.9 ]
 | ||||
| // [ -10.0 ,   4.4087  ,   4.7 ]
 | ||||
| // [  -5.0 ,   3.4971  ,   4.6 ]
 | ||||
| // [   0.0 ,   2.7936  ,   4.4 ]
 | ||||
| // [   5.0 ,   2.2468  ,   4.3 ]
 | ||||
| // [  10.0 ,   1.8187  ,   4.2 ]
 | ||||
| // [  15.0 ,   1.4813  ,   4.0 ]
 | ||||
| // [  20.0 ,   1.2136  ,   3.9 ]
 | ||||
| // [  25.0 ,   1.0000  ,   3.8 ]
 | ||||
| // [  30.0 ,   0.82845 ,   3.7 ]
 | ||||
| // [  35.0 ,   0.68991 ,   3.6 ]
 | ||||
| // [  40.0 ,   0.57742 ,   3.5 ]
 | ||||
| // -> Steinhart–Hart coefficients (polyfit):
 | ||||
|     float p0 = 1.09698417e-03, | ||||
|           p1 = 2.39564629e-04, | ||||
|           p2 = 2.48821437e-06, | ||||
|           p3 = 5.84354921e-08; | ||||
| // T/K = 1/( p0 + p1*ln(R) + p2*ln(R)^2 + p3*ln(R)^3 )
 | ||||
|     float Rf = 220e3;    // Rf = 220k
 | ||||
|     float g = meas[4]/Rf; | ||||
|     float R = (meas[0]-meas[3]) / g; // meas[0,3,4] > 0 ?
 | ||||
|     float T = 0; // T/Kelvin
 | ||||
|     if (R > 0)  T = 1/( p0 + p1*log(R) + p2*log(R)*log(R) + p3*log(R)*log(R)*log(R) ); | ||||
|     return  T - 273.15; // Celsius
 | ||||
| //  DFM-06: meas20 * 16 = meas24
 | ||||
| //      -> (meas24[0]-meas24[3])/meas24[4]=(meas20[0]-meas20[3])/meas20[4]
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #define SNbit 0x0100 | ||||
| int conf_out(ui8_t *conf_bits) { | ||||
|     int conf_id; | ||||
|     int ret = 0; | ||||
|     int val, hl; | ||||
|     static int chAbit, chA[2]; | ||||
|     ui32_t SN6, SN9; | ||||
| 
 | ||||
|     conf_id = bits2val(conf_bits, 4); | ||||
| 
 | ||||
|     //if (conf_id > 6) gpx.SN6 = 0;  //// gpx.sonde_typ & 0xF = 9; // SNbit?
 | ||||
| 
 | ||||
|     if ((gpx.sonde_typ & 0xFF) < 9  &&  conf_id == 6) { | ||||
|         SN6 = bits2val(conf_bits+4, 4*6);  // DFM-06: Kanal 6
 | ||||
|         if ( SN6 == gpx.SN6 ) {            // nur Nibble-Werte 0..9
 | ||||
|             gpx.sonde_typ = SNbit | 6; | ||||
|             ret = 6; | ||||
|         } | ||||
|         else { | ||||
|             gpx.sonde_typ = 0; | ||||
|         } | ||||
|         gpx.SN6 = SN6; | ||||
|     } | ||||
|     if (conf_id == 0xA) {  // 0xACxxxxy
 | ||||
|         val = bits2val(conf_bits+8, 4*5); | ||||
|         hl =  (val & 1) == 0; | ||||
|         chA[hl] = (val >> 4) & 0xFFFF; | ||||
|         chAbit |= 1 << hl; | ||||
|         if (chAbit == 3) {  // DFM-09: Kanal A
 | ||||
|             SN9 = (chA[1] << 16) | chA[0]; | ||||
|             if ( SN9 == gpx.SN9 ) { | ||||
|                 gpx.sonde_typ = SNbit | 9; | ||||
|                 ret = 9; | ||||
|             } | ||||
|             else { | ||||
|                 gpx.sonde_typ = 0; | ||||
|             } | ||||
|             gpx.SN9 = SN9; | ||||
|             chAbit = 0; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (conf_id >= 0 && conf_id <= 4) { | ||||
|         val = bits2val(conf_bits+4, 4*6); | ||||
|         gpx.meas24[conf_id] = fl24(val); | ||||
|         // DFM-09 (STM32): 24bit 0exxxxx
 | ||||
|         // DFM-06 (NXP8):  20bit 0exxxx0
 | ||||
|         //   fl20(bits2val(conf_bits+4, 4*5))
 | ||||
|         //       = fl20(exxxx)
 | ||||
|         //       = fl24(exxxx0)/2^4
 | ||||
|         //   meas20 * 16 = meas24
 | ||||
|     } | ||||
| 
 | ||||
|     // STM32-status: Bat, MCU-Temp
 | ||||
|     if ((gpx.sonde_typ & 0xFF) == 9) { // DFM-09 (STM32)
 | ||||
|         if (conf_id == 0x5) { // voltage
 | ||||
|             val = bits2val(conf_bits+8, 4*4); | ||||
|             gpx.status[0] = val/1000.0; | ||||
|         } | ||||
|         if (conf_id == 0x6) { // T-intern (STM32)
 | ||||
|             val = bits2val(conf_bits+8, 4*4); | ||||
|             gpx.status[1] = val/100.0; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| void print_gpx() { | ||||
|   int i, j; | ||||
| 
 | ||||
|   if (start) { | ||||
| 
 | ||||
|       if (option_raw == 2) { | ||||
|            for (i = 0; i < 9; i++) { | ||||
|                printf(" %s", dat_str[i]); | ||||
|            } | ||||
|            for (i = 0; i < 9; i++) { | ||||
|                for (j = 0; j < 13; j++) dat_str[i][j] = ' '; | ||||
|            } | ||||
|       } | ||||
|       else { | ||||
|           //if (option_auto && option_verbose) printf("[%c] ", option_inv?'-':'+');
 | ||||
|           printf("[%3d] ", gpx.frnr); | ||||
|           printf("%4d-%02d-%02d ", gpx.jahr, gpx.monat, gpx.tag); | ||||
|           printf("%02d:%02d:%04.1f ", gpx.std, gpx.min, gpx.sek); | ||||
|           printf("  "); | ||||
|           printf("lat: %.6f  ", gpx.lat); | ||||
|           printf("lon: %.6f  ", gpx.lon); | ||||
|           printf("alt: %.1f  ", gpx.alt); | ||||
|           printf(" vH: %5.2f ", gpx.horiV); | ||||
|           printf(" D: %5.1f ", gpx.dir); | ||||
|           printf(" vV: %5.2f ", gpx.vertV); | ||||
|           if (option_ptu) { | ||||
|               float t = get_Temp(gpx.meas24); | ||||
|               if (t > -270.0) printf("  T=%.1fC ", t); | ||||
|               if (option_verbose == 2) { | ||||
|                   float t2 = get_Temp2(gpx.meas24); | ||||
|                   float t4 = get_Temp4(gpx.meas24); | ||||
|                   if (t2 > -270.0) printf("  T2=%.1fC ", t2); | ||||
|                   if (t4 > -270.0) printf(" T4=%.1fC  ", t4); | ||||
|                   printf(" f0: %.2f ", gpx.meas24[0]); | ||||
|                   printf(" f3: %.2f ", gpx.meas24[3]); | ||||
|                   printf(" f4: %.2f ", gpx.meas24[4]); | ||||
|               } | ||||
|           } | ||||
|           if (option_verbose == 2  &&  (gpx.sonde_typ & 0xFF) == 9) { | ||||
|               printf("  U: %.2fV ", gpx.status[0]); | ||||
|               printf("  Ti: %.1fK ", gpx.status[1]); | ||||
|           } | ||||
|           if (option_verbose  &&  (gpx.sonde_typ & SNbit)) | ||||
|           { | ||||
|               if ((gpx.sonde_typ & 0xFF) == 6) { | ||||
|                   printf(" (ID%1d:%06X) ", gpx.sonde_typ & 0xF, gpx.SN6); | ||||
|               } | ||||
|               if ((gpx.sonde_typ & 0xFF) == 9) { | ||||
|                   printf(" (ID%1d:%06u) ", gpx.sonde_typ & 0xF, gpx.SN9); | ||||
|               } | ||||
|               gpx.sonde_typ ^= SNbit; | ||||
|           } | ||||
|       } | ||||
|       printf("\n"); | ||||
| 
 | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| int print_frame() { | ||||
|     int i; | ||||
|     int nib = 0; | ||||
|     int frid = -1; | ||||
|     int ret0, ret1, ret2; | ||||
|     int ret = 0; | ||||
| 
 | ||||
| 
 | ||||
|     deinterleave(frame_bits+CONF,  7, hamming_conf); | ||||
|     deinterleave(frame_bits+DAT1, 13, hamming_dat1); | ||||
|     deinterleave(frame_bits+DAT2, 13, hamming_dat2); | ||||
| 
 | ||||
|     ret0 = hamming(hamming_conf,  7, block_conf); | ||||
|     ret1 = hamming(hamming_dat1, 13, block_dat1); | ||||
|     ret2 = hamming(hamming_dat2, 13, block_dat2); | ||||
|     ret = ret0 | ret1 | ret2; | ||||
| 
 | ||||
|     if (option_raw == 1) { | ||||
| 
 | ||||
|         for (i = 0; i < 7; i++) { | ||||
|             nib = bits2val(block_conf+S*i, S); | ||||
|             printf("%01X", nib & 0xFF); | ||||
|         } | ||||
|         if (option_ecc) { | ||||
|             if      (ret0 == 0) printf(" [OK] "); | ||||
|             else if (ret0  > 0) printf(" [KO] "); | ||||
|             else                printf(" [NO] "); | ||||
|         } | ||||
|         printf("  "); | ||||
|         for (i = 0; i < 13; i++) { | ||||
|             nib = bits2val(block_dat1+S*i, S); | ||||
|             printf("%01X", nib & 0xFF); | ||||
|         } | ||||
|         if (option_ecc) { | ||||
|             if      (ret1 == 0) printf(" [OK] "); | ||||
|             else if (ret1  > 0) printf(" [KO] "); | ||||
|             else                printf(" [NO] "); | ||||
|         } | ||||
|         printf("  "); | ||||
|         for (i = 0; i < 13; i++) { | ||||
|             nib = bits2val(block_dat2+S*i, S); | ||||
|             printf("%01X", nib & 0xFF); | ||||
|         } | ||||
|         if (option_ecc) { | ||||
|             if      (ret2 == 0) printf(" [OK] "); | ||||
|             else if (ret2  > 0) printf(" [KO] "); | ||||
|             else                printf(" [NO] "); | ||||
|         } | ||||
|         printf("\n"); | ||||
| 
 | ||||
|     } | ||||
|     else if (option_ecc) { | ||||
| 
 | ||||
|         if (ret0 == 0 || ret0 > 0) { | ||||
|             conf_out(block_conf); | ||||
|         } | ||||
|         if (ret1 == 0 || ret1 > 0) { | ||||
|             frid = dat_out(block_dat1); | ||||
|             if (frid == 8) print_gpx(); | ||||
|         } | ||||
|         if (ret2 == 0 || ret2 > 0) { | ||||
|             frid = dat_out(block_dat2); | ||||
|             if (frid == 8) print_gpx(); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
|     else { | ||||
| 
 | ||||
|         conf_out(block_conf); | ||||
|         frid = dat_out(block_dat1); | ||||
|         if (frid == 8) print_gpx(); | ||||
|         frid = dat_out(block_dat2); | ||||
|         if (frid == 8) print_gpx(); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| /* -------------------------------------------------------------------------- */ | ||||
| 
 | ||||
| 
 | ||||
| int main(int argc, char **argv) { | ||||
| 
 | ||||
|     FILE *fp = NULL; | ||||
|     char *fpname = NULL; | ||||
|     int header_found = 0; | ||||
|     int ret = 0; | ||||
| 
 | ||||
|     int bit; | ||||
|     int bitpos = 0; | ||||
|     int bitQ; | ||||
|     int pos; | ||||
|     int herrs; | ||||
|     int headerlen = 0; | ||||
|     int frm = 0, nfrms = 4; // nfrms=1,2,4,8
 | ||||
| 
 | ||||
|     float mv; | ||||
|     unsigned int mv_pos, mv0_pos; | ||||
| 
 | ||||
|     float thres = 0.6; | ||||
| 
 | ||||
|     int bitofs = 0; | ||||
| 
 | ||||
| 
 | ||||
| #ifdef CYGWIN | ||||
|     _setmode(fileno(stdin), _O_BINARY);  // _setmode(_fileno(stdin), _O_BINARY);
 | ||||
| #endif | ||||
|     setbuf(stdout, NULL); | ||||
| 
 | ||||
|     fpname = argv[0]; | ||||
|     ++argv; | ||||
|     while ((*argv) && (!wavloaded)) { | ||||
|         if      ( (strcmp(*argv, "-h") == 0) || (strcmp(*argv, "--help") == 0) ) { | ||||
|             fprintf(stderr, "%s [options] audio.wav\n", fpname); | ||||
|             fprintf(stderr, "  options:\n"); | ||||
|             fprintf(stderr, "       -v, -vv\n"); | ||||
|             fprintf(stderr, "       -r, --raw\n"); | ||||
|             fprintf(stderr, "       -i, --invert\n"); | ||||
|             fprintf(stderr, "       --ecc        (Hamming ECC)\n"); | ||||
|             fprintf(stderr, "       --ths <x>    (peak threshold; default=%.1f)\n", thres); | ||||
|             return 0; | ||||
|         } | ||||
|         else if ( (strcmp(*argv, "-v") == 0) || (strcmp(*argv, "--verbose") == 0) ) { | ||||
|             option_verbose = 1; | ||||
|         } | ||||
|         else if ( (strcmp(*argv, "-vv") == 0) ) { option_verbose = 2; } | ||||
|         else if ( (strcmp(*argv, "-r") == 0) || (strcmp(*argv, "--raw") == 0) ) { | ||||
|             option_raw = 1; | ||||
|         } | ||||
|         else if ( (strcmp(*argv, "-R") == 0) || (strcmp(*argv, "--RAW") == 0) ) { | ||||
|             option_raw = 2; | ||||
|         } | ||||
|         else if ( (strcmp(*argv, "-i") == 0) || (strcmp(*argv, "--invert") == 0) ) { | ||||
|             option_inv = 0x1; | ||||
|         } | ||||
|         else if ( (strcmp(*argv, "--ecc") == 0) ) { option_ecc = 1; } | ||||
|         else if ( (strcmp(*argv, "--ptu") == 0) ) { option_ptu = 1; } | ||||
|         else if ( (strcmp(*argv, "--ths") == 0) ) { | ||||
|             ++argv; | ||||
|             if (*argv) { | ||||
|                 thres = atof(*argv); | ||||
|             } | ||||
|             else return -1; | ||||
|         } | ||||
|         else { | ||||
|             fp = fopen(*argv, "rb"); | ||||
|             if (fp == NULL) { | ||||
|                 fprintf(stderr, "%s konnte nicht geoeffnet werden\n", *argv); | ||||
|                 return -1; | ||||
|             } | ||||
|             wavloaded = 1; | ||||
|         } | ||||
|         ++argv; | ||||
|     } | ||||
|     if (!wavloaded) fp = stdin; | ||||
| 
 | ||||
| 
 | ||||
|     if ( read_wav_header(fp, (float)BAUD_RATE) != 0 ) { | ||||
|         fclose(fp); | ||||
|         fprintf(stderr, "error: wav header\n"); | ||||
|         return -1; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     headerlen = strlen(rawheader); | ||||
|     bitofs = 0; // -1 .. +1
 | ||||
|     if (init_buffers(rawheader, headerlen, bitofs, 1) < 0) { // shape=1
 | ||||
|         fprintf(stderr, "error: init buffers\n"); | ||||
|         return -1; | ||||
|     }; | ||||
| 
 | ||||
| 
 | ||||
|     mv = -1; mv_pos = 0; | ||||
| 
 | ||||
|     while ( f32buf_sample(fp, option_inv, 1) != EOF ) { | ||||
| 
 | ||||
|         mv0_pos = mv_pos; | ||||
|         getmaxCorr(&mv, &mv_pos, headerlen+headerlen/2); | ||||
| 
 | ||||
|         if (mv > thres) { | ||||
|             if (mv_pos > mv0_pos) { | ||||
| 
 | ||||
|                 header_found = 0; | ||||
|                 herrs = headcmp(2, rawheader, headerlen, bitofs); // symlen=2
 | ||||
|                 if (herrs <= 1) header_found = 1; // herrs <= 1 bitfehler in header
 | ||||
| 
 | ||||
|                 if (header_found) { | ||||
| 
 | ||||
|                     bitpos = 0; | ||||
|                     pos = headerlen; | ||||
|                     pos /= 2; | ||||
| 
 | ||||
|                     frm = 0; | ||||
|                     while ( frm < nfrms ) { // nfrms=1,4,8
 | ||||
|                         while ( pos < BITFRAME_LEN ) { | ||||
|                             header_found = !(frm==nfrms-1 && pos>=BITFRAME_LEN-10); | ||||
|                             bitQ = read_sbit(fp, 2, &bit, option_inv, bitofs, bitpos==0, !header_found); // symlen=2, return: zeroX/bit
 | ||||
|                             //bitQ = read_sbit(fp, 2, &bit, option_inv, bitofs, bitpos==0, 0); // symlen=2, return: zeroX/bit
 | ||||
|                             if (bitQ == EOF) { frm = nfrms; break; } | ||||
|                             frame_bits[pos] = 0x30 + bit; | ||||
|                             pos++; | ||||
|                             bitpos += 1; | ||||
|                         } | ||||
|                         frame_bits[pos] = '\0'; | ||||
|                         ret = print_frame(); | ||||
|                         if (pos < BITFRAME_LEN) break; | ||||
|                         pos = 0; | ||||
|                         frm += 1; | ||||
|                         //if (ret < 0) frms += 1;
 | ||||
|                     } | ||||
| 
 | ||||
|                     header_found = 0; | ||||
|                     pos = headerlen; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     free_buffers(); | ||||
| 
 | ||||
|     fclose(fp); | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
										
											
												Plik diff jest za duży
												Load Diff
											
										
									
								
							
										
											
												Plik diff jest za duży
												Load Diff
											
										
									
								
							
		Ładowanie…
	
		Reference in New Issue
	
	 Zilog80
						Zilog80