mirror of
				https://github.com/rtlsdrblog/rtl-sdr-blog.git
				synced 2025-10-31 00:48:08 +01:00 
			
		
		
		
	rtl_adsb: 16 bit magnitudes
Signed-off-by: Steve Markgraf <steve@steve-m.de>
This commit is contained in:
		
				
					committed by
					
						 Steve Markgraf
						Steve Markgraf
					
				
			
			
				
	
			
			
			
						parent
						
							b656896f66
						
					
				
				
					commit
					c6a731a0dc
				
			| @@ -54,16 +54,19 @@ | ||||
| #define DEFAULT_BUF_LENGTH		(16 * 16384) | ||||
| #define AUTO_GAIN			-100 | ||||
|  | ||||
| #define MESSAGEGO    253 | ||||
| #define OVERWRITE    254 | ||||
| #define BADSAMPLE    255 | ||||
|  | ||||
| static pthread_t demod_thread; | ||||
| static sem_t data_ready; | ||||
| static volatile int do_exit = 0; | ||||
| static rtlsdr_dev_t *dev = NULL; | ||||
|  | ||||
| /* look up table, could be made smaller */ | ||||
| uint8_t pyth[129][129]; | ||||
| uint16_t squares[256]; | ||||
|  | ||||
| /* todo, bundle these up in a struct */ | ||||
| uint8_t *buffer; | ||||
| uint8_t *buffer;  /* also abused for uint16_t */ | ||||
| int verbose_output = 0; | ||||
| int short_output = 0; | ||||
| double quality = 1.0; | ||||
| @@ -141,17 +144,7 @@ void display(int *frame, int len) | ||||
| 	fprintf(file, "--------------\n"); | ||||
| } | ||||
|  | ||||
| void pyth_precompute(void) | ||||
| { | ||||
| 	int x, y; | ||||
| 	double scale = 1.408 ;  /* use the full 8 bits */ | ||||
| 	for (x=0; x<129; x++) { | ||||
| 	for (y=0; y<129; y++) { | ||||
| 		pyth[x][y] = (uint8_t)round(scale * sqrt(x*x + y*y)); | ||||
| 	}} | ||||
| } | ||||
|  | ||||
| inline uint8_t abs8(uint8_t x) | ||||
| int abs8(int x) | ||||
| /* do not subtract 128 from the raw iq, this handles it */ | ||||
| { | ||||
| 	if (x >= 128) { | ||||
| @@ -159,18 +152,31 @@ inline uint8_t abs8(uint8_t x) | ||||
| 	return 128 - x; | ||||
| } | ||||
|  | ||||
| void squares_precompute(void) | ||||
| /* equiv to abs(x-128) ^ 2 */ | ||||
| { | ||||
| 	int i, j; | ||||
| 	// todo, check if this LUT is actually any faster | ||||
| 	for (i=0; i<256; i++) { | ||||
| 		j = abs8(i); | ||||
| 		squares[i] = (uint16_t)(j*j); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int magnitute(uint8_t *buf, int len) | ||||
| /* takes i/q, changes buf in place, returns new len */ | ||||
| /* takes i/q, changes buf in place (16 bit), returns new len (16 bit) */ | ||||
| { | ||||
| 	int i; | ||||
| 	uint16_t *m; | ||||
| 	for (i=0; i<len; i+=2) { | ||||
| 		buf[i/2] = pyth[abs8(buf[i])][abs8(buf[i+1])]; | ||||
| 		m = (uint16_t*)(&buf[i]); | ||||
| 		*m = squares[buf[i]] + squares[buf[i+1]]; | ||||
| 	} | ||||
| 	return len/2; | ||||
| } | ||||
|  | ||||
| inline uint8_t single_manchester(uint8_t a, uint8_t b, uint8_t c, uint8_t d) | ||||
| /* takes 4 consecutive real samples, return 0 or 1, 255 on error */ | ||||
| inline uint16_t single_manchester(uint16_t a, uint16_t b, uint16_t c, uint16_t d) | ||||
| /* takes 4 consecutive real samples, return 0 or 1, BADSAMPLE on error */ | ||||
| { | ||||
| 	int bit, bit_p; | ||||
| 	bit_p = a > b; | ||||
| @@ -181,9 +187,9 @@ inline uint8_t single_manchester(uint8_t a, uint8_t b, uint8_t c, uint8_t d) | ||||
|  | ||||
| 	if (quality == 0.5) { | ||||
| 		if ( bit &&  bit_p && b > c) { | ||||
| 			return 255;} | ||||
| 			return BADSAMPLE;} | ||||
| 		if (!bit && !bit_p && b < c) { | ||||
| 			return 255;} | ||||
| 			return BADSAMPLE;} | ||||
| 		return bit; | ||||
| 	} | ||||
|  | ||||
| @@ -196,7 +202,7 @@ inline uint8_t single_manchester(uint8_t a, uint8_t b, uint8_t c, uint8_t d) | ||||
| 			return 0;} | ||||
| 		if (!bit && !bit_p && c < b) { | ||||
| 			return 0;} | ||||
| 		return 255; | ||||
| 		return BADSAMPLE; | ||||
| 	} | ||||
|  | ||||
| 	if ( bit &&  bit_p && c > b && d < a) { | ||||
| @@ -207,36 +213,36 @@ inline uint8_t single_manchester(uint8_t a, uint8_t b, uint8_t c, uint8_t d) | ||||
| 		return 0;} | ||||
| 	if (!bit && !bit_p && c < b && d > a) { | ||||
| 		return 0;} | ||||
| 	return 255; | ||||
| 	return BADSAMPLE; | ||||
| } | ||||
|  | ||||
| inline uint8_t min8(uint8_t a, uint8_t b) | ||||
| inline uint16_t min16(uint16_t a, uint16_t b) | ||||
| { | ||||
| 	return a<b ? a : b; | ||||
| } | ||||
|  | ||||
| inline uint8_t max8(uint8_t a, uint8_t b) | ||||
| inline uint16_t max16(uint16_t a, uint16_t b) | ||||
| { | ||||
| 	return a>b ? a : b; | ||||
| } | ||||
|  | ||||
| inline int preamble(uint8_t *buf, int len, int i) | ||||
| inline int preamble(uint16_t *buf, int i) | ||||
| /* returns 0/1 for preamble at index i */ | ||||
| { | ||||
| 	int i2; | ||||
| 	uint8_t low  = 0; | ||||
| 	uint8_t high = 255; | ||||
| 	uint16_t low  = 0; | ||||
| 	uint16_t high = 65535; | ||||
| 	for (i2=0; i2<preamble_len; i2++) { | ||||
| 		switch (i2) { | ||||
| 			case 0: | ||||
| 			case 2: | ||||
| 			case 7: | ||||
| 			case 9: | ||||
| 				//high = min8(high, buf[i+i2]); | ||||
| 				//high = min16(high, buf[i+i2]); | ||||
| 				high = buf[i+i2]; | ||||
| 				break; | ||||
| 			default: | ||||
| 				//low  = max8(low,  buf[i+i2]); | ||||
| 				//low  = max16(low,  buf[i+i2]); | ||||
| 				low = buf[i+i2]; | ||||
| 				break; | ||||
| 		} | ||||
| @@ -246,24 +252,24 @@ inline int preamble(uint8_t *buf, int len, int i) | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| void manchester(uint8_t *buf, int len) | ||||
| /* overwrites magnitude buffer with valid bits (255 on errors) */ | ||||
| void manchester(uint16_t *buf, int len) | ||||
| /* overwrites magnitude buffer with valid bits (BADSAMPLE on errors) */ | ||||
| { | ||||
| 	/* a and b hold old values to verify local manchester */ | ||||
| 	uint8_t a=0, b=0; | ||||
| 	uint8_t bit; | ||||
| 	uint16_t a=0, b=0; | ||||
| 	uint16_t bit; | ||||
| 	int i, i2, start, errors; | ||||
| 	// todo, allow wrap across buffers | ||||
| 	i = 0; | ||||
| 	while (i < len) { | ||||
| 		/* find preamble */ | ||||
| 		for ( ; i < (len - preamble_len); i++) { | ||||
| 			if (!preamble(buf, len, i)) { | ||||
| 			if (!preamble(buf, i)) { | ||||
| 				continue;} | ||||
| 			a = buf[i]; | ||||
| 			b = buf[i+1]; | ||||
| 			for (i2=0; i2<preamble_len; i2++) { | ||||
| 				buf[i+i2] = 253;} | ||||
| 				buf[i+i2] = MESSAGEGO;} | ||||
| 			i += preamble_len; | ||||
| 			break; | ||||
| 		} | ||||
| @@ -274,25 +280,25 @@ void manchester(uint8_t *buf, int len) | ||||
| 			bit = single_manchester(a, b, buf[i], buf[i+1]); | ||||
| 			a = buf[i]; | ||||
| 			b = buf[i+1]; | ||||
| 			if (bit == 255) { | ||||
| 			if (bit == BADSAMPLE) { | ||||
| 				errors += 1; | ||||
| 				if (errors > allowed_errors) { | ||||
| 					buf[i2] = 255; | ||||
| 					buf[i2] = BADSAMPLE; | ||||
| 					break; | ||||
| 				} else { | ||||
| 					bit = a > b; | ||||
| 					/* these don't have to match the bit */ | ||||
| 					a = 0; | ||||
| 					b = 255; | ||||
| 					b = 65535; | ||||
| 				} | ||||
| 			} | ||||
| 			buf[i] = buf[i+1] = 254;  /* to be overwritten */ | ||||
| 			buf[i] = buf[i+1] = OVERWRITE; | ||||
| 			buf[i2] = bit; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void messages(uint8_t *buf, int len) | ||||
| void messages(uint16_t *buf, int len) | ||||
| { | ||||
| 	int i, i2, start, preamble_found; | ||||
| 	int data_i, index, shift, frame_len; | ||||
| @@ -343,8 +349,8 @@ static void *demod_thread_fn(void *arg) | ||||
| 	while (!do_exit) { | ||||
| 		sem_wait(&data_ready); | ||||
| 		len = magnitute(buffer, DEFAULT_BUF_LENGTH); | ||||
| 		manchester(buffer, len); | ||||
| 		messages(buffer, len); | ||||
| 		manchester((uint16_t*)buffer, len); | ||||
| 		messages((uint16_t*)buffer, len); | ||||
| 	} | ||||
| 	rtlsdr_cancel_async(dev); | ||||
| 	return 0; | ||||
| @@ -363,7 +369,7 @@ int main(int argc, char **argv) | ||||
| 	int ppm_error = 0; | ||||
| 	char vendor[256], product[256], serial[256]; | ||||
| 	sem_init(&data_ready, 0, 0); | ||||
| 	pyth_precompute(); | ||||
| 	squares_precompute(); | ||||
|  | ||||
| 	while ((opt = getopt(argc, argv, "d:g:p:e:Q:VS")) != -1) | ||||
| 	{ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user