|
|
@ -3,6 +3,7 @@ |
|
|
|
* Copyright (C) 2012 by Steve Markgraf <steve@steve-m.de> |
|
|
|
* Copyright (C) 2012 by Steve Markgraf <steve@steve-m.de> |
|
|
|
* Copyright (C) 2012 by Hoernchen <la@tfc-server.de> |
|
|
|
* Copyright (C) 2012 by Hoernchen <la@tfc-server.de> |
|
|
|
* Copyright (C) 2012 by Kyle Keen <keenerd@gmail.com> |
|
|
|
* Copyright (C) 2012 by Kyle Keen <keenerd@gmail.com> |
|
|
|
|
|
|
|
* Copyright (C) 2013 by Elias Oenal <EliasOenal@gmail.com> |
|
|
|
* |
|
|
|
* |
|
|
|
* This program is free software: you can redistribute it and/or modify |
|
|
|
* This program is free software: you can redistribute it and/or modify |
|
|
|
* it under the terms of the GNU General Public License as published by |
|
|
|
* it under the terms of the GNU General Public License as published by |
|
|
@ -53,7 +54,6 @@ |
|
|
|
#define round(x) (x > 0.0 ? floor(x + 0.5): ceil(x - 0.5)) |
|
|
|
#define round(x) (x > 0.0 ? floor(x + 0.5): ceil(x - 0.5)) |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#include <semaphore.h> |
|
|
|
|
|
|
|
#include <pthread.h> |
|
|
|
#include <pthread.h> |
|
|
|
#include <libusb.h> |
|
|
|
#include <libusb.h> |
|
|
|
|
|
|
|
|
|
|
@ -67,7 +67,8 @@ |
|
|
|
#define AUTO_GAIN -100 |
|
|
|
#define AUTO_GAIN -100 |
|
|
|
|
|
|
|
|
|
|
|
static pthread_t demod_thread; |
|
|
|
static pthread_t demod_thread; |
|
|
|
static sem_t data_ready; |
|
|
|
static pthread_mutex_t data_ready; /* locked when no fresh data available */ |
|
|
|
|
|
|
|
static pthread_mutex_t data_write; /* locked when r/w buffer */ |
|
|
|
static int do_exit = 0; |
|
|
|
static int do_exit = 0; |
|
|
|
static rtlsdr_dev_t *dev = NULL; |
|
|
|
static rtlsdr_dev_t *dev = NULL; |
|
|
|
static int lcm_post[17] = {1,1,1,3,1,5,3,7,1,9,5,11,3,13,7,15,1}; |
|
|
|
static int lcm_post[17] = {1,1,1,3,1,5,3,7,1,9,5,11,3,13,7,15,1}; |
|
|
@ -579,6 +580,7 @@ void full_demod(struct fm_state *fm) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
low_pass(fm, fm->buf, fm->buf_len); |
|
|
|
low_pass(fm, fm->buf, fm->buf_len); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
pthread_mutex_unlock(&data_write); |
|
|
|
fm->mode_demod(fm); |
|
|
|
fm->mode_demod(fm); |
|
|
|
if (fm->mode_demod == &raw_demod) { |
|
|
|
if (fm->mode_demod == &raw_demod) { |
|
|
|
fwrite(fm->signal2, 2, fm->signal2_len, fm->file); |
|
|
|
fwrite(fm->signal2, 2, fm->signal2_len, fm->file); |
|
|
@ -619,25 +621,23 @@ void full_demod(struct fm_state *fm) |
|
|
|
static void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx) |
|
|
|
static void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx) |
|
|
|
{ |
|
|
|
{ |
|
|
|
struct fm_state *fm2 = ctx; |
|
|
|
struct fm_state *fm2 = ctx; |
|
|
|
int dr_val; |
|
|
|
|
|
|
|
if (do_exit) { |
|
|
|
if (do_exit) { |
|
|
|
return;} |
|
|
|
return;} |
|
|
|
if (!ctx) { |
|
|
|
if (!ctx) { |
|
|
|
return;} |
|
|
|
return;} |
|
|
|
|
|
|
|
pthread_mutex_lock(&data_write); |
|
|
|
memcpy(fm2->buf, buf, len); |
|
|
|
memcpy(fm2->buf, buf, len); |
|
|
|
fm2->buf_len = len; |
|
|
|
fm2->buf_len = len; |
|
|
|
|
|
|
|
pthread_mutex_unlock(&data_ready); |
|
|
|
/* single threaded uses 25% less CPU? */ |
|
|
|
/* single threaded uses 25% less CPU? */ |
|
|
|
/* full_demod(fm2); */ |
|
|
|
/* full_demod(fm2); */ |
|
|
|
sem_getvalue(&data_ready, &dr_val); |
|
|
|
|
|
|
|
if (dr_val <= 0) { |
|
|
|
|
|
|
|
sem_post(&data_ready);} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void *demod_thread_fn(void *arg) |
|
|
|
static void *demod_thread_fn(void *arg) |
|
|
|
{ |
|
|
|
{ |
|
|
|
struct fm_state *fm2 = arg; |
|
|
|
struct fm_state *fm2 = arg; |
|
|
|
while (!do_exit) { |
|
|
|
while (!do_exit) { |
|
|
|
sem_wait(&data_ready); |
|
|
|
pthread_mutex_lock(&data_ready); |
|
|
|
full_demod(fm2); |
|
|
|
full_demod(fm2); |
|
|
|
if (fm2->exit_flag) { |
|
|
|
if (fm2->exit_flag) { |
|
|
|
do_exit = 1; |
|
|
|
do_exit = 1; |
|
|
@ -725,7 +725,8 @@ 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]; |
|
|
|
fm_init(&fm); |
|
|
|
fm_init(&fm); |
|
|
|
sem_init(&data_ready, 0, 0); |
|
|
|
pthread_mutex_init(&data_ready, NULL); |
|
|
|
|
|
|
|
pthread_mutex_init(&data_write, NULL); |
|
|
|
|
|
|
|
|
|
|
|
while ((opt = getopt(argc, argv, "d:f:g:s:b:l:o:t:r:p:EFA:NWMULRDC")) != -1) { |
|
|
|
while ((opt = getopt(argc, argv, "d:f:g:s:b:l:o:t:r:p:EFA:NWMULRDC")) != -1) { |
|
|
|
switch (opt) { |
|
|
|
switch (opt) { |
|
|
@ -929,6 +930,8 @@ int main(int argc, char **argv) |
|
|
|
else { |
|
|
|
else { |
|
|
|
fprintf(stderr, "\nLibrary error %d, exiting...\n", r);} |
|
|
|
fprintf(stderr, "\nLibrary error %d, exiting...\n", r);} |
|
|
|
rtlsdr_cancel_async(dev); |
|
|
|
rtlsdr_cancel_async(dev); |
|
|
|
|
|
|
|
pthread_mutex_destroy(&data_ready); |
|
|
|
|
|
|
|
pthread_mutex_destroy(&data_write); |
|
|
|
|
|
|
|
|
|
|
|
if (fm.file != stdout) { |
|
|
|
if (fm.file != stdout) { |
|
|
|
fclose(fm.file);} |
|
|
|
fclose(fm.file);} |
|
|
|