| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2016-01-09 22:13:39 +00:00
										 |  |  |  * radiosonde iMet-1-AB (GPS: Trimble/ublox) | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |  * author: zilog80 | 
					
						
							|  |  |  |  * usage: | 
					
						
							| 
									
										
										
										
											2015-12-10 09:49:56 +00:00
										 |  |  |  *     gcc imet1ab.c -lm -o imet1ab | 
					
						
							|  |  |  |  *     ./imet1ab [options] audio.wav | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |  *       options: | 
					
						
							|  |  |  |  *               -r, --raw | 
					
						
							|  |  |  |  *               -i, --invert | 
					
						
							| 
									
										
										
										
											2016-01-09 22:13:39 +00:00
										 |  |  |  *               -1  (trimble: TOW/s) | 
					
						
							|  |  |  |  *               -2  (ublox: TOW/ms) | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							| 
									
										
										
										
											2015-12-10 09:49:56 +00:00
										 |  |  | #include <math.h>
 | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  | #include <string.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef CYGWIN
 | 
					
						
							|  |  |  |   #include <fcntl.h>  // cygwin: _setmode()
 | 
					
						
							|  |  |  |   #include <io.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef unsigned char ui8_t; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  |     int frnr; | 
					
						
							| 
									
										
										
										
											2015-12-09 09:12:38 +00:00
										 |  |  |     char id1[9]; char id2[9]; | 
					
						
							| 
									
										
										
										
											2015-12-30 21:46:28 +00:00
										 |  |  |     int week; double gpssec; | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |     //int jahr; int monat; int tag;
 | 
					
						
							|  |  |  |     int wday; | 
					
						
							| 
									
										
										
										
											2015-12-30 21:46:28 +00:00
										 |  |  |     int std; int min; int sek; int ms; | 
					
						
							| 
									
										
										
										
											2016-11-02 14:41:18 +00:00
										 |  |  |     double lat; double lon; double alt; | 
					
						
							| 
									
										
										
										
											2015-12-10 09:49:56 +00:00
										 |  |  |     double vH; double vD; double vV; | 
					
						
							|  |  |  |     double vx; double vy; double vD2; | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  | } gpx_t; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | gpx_t gpx; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int option_verbose = 0,  // ausfuehrliche Anzeige
 | 
					
						
							|  |  |  |     option_raw = 0,      // rohe Frames
 | 
					
						
							|  |  |  |     option_color = 0,    // Farbe
 | 
					
						
							|  |  |  |     option_inv = 0,      // invertiert Signal
 | 
					
						
							| 
									
										
										
										
											2016-01-09 22:13:39 +00:00
										 |  |  |     option_gps = 0, | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |     wavloaded = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define BAUD_RATE  2400
 | 
					
						
							|  |  |  | // iMet: AFSK Baudrate 2400
 | 
					
						
							|  |  |  | /* 1200 Hz: out-in
 | 
					
						
							|  |  |  |    2400 Hz: lang  ->  Baudrate | 
					
						
							|  |  |  |    4800 Hz: kurz (2x) | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int sample_rate = 0, bits_sample = 0, channels = 0; | 
					
						
							|  |  |  | float samples_per_bit = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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) { | 
					
						
							| 
									
										
										
										
											2015-11-17 10:00:05 +00:00
										 |  |  |     char txt[4+1] = "\0\0\0\0"; | 
					
						
							|  |  |  |     unsigned char dat[4]; | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |     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; | 
					
						
							| 
									
										
										
										
											2015-11-17 10:00:05 +00:00
										 |  |  |     // pos_WAVE = 8L
 | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |     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; | 
					
						
							| 
									
										
										
										
											2015-11-17 10:00:05 +00:00
										 |  |  |         txt[p % 4] = byte; | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |         p++; if (p==4) p=0; | 
					
						
							| 
									
										
										
										
											2015-11-17 10:00:05 +00:00
										 |  |  |         if (findstr(txt, "fmt ", p) == 4) break; | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-11-17 10:00:05 +00:00
										 |  |  |     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); | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-17 10:00:05 +00:00
										 |  |  |     // pos_dat = 36L + info
 | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |     for ( ; ; ) { | 
					
						
							|  |  |  |         if ( (byte=fgetc(fp)) == EOF ) return -1; | 
					
						
							| 
									
										
										
										
											2015-11-17 10:00:05 +00:00
										 |  |  |         txt[p % 4] = byte; | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |         p++; if (p==4) p=0; | 
					
						
							| 
									
										
										
										
											2015-11-17 10:00:05 +00:00
										 |  |  |         if (findstr(txt, "data", p) == 4) break; | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-11-17 10:00:05 +00:00
										 |  |  |     if (fread(dat, 1, 4, fp) < 4) return -1; | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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/(float)BAUD_RATE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     fprintf(stderr, "samples/bit: %.2f\n", samples_per_bit); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define EOF_INT  0x1000000
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int read_signed_sample(FILE *fp) {  // int = i32_t
 | 
					
						
							|  |  |  |     int byte, i, ret;         //  EOF -> 0x1000000
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < channels; i++) { | 
					
						
							|  |  |  |                           // i = 0: links bzw. mono
 | 
					
						
							|  |  |  |         byte = fgetc(fp); | 
					
						
							|  |  |  |         if (byte == EOF) return EOF_INT; | 
					
						
							|  |  |  |         if (i == 0) ret = byte; | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |         if (bits_sample == 16) { | 
					
						
							|  |  |  |             byte = fgetc(fp); | 
					
						
							|  |  |  |             if (byte == EOF) return EOF_INT; | 
					
						
							|  |  |  |             if (i == 0) ret +=  byte << 8; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (bits_sample ==  8) return ret-128; | 
					
						
							|  |  |  |     if (bits_sample == 16) return (short)ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-20 14:40:45 +00:00
										 |  |  | int par=1,     // init_sample > 0
 | 
					
						
							|  |  |  |     par_alt=1; | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  | unsigned long sample_count = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int read_afsk_bits(FILE *fp, int *len) { | 
					
						
							|  |  |  |     int n, sample; | 
					
						
							|  |  |  |     float l; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     n = 0; | 
					
						
							| 
									
										
										
										
											2016-11-20 14:40:45 +00:00
										 |  |  |     do{ // High                               // par>0
 | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |         sample = read_signed_sample(fp); | 
					
						
							|  |  |  |         if (sample == EOF_INT) return EOF; | 
					
						
							|  |  |  |         if (option_inv) sample = -sample; | 
					
						
							|  |  |  |         sample_count++; | 
					
						
							|  |  |  |         par_alt = par; | 
					
						
							|  |  |  |         par =  (sample >= 0) ? 1 : -1; | 
					
						
							|  |  |  |         n++; | 
					
						
							|  |  |  |     } while (par*par_alt > 0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-20 14:40:45 +00:00
										 |  |  |     do{ // Low                                // par<0
 | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |         sample = read_signed_sample(fp); | 
					
						
							|  |  |  |         if (sample == EOF_INT) return EOF; | 
					
						
							|  |  |  |         if (option_inv) sample = -sample; | 
					
						
							|  |  |  |         sample_count++; | 
					
						
							|  |  |  |         par_alt = par; | 
					
						
							|  |  |  |         par =  (sample >= 0) ? 1 : -1; | 
					
						
							|  |  |  |         n++; | 
					
						
							| 
									
										
										
										
											2016-11-20 14:40:45 +00:00
										 |  |  |     } while (par*par_alt > 0);                // par>0
 | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     l = (float)n / (samples_per_bit/2.0); | 
					
						
							|  |  |  |     *len = (int)(l+0.5); // round(l)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int read_afsk_bits1(FILE *fp, int *len) { | 
					
						
							|  |  |  |     int n; static int sample; | 
					
						
							|  |  |  |     float l; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while (sample >= 0) { | 
					
						
							|  |  |  |         sample = read_signed_sample(fp); | 
					
						
							|  |  |  |         if (sample == EOF_INT) return EOF; | 
					
						
							|  |  |  |         if (option_inv) sample = -sample; | 
					
						
							|  |  |  |         sample_count++;      | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     n = 0; | 
					
						
							|  |  |  |     while (sample < 0) { | 
					
						
							|  |  |  |         n++; | 
					
						
							|  |  |  |         par_alt = par; | 
					
						
							|  |  |  |         par =  (sample >= 0) ? 1 : -1; | 
					
						
							|  |  |  |         sample = read_signed_sample(fp); | 
					
						
							|  |  |  |         if (sample == EOF_INT) return EOF; | 
					
						
							|  |  |  |         if (option_inv) sample = -sample; | 
					
						
							|  |  |  |         sample_count++;      | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     while (sample >= 0) { | 
					
						
							|  |  |  |         n++; | 
					
						
							|  |  |  |         par_alt = par; | 
					
						
							|  |  |  |         par =  (sample >= 0) ? 1 : -1; | 
					
						
							|  |  |  |         sample = read_signed_sample(fp); | 
					
						
							|  |  |  |         if (sample == EOF_INT) return EOF; | 
					
						
							|  |  |  |         if (option_inv) sample = -sample; | 
					
						
							|  |  |  |         sample_count++;      | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     l = (float)n / (samples_per_bit/2.0); | 
					
						
							|  |  |  |     *len = (int)(l+0.5); // round(l)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  | Beginn/Header: | 
					
						
							|  |  |  | 69 69 69 69 69 10 | 
					
						
							|  |  |  | Ende: | 
					
						
							|  |  |  | 96 96 96 96 96 96 96 96 96 | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-02 17:20:58 +00:00
										 |  |  | #define pos_Start  0x05  // 2 byte
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  | #define pos_RecordNo  0x08  // 2 byte
 | 
					
						
							|  |  |  | #define pos_SondeID1  0x12  // 5 byte
 | 
					
						
							|  |  |  | #define pos_SondeID2  0x2C  // 5 byte
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define pos_GPSTOW  0x8A  // 4 byte
 | 
					
						
							|  |  |  | #define pos_GPSlat  0x8E  // 4 byte
 | 
					
						
							|  |  |  | #define pos_GPSlon  0x92  // 4 byte
 | 
					
						
							|  |  |  | #define pos_GPSalt  0x96  // 4 byte
 | 
					
						
							| 
									
										
										
										
											2015-12-10 09:49:56 +00:00
										 |  |  | //Velocity East-North-Up (ENU)
 | 
					
						
							|  |  |  | #define pos_GPSvO  0x84  // 2 byte
 | 
					
						
							|  |  |  | #define pos_GPSvN  0x86  // 2 byte
 | 
					
						
							|  |  |  | #define pos_GPSvV  0x88  // 2 byte
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-02 17:20:58 +00:00
										 |  |  | #define pos_xcSum  0xC2  // 1 byte: xsumDLE(frame+pos_Start, 189)
 | 
					
						
							|  |  |  |                          //         189 = pos_xcSum-pos_Start
 | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define FRAMELEN 204
 | 
					
						
							|  |  |  | ui8_t frame[FRAMELEN+6]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | double B60B60 = 0xB60B60;  // 2^32/360 = 0xB60B60.xxx
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | char weekday[7][3] = { "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-09 22:13:39 +00:00
										 |  |  | typedef struct { | 
					
						
							|  |  |  |     int cnt; | 
					
						
							|  |  |  |     int tow; | 
					
						
							|  |  |  | } gpstow_t; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | gpstow_t tow0, tow1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  | int gpsTOW(int gpstime) { | 
					
						
							|  |  |  |     int day; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-09 22:13:39 +00:00
										 |  |  |     tow0 = tow1; | 
					
						
							|  |  |  |     tow1.tow = gpstime; | 
					
						
							|  |  |  |     tow1.cnt = gpx.frnr; | 
					
						
							|  |  |  |     if (!option_gps) { | 
					
						
							|  |  |  |         if (tow1.cnt-tow0.cnt == 1) { | 
					
						
							|  |  |  |             if (tow1.tow-tow0.tow > 998  &&  tow1.tow-tow0.tow < 1002)  option_gps = 2; | 
					
						
							|  |  |  |             if (tow1.tow-tow0.tow > 0    &&  tow1.tow-tow0.tow < 2   )  option_gps = 1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |     gpx.gpssec = gpstime; | 
					
						
							| 
									
										
										
										
											2016-01-09 22:13:39 +00:00
										 |  |  |     if (option_gps == 2) { | 
					
						
							| 
									
										
										
										
											2015-12-30 21:46:28 +00:00
										 |  |  |         gpx.ms = gpstime % 1000; | 
					
						
							|  |  |  |         gpx.gpssec /= 1000.0; | 
					
						
							|  |  |  |         gpstime /= 1000; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-12-31 19:51:58 +00:00
										 |  |  |     if (gpx.gpssec<0 || gpx.gpssec>7*24*60*60) return 1;  // 1 Woche = 604800 sek
 | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     day = gpstime / (24 * 3600); | 
					
						
							|  |  |  |     gpstime %= (24*3600); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((day < 0) || (day > 6)) { | 
					
						
							|  |  |  |         //gpx.wday = 0;
 | 
					
						
							| 
									
										
										
										
											2015-12-31 19:51:58 +00:00
										 |  |  |         return 1; | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     gpx.wday = day; | 
					
						
							|  |  |  |     gpx.std = gpstime / 3600; | 
					
						
							|  |  |  |     gpx.min = (gpstime % 3600) / 60; | 
					
						
							|  |  |  |     gpx.sek = gpstime % 60; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int gpsLat(int lat) { | 
					
						
							|  |  |  |     gpx.lat = lat / B60B60; | 
					
						
							| 
									
										
										
										
											2015-12-31 19:51:58 +00:00
										 |  |  |     if (gpx.lat < -90  ||  gpx.lat > 90) return 1; | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int gpsLon(int lon) { | 
					
						
							|  |  |  |     gpx.lon = lon / B60B60; | 
					
						
							| 
									
										
										
										
											2015-12-31 19:51:58 +00:00
										 |  |  |     if (gpx.lon < -180  ||  gpx.lon > 180) return 1; | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int gpsAlt(int alt) { | 
					
						
							| 
									
										
										
										
											2016-11-02 14:41:18 +00:00
										 |  |  |     gpx.alt = alt / 1000.0; | 
					
						
							|  |  |  |     if (gpx.alt < -200  ||  gpx.alt > 50000) return 1; | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-31 19:51:58 +00:00
										 |  |  | int get_GPStow() { | 
					
						
							|  |  |  |     int i, tow; | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |     int err = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-31 19:51:58 +00:00
										 |  |  |     tow = 0; | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |     for (i = 0; i < 4; i++) { | 
					
						
							|  |  |  |         tow |= frame[pos_GPSTOW+i] << (8*i); | 
					
						
							| 
									
										
										
										
											2015-12-31 19:51:58 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     err = gpsTOW(tow); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return err; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int get_GPSpos() { | 
					
						
							|  |  |  |     int i, lat, lon, alt; | 
					
						
							|  |  |  |     int err = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     lat = lon = alt = 0; | 
					
						
							|  |  |  |     for (i = 0; i < 4; i++) { | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |         lat |= frame[pos_GPSlat+i] << (8*i); | 
					
						
							|  |  |  |         lon |= frame[pos_GPSlon+i] << (8*i); | 
					
						
							|  |  |  |         alt |= frame[pos_GPSalt+i] << (8*i); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     err = 0; | 
					
						
							| 
									
										
										
										
											2015-12-31 19:51:58 +00:00
										 |  |  |     err |= gpsLat(lat) << 1; | 
					
						
							|  |  |  |     err |= gpsLon(lon) << 2; | 
					
						
							|  |  |  |     err |= gpsAlt(alt) << 3; | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return err; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-10 09:49:56 +00:00
										 |  |  | int get_GPSvel() { | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  |     unsigned byte; | 
					
						
							|  |  |  |     ui8_t gpsVel_bytes[2]; | 
					
						
							|  |  |  |     short vel16; | 
					
						
							|  |  |  |     double vx, vy, dir, alpha; | 
					
						
							| 
									
										
										
										
											2016-11-02 14:41:18 +00:00
										 |  |  |     const double ms2kn100 = 2e2;  // m/s -> knots: 1 m/s = 3.6/1.852 kn = 1.94 kn
 | 
					
						
							| 
									
										
										
										
											2015-12-10 09:49:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < 2; i++) { | 
					
						
							|  |  |  |         byte = frame[pos_GPSvO + i]; | 
					
						
							|  |  |  |         if (byte > 0xFF) return -1; | 
					
						
							|  |  |  |         gpsVel_bytes[i] = byte; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     vel16 = gpsVel_bytes[0] | gpsVel_bytes[1] << 8; | 
					
						
							| 
									
										
										
										
											2016-11-02 14:41:18 +00:00
										 |  |  |     vx = vel16 / ms2kn100; // ost
 | 
					
						
							| 
									
										
										
										
											2015-12-10 09:49:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < 2; i++) { | 
					
						
							|  |  |  |         byte = frame[pos_GPSvN + i]; | 
					
						
							|  |  |  |         if (byte > 0xFF) return -1; | 
					
						
							|  |  |  |         gpsVel_bytes[i] = byte; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     vel16 = gpsVel_bytes[0] | gpsVel_bytes[1] << 8; | 
					
						
							| 
									
										
										
										
											2016-11-02 14:41:18 +00:00
										 |  |  |     vy= vel16 / ms2kn100; // nord
 | 
					
						
							| 
									
										
										
										
											2015-12-10 09:49:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     gpx.vx = vx; | 
					
						
							|  |  |  |     gpx.vy = vy; | 
					
						
							|  |  |  |     gpx.vH = sqrt(vx*vx+vy*vy); | 
					
						
							|  |  |  | ///*
 | 
					
						
							|  |  |  |     alpha = atan2(vy, vx)*180/M_PI;  // ComplexPlane (von x-Achse nach links) - GeoMeteo (von y-Achse nach rechts)
 | 
					
						
							|  |  |  |     dir = 90-alpha;                  // z=x+iy= -> i*conj(z)=y+ix=re(i(pi/2-t)), Achsen und Drehsinn vertauscht
 | 
					
						
							|  |  |  |     if (dir < 0) dir += 360;         // atan2(y,x)=atan(y/x)=pi/2-atan(x/y) , atan(1/t) = pi/2 - atan(t)
 | 
					
						
							|  |  |  |     gpx.vD2 = dir; | 
					
						
							|  |  |  | //*/
 | 
					
						
							|  |  |  |     dir = atan2(vx, vy) * 180 / M_PI; | 
					
						
							|  |  |  |     if (dir < 0) dir += 360; | 
					
						
							|  |  |  |     gpx.vD = dir; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < 2; i++) { | 
					
						
							|  |  |  |         byte = frame[pos_GPSvV + i]; | 
					
						
							|  |  |  |         if (byte > 0xFF) return -1; | 
					
						
							|  |  |  |         gpsVel_bytes[i] = byte; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     vel16 = gpsVel_bytes[0] | gpsVel_bytes[1] << 8; | 
					
						
							| 
									
										
										
										
											2016-11-02 14:41:18 +00:00
										 |  |  |     gpx.vV = vel16 / ms2kn100; | 
					
						
							| 
									
										
										
										
											2015-12-10 09:49:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  | int get_RecordNo() { | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  |     unsigned byte; | 
					
						
							|  |  |  |     ui8_t frnr_bytes[2]; | 
					
						
							|  |  |  |     int frnr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < 2; i++) { | 
					
						
							|  |  |  |         byte = frame[pos_RecordNo + i]; | 
					
						
							|  |  |  |         frnr_bytes[i] = byte; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     frnr = frnr_bytes[0] + (frnr_bytes[1] << 8); | 
					
						
							|  |  |  |     gpx.frnr = frnr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int get_SondeID() { | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  |     unsigned byte; | 
					
						
							| 
									
										
										
										
											2015-11-17 10:00:05 +00:00
										 |  |  |     ui8_t sondeid_bytes[8]; // 5 bis 6 ascii + '\0'
 | 
					
						
							|  |  |  |     int IDlen = 6+1; // < 9
 | 
					
						
							| 
									
										
										
										
											2015-12-09 09:12:38 +00:00
										 |  |  |     int err = 0; | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < IDlen; i++) { | 
					
						
							|  |  |  |         byte = frame[pos_SondeID1 + i]; | 
					
						
							| 
									
										
										
										
											2015-11-17 10:00:05 +00:00
										 |  |  |         if (byte == 0) IDlen = i+1; | 
					
						
							|  |  |  |         else | 
					
						
							| 
									
										
										
										
											2015-12-09 09:12:38 +00:00
										 |  |  |         if (byte < 0x20 || byte > 0x7E) err |= 0x1; | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |         sondeid_bytes[i] = byte; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-12-09 09:12:38 +00:00
										 |  |  |     for (i = 0; i < IDlen; i++) { | 
					
						
							|  |  |  |         gpx.id1[i] = sondeid_bytes[i]; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-09 09:12:38 +00:00
										 |  |  |     IDlen = 6+1; | 
					
						
							|  |  |  |     for (i = 0; i < IDlen; i++) { | 
					
						
							|  |  |  |         byte = frame[pos_SondeID2 + i]; | 
					
						
							|  |  |  |         if (byte == 0) IDlen = i+1; | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         if (byte < 0x20 || byte > 0x7E) err |= 0x2; | 
					
						
							|  |  |  |         sondeid_bytes[i] = byte; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |     for (i = 0; i < IDlen; i++) { | 
					
						
							| 
									
										
										
										
											2015-12-09 09:12:38 +00:00
										 |  |  |         gpx.id2[i] = sondeid_bytes[i]; | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-09 09:12:38 +00:00
										 |  |  |     return err; | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-02 17:20:58 +00:00
										 |  |  | // Frame: <DLE><id><data_bytes><DLE><ETX>,
 | 
					
						
							|  |  |  | //        <DLE>=0x10, <ETX>=0x03; <id>=0xb9
 | 
					
						
							|  |  |  | // (.. 69) 10 b9 01 .. .. 10 03 cs (96 ..)
 | 
					
						
							|  |  |  | // 8bit-xor-checksum:
 | 
					
						
							|  |  |  | //  xsumDLE(frame+pos_Start, pos_xcSum-pos_Start)
 | 
					
						
							|  |  |  | int xsumDLE(ui8_t bytes[], int len) { | 
					
						
							|  |  |  |     int i, xsum = 0; | 
					
						
							|  |  |  |     for (i = 0; i < len; i++) {  // TSIP-Protokoll: <DLE>=0x10
 | 
					
						
							|  |  |  |         // innnerhalb <DLE>, 0x10 doppelt, und 0x10^0x10=0x00
 | 
					
						
							|  |  |  |         if (bytes[i] != 0x10) xsum ^= bytes[i]; | 
					
						
							|  |  |  |         // ausser <DLE> zu Beginn/Ende
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return xsum & 0xFF; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | int bits2byte(char *bits) { | 
					
						
							|  |  |  |     int i, d = 1, byte = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < 8; i++) { | 
					
						
							|  |  |  |         if      (bits[i] == 1)  byte += d; | 
					
						
							|  |  |  |         else if (bits[i] == 0)  byte += 0; | 
					
						
							|  |  |  |         d <<= 1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return byte & 0xFF; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define ANSI_COLOR_CYAN    "\x1b[36m"
 | 
					
						
							|  |  |  | #define ANSI_COLOR_RESET   "\x1b[0m"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void print_frame(int len) { | 
					
						
							| 
									
										
										
										
											2015-12-31 19:51:58 +00:00
										 |  |  |     FILE *fp; | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |     int i; | 
					
						
							| 
									
										
										
										
											2015-12-31 19:51:58 +00:00
										 |  |  |     int err1, err2, err3; | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (option_raw) { | 
					
						
							|  |  |  |         for (i = 0; i < len; i++) { | 
					
						
							|  |  |  |             if (option_color) { | 
					
						
							|  |  |  |                 if (i >= pos_GPSTOW  &&  i < pos_GPSalt+4) fprintf(stdout, ANSI_COLOR_CYAN); | 
					
						
							|  |  |  |                 else fprintf(stdout, ANSI_COLOR_RESET); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             fprintf(stdout, "%02x ", frame[i]); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-10-02 17:20:58 +00:00
										 |  |  |         if (option_verbose) {                                                          // pos_xcSum-pos_Start=189
 | 
					
						
							|  |  |  |              fprintf(stdout, " [%02X # %02X]", frame[pos_xcSum], xsumDLE(frame+pos_Start, pos_xcSum-pos_Start)); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |         fprintf(stdout, "\n"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2015-12-31 19:51:58 +00:00
										 |  |  |         fp = stdout; | 
					
						
							|  |  |  |         get_RecordNo(); | 
					
						
							|  |  |  |         err1 = get_SondeID(); | 
					
						
							|  |  |  |         err2 = get_GPStow(); | 
					
						
							|  |  |  |         err3 = get_GPSpos(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ( !err1 || !err2 || !err3 ) { | 
					
						
							|  |  |  |             fprintf(fp, "[%5d] ", gpx.frnr); | 
					
						
							|  |  |  |             if ( err1!=0x3 ) { | 
					
						
							|  |  |  |                 fprintf(fp, "(%s)  ", err1&0x1?gpx.id2:gpx.id1); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if ( !err2 ) { | 
					
						
							|  |  |  |                 fprintf(fp, "%s ",weekday[gpx.wday]); | 
					
						
							|  |  |  |                 fprintf(fp, "%02d:%02d:%02d", gpx.std, gpx.min, gpx.sek); | 
					
						
							| 
									
										
										
										
											2016-01-09 22:13:39 +00:00
										 |  |  |                 if (option_gps == 2) fprintf(fp, ".%03d", gpx.ms); | 
					
						
							| 
									
										
										
										
											2015-12-31 19:51:58 +00:00
										 |  |  |                 fprintf(fp, " "); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if ( !err3 ) { | 
					
						
							|  |  |  |                 fprintf(fp, " lat: %.6f ", gpx.lat); | 
					
						
							|  |  |  |                 fprintf(fp, " lon: %.6f ", gpx.lon); | 
					
						
							| 
									
										
										
										
											2016-11-02 14:41:18 +00:00
										 |  |  |                 fprintf(fp, " alt: %.2f ", gpx.alt); | 
					
						
							| 
									
										
										
										
											2015-12-31 19:51:58 +00:00
										 |  |  |                 if (option_verbose) { | 
					
						
							|  |  |  |                     err3 = get_GPSvel(); | 
					
						
							|  |  |  |                     if (!err3) { | 
					
						
							|  |  |  |                         if (option_verbose == 2) fprintf(fp, "  (%.1f , %.1f : %.1f°) ", gpx.vx, gpx.vy, gpx.vD2); | 
					
						
							|  |  |  |                         fprintf(fp, "  vH: %.1f  D: %.1f°  vV: %.1f ", gpx.vH, gpx.vD, gpx.vV); | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2015-12-10 09:49:56 +00:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2015-12-31 19:51:58 +00:00
										 |  |  |             fprintf(fp, "\n"); | 
					
						
							| 
									
										
										
										
											2015-12-09 11:39:17 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int main(int argc, char **argv) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     FILE *fp; | 
					
						
							|  |  |  |     char *fpname; | 
					
						
							|  |  |  |     int  i, len; | 
					
						
							|  |  |  |     char bitbuf[8]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int bitl1 = 0, | 
					
						
							|  |  |  |     bitl2 = 0, | 
					
						
							|  |  |  |     bitl4 = 0, | 
					
						
							|  |  |  |     bytepos = 0, | 
					
						
							|  |  |  |     bitpos = 0, | 
					
						
							|  |  |  |     head = 0, | 
					
						
							|  |  |  |     inout = 0, | 
					
						
							|  |  |  |     byteval = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef CYGWIN
 | 
					
						
							|  |  |  |     _setmode(fileno(stdin), _O_BINARY);  // _setmode(_fileno(stdin), _O_BINARY);
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-11-02 14:41:18 +00:00
										 |  |  |     setbuf(stdout, NULL); | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     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, "       -r, --raw\n"); | 
					
						
							| 
									
										
										
										
											2015-12-01 13:06:16 +00:00
										 |  |  |             fprintf(stderr, "       -i, --invert\n"); | 
					
						
							| 
									
										
										
										
											2015-12-30 21:46:28 +00:00
										 |  |  |             fprintf(stderr, "       -v, --verbose\n"); | 
					
						
							| 
									
										
										
										
											2016-01-09 22:13:39 +00:00
										 |  |  |             fprintf(stderr, "       -1  (v1: TOW/s)\n"); | 
					
						
							| 
									
										
										
										
											2015-12-30 21:46:28 +00:00
										 |  |  |             fprintf(stderr, "       -2  (v2: TOW/ms)\n"); | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |             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, "-c") == 0) || (strcmp(*argv, "--color") == 0) ) { | 
					
						
							|  |  |  |             option_color = 1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else if ( (strcmp(*argv, "-i") == 0) || (strcmp(*argv, "--invert") == 0) ) { | 
					
						
							|  |  |  |             option_inv = 1; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-01-09 22:13:39 +00:00
										 |  |  |         else if ( (strcmp(*argv, "-1") == 0) ) { option_gps = 1; }  // Trimble
 | 
					
						
							|  |  |  |         else if ( (strcmp(*argv, "-2") == 0) ) { option_gps = 2; }  // ublox
 | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |         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; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     i = read_wav_header(fp); | 
					
						
							|  |  |  |     if (i) { | 
					
						
							|  |  |  |         fclose(fp); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bitl1 = 0; | 
					
						
							|  |  |  |     bitl2 = 0; | 
					
						
							|  |  |  |     bitl4 = 0; | 
					
						
							|  |  |  |     bytepos = 0; | 
					
						
							|  |  |  |     bitpos = 0; | 
					
						
							|  |  |  |     head = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while (!read_afsk_bits(fp, &len)) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (len == 0) continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (len == 1) { | 
					
						
							|  |  |  |             bitl1++; | 
					
						
							|  |  |  |             if (bitl1 < 2) continue; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (len == 2) bitl2++; | 
					
						
							|  |  |  |         if (len == 4) {  | 
					
						
							|  |  |  |             bitl4++; | 
					
						
							|  |  |  |             inout = 1; | 
					
						
							|  |  |  |             bitl1 = 0; | 
					
						
							|  |  |  |             bitl2 = 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-20 14:40:45 +00:00
										 |  |  |         if (len == 3) { | 
					
						
							|  |  |  |             if (bitl1 == 1 && bitpos < 7) { | 
					
						
							|  |  |  |                 bitl1 = 0; bitbuf[bitpos++] = 1; | 
					
						
							|  |  |  |                 bitl2++; | 
					
						
							|  |  |  |                 len = 2; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |         if (len > 0 && len < 3) { | 
					
						
							|  |  |  |             bitl4 = 0; | 
					
						
							|  |  |  |             inout = 0; | 
					
						
							|  |  |  |             if (head > 0) {  | 
					
						
							|  |  |  |                 head = 0; | 
					
						
							|  |  |  |                 if (bytepos > pos_GPSalt+4) print_frame(FRAMELEN); | 
					
						
							|  |  |  |                 bitpos = 0; | 
					
						
							|  |  |  |                 bytepos = 0; | 
					
						
							|  |  |  |                 for (i=0; i<FRAMELEN; i++) frame[i] = 0; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (bitl1 == 2) { bitl1 = 0; bitbuf[bitpos++] = 1; } | 
					
						
							|  |  |  |         if (bitl2 == 1) { bitl2 = 0; bitbuf[bitpos++] = 0; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (bitpos > 7 || inout) { | 
					
						
							|  |  |  |             if (bitpos > 2) { | 
					
						
							|  |  |  |                 if (bytepos < FRAMELEN) { | 
					
						
							|  |  |  |                     byteval = bits2byte(bitbuf); | 
					
						
							|  |  |  |                     if (byteval == 0x10  &&  frame[bytepos-1] == 0x10) frame[bytepos-1] = 0x10; | 
					
						
							|  |  |  |                     else {                                          // woher die doppelte 0x10?
 | 
					
						
							| 
									
										
										
										
											2015-06-18 08:46:42 +00:00
										 |  |  |                         frame[bytepos] = byteval & 0xFF;            // koennte vom TSIP-Protokoll kommen:
 | 
					
						
							|  |  |  |                         bytepos++;                                  // <DLE><id><data_bytes><DLE><ETX>,
 | 
					
						
							|  |  |  |                     }                                               // wobei <DLE>=0x10, <ETX>=0x03.
 | 
					
						
							|  |  |  |                 }                                                   // wenn 0x10 in data, dann doppelt.
 | 
					
						
							| 
									
										
										
										
											2015-06-11 09:26:25 +00:00
										 |  |  |                  | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             bitpos = 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (bitl4 > 2) { head = 1; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     printf("\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     fclose(fp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 |