From 240abf60761c63d6e1b5955e3ce9328f5d3d61de Mon Sep 17 00:00:00 2001 From: Hayati Ayguen Date: Fri, 25 Mar 2016 15:31:13 +0000 Subject: [PATCH 1/3] use offset tuning when using bandwidth option bandwidth filter are around center frequency without offset tuning rtl_fm automatically uses the frequency -fs/4 for demodulation but this lies outside the bandwidth filter! switch on offset option to use the center frequency for demodulation fixed/precised output texts output available bandwidths in kHz for better readability --- include/rtl-sdr.h | 7 +++++++ src/convenience/convenience.c | 34 ++++++++++++++++++++------------- src/rtl_fm.c | 36 ++++++++++++++++++----------------- src/rtl_tcp.c | 2 +- 4 files changed, 48 insertions(+), 31 deletions(-) mode change 100644 => 100755 src/rtl_tcp.c diff --git a/include/rtl-sdr.h b/include/rtl-sdr.h index 384caa9..633524c 100755 --- a/include/rtl-sdr.h +++ b/include/rtl-sdr.h @@ -143,6 +143,13 @@ RTLSDR_API int rtlsdr_write_eeprom(rtlsdr_dev_t *dev, uint8_t *data, RTLSDR_API int rtlsdr_read_eeprom(rtlsdr_dev_t *dev, uint8_t *data, uint8_t offset, uint16_t len); +/*! + * Set the frequency the device is tuned to. + * + * \param dev the device handle given by rtlsdr_open() + * \param frequency in Hz + * \return 0 on error, frequency in Hz otherwise + */ RTLSDR_API int rtlsdr_set_center_freq(rtlsdr_dev_t *dev, uint32_t freq); /*! diff --git a/src/convenience/convenience.c b/src/convenience/convenience.c index fb6ac3b..e234333 100755 --- a/src/convenience/convenience.c +++ b/src/convenience/convenience.c @@ -162,18 +162,21 @@ int verbose_set_sample_rate(rtlsdr_dev_t *dev, uint32_t samp_rate) int verbose_set_bandwidth(rtlsdr_dev_t *dev, uint32_t bandwidth) { - int r; - uint32_t applied_bw = 0; - /* r = rtlsdr_set_tuner_bandwidth(dev, bandwidth); */ - r = rtlsdr_set_and_get_tuner_bandwidth(dev, bandwidth, &applied_bw, 1 /* =apply_bw */); - if (r < 0) { - fprintf(stderr, "WARNING: Failed to set bandwidth.\n"); - } else if (bandwidth > 0) { - fprintf(stderr, "Bandwidth set to %u Hz resulted in %u Hz.\n", bandwidth, applied_bw); - } else { - fprintf(stderr, "Bandwidth set to automatic resulted in %u Hz.\n", applied_bw); - } - return r; + int r; + uint32_t applied_bw = 0; + /* r = rtlsdr_set_tuner_bandwidth(dev, bandwidth); */ + r = rtlsdr_set_and_get_tuner_bandwidth(dev, bandwidth, &applied_bw, 1 /* =apply_bw */); + if (r < 0) { + fprintf(stderr, "WARNING: Failed to set bandwidth.\n"); + } else if (bandwidth > 0) { + if (applied_bw) + fprintf(stderr, "Bandwidth parameter %u Hz resulted in %u Hz.\n", bandwidth, applied_bw); + else + fprintf(stderr, "Set bandwidth parameter %u Hz.\n", bandwidth); + } else { + fprintf(stderr, "Bandwidth set to automatic resulted in %u Hz.\n", applied_bw); + } + return r; } int verbose_direct_sampling(rtlsdr_dev_t *dev, int on) @@ -198,7 +201,12 @@ int verbose_offset_tuning(rtlsdr_dev_t *dev) int r; r = rtlsdr_set_offset_tuning(dev, 1); if (r != 0) { - fprintf(stderr, "WARNING: Failed to set offset tuning.\n"); + if ( r == -2 ) + fprintf(stderr, "WARNING: Failed to set offset tuning: tuner doesn't support offset tuning!\n"); + else if ( r == -3 ) + fprintf(stderr, "WARNING: Failed to set offset tuning: direct sampling not combinable with offset tuning!\n"); + else + fprintf(stderr, "WARNING: Failed to set offset tuning.\n"); } else { fprintf(stderr, "Offset tuning mode enabled.\n"); } diff --git a/src/rtl_fm.c b/src/rtl_fm.c index baf8bb9..c9f2f50 100755 --- a/src/rtl_fm.c +++ b/src/rtl_fm.c @@ -205,7 +205,7 @@ void usage(void) "\t[-s sample_rate (default: 24k)]\n" "\t[-d device_index (default: 0)]\n" "\t[-g tuner_gain (default: automatic)]\n" - "\t[-w tuner_bandwidth (default: automatic)]\n" + "\t[-w tuner_bandwidth (default: automatic. enables offset tuning)]\n" "\t[-l squelch_level (default: 0/off)]\n" "\t[-L N prints levels every N calculations]\n" "\t output are comma separated values (csv):\n" @@ -221,8 +221,8 @@ void usage(void) "\t adc: enable dc blocking filter on demodulated audio\n" "\t dc: same as adc\n" "\t deemp: enable de-emphasis filter\n" - "\t direct: enable direct sampling\n" - "\t offset: enable offset tuning\n" + "\t direct: enable direct sampling (bypasses tuner, uses rtl2832 xtal)\n" + "\t offset: enable offset tuning (only e4000 tuner)\n" "\t[-q dc_avg_factor for option rdc (default: 9)]\n" "\tfilename ('-' means stdout)\n" "\t omitting the filename also uses stdout\n\n" @@ -986,7 +986,7 @@ static void *controller_thread_fn(void *arg) if (s->wb_mode) { if (verbosity) - fprintf(stderr, "wbfm: adding 16000 Hz to every intput frequency\n"); + fprintf(stderr, "wbfm: adding 16000 Hz to every input frequency\n"); for (i=0; i < s->freq_len; i++) { s->freqs[i] += 16000;} } @@ -1001,7 +1001,8 @@ static void *controller_thread_fn(void *arg) /* Set the frequency */ if (verbosity) { fprintf(stderr, "verbose_set_frequency(%.0f Hz)\n", (double)dongle.freq); - fprintf(stderr, " frequency is away from parametrized one, to avoid negative impact from dc\n"); + if (!dongle.offset_tuning) + fprintf(stderr, " frequency is away from parametrized one, to avoid negative impact from dc\n"); } verbose_set_frequency(dongle.dev, dongle.freq); fprintf(stderr, "Oversampling input by: %ix.\n", demod.downsample); @@ -1279,6 +1280,8 @@ int main(int argc, char **argv) break; case 'w': dongle.bandwidth = (uint32_t)atofs(optarg); + if (dongle.bandwidth) + dongle.offset_tuning = 1; /* automatically switch offset tuning, when using bandwidth filter */ break; case 'h': default: @@ -1350,20 +1353,19 @@ int main(int argc, char **argv) verbose_set_bandwidth(dongle.dev, dongle.bandwidth); - verbose_set_bandwidth(dongle.dev, dongle.bandwidth); - if (verbosity && dongle.bandwidth) { - int r; - uint32_t in_bw, out_bw, last_bw = 0; - for ( in_bw = 1; in_bw < 3200; ++in_bw ) - { - r = rtlsdr_set_and_get_tuner_bandwidth(dongle.dev, in_bw*1000, &out_bw, 0 /* =apply_bw */); - if ( r == 0 && ( out_bw != last_bw || in_bw == 1 ) ) - fprintf(stderr, "device sets bandwidth %u Hz for bw para >= %u kHz\n", out_bw, in_bw ); - last_bw = out_bw; - } - fprintf(stderr,"\n"); + int r; + uint32_t in_bw, out_bw, last_bw = 0; + fprintf(stderr, "Supported bandwidth values in kHz:\n"); + for ( in_bw = 1; in_bw < 3200; ++in_bw ) + { + r = rtlsdr_set_and_get_tuner_bandwidth(dongle.dev, in_bw*1000, &out_bw, 0 /* =apply_bw */); + if ( r == 0 && out_bw != 0 && ( out_bw != last_bw || in_bw == 1 ) ) + fprintf(stderr, "%s%.1f", (in_bw==1 ? "" : ", "), out_bw/1000.0 ); + last_bw = out_bw; + } + fprintf(stderr,"\n"); } if (strcmp(output.filename, "-") == 0) { /* Write samples to stdout */ diff --git a/src/rtl_tcp.c b/src/rtl_tcp.c old mode 100644 new mode 100755 index bf0e3ea..3f90923 --- a/src/rtl_tcp.c +++ b/src/rtl_tcp.c @@ -94,7 +94,7 @@ void usage(void) "\t[-s samplerate in Hz (default: 2048000 Hz)]\n" "\t[-b number of buffers (default: 15, set by library)]\n" "\t[-n max number of linked list buffers to keep (default: 500)]\n" - "\t[-w rtlsdr device bandwidth (for R820T device)\n" + "\t[-w rtlsdr device bandwidth [Hz] (for R820T device)\n" "\t[-d device index (default: 0)]\n" "\t[-P ppm_error (default: 0)]\n"); exit(1); From 57238073b82edb999063abe24c07bf04f8808726 Mon Sep 17 00:00:00 2001 From: Hayati Ayguen Date: Fri, 25 Mar 2016 16:37:03 +0000 Subject: [PATCH 2/3] merged option to activate digital agc of rtl2832 with '-E rtlagc' also reformatted -E options --- src/rtl_fm.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/rtl_fm.c b/src/rtl_fm.c index c9f2f50..0d59056 100755 --- a/src/rtl_fm.c +++ b/src/rtl_fm.c @@ -217,9 +217,11 @@ void usage(void) "\t[-E enable_option (default: none)]\n" "\t use multiple -E to enable multiple options\n" "\t edge: enable lower edge tuning\n" - "\t rdc: enable dc blocking filter on raw I/Q data at capture rate\n" - "\t adc: enable dc blocking filter on demodulated audio\n" - "\t dc: same as adc\n" + "\t rdc: enable dc blocking filter on raw I/Q data at capture rate\n" + "\t adc: enable dc blocking filter on demodulated audio\n" + "\t dc: same as adc\n" + "\t rtlagc: enable rtl2832's digital agc (default: off)\n" + "\t agc: same as rtlagc\n" "\t deemp: enable de-emphasis filter\n" "\t direct: enable direct sampling (bypasses tuner, uses rtl2832 xtal)\n" "\t offset: enable offset tuning (only e4000 tuner)\n" @@ -1159,6 +1161,7 @@ int main(int argc, char **argv) int dev_given = 0; int custom_ppm = 0; int timeConstant = 75; /* default: U.S. 75 uS */ + int rtlagc = 0; dongle_init(&dongle); demod_init(&demod); output_init(&output); @@ -1228,6 +1231,8 @@ int main(int argc, char **argv) dongle.direct_sampling = 1;} if (strcmp("offset", optarg) == 0) { dongle.offset_tuning = 1;} + if (strcmp("rtlagc", optarg) == 0 || strcmp("agc", optarg) == 0) { + rtlagc = 1;} break; case 'q': demod.rdc_block_const = atoi(optarg); @@ -1349,6 +1354,8 @@ int main(int argc, char **argv) verbose_gain_set(dongle.dev, dongle.gain); } + rtlsdr_set_agc_mode(dongle.dev, rtlagc); + verbose_ppm_set(dongle.dev, dongle.ppm_error); verbose_set_bandwidth(dongle.dev, dongle.bandwidth); From aabe859851c8cd5471adcf68cea527a08acb369a Mon Sep 17 00:00:00 2001 From: Hayati Ayguen Date: Sun, 3 Apr 2016 16:08:23 +0000 Subject: [PATCH 3/3] rtl_fm: made -v flag without argument rtl_tcp: added verbose option -v rtl_tcp: reduced mutex timeout from 5 to 1 sec. makes rtl_tcp re-available faster fixed formatting/indentation with tabs --- src/librtlsdr.c | 0 src/rtl_fm.c | 26 ++++++++++++---------- src/rtl_tcp.c | 55 ++++++++++++++++++++++++++++++----------------- src/tuner_r82xx.c | 0 4 files changed, 50 insertions(+), 31 deletions(-) mode change 100755 => 100644 src/librtlsdr.c mode change 100755 => 100644 src/rtl_fm.c mode change 100755 => 100644 src/rtl_tcp.c mode change 100755 => 100644 src/tuner_r82xx.c diff --git a/src/librtlsdr.c b/src/librtlsdr.c old mode 100755 new mode 100644 diff --git a/src/rtl_fm.c b/src/rtl_fm.c old mode 100755 new mode 100644 index 0d59056..80688fa --- a/src/rtl_fm.c +++ b/src/rtl_fm.c @@ -108,7 +108,7 @@ struct dongle_state int dev_index; uint32_t freq; uint32_t rate; - uint32_t bandwidth; + uint32_t bandwidth; int gain; int16_t buf16[MAXIMUM_BUF_LENGTH]; uint32_t buf_len; @@ -197,15 +197,15 @@ void usage(void) "\t-f frequency_to_tune_to [Hz]\n" "\t use multiple -f for scanning (requires squelch)\n" "\t ranges supported, -f 118M:137M:25k\n" - "\t[-v verbosity (default: 0)]\n" + "\t[-v increase verbosity (default: 0)]\n" "\t[-M modulation (default: fm)]\n" "\t fm or nbfm or nfm, wbfm or wfm, raw or iq, am, usb, lsb\n" "\t wbfm == -M fm -s 170k -o 4 -A fast -r 32k -l 0 -E deemp\n" "\t raw mode outputs 2x16 bit IQ pairs\n" "\t[-s sample_rate (default: 24k)]\n" "\t[-d device_index (default: 0)]\n" - "\t[-g tuner_gain (default: automatic)]\n" - "\t[-w tuner_bandwidth (default: automatic. enables offset tuning)]\n" + "\t[-g tuner_gain (default: automatic)]\n" + "\t[-w tuner_bandwidth (default: automatic. enables offset tuning)]\n" "\t[-l squelch_level (default: 0/off)]\n" "\t[-L N prints levels every N calculations]\n" "\t output are comma separated values (csv):\n" @@ -1167,7 +1167,7 @@ int main(int argc, char **argv) output_init(&output); controller_init(&controller); - while ((opt = getopt(argc, argv, "d:f:g:s:b:l:L:o:t:r:p:E:q:F:A:M:c:v:h:w:")) != -1) { + while ((opt = getopt(argc, argv, "d:f:g:s:b:l:L:o:t:r:p:E:q:F:A:M:c:h:w:v")) != -1) { switch (opt) { case 'd': dongle.dev_index = verbose_device_search(optarg); @@ -1281,20 +1281,24 @@ int main(int argc, char **argv) timeConstant = (int)atof(optarg); break; case 'v': - verbosity = (int)atof(optarg); + ++verbosity; + break; + case 'w': + dongle.bandwidth = (uint32_t)atofs(optarg); + if (dongle.bandwidth) + dongle.offset_tuning = 1; /* automatically switch offset tuning, when using bandwidth filter */ break; - case 'w': - dongle.bandwidth = (uint32_t)atofs(optarg); - if (dongle.bandwidth) - dongle.offset_tuning = 1; /* automatically switch offset tuning, when using bandwidth filter */ - break; case 'h': + case '?': default: usage(); break; } } + if (verbosity) + fprintf(stderr, "verbosity set to %d\n", verbosity); + /* quadruple sample_rate to limit to Δθ to ±π/2 */ demod.rate_in *= demod.post_downsample; diff --git a/src/rtl_tcp.c b/src/rtl_tcp.c old mode 100755 new mode 100644 index 3f90923..3906f9c --- a/src/rtl_tcp.c +++ b/src/rtl_tcp.c @@ -78,6 +78,8 @@ typedef struct { /* structure size must be multiple of 2 bytes */ static rtlsdr_dev_t *dev = NULL; +static int verbosity = 0; +static uint32_t bandwidth = 0; static int global_numq = 0; static struct llist *ll_buffers = 0; static int llbuf_num = 500; @@ -94,9 +96,10 @@ void usage(void) "\t[-s samplerate in Hz (default: 2048000 Hz)]\n" "\t[-b number of buffers (default: 15, set by library)]\n" "\t[-n max number of linked list buffers to keep (default: 500)]\n" - "\t[-w rtlsdr device bandwidth [Hz] (for R820T device)\n" + "\t[-w rtlsdr device bandwidth [Hz] (for R820T device)]\n" "\t[-d device index (default: 0)]\n" - "\t[-P ppm_error (default: 0)]\n"); + "\t[-P ppm_error (default: 0)]\n" + "\t[-v increase verbosity (default: 0)]\n"); exit(1); } @@ -203,7 +206,7 @@ static void *tcp_worker(void *arg) pthread_mutex_lock(&ll_mutex); gettimeofday(&tp, NULL); - ts.tv_sec = tp.tv_sec+5; + ts.tv_sec = tp.tv_sec+1; ts.tv_nsec = tp.tv_usec * 1000; r = pthread_cond_timedwait(&cond, &ll_mutex, &ts); if(r == ETIMEDOUT) { @@ -257,6 +260,8 @@ static int set_gain_by_index(rtlsdr_dev_t *_dev, unsigned int index) count = rtlsdr_get_tuner_gains(_dev, gains); res = rtlsdr_set_tuner_gain(_dev, gains[index]); + if (verbosity) + fprintf(stderr, "set tuner gain to %.1f dB\n", gains[index] / 10.0); free(gains); } @@ -310,6 +315,7 @@ static void *command_worker(void *arg) case SET_SAMPLE_RATE: printf("set sample rate %d\n", ntohl(cmd.param)); rtlsdr_set_sample_rate(dev, ntohl(cmd.param)); + /*verbose_set_bandwidth(dev, bandwidth);*/ break; case SET_GAIN_MODE: printf("set gain mode %d\n", ntohl(cmd.param)); @@ -356,10 +362,11 @@ static void *command_worker(void *arg) printf("set tuner gain by index %d\n", ntohl(cmd.param)); set_gain_by_index(dev, ntohl(cmd.param)); break; - case SET_TUNER_BANDWIDTH: - printf("set tuner bandwidth to %i Hz\n", ntohl(cmd.param)); - rtlsdr_set_tuner_bandwidth(dev, ntohl(cmd.param)); - break; + case SET_TUNER_BANDWIDTH: + bandwidth = ntohl(cmd.param); + printf("set tuner bandwidth to %i Hz\n", bandwidth); + verbose_set_bandwidth(dev, bandwidth); + break; default: break; } @@ -372,7 +379,7 @@ int main(int argc, char **argv) int r, opt, i; char* addr = "127.0.0.1"; int port = 1234; - uint32_t frequency = 100000000, samp_rate = 2048000, bandwidth = 0; + uint32_t frequency = 100000000, samp_rate = 2048000; struct sockaddr_in local, remote; uint32_t buf_num = 0; int dev_index = 0; @@ -389,6 +396,7 @@ int main(int argc, char **argv) fd_set readfds; u_long blockmode = 1; dongle_info_t dongle_info; + int gains[100]; #ifdef _WIN32 WSADATA wsd; i = WSAStartup(MAKEWORD(2,2), &wsd); @@ -396,7 +404,7 @@ int main(int argc, char **argv) struct sigaction sigact, sigign; #endif - while ((opt = getopt(argc, argv, "a:p:f:g:s:b:n:d:P:w:")) != -1) { + while ((opt = getopt(argc, argv, "a:p:f:g:s:b:n:d:P:w:v")) != -1) { switch (opt) { case 'd': dev_index = verbose_device_search(optarg); @@ -425,9 +433,12 @@ int main(int argc, char **argv) break; case 'P': ppm_error = atoi(optarg); - break; - case 'w': - bandwidth = (uint32_t)atofs(optarg); + break; + case 'w': + bandwidth = (uint32_t)atofs(optarg); + break; + case 'v': + ++verbosity; break; default: usage(); @@ -438,6 +449,9 @@ int main(int argc, char **argv) if (argc < optind) usage(); + if (verbosity) + fprintf(stderr, "verbosity set to %d\n", verbosity); + if (!dev_given) { dev_index = verbose_device_search("0"); } @@ -499,13 +513,7 @@ int main(int argc, char **argv) fprintf(stderr, "Tuner gain set to %f dB.\n", gain/10.0); } - r = rtlsdr_set_tuner_bandwidth(dev, bandwidth); - if (r < 0) - fprintf(stderr, "WARNING: Failed to set tuner bandwidth.\n"); - else if (bandwidth != 0) - fprintf(stderr, "Tuner bandwidth set to %i.\n", bandwidth); - else - fprintf(stderr, "Tuner bandwidth set to automatic.\n"); + verbose_set_bandwidth(dev, bandwidth); /* Reset endpoint before we start reading from it (mandatory) */ r = rtlsdr_reset_buffer(dev); @@ -571,9 +579,16 @@ int main(int argc, char **argv) if (r >= 0) dongle_info.tuner_type = htonl(r); - r = rtlsdr_get_tuner_gains(dev, NULL); + r = rtlsdr_get_tuner_gains(dev, gains); if (r >= 0) dongle_info.tuner_gain_count = htonl(r); + if (verbosity) + { + fprintf(stderr, "Supported gain values (%d): ", r); + for (i = 0; i < r; i++) + fprintf(stderr, "%.1f ", gains[i] / 10.0); + fprintf(stderr, "\n"); + } r = send(s, (const char *)&dongle_info, sizeof(dongle_info), 0); if (sizeof(dongle_info) != r) diff --git a/src/tuner_r82xx.c b/src/tuner_r82xx.c old mode 100755 new mode 100644