kopia lustrzana https://github.com/projecthorus/radiosonde_auto_rx
				
				
				
			M10: source
							rodzic
							
								
									99ca8baada
								
							
						
					
					
						commit
						c7d27afad0
					
				|  | @ -0,0 +1,685 @@ | ||||||
|  | 
 | ||||||
|  | /* big endian forest
 | ||||||
|  |  * | ||||||
|  |  * gcc -o m10x m10x.c | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  | // #include <math.h>
 | ||||||
|  | #ifdef WIN | ||||||
|  |   #include <fcntl.h>  // cygwin: _setmode() | ||||||
|  |   #include <io.h> | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | typedef unsigned char ui8_t; | ||||||
|  | typedef unsigned short ui16_t; | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  |     int week; int gpssec; | ||||||
|  |     int jahr; int monat; int tag; | ||||||
|  |     int wday; | ||||||
|  |     int std; int min; int sek; | ||||||
|  |     double lat; double lon; double h; | ||||||
|  | } datum_t; | ||||||
|  | 
 | ||||||
|  | datum_t datum; | ||||||
|  | 
 | ||||||
|  | int option_verbose = 0,  // ausfuehrliche Anzeige
 | ||||||
|  |     option_raw = 0,      // rohe Frames
 | ||||||
|  |     option_inv = 0,      // invertiert Signal
 | ||||||
|  |     option_res = 0,      // genauere Bitmessung
 | ||||||
|  |     option_color = 0, | ||||||
|  |     wavloaded = 0; | ||||||
|  | int inv = 1; | ||||||
|  | 
 | ||||||
|  | /* -------------------------------------------------------------------------- */ | ||||||
|  | /*
 | ||||||
|  |  * Convert GPS Week and Seconds to Modified Julian Day. | ||||||
|  |  * - Adapted from sci.astro FAQ. | ||||||
|  |  * - Ignores UTC leap seconds. | ||||||
|  |  */ | ||||||
|  | void Gps2Date(long GpsWeek, long GpsSeconds, int *Year, int *Month, int *Day) { | ||||||
|  | 
 | ||||||
|  |     long GpsDays, Mjd; | ||||||
|  |     long J, C, Y, M; | ||||||
|  | 
 | ||||||
|  |     GpsDays = GpsWeek * 7 + (GpsSeconds / 86400); | ||||||
|  |     Mjd = 44244 + GpsDays; | ||||||
|  | 
 | ||||||
|  |     J = Mjd + 2468570; | ||||||
|  |     C = 4 * J / 146097; | ||||||
|  |     J = J - (146097 * C + 3) / 4; | ||||||
|  |     Y = 4000 * (J + 1) / 1461001; | ||||||
|  |     J = J - 1461 * Y / 4 + 31; | ||||||
|  |     M = 80 * J / 2447; | ||||||
|  |     *Day = J - 2447 * M / 80; | ||||||
|  |     J = M / 11; | ||||||
|  |     *Month = M + 2 - (12 * J); | ||||||
|  |     *Year = 100 * (C - 49) + Y + J; | ||||||
|  | } | ||||||
|  | /* -------------------------------------------------------------------------- */ | ||||||
|  | 
 | ||||||
|  | #define BAUD_RATE   9600 //2*4800
 | ||||||
|  | 
 | ||||||
|  | int sample_rate = 0, bits_sample = 0, channels = 0; | ||||||
|  | float samples_per_bit = 0; | ||||||
|  | 
 | ||||||
|  | int findstr(char *buf, char *str, int pos) { | ||||||
|  |     int i; | ||||||
|  |     for (i = 0; i < 4; i++) { | ||||||
|  |         if (buf[(pos+i)%4] != str[i]) break; | ||||||
|  |     } | ||||||
|  |     return i; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int read_wav_header(FILE *fp) { | ||||||
|  |     char txt[5] = "\0\0\0\0"; | ||||||
|  |     char buff[4]; | ||||||
|  |     int byte, p=0; | ||||||
|  |     // long pos_fmt, pos_dat;
 | ||||||
|  |     char fmt_[5] = "fmt "; | ||||||
|  |     char data[5] = "data"; | ||||||
|  | 
 | ||||||
|  |     //if (fseek(fp, 0L, SEEK_SET)) return -1;
 | ||||||
|  |     if (fread(txt, 1, 4, fp) < 4) return -1; | ||||||
|  |     if (strncmp(txt, "RIFF", 4)) return -1; | ||||||
|  | 
 | ||||||
|  |     // pos_WAVE = 8L
 | ||||||
|  |     if (fread(txt, 1, 4, fp) < 4) return -1; | ||||||
|  |     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; | ||||||
|  |         buff[p % 4] = byte; | ||||||
|  |         p++; if (p==4) p=0; | ||||||
|  |         if (findstr(buff, fmt_, p) == 4) break; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     if (fread(buff, 1, 4, fp) < 4) return -1; | ||||||
|  |     //memcpy(&byte, buff, 4); fprintf(stderr, "fmt_length : %04x\n", byte);
 | ||||||
|  |     if (fread(buff, 1, 2, fp) < 2) return -1; | ||||||
|  |     //byte = buff[0] + (buff[1] << 8); fprintf(stderr, "fmt_tag    : %04x\n", byte & 0xFFFF);
 | ||||||
|  |     if (fread(buff, 1, 2, fp) < 2) return -1; | ||||||
|  |     channels = buff[0] + (buff[1] << 8); | ||||||
|  |     //fprintf(stderr, "channels   : %d\n", channels & 0xFFFF);
 | ||||||
|  |     if (fread(buff, 1, 4, fp) < 4) return -1; | ||||||
|  |     memcpy(&sample_rate, buff, 4); | ||||||
|  |     //fprintf(stderr, "samplerate : %d\n", sample_rate);
 | ||||||
|  |     if (fread(buff, 1, 4, fp) < 4) return -1; | ||||||
|  |     //memcpy(&byte, buff, 4); fprintf(stderr, "bytes/sec  : %d\n", byte);
 | ||||||
|  |     if (fread(buff, 1, 2, fp) < 2) return -1; | ||||||
|  |     byte = buff[0] + (buff[1] << 8); | ||||||
|  |     //fprintf(stderr, "block_align: %04x\n", byte & 0xFFFF);
 | ||||||
|  |     if (fread(buff, 1, 2, fp) < 2) return -1; | ||||||
|  |     bits_sample = buff[0] + (buff[1] << 8); | ||||||
|  |     //fprintf(stderr, "bits/sample: %d\n", bits_sample & 0xFFFF);
 | ||||||
|  | 
 | ||||||
|  |     // pos_dat = 36L + info
 | ||||||
|  |     //if (fread(txt, 1, 4, fp) < 4) return -1;
 | ||||||
|  |     //fprintf(stderr, "data: %s\n", txt);
 | ||||||
|  |     for ( ; ; ) { | ||||||
|  |         if ( (byte=fgetc(fp)) == EOF ) return -1; | ||||||
|  |         buff[p % 4] = byte; | ||||||
|  |         p++; if (p==4) p=0; | ||||||
|  |         if (findstr(buff, data, p) == 4) break; | ||||||
|  |     } | ||||||
|  |     if (fread(buff, 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/(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;   // 8bit: 00..FF, centerpoint 0x80=128
 | ||||||
|  |     if (bits_sample == 16) return (short)ret; | ||||||
|  | 
 | ||||||
|  |     return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int par=1, par_alt=1; | ||||||
|  | unsigned long sample_count = 0; | ||||||
|  | 
 | ||||||
|  | int read_bits_fsk(FILE *fp, int *bit, int *len) { | ||||||
|  |     static int sample; | ||||||
|  |     int n, y0; | ||||||
|  |     float l, x1; | ||||||
|  |     static float x0; | ||||||
|  | 
 | ||||||
|  |     n = 0; | ||||||
|  |     do{ | ||||||
|  |         y0 = sample; | ||||||
|  |         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;  // 8bit: 0..127,128..255 (-128..-1,0..127)
 | ||||||
|  |         n++; | ||||||
|  |     } while (par*par_alt > 0); | ||||||
|  | 
 | ||||||
|  |     if (!option_res) l = (float)n / samples_per_bit; | ||||||
|  |     else {                                 // genauere Bitlaengen-Messung
 | ||||||
|  |         x1 = sample/(float)(sample-y0);    // hilft bei niedriger sample rate
 | ||||||
|  |         l = (n+x0-x1) / samples_per_bit;   // meist mehr frames (nicht immer)
 | ||||||
|  |         x0 = x1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     *len = (int)(l+0.5); | ||||||
|  | 
 | ||||||
|  |     if (inv > 0) *bit = (1+par_alt)/2;  // oben 1, unten -1
 | ||||||
|  |     else         *bit = (1-par_alt)/2;  // sdr#<rev1381?, invers: unten 1, oben -1
 | ||||||
|  | // *bit = (1+inv*par_alt)/2; // ausser inv=0
 | ||||||
|  | 
 | ||||||
|  |     /* Y-offset ? */ | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* -------------------------------------------------------------------------- */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | Header = Sync-Header + Sonde-Header: | ||||||
|  | 1100110011001100 1010011001001100  1101010011010011 0100110101010101 0011010011001100 | ||||||
|  | uudduudduudduudd ududduuddudduudd  uudududduududduu dudduudududududu dduududduudduudd (oder:) | ||||||
|  | dduudduudduudduu duduudduuduudduu  ddududuudduduudd uduuddududududud uudduduudduudduu (komplement) | ||||||
|  |  0 0 0 0 0 0 0 0  1 1 - - - 0 0 0   0 1 1 0 0 1 0 0  1 0 0 1 1 1 1 1  0 0 1 0 0 0 0 0 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #define BYTELEN 8 | ||||||
|  |   | ||||||
|  | char bits[BYTELEN+1]; | ||||||
|  | int bitpos = 0; | ||||||
|  | 
 | ||||||
|  | unsigned char header_bytes[] = { 0x00, 0x00}; //{0x64, 0x9F, 0x20 }; // ggf. an header[] anpassen
 | ||||||
|  | #define HEADLEN 32 | ||||||
|  | #define HEADOFS 0 | ||||||
|  |                  // Sync-Header                     // Sonde-Header
 | ||||||
|  | char header[] = "11001100110011001010011001001100"; //"011001001001111100100000"; // M10: 64 9F 20 , M2K2: 64 8F 20
 | ||||||
|  |                                                     //"011101101001111100100000"; // M??: 76 9F 20
 | ||||||
|  |                                                     //"011001000100100100001001"; // M10-dop: 64 49 09
 | ||||||
|  | int header_found = 0; | ||||||
|  | 
 | ||||||
|  | #define FRAME_LEN       102 | ||||||
|  | #define BITFRAME_LEN    (FRAME_LEN*BYTELEN) | ||||||
|  | #define RAWBITFRAME_LEN (BITFRAME_LEN*2) | ||||||
|  | 
 | ||||||
|  | char buf[HEADLEN]; | ||||||
|  | int bufpos = -1; | ||||||
|  | 
 | ||||||
|  | int frame_bytes[FRAME_LEN+10]; | ||||||
|  | 
 | ||||||
|  | #define FRAMESTART 0 | ||||||
|  | char frame_rawbits[RAWBITFRAME_LEN+8];  // frame_rawbits-32="11001100110011001010011001001100";
 | ||||||
|  | char frame_bits[BITFRAME_LEN+4]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void inc_bufpos() { | ||||||
|  |   bufpos = (bufpos+1) % HEADLEN; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char cb_inv(char c) { | ||||||
|  |     if (c == '0') return '1'; | ||||||
|  |     if (c == '1') return '0'; | ||||||
|  |     return c; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Gefahr bei Manchester-Codierung: inverser Header wird leicht fehl-erkannt
 | ||||||
|  | int compare2() { | ||||||
|  |     int i, j; | ||||||
|  | 
 | ||||||
|  |     i = 0; | ||||||
|  |     j = bufpos; | ||||||
|  |     while (i < HEADLEN) { | ||||||
|  |         if (j < 0) j = HEADLEN-1; | ||||||
|  |         if (buf[j] != header[HEADOFS+HEADLEN-1-i]) break; | ||||||
|  |         j--; | ||||||
|  |         i++; | ||||||
|  |     } | ||||||
|  |     if (i == HEADLEN) return 1; | ||||||
|  | 
 | ||||||
|  |     i = 0; | ||||||
|  |     j = bufpos; | ||||||
|  |     while (i < HEADLEN) { | ||||||
|  |         if (j < 0) j = HEADLEN-1; | ||||||
|  |         if (buf[j] != cb_inv(header[HEADOFS+HEADLEN-1-i])) break; | ||||||
|  |         j--; | ||||||
|  |         i++; | ||||||
|  |     } | ||||||
|  |     if (i == HEADLEN) return -1; | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int bits2bytes(char *bitstr, int *bytes) { | ||||||
|  |     int i, bit, d, byteval; | ||||||
|  |     int bitpos, bytepos; | ||||||
|  | 
 | ||||||
|  |     bitpos = 0; | ||||||
|  |     bytepos = 0; | ||||||
|  | 
 | ||||||
|  |     while (bytepos < FRAME_LEN) { | ||||||
|  | 
 | ||||||
|  |         byteval = 0; | ||||||
|  |         d = 1; | ||||||
|  |         for (i = 0; i < BYTELEN; i++) {  | ||||||
|  |             //bit=*(bitstr+bitpos+i); /* little endian */
 | ||||||
|  |             bit=*(bitstr+bitpos+7-i);  /* big endian */ | ||||||
|  |             // bit == 'x' ?
 | ||||||
|  |             if         (bit == '1')                     byteval += d; | ||||||
|  |             else /*if ((bit == '0') || (bit == 'x'))*/  byteval += 0; | ||||||
|  |             d <<= 1; | ||||||
|  |         } | ||||||
|  |         bitpos += BYTELEN; | ||||||
|  |         bytes[bytepos++] = byteval; | ||||||
|  |          | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //while (bytepos < FRAME_LEN) bytes[bytepos++] = 0;
 | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* -------------------------------------------------------------------------- */ | ||||||
|  | // PSK  (bzw. biphase-M (oder differential Manchester?))
 | ||||||
|  | // nach Synchronisation: 00,11->0 ; 01,10->1 (Phasenwechsel)
 | ||||||
|  | void psk_bpm(char* frame_rawbits, char *frame_bits) { | ||||||
|  |     int i; | ||||||
|  |     char bit; | ||||||
|  |     //int err = 0;
 | ||||||
|  | 
 | ||||||
|  |     for (i = 0; i < BITFRAME_LEN; i++) { | ||||||
|  | 
 | ||||||
|  |         //if (i > 0 && (frame_rawbits[2*i] == frame_rawbits[2*i-1])) err = 1;
 | ||||||
|  | 
 | ||||||
|  |         if (frame_rawbits[2*i] == frame_rawbits[2*i+1]) bit = '0'; | ||||||
|  |         else                                            bit = '1'; | ||||||
|  | 
 | ||||||
|  |         //if (err) frame_bits[i] = 'x'; else
 | ||||||
|  |         frame_bits[i] = bit; | ||||||
|  |         //err = 0;
 | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* -------------------------------------------------------------------------- */ | ||||||
|  | 
 | ||||||
|  | #define pos_GPSTOW     0x0A  // 4 byte
 | ||||||
|  | #define pos_GPSlat     0x0E  // 4 byte
 | ||||||
|  | #define pos_GPSlon     0x12  // 4 byte
 | ||||||
|  | #define pos_GPSheight  0x16  // 4 byte
 | ||||||
|  | #define pos_GPSweek    0x20  // 2 byte
 | ||||||
|  | 
 | ||||||
|  | #define ANSI_COLOR_RED     "\x1b[31m" | ||||||
|  | #define ANSI_COLOR_GREEN   "\x1b[32m" | ||||||
|  | #define ANSI_COLOR_YELLOW  "\x1b[33m" | ||||||
|  | #define ANSI_COLOR_BLUE    "\x1b[34m" | ||||||
|  | #define ANSI_COLOR_MAGENTA "\x1b[35m" | ||||||
|  | #define ANSI_COLOR_CYAN    "\x1b[36m" | ||||||
|  | #define ANSI_COLOR_RESET   "\x1b[0m" | ||||||
|  | 
 | ||||||
|  | #define XTERM_COLOR_BROWN   "\x1b[38;5;94m"  // 38;5;{0..255}m
 | ||||||
|  | 
 | ||||||
|  | #define col_GPSweek    "\x1b[38;5;20m"  // 2 byte
 | ||||||
|  | #define col_GPSTOW     "\x1b[38;5;27m"  // 4 byte
 | ||||||
|  | #define col_GPSdate    "\x1b[38;5;94m" //111
 | ||||||
|  | #define col_GPSlat     "\x1b[38;5;34m"  // 4 byte
 | ||||||
|  | #define col_GPSlon     "\x1b[38;5;70m"  // 4 byte
 | ||||||
|  | #define col_GPSheight  "\x1b[38;5;82m"  // 4 byte
 | ||||||
|  | #define col_TXT        "\x1b[38;5;244m" | ||||||
|  | #define col_FRTXT      "\x1b[38;5;244m" | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | $ for code in  {0..255} | ||||||
|  | > do echo -e "\e[38;5;${code}m"'\\e[38;5;'"$code"m"\e[0m" | ||||||
|  | > done | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | int get_GPSweek() { | ||||||
|  |     int i; | ||||||
|  |     unsigned byte; | ||||||
|  |     ui8_t gpsweek_bytes[2]; | ||||||
|  |     int gpsweek; | ||||||
|  | 
 | ||||||
|  |     for (i = 0; i < 2; i++) { | ||||||
|  |         byte = frame_bytes[pos_GPSweek + i]; | ||||||
|  |         if (byte > 0xFF) return -1; | ||||||
|  |         gpsweek_bytes[i] = byte; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     gpsweek = (gpsweek_bytes[0] << 8) + gpsweek_bytes[1]; | ||||||
|  |     datum.week = gpsweek; | ||||||
|  | 
 | ||||||
|  |     if (gpsweek < 0 || gpsweek > 3000) return -1; | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char weekday[7][3] = { "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"}; | ||||||
|  | 
 | ||||||
|  | int get_GPStime() { | ||||||
|  |     int i; | ||||||
|  |     unsigned byte; | ||||||
|  |     ui8_t gpstime_bytes[4]; | ||||||
|  |     int gpstime, day; // int ms;
 | ||||||
|  | 
 | ||||||
|  |     for (i = 0; i < 4; i++) { | ||||||
|  |         byte = frame_bytes[pos_GPSTOW + i]; | ||||||
|  |         if (byte > 0xFF) return -1; | ||||||
|  |         gpstime_bytes[i] = byte; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     gpstime = 0; | ||||||
|  |     for (i = 0; i < 4; i++) { | ||||||
|  |         gpstime |= gpstime_bytes[i] << (8*(3-i)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //ms = gpstime % 1000;
 | ||||||
|  |     gpstime /= 1000; | ||||||
|  |     datum.gpssec = gpstime; | ||||||
|  | 
 | ||||||
|  |     day = gpstime / (24 * 3600); | ||||||
|  |     gpstime %= (24*3600); | ||||||
|  | 
 | ||||||
|  |     if ((day < 0) || (day > 6)) return -1; | ||||||
|  |     datum.wday = day; | ||||||
|  |     datum.std = gpstime/3600; | ||||||
|  |     datum.min = (gpstime%3600)/60; | ||||||
|  |     datum.sek = gpstime%60; | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | double B60B60 = 0xB60B60;  // 2^32/360 = 0xB60B60.xxx
 | ||||||
|  | 
 | ||||||
|  | int get_GPSlat() { | ||||||
|  |     int i; | ||||||
|  |     unsigned byte; | ||||||
|  |     ui8_t gpslat_bytes[4]; | ||||||
|  |     int gpslat; | ||||||
|  |     double lat; | ||||||
|  | 
 | ||||||
|  |     for (i = 0; i < 4; i++) { | ||||||
|  |         byte = frame_bytes[pos_GPSlat + i]; | ||||||
|  |         if (byte > 0xFF) return -1; | ||||||
|  |         gpslat_bytes[i] = byte; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     gpslat = 0; | ||||||
|  |     for (i = 0; i < 4; i++) { | ||||||
|  |         gpslat |= gpslat_bytes[i] << (8*(3-i)); | ||||||
|  |     } | ||||||
|  |     lat = gpslat / B60B60; | ||||||
|  |     datum.lat = lat; | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int get_GPSlon() { | ||||||
|  |     int i; | ||||||
|  |     unsigned byte; | ||||||
|  |     ui8_t gpslon_bytes[4]; | ||||||
|  |     int gpslon; | ||||||
|  |     double lon; | ||||||
|  | 
 | ||||||
|  |     for (i = 0; i < 4; i++) { | ||||||
|  |         byte = frame_bytes[pos_GPSlon + i]; | ||||||
|  |         if (byte > 0xFF) return -1; | ||||||
|  |         gpslon_bytes[i] = byte; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     gpslon = 0; | ||||||
|  |     for (i = 0; i < 4; i++) { | ||||||
|  |         gpslon |= gpslon_bytes[i] << (8*(3-i)); | ||||||
|  |     } | ||||||
|  |     lon = gpslon / B60B60; | ||||||
|  |     datum.lon = lon; | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int get_GPSheight() { | ||||||
|  |     int i; | ||||||
|  |     unsigned byte; | ||||||
|  |     ui8_t gpsheight_bytes[4]; | ||||||
|  |     int gpsheight; | ||||||
|  |     double height; | ||||||
|  | 
 | ||||||
|  |     for (i = 0; i < 4; i++) { | ||||||
|  |         byte = frame_bytes[pos_GPSheight + i]; | ||||||
|  |         if (byte > 0xFF) return -1; | ||||||
|  |         gpsheight_bytes[i] = byte; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     gpsheight = 0; | ||||||
|  |     for (i = 0; i < 4; i++) { | ||||||
|  |         gpsheight |= gpsheight_bytes[i] << (8*(3-i)); | ||||||
|  |     } | ||||||
|  |     height = gpsheight / 1000.0; | ||||||
|  |     datum.h = height; | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* -------------------------------------------------------------------------- */ | ||||||
|  | 
 | ||||||
|  | int print_pos() { | ||||||
|  |     int err; | ||||||
|  | 
 | ||||||
|  |     err = 0; | ||||||
|  |     err |= get_GPSweek(); | ||||||
|  |     err |= get_GPStime(); | ||||||
|  |     err |= get_GPSlat(); | ||||||
|  |     err |= get_GPSlon(); | ||||||
|  |     err |= get_GPSheight(); | ||||||
|  | 
 | ||||||
|  |     if (!err) { | ||||||
|  | 
 | ||||||
|  |         Gps2Date(datum.week, datum.gpssec, &datum.jahr, &datum.monat, &datum.tag); | ||||||
|  | 
 | ||||||
|  |         if (option_color) { | ||||||
|  |             printf(col_TXT); | ||||||
|  |             printf(" (W "col_GPSweek"%d"col_TXT") ", datum.week); | ||||||
|  |             printf(col_GPSTOW"%s"col_TXT" ", weekday[datum.wday]); | ||||||
|  |             printf(col_GPSdate"%04d-%02d-%02d"col_TXT" ("col_GPSTOW"%02d:%02d:%02d"col_TXT") ",  | ||||||
|  |                    datum.jahr, datum.monat, datum.tag, datum.std, datum.min, datum.sek); | ||||||
|  |             printf(" lat: "col_GPSlat"%.6f"col_TXT" ", datum.lat); | ||||||
|  |             printf(" lon: "col_GPSlon"%.6f"col_TXT" ", datum.lon); | ||||||
|  |             printf(" h: "col_GPSheight"%.2f"col_TXT" ", datum.h); | ||||||
|  |             printf(ANSI_COLOR_RESET"\n"); | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             printf(" (W %d) ", datum.week); | ||||||
|  |             printf("%s ", weekday[datum.wday]); | ||||||
|  |             printf("%04d-%02d-%02d (%02d:%02d:%02d) ",  | ||||||
|  |                     datum.jahr, datum.monat, datum.tag, datum.std, datum.min, datum.sek); | ||||||
|  |             printf(" lat: %.6f ", datum.lat); | ||||||
|  |             printf(" lon: %.6f ", datum.lon); | ||||||
|  |             printf(" h: %.2f ", datum.h); | ||||||
|  |             printf("\n"); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return err; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void print_frame(int pos) { | ||||||
|  |     int i; | ||||||
|  |     ui8_t byte; | ||||||
|  | 
 | ||||||
|  |     psk_bpm(frame_rawbits, frame_bits); | ||||||
|  |     bits2bytes(frame_bits, frame_bytes); | ||||||
|  | 
 | ||||||
|  |     if (option_raw) { | ||||||
|  | 
 | ||||||
|  |         if (option_color) { | ||||||
|  |             fprintf(stdout, col_FRTXT); | ||||||
|  |             for (i = 0; i < FRAME_LEN; i++) { | ||||||
|  |                 byte = frame_bytes[i]; | ||||||
|  |                 if ((i >= pos_GPSTOW)    && (i < pos_GPSTOW+4))    fprintf(stdout, col_GPSTOW); | ||||||
|  |                 if ((i >= pos_GPSlat)    && (i < pos_GPSlat+4))    fprintf(stdout, col_GPSlat); | ||||||
|  |                 if ((i >= pos_GPSlon)    && (i < pos_GPSlon+4))    fprintf(stdout, col_GPSlon); | ||||||
|  |                 if ((i >= pos_GPSheight) && (i < pos_GPSheight+4)) fprintf(stdout, col_GPSheight); | ||||||
|  |                 if ((i >= pos_GPSweek)   && (i < pos_GPSweek+2))   fprintf(stdout, col_GPSweek); | ||||||
|  |                 fprintf(stdout, "%02x", byte); | ||||||
|  |                 fprintf(stdout, col_FRTXT); | ||||||
|  |             } | ||||||
|  |             fprintf(stdout, ANSI_COLOR_RESET"\n"); | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             for (i = 0; i < FRAME_LEN; i++) { | ||||||
|  |                 byte = frame_bytes[i]; | ||||||
|  |                 fprintf(stdout, "%02x", byte); | ||||||
|  |             } | ||||||
|  |             fprintf(stdout, "\n"); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  |     else print_pos(); | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | int main(int argc, char **argv) { | ||||||
|  | 
 | ||||||
|  |     FILE *fp; | ||||||
|  |     char *fpname; | ||||||
|  |     int i, bit, len; | ||||||
|  |     int pos; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifdef WIN | ||||||
|  |     _setmode(fileno(stdin), _O_BINARY);  // _setmode(_fileno(stdin), _O_BINARY);
 | ||||||
|  |     setbuf(stdout, NULL); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     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, --verbose\n");
 | ||||||
|  |             fprintf(stderr, "       -r, --raw\n"); | ||||||
|  |             fprintf(stderr, "       -c, --color\n"); | ||||||
|  |             //fprintf(stderr, "       -o, --offset\n");
 | ||||||
|  |             return 0; | ||||||
|  |         } | ||||||
|  |         else if ( (strcmp(*argv, "-v") == 0) || (strcmp(*argv, "--verbose") == 0) ) { | ||||||
|  |             option_verbose = 1; | ||||||
|  |         } | ||||||
|  |         else if ( (strcmp(*argv, "-r") == 0) || (strcmp(*argv, "--raw") == 0) ) { | ||||||
|  |             option_raw = 1; | ||||||
|  |         } | ||||||
|  |         else if ( (strcmp(*argv, "-i") == 0) || (strcmp(*argv, "--invert") == 0) ) { | ||||||
|  |             option_inv = 1;  // nicht noetig
 | ||||||
|  |         } | ||||||
|  |         else if ( (strcmp(*argv, "-c") == 0) || (strcmp(*argv, "--color") == 0) ) { | ||||||
|  |             option_color = 1; | ||||||
|  |         } | ||||||
|  |         else if   (strcmp(*argv, "--res") == 0) { option_res = 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; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     i = read_wav_header(fp); | ||||||
|  |     if (i) { | ||||||
|  |         fclose(fp); | ||||||
|  |         return -1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     bufpos = 0; | ||||||
|  |     pos = FRAMESTART; | ||||||
|  | 
 | ||||||
|  |     while (!read_bits_fsk(fp, &bit, &len)) { | ||||||
|  | 
 | ||||||
|  |         if (len == 0) { // reset_frame();
 | ||||||
|  |             if (pos > (pos_GPSweek+2)*2*BYTELEN) { | ||||||
|  |                 for (i = pos; i < RAWBITFRAME_LEN; i++) frame_rawbits[i] = 0x30 + 0; | ||||||
|  |                 print_frame(pos);//byte_count
 | ||||||
|  |                 header_found = 0; | ||||||
|  |                 pos = FRAMESTART; | ||||||
|  |             } | ||||||
|  |             //inc_bufpos();
 | ||||||
|  |             //buf[bufpos] = 'x';
 | ||||||
|  |             continue;   // ...
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         for (i = 0; i < len; i++) { | ||||||
|  | 
 | ||||||
|  |             inc_bufpos(); | ||||||
|  |             buf[bufpos] = 0x30 + bit;  // Ascii
 | ||||||
|  | 
 | ||||||
|  |             if (!header_found) { | ||||||
|  |                 header_found = compare2(); | ||||||
|  |                 if (header_found != 0) { | ||||||
|  |                   inv = header_found; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             else { | ||||||
|  |                 frame_rawbits[pos] = 0x30 + bit;  // Ascii
 | ||||||
|  |                 pos++; | ||||||
|  |              | ||||||
|  |                 if (pos == RAWBITFRAME_LEN) { | ||||||
|  |                     print_frame(pos);//FRAME_LEN
 | ||||||
|  |                     header_found = 0; | ||||||
|  |                     pos = FRAMESTART; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     printf("\n"); | ||||||
|  | 
 | ||||||
|  |     fclose(fp); | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
		Ładowanie…
	
		Reference in New Issue
	
	 Zilog80
						Zilog80