diff options
Diffstat (limited to 'src/rtl_adsb.c')
| -rw-r--r-- | src/rtl_adsb.c | 106 |
1 files changed, 55 insertions, 51 deletions
diff --git a/src/rtl_adsb.c b/src/rtl_adsb.c index 2fb7418..44b62e2 100644 --- a/src/rtl_adsb.c +++ b/src/rtl_adsb.c @@ -37,7 +37,6 @@ #include "getopt/getopt.h" #endif -#include <semaphore.h> #include <pthread.h> #include <libusb.h> @@ -54,16 +53,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 pthread_mutex_t data_ready; /* locked when no data available */ 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 +143,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 +151,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 +186,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 +201,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 +212,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 +251,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 +279,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; @@ -328,23 +333,21 @@ void messages(uint8_t *buf, int len) static void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx) { - int dr_val; if (do_exit) { return;} memcpy(buffer, buf, len); - sem_getvalue(&data_ready, &dr_val); - if (dr_val <= 0) { - sem_post(&data_ready);} + pthread_mutex_trylock(&data_ready); + pthread_mutex_unlock(&data_ready); } static void *demod_thread_fn(void *arg) { int len; while (!do_exit) { - sem_wait(&data_ready); + pthread_mutex_lock(&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; @@ -362,8 +365,8 @@ int main(int argc, char **argv) int device_count; int ppm_error = 0; char vendor[256], product[256], serial[256]; - sem_init(&data_ready, 0, 0); - pyth_precompute(); + pthread_mutex_init(&data_ready, NULL); + squares_precompute(); while ((opt = getopt(argc, argv, "d:g:p:e:Q:VS")) != -1) { @@ -501,6 +504,7 @@ int main(int argc, char **argv) else { fprintf(stderr, "\nLibrary error %d, exiting...\n", r);} rtlsdr_cancel_async(dev); + pthread_mutex_destroy(&data_ready); if (file != stdout) { fclose(file);} |
