rtl_adsb: 16 bit magnitudes

Signed-off-by: Steve Markgraf <steve@steve-m.de>
This commit is contained in:
Kyle Keen 2013-01-29 20:31:49 -05:00 committed by Steve Markgraf
parent b656896f66
commit c6a731a0dc
1 changed files with 49 additions and 43 deletions

View File

@ -54,16 +54,19 @@
#define DEFAULT_BUF_LENGTH (16 * 16384) #define DEFAULT_BUF_LENGTH (16 * 16384)
#define AUTO_GAIN -100 #define AUTO_GAIN -100
#define MESSAGEGO 253
#define OVERWRITE 254
#define BADSAMPLE 255
static pthread_t demod_thread; static pthread_t demod_thread;
static sem_t data_ready; static sem_t data_ready;
static volatile int do_exit = 0; static volatile int do_exit = 0;
static rtlsdr_dev_t *dev = NULL; static rtlsdr_dev_t *dev = NULL;
/* look up table, could be made smaller */ uint16_t squares[256];
uint8_t pyth[129][129];
/* todo, bundle these up in a struct */ /* todo, bundle these up in a struct */
uint8_t *buffer; uint8_t *buffer; /* also abused for uint16_t */
int verbose_output = 0; int verbose_output = 0;
int short_output = 0; int short_output = 0;
double quality = 1.0; double quality = 1.0;
@ -141,17 +144,7 @@ void display(int *frame, int len)
fprintf(file, "--------------\n"); fprintf(file, "--------------\n");
} }
void pyth_precompute(void) int abs8(int x)
{
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)
/* do not subtract 128 from the raw iq, this handles it */ /* do not subtract 128 from the raw iq, this handles it */
{ {
if (x >= 128) { if (x >= 128) {
@ -159,18 +152,31 @@ inline uint8_t abs8(uint8_t x)
return 128 - 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) 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; int i;
uint16_t *m;
for (i=0; i<len; i+=2) { 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; return len/2;
} }
inline uint8_t single_manchester(uint8_t a, uint8_t b, uint8_t c, uint8_t d) 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, 255 on error */ /* takes 4 consecutive real samples, return 0 or 1, BADSAMPLE on error */
{ {
int bit, bit_p; int bit, bit_p;
bit_p = a > b; 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 (quality == 0.5) {
if ( bit && bit_p && b > c) { if ( bit && bit_p && b > c) {
return 255;} return BADSAMPLE;}
if (!bit && !bit_p && b < c) { if (!bit && !bit_p && b < c) {
return 255;} return BADSAMPLE;}
return bit; 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;} return 0;}
if (!bit && !bit_p && c < b) { if (!bit && !bit_p && c < b) {
return 0;} return 0;}
return 255; return BADSAMPLE;
} }
if ( bit && bit_p && c > b && d < a) { 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;} return 0;}
if (!bit && !bit_p && c < b && d > a) { if (!bit && !bit_p && c < b && d > a) {
return 0;} 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; 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; 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 */ /* returns 0/1 for preamble at index i */
{ {
int i2; int i2;
uint8_t low = 0; uint16_t low = 0;
uint8_t high = 255; uint16_t high = 65535;
for (i2=0; i2<preamble_len; i2++) { for (i2=0; i2<preamble_len; i2++) {
switch (i2) { switch (i2) {
case 0: case 0:
case 2: case 2:
case 7: case 7:
case 9: case 9:
//high = min8(high, buf[i+i2]); //high = min16(high, buf[i+i2]);
high = buf[i+i2]; high = buf[i+i2];
break; break;
default: default:
//low = max8(low, buf[i+i2]); //low = max16(low, buf[i+i2]);
low = buf[i+i2]; low = buf[i+i2];
break; break;
} }
@ -246,24 +252,24 @@ inline int preamble(uint8_t *buf, int len, int i)
return 1; return 1;
} }
void manchester(uint8_t *buf, int len) void manchester(uint16_t *buf, int len)
/* overwrites magnitude buffer with valid bits (255 on errors) */ /* overwrites magnitude buffer with valid bits (BADSAMPLE on errors) */
{ {
/* a and b hold old values to verify local manchester */ /* a and b hold old values to verify local manchester */
uint8_t a=0, b=0; uint16_t a=0, b=0;
uint8_t bit; uint16_t bit;
int i, i2, start, errors; int i, i2, start, errors;
// todo, allow wrap across buffers // todo, allow wrap across buffers
i = 0; i = 0;
while (i < len) { while (i < len) {
/* find preamble */ /* find preamble */
for ( ; i < (len - preamble_len); i++) { for ( ; i < (len - preamble_len); i++) {
if (!preamble(buf, len, i)) { if (!preamble(buf, i)) {
continue;} continue;}
a = buf[i]; a = buf[i];
b = buf[i+1]; b = buf[i+1];
for (i2=0; i2<preamble_len; i2++) { for (i2=0; i2<preamble_len; i2++) {
buf[i+i2] = 253;} buf[i+i2] = MESSAGEGO;}
i += preamble_len; i += preamble_len;
break; break;
} }
@ -274,25 +280,25 @@ void manchester(uint8_t *buf, int len)
bit = single_manchester(a, b, buf[i], buf[i+1]); bit = single_manchester(a, b, buf[i], buf[i+1]);
a = buf[i]; a = buf[i];
b = buf[i+1]; b = buf[i+1];
if (bit == 255) { if (bit == BADSAMPLE) {
errors += 1; errors += 1;
if (errors > allowed_errors) { if (errors > allowed_errors) {
buf[i2] = 255; buf[i2] = BADSAMPLE;
break; break;
} else { } else {
bit = a > b; bit = a > b;
/* these don't have to match the bit */ /* these don't have to match the bit */
a = 0; a = 0;
b = 255; b = 65535;
} }
} }
buf[i] = buf[i+1] = 254; /* to be overwritten */ buf[i] = buf[i+1] = OVERWRITE;
buf[i2] = bit; buf[i2] = bit;
} }
} }
} }
void messages(uint8_t *buf, int len) void messages(uint16_t *buf, int len)
{ {
int i, i2, start, preamble_found; int i, i2, start, preamble_found;
int data_i, index, shift, frame_len; int data_i, index, shift, frame_len;
@ -343,8 +349,8 @@ static void *demod_thread_fn(void *arg)
while (!do_exit) { while (!do_exit) {
sem_wait(&data_ready); sem_wait(&data_ready);
len = magnitute(buffer, DEFAULT_BUF_LENGTH); len = magnitute(buffer, DEFAULT_BUF_LENGTH);
manchester(buffer, len); manchester((uint16_t*)buffer, len);
messages(buffer, len); messages((uint16_t*)buffer, len);
} }
rtlsdr_cancel_async(dev); rtlsdr_cancel_async(dev);
return 0; return 0;
@ -363,7 +369,7 @@ int main(int argc, char **argv)
int ppm_error = 0; int ppm_error = 0;
char vendor[256], product[256], serial[256]; char vendor[256], product[256], serial[256];
sem_init(&data_ready, 0, 0); sem_init(&data_ready, 0, 0);
pyth_precompute(); squares_precompute();
while ((opt = getopt(argc, argv, "d:g:p:e:Q:VS")) != -1) while ((opt = getopt(argc, argv, "d:g:p:e:Q:VS")) != -1)
{ {