void retune(rtlsdr_dev_t *d, int freq) { uint8_t dump[BUFFER_DUMP]; int f, n_read; f = (int)rtlsdr_get_center_freq(d); if (f == freq) { return;} rtlsdr_set_center_freq(d, (uint32_t)freq); /* wait for settling and flush buffer */ usleep(5000); rtlsdr_read_sync(d, &dump, BUFFER_DUMP, &n_read); if (n_read != BUFFER_DUMP) { fprintf(stderr, "Error: bad retune.\n");} }
void scanner(void) { int i, j, j2, f, n_read, offset, bin_e, bin_len, buf_len, ds, ds_p; int32_t w; struct tuning_state *ts; bin_e = tunes[0].bin_e; bin_len = 1 << bin_e; buf_len = tunes[0].buf_len; for (i=0; i<tune_count; i++) { if (do_exit >= 2) {return;} ts = &tunes[i]; f = (int)rtlsdr_get_center_freq(dev); if (f != ts->freq) { retune(dev, ts->freq);} rtlsdr_read_sync(dev, ts->buf8, buf_len, &n_read); if (n_read != buf_len) { fprintf(stderr, "Error: dropped samples.\n");} /* rms */ if (bin_len == 1) { rms_power(ts); continue; } /* prep for fft */ for (j=0; j<buf_len; j++) { fft_buf[j] = (int16_t)ts->buf8[j] - 127; } ds = ts->downsample; ds_p = ts->downsample_passes; if (boxcar && ds > 1) { j=2, j2=0; while (j < buf_len) { fft_buf[j2] += fft_buf[j]; fft_buf[j2+1] += fft_buf[j+1]; fft_buf[j] = 0; fft_buf[j+1] = 0; j += 2; if (j % (ds*2) == 0) { j2 += 2;} } } else if (ds_p) { /* recursive */ for (j=0; j < ds_p; j++) { downsample_iq(fft_buf, buf_len >> j); } /* droop compensation */ if (comp_fir_size == 9 && ds_p <= CIC_TABLE_MAX) { generic_fir(fft_buf, buf_len >> j, cic_9_tables[ds_p]); generic_fir(fft_buf+1, (buf_len >> j)-1, cic_9_tables[ds_p]); } } remove_dc(fft_buf, buf_len / ds); remove_dc(fft_buf+1, (buf_len / ds) - 1); /* window function and fft */ for (offset=0; offset<(buf_len/ds); offset+=(2*bin_len)) { // todo, let rect skip this for (j=0; j<bin_len; j++) { w = (int32_t)fft_buf[offset+j*2]; w *= (int32_t)(window_coefs[j]); //w /= (int32_t)(ds); fft_buf[offset+j*2] = (int16_t)w; w = (int32_t)fft_buf[offset+j*2+1]; w *= (int32_t)(window_coefs[j]); //w /= (int32_t)(ds); fft_buf[offset+j*2+1] = (int16_t)w; } fix_fft(fft_buf+offset, bin_e); if (!peak_hold) { for (j=0; j<bin_len; j++) { ts->avg[j] += real_conj(fft_buf[offset+j*2], fft_buf[offset+j*2+1]); } } else { for (j=0; j<bin_len; j++) { ts->avg[j] = MAX(real_conj(fft_buf[offset+j*2], fft_buf[offset+j*2+1]), ts->avg[j]); } } ts->samples += ds; } }
int main(int argc, char **argv) { #ifndef _WIN32 struct sigaction sigact; #endif char *out_filename = NULL; char *in_filename = NULL; FILE *in_file; int n_read; int r = 0, opt; int i, gain = 0; int sync_mode = 0; int ppm_error = 0; struct dm_state* demod; uint32_t dev_index = 0; int frequency_current = 0; uint32_t out_block_size = DEFAULT_BUF_LENGTH; int device_count; char vendor[256], product[256], serial[256]; int have_opt_R = 0; setbuf(stdout, NULL); setbuf(stderr, NULL); demod = malloc(sizeof (struct dm_state)); memset(demod, 0, sizeof (struct dm_state)); /* initialize tables */ baseband_init(); r_device devices[] = { #define DECL(name) name, DEVICES #undef DECL }; num_r_devices = sizeof(devices)/sizeof(*devices); demod->level_limit = DEFAULT_LEVEL_LIMIT; while ((opt = getopt(argc, argv, "x:z:p:DtaAqm:r:l:d:f:g:s:b:n:SR:F:C:T:UW")) != -1) { switch (opt) { case 'd': dev_index = atoi(optarg); break; case 'f': if (frequencies < MAX_PROTOCOLS) frequency[frequencies++] = (uint32_t) atof(optarg); else fprintf(stderr, "Max number of frequencies reached %d\n", MAX_PROTOCOLS); break; case 'g': gain = (int) (atof(optarg) * 10); /* tenths of a dB */ break; case 'p': ppm_error = atoi(optarg); break; case 's': samp_rate = (uint32_t) atof(optarg); break; case 'b': out_block_size = (uint32_t) atof(optarg); break; case 'l': demod->level_limit = (uint32_t) atof(optarg); break; case 'n': bytes_to_read = (uint32_t) atof(optarg) * 2; break; case 'a': demod->analyze = 1; break; case 'A': demod->analyze_pulses = 1; break; case 'r': in_filename = optarg; break; case 't': demod->signal_grabber = 1; break; case 'm': demod->debug_mode = atoi(optarg); break; case 'S': sync_mode = 1; break; case 'D': debug_output++; break; case 'z': override_short = atoi(optarg); break; case 'x': override_long = atoi(optarg); break; case 'R': if (!have_opt_R) { for (i = 0; i < num_r_devices; i++) { devices[i].disabled = 1; } have_opt_R = 1; } i = atoi(optarg); if (i > num_r_devices) { fprintf(stderr, "Remote device number specified larger than number of devices\n\n"); usage(devices); } devices[i - 1].disabled = 0; break; case 'q': quiet_mode = 1; break; case 'F': if (strcmp(optarg, "json") == 0) { add_json_output(); } else if (strcmp(optarg, "csv") == 0) { add_csv_output(determine_csv_fields(devices, num_r_devices)); } else if (strcmp(optarg, "kv") == 0) { add_kv_output(); } else { fprintf(stderr, "Invalid output format %s\n", optarg); usage(devices); } break; case 'C': if (strcmp(optarg, "native") == 0) { conversion_mode = CONVERT_NATIVE; } else if (strcmp(optarg, "si") == 0) { conversion_mode = CONVERT_SI; } else if (strcmp(optarg, "customary") == 0) { conversion_mode = CONVERT_CUSTOMARY; } else { fprintf(stderr, "Invalid conversion mode %s\n", optarg); usage(devices); } break; case 'U': #if !defined(__MINGW32__) utc_mode = setenv("TZ", "UTC", 1); if(utc_mode != 0) fprintf(stderr, "Unable to set TZ to UTC; error code: %d\n", utc_mode); #endif break; case 'W': overwrite_mode = 1; break; case 'T': time(&stop_time); duration = atoi(optarg); if (duration < 1) { fprintf(stderr, "Duration '%s' was not positive integer; will continue indefinitely\n", optarg); } else { stop_time += duration; } break; default: usage(devices); break; } } if (argc <= optind - 1) { usage(devices); } else { out_filename = argv[optind]; } if (!output_handler) { add_kv_output(); } for (i = 0; i < num_r_devices; i++) { if (!devices[i].disabled) { register_protocol(demod, &devices[i]); if(devices[i].modulation >= FSK_DEMOD_MIN_VAL) { demod->enable_FM_demod = 1; } } } if (out_block_size < MINIMAL_BUF_LENGTH || out_block_size > MAXIMAL_BUF_LENGTH) { fprintf(stderr, "Output block size wrong value, falling back to default\n"); fprintf(stderr, "Minimal length: %u\n", MINIMAL_BUF_LENGTH); fprintf(stderr, "Maximal length: %u\n", MAXIMAL_BUF_LENGTH); out_block_size = DEFAULT_BUF_LENGTH; } if (!in_filename) { device_count = rtlsdr_get_device_count(); if (!device_count) { fprintf(stderr, "No supported devices found.\n"); if (!in_filename) exit(1); } if (!quiet_mode) { fprintf(stderr, "Found %d device(s):\n", device_count); for (i = 0; i < device_count; i++) { rtlsdr_get_device_usb_strings(i, vendor, product, serial); fprintf(stderr, " %d: %s, %s, SN: %s\n", i, vendor, product, serial); } fprintf(stderr, "\n"); fprintf(stderr, "Using device %d: %s\n", dev_index, rtlsdr_get_device_name(dev_index)); } r = rtlsdr_open(&dev, dev_index); if (r < 0) { fprintf(stderr, "Failed to open rtlsdr device #%d.\n", dev_index); exit(1); } #ifndef _WIN32 sigact.sa_handler = sighandler; sigemptyset(&sigact.sa_mask); sigact.sa_flags = 0; sigaction(SIGINT, &sigact, NULL); sigaction(SIGTERM, &sigact, NULL); sigaction(SIGQUIT, &sigact, NULL); sigaction(SIGPIPE, &sigact, NULL); #else SetConsoleCtrlHandler((PHANDLER_ROUTINE) sighandler, TRUE); #endif /* Set the sample rate */ r = rtlsdr_set_sample_rate(dev, samp_rate); if (r < 0) fprintf(stderr, "WARNING: Failed to set sample rate.\n"); else fprintf(stderr, "Sample rate set to %d.\n", rtlsdr_get_sample_rate(dev)); // Unfortunately, doesn't return real rate fprintf(stderr, "Bit detection level set to %d.\n", demod->level_limit); if (0 == gain) { /* Enable automatic gain */ r = rtlsdr_set_tuner_gain_mode(dev, 0); if (r < 0) fprintf(stderr, "WARNING: Failed to enable automatic gain.\n"); else fprintf(stderr, "Tuner gain set to Auto.\n"); } else { /* Enable manual gain */ r = rtlsdr_set_tuner_gain_mode(dev, 1); if (r < 0) fprintf(stderr, "WARNING: Failed to enable manual gain.\n"); /* Set the tuner gain */ r = rtlsdr_set_tuner_gain(dev, gain); if (r < 0) fprintf(stderr, "WARNING: Failed to set tuner gain.\n"); else fprintf(stderr, "Tuner gain set to %f dB.\n", gain / 10.0); } r = rtlsdr_set_freq_correction(dev, ppm_error); } if (out_filename) { if (strcmp(out_filename, "-") == 0) { /* Write samples to stdout */ demod->out_file = stdout; #ifdef _WIN32 _setmode(_fileno(stdin), _O_BINARY); #endif } else { if (access(out_filename, F_OK) == 0 && !overwrite_mode) { fprintf(stderr, "Output file %s already exists, exiting\n", out_filename); goto out; } demod->out_file = fopen(out_filename, "wb"); if (!demod->out_file) { fprintf(stderr, "Failed to open %s\n", out_filename); goto out; } } } if (demod->signal_grabber) demod->sg_buf = malloc(SIGNAL_GRABBER_BUFFER); if (in_filename) { int i = 0; unsigned char test_mode_buf[DEFAULT_BUF_LENGTH]; float test_mode_float_buf[DEFAULT_BUF_LENGTH]; if (strcmp(in_filename, "-") == 0) { /* read samples from stdin */ in_file = stdin; in_filename = "<stdin>"; } else { in_file = fopen(in_filename, "rb"); if (!in_file) { fprintf(stderr, "Opening file: %s failed!\n", in_filename); goto out; } } fprintf(stderr, "Test mode active. Reading samples from file: %s\n", in_filename); // Essential information (not quiet) if (!quiet_mode) { fprintf(stderr, "Input format: %s\n", (demod->debug_mode == 3) ? "cf32" : "uint8"); } sample_file_pos = 0.0; int n_read, cf32_tmp; do { if (demod->debug_mode == 3) { n_read = fread(test_mode_float_buf, sizeof(float), 131072, in_file); for(int n = 0; n < n_read; n++) { cf32_tmp = test_mode_float_buf[n]*127 + 127; if (cf32_tmp < 0) cf32_tmp = 0; else if (cf32_tmp > 255) cf32_tmp = 255; test_mode_buf[n] = (uint8_t)cf32_tmp; } } else { n_read = fread(test_mode_buf, 1, 131072, in_file); } if (n_read == 0) break; // rtlsdr_callback() will Segmentation Fault with len=0 rtlsdr_callback(test_mode_buf, n_read, demod); i++; sample_file_pos = (float)i * n_read / samp_rate; } while (n_read != 0); // Call a last time with cleared samples to ensure EOP detection memset(test_mode_buf, 128, DEFAULT_BUF_LENGTH); // 128 is 0 in unsigned data rtlsdr_callback(test_mode_buf, 131072, demod); // Why the magic value 131072? //Always classify a signal at the end of the file classify_signal(); if (!quiet_mode) { fprintf(stderr, "Test mode file issued %d packets\n", i); } exit(0); } /* Reset endpoint before we start reading from it (mandatory) */ r = rtlsdr_reset_buffer(dev); if (r < 0) fprintf(stderr, "WARNING: Failed to reset buffers.\n"); if (sync_mode) { if (!demod->out_file) { fprintf(stderr, "Specify an output file for sync mode.\n"); exit(0); } fprintf(stderr, "Reading samples in sync mode...\n"); uint8_t *buffer = malloc(out_block_size * sizeof (uint8_t)); time_t timestamp; while (!do_exit) { r = rtlsdr_read_sync(dev, buffer, out_block_size, &n_read); if (r < 0) { fprintf(stderr, "WARNING: sync read failed.\n"); break; } if ((bytes_to_read > 0) && (bytes_to_read < (uint32_t) n_read)) { n_read = bytes_to_read; do_exit = 1; } if (fwrite(buffer, 1, n_read, demod->out_file) != (size_t) n_read) { fprintf(stderr, "Short write, samples lost, exiting!\n"); break; } if ((uint32_t) n_read < out_block_size) { fprintf(stderr, "Short read, samples lost, exiting!\n"); break; } if (duration > 0) { time(×tamp); if (timestamp >= stop_time) { do_exit = 1; fprintf(stderr, "Time expired, exiting!\n"); } } if (bytes_to_read > 0) bytes_to_read -= n_read; } free(buffer); } else { if (frequencies == 0) { frequency[0] = DEFAULT_FREQUENCY; frequencies = 1; } else { time(&rawtime_old); } if (!quiet_mode) { fprintf(stderr, "Reading samples in async mode...\n"); } while (!do_exit) { /* Set the frequency */ r = rtlsdr_set_center_freq(dev, frequency[frequency_current]); if (r < 0) fprintf(stderr, "WARNING: Failed to set center freq.\n"); else fprintf(stderr, "Tuned to %u Hz.\n", rtlsdr_get_center_freq(dev)); r = rtlsdr_read_async(dev, rtlsdr_callback, (void *) demod, DEFAULT_ASYNC_BUF_NUMBER, out_block_size); do_exit_async = 0; frequency_current++; if (frequency_current > frequencies - 1) frequency_current = 0; } } if (do_exit) fprintf(stderr, "\nUser cancel, exiting...\n"); else fprintf(stderr, "\nLibrary error %d, exiting...\n", r); if (demod->out_file && (demod->out_file != stdout)) fclose(demod->out_file); for (i = 0; i < demod->r_dev_num; i++) free(demod->r_devs[i]); if (demod->signal_grabber) free(demod->sg_buf); free(demod); rtlsdr_close(dev); out: for (output_handler_t *output = output_handler; output; output = output->next) { if (output->aux_free) { output->aux_free(output->aux); } } return r >= 0 ? r : -r; }
int32_t dabStick::getVFOFrequency (void) { if (!open || !libraryLoaded) return defaultFrequency (); return (int32_t)rtlsdr_get_center_freq (device) - vfoOffset; }
uint32_t rtl_get_center_freq(rtl r) { return rtlsdr_get_center_freq(r->device); }
int main(int argc, char* argv[]) { int rv; async_started = 0; quit_please = 0; buffers_received = 0; signal(SIGINT, sighandler); printf("Opening output file...\n"); outf = fopen("rtlsdr_out.bin", "w"); if(outf == NULL) { printf("Error opening output file: %d.\nExiting.\n", errno); return 1; } rv = rtlsdr_get_device_count(); if(rv == 0) { printf("No RTL-SDR devices found, exiting.\n"); return 2; } printf("Found %d device(s).\n", rv); printf("Opening the first, '%s'...\n", rtlsdr_get_device_name(0)); rv = rtlsdr_open(&rtlsdr, 0); if(rv != 0) { printf("Error opening device: %d\nExiting.\n", rv); return 3; } printf("Setting frequency to 315MHz...\n"); rv = rtlsdr_set_center_freq(rtlsdr, 315000000); if(rv != 0) { printf("Error setting frequency: %d\nExiting.\n", rv); return 4; } printf("Frequency set to %uHz.\n", rtlsdr_get_center_freq(rtlsdr)); printf("Setting gain mode to automatic.\n"); rv = rtlsdr_set_tuner_gain_mode(rtlsdr, 0); if(rv != 0) { printf("Error setting gain mode: %d\nExiting.\n", rv); return 5; } printf("Gain currently set to %d.\n", rtlsdr_get_tuner_gain(rtlsdr)); printf("Setting sample rate to 240kHz...\n"); rv = rtlsdr_set_sample_rate(rtlsdr, 240000); if(rv != 0) { printf("Error setting sample rate: %d\nExiting.\n", rv); return 6; } printf("Sample rate set to %u.\n", rtlsdr_get_sample_rate(rtlsdr)); printf("Setting AGC on...\n"); rv = rtlsdr_set_agc_mode(rtlsdr, 1); if(rv != 0) { printf("Error setting AGC: %d\nExiting.\n", rv); return 7; } printf("Clearing buffer and streaming data...\n"); rv = rtlsdr_reset_buffer(rtlsdr); if(rv != 0) { printf("Error clearing buffer: %d\nExiting.\n", rv); return 8; } async_started = 1; rv = rtlsdr_read_async(rtlsdr, read_callback, NULL, 0, 0); if(rv != 0) { printf("Error setting up async streaming: %d\nExiting.\n", rv); return 9; } rtlsdr_cancel_async(rtlsdr); rtlsdr_close(rtlsdr); return 0; }
uint CRtlSdr::getFrequency() { if (!power) return 0; return rtlsdr_get_center_freq(dongle.dev); }