/* We read data using a thread, so the main thread only handles decoding * without caring about data acquisition. */ void *readerThreadEntryPoint(void *arg) { MODES_NOTUSED(arg); rtlsdr_read_async(Modes.dev, rtlsdrCallback, NULL, MODES_ASYNC_BUF_NUMBER, MODES_DATA_LEN); Modes.exit --; return NULL; }
static void * _rtl_thread_fn(void * arg) { rtl r = (rtl) arg; // this takes over thread rtlsdr_read_async(r->device, _rtl_read_async_callback, (void *) r, 0, 0); // async canceled, spin until we're supposed to exit while (_rtl_get_state(r) != RTL_EXITING) { usleep(0.01e6); } return NULL; }
void RTLSDRThread::run() { int res; m_running = true; m_startWaiter.wakeAll(); while(m_running) { if((res = rtlsdr_read_async(m_dev, &RTLSDRThread::callbackHelper, this, 32, BLOCKSIZE)) < 0) { qCritical("RTLSDRThread: async error: %s", strerror(errno)); break; } } m_running = false; }
void *readerThreadEntryPoint(void *arg) { MODES_NOTUSED(arg); start_cpu_timing(&reader_thread_start); // we accumulate in rtlsdrCallback() or readDataFromFile() if (Modes.filename == NULL) { while (!Modes.exit) { rtlsdr_read_async(Modes.dev, rtlsdrCallback, NULL, MODES_RTL_BUFFERS, MODES_RTL_BUF_SIZE); if (!Modes.exit) { log_with_timestamp("Warning: lost the connection to the RTLSDR device."); rtlsdr_close(Modes.dev); Modes.dev = NULL; do { sleep(5); log_with_timestamp("Trying to reconnect to the RTLSDR device.."); } while (!Modes.exit && modesInitRTLSDR() < 0); } } if (Modes.dev != NULL) { rtlsdr_close(Modes.dev); Modes.dev = NULL; } } else { readDataFromFile(); } // Wake the main thread (if it's still waiting) pthread_mutex_lock(&Modes.data_mutex); Modes.exit = 1; // just in case pthread_cond_signal(&Modes.data_cond); pthread_mutex_unlock(&Modes.data_mutex); #ifndef _WIN32 pthread_exit(NULL); #else return NULL; #endif }
// //========================================================================= // // We read data using a thread, so the main thread only handles decoding // without caring about data acquisition // void *readerThreadEntryPoint(void *arg) { MODES_NOTUSED(arg); if (Modes.filename == NULL) { rtlsdr_read_async(Modes.dev, rtlsdrCallback, NULL, MODES_ASYNC_BUF_NUMBER, MODES_ASYNC_BUF_SIZE); } else { readDataFromFile(); } // Signal to the other thread that new data is ready - dummy really so threads don't mutually lock pthread_cond_signal(&Modes.data_cond); pthread_mutex_unlock(&Modes.data_mutex); #ifndef _WIN32 pthread_exit(NULL); #else return NULL; #endif }
/* start grabber --------------------------------------------------------------- * start grabber of front end * args : none * return : int status 0:okay -1:failure *-----------------------------------------------------------------------------*/ extern int rtlsdr_start(void) { int ret; /* reset endpoint before we start reading from it (mandatory) */ ret=verbose_reset_buffer(dev); if (ret<0) { SDRPRINTF("error: failed to reset buffers\n"); return -1; } /* start stream and stay there until we kill the stream */ ret=rtlsdr_read_async(dev,stream_callback_rtlsdr, NULL,RTLSDR_ASYNC_BUF_NUMBER,2*RTLSDR_DATABUFF_SIZE); if (ret<0&&!sdrstat.stopflag) { SDRPRINTF("error: failed to read in async mode\n"); return -1; } return 0; }
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; }
int main(int argc, char **argv) { #ifndef _WIN32 struct sigaction sigact; #endif char *filename = NULL; int n_read; int r, opt; int gain = 0; int ppm_error = 0; int sync_mode = 0; FILE *file; uint8_t *buffer; int dev_index = 0; int dev_given = 0; uint32_t frequency = 100000000; uint32_t bandwidth = DEFAULT_BANDWIDTH; uint32_t samp_rate = DEFAULT_SAMPLE_RATE; uint32_t out_block_size = DEFAULT_BUF_LENGTH; while ((opt = getopt(argc, argv, "d:f:g:s:w:b:n:p:S")) != -1) { switch (opt) { case 'd': dev_index = verbose_device_search(optarg); dev_given = 1; break; case 'f': frequency = (uint32_t)atofs(optarg); break; case 'g': gain = (int)(atof(optarg) * 10); /* tenths of a dB */ break; case 's': samp_rate = (uint32_t)atofs(optarg); break; case 'w': bandwidth = (uint32_t)atofs(optarg); break; case 'p': ppm_error = atoi(optarg); break; case 'b': out_block_size = (uint32_t)atof(optarg); break; case 'n': bytes_to_read = (uint32_t)atof(optarg) * 2; break; case 'S': sync_mode = 1; break; default: usage(); break; } } if (argc <= optind) { usage(); } else { filename = argv[optind]; } 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; } buffer = malloc(out_block_size * sizeof(uint8_t)); if (!dev_given) { dev_index = verbose_device_search("0"); } if (dev_index < 0) { exit(1); } r = rtlsdr_open(&dev, (uint32_t)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 */ verbose_set_sample_rate(dev, samp_rate); /* Set the tuner bandwidth */ verbose_set_bandwidth(dev, bandwidth); /* Set the frequency */ verbose_set_frequency(dev, frequency); if (0 == gain) { /* Enable automatic gain */ verbose_auto_gain(dev); } else { /* Enable manual gain */ gain = nearest_gain(dev, gain); verbose_gain_set(dev, gain); } verbose_ppm_set(dev, ppm_error); if(strcmp(filename, "-") == 0) { /* Write samples to stdout */ file = stdout; #ifdef _WIN32 _setmode(_fileno(stdin), _O_BINARY); #endif } else { file = fopen(filename, "wb"); if (!file) { fprintf(stderr, "Failed to open %s\n", filename); goto out; } } /* Reset endpoint before we start reading from it (mandatory) */ verbose_reset_buffer(dev); if (sync_mode) { fprintf(stderr, "Reading samples in sync mode...\n"); 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, 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 (bytes_to_read > 0) bytes_to_read -= n_read; } } else { fprintf(stderr, "Reading samples in async mode...\n"); r = rtlsdr_read_async(dev, rtlsdr_callback, (void *)file, 0, out_block_size); } if (do_exit) fprintf(stderr, "\nUser cancel, exiting...\n"); else fprintf(stderr, "\nLibrary error %d, exiting...\n", r); if (file != stdout) fclose(file); rtlsdr_close(dev); free (buffer); out: return r >= 0 ? r : -r; }
int main(int argc, char **argv) { #ifndef _WIN32 struct sigaction sigact; #endif struct fm_state fm; char *filename = NULL; int n_read, r, opt, wb_mode = 0; int i, gain = AUTO_GAIN; // tenths of a dB uint8_t *buffer; uint32_t dev_index = 0; int device_count; int ppm_error = 0; char vendor[256], product[256], serial[256]; fm_init(&fm); // 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) { switch (opt) { case 'd': dev_index = atoi(optarg); break; case 'f': if (strchr(optarg, ':')) {frequency_range(&fm, optarg);} else { fm.freqs[fm.freq_len] = (uint32_t)atofs(optarg); fm.freq_len++; } break; case 'g': gain = (int)(atof(optarg) * 10); break; case 'l': fm.squelch_level = (int)atof(optarg); break; case 's': fm.sample_rate = (uint32_t)atofs(optarg); break; case 'r': fm.output_rate = (int)atofs(optarg); break; case 'o': fm.post_downsample = (int)atof(optarg); if (fm.post_downsample < 1 || fm.post_downsample > MAXIMUM_OVERSAMPLE) { fprintf(stderr, "Oversample must be between 1 and %i\n", MAXIMUM_OVERSAMPLE);} break; case 't': fm.conseq_squelch = (int)atof(optarg); if (fm.conseq_squelch < 0) { fm.conseq_squelch = -fm.conseq_squelch; fm.terminate_on_squelch = 1; } break; case 'p': ppm_error = atoi(optarg); break; case 'E': fm.edge = 1; break; case 'F': fm.fir_enable = 1; break; case 'A': if (strcmp("std", optarg) == 0) { fm.custom_atan = 0;} if (strcmp("fast", optarg) == 0) { fm.custom_atan = 1;} if (strcmp("lut", optarg) == 0) { atan_lut_init(); fm.custom_atan = 2;} break; case 'D': fm.deemph = 1; break; case 'C': fm.dc_block = 1; break; case 'N': fm.mode_demod = &fm_demod; break; case 'W': wb_mode = 1; fm.mode_demod = &fm_demod; fm.sample_rate = 170000; fm.output_rate = 32000; fm.custom_atan = 1; fm.post_downsample = 4; fm.deemph = 1; fm.squelch_level = 0; break; case 'M': fm.mode_demod = &am_demod; break; case 'U': fm.mode_demod = &usb_demod; break; case 'L': fm.mode_demod = &lsb_demod; break; case 'R': fm.mode_demod = &raw_demod; break; default: usage(); break; } } /* quadruple sample_rate to limit to Δθ to ±π/2 */ fm.sample_rate *= fm.post_downsample; if (fm.freq_len == 0) { fprintf(stderr, "Please specify a frequency.\n"); exit(1); } if (fm.freq_len > 1) { fm.terminate_on_squelch = 0; } if (argc <= optind) { //usage(); filename = "-"; } else { filename = argv[optind]; } buffer = malloc(lcm_post[fm.post_downsample] * DEFAULT_BUF_LENGTH * sizeof(uint8_t)); device_count = rtlsdr_get_device_count(); if (!device_count) { fprintf(stderr, "No supported devices found.\n"); exit(1); } 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 /* WBFM is special */ if (wb_mode) { fm.freqs[0] += 16000; } if (fm.deemph) { fm.deemph_a = (int)round(1.0/((1.0-exp(-1.0/(fm.output_rate * 75e-6))))); } optimal_settings(&fm, 0, 0); build_fir(&fm); /* Set the tuner gain */ if (gain == AUTO_GAIN) { r = rtlsdr_set_tuner_gain_mode(dev, 0); } else { r = rtlsdr_set_tuner_gain_mode(dev, 1); r = rtlsdr_set_tuner_gain(dev, gain); } if (r != 0) { fprintf(stderr, "WARNING: Failed to set tuner gain.\n"); } else if (gain == AUTO_GAIN) { fprintf(stderr, "Tuner gain set to automatic.\n"); } else { fprintf(stderr, "Tuner gain set to %0.2f dB.\n", gain/10.0); } r = rtlsdr_set_freq_correction(dev, ppm_error); if (strcmp(filename, "-") == 0) { /* Write samples to stdout */ fm.file = stdout; #ifdef _WIN32 _setmode(_fileno(fm.file), _O_BINARY); #endif } else { fm.file = fopen(filename, "wb"); if (!fm.file) { fprintf(stderr, "Failed to open %s\n", filename); exit(1); } } /* 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");} pthread_create(&demod_thread, NULL, demod_thread_fn, (void *)(&fm)); rtlsdr_read_async(dev, rtlsdr_callback, (void *)(&fm), DEFAULT_ASYNC_BUF_NUMBER, lcm_post[fm.post_downsample] * DEFAULT_BUF_LENGTH); if (do_exit) { fprintf(stderr, "\nUser cancel, exiting...\n");} else { fprintf(stderr, "\nLibrary error %d, exiting...\n", r);} rtlsdr_cancel_async(dev); // pthread_mutex_destroy(&data_ready); // pthread_mutex_destroy(&data_write); if (fm.file != stdout) { fclose(fm.file);} rtlsdr_close(dev); free(fm.buf); free (buffer); return r >= 0 ? r : -r; }
int main(int argc, char **argv) { struct sigaction sigact; char *filename = NULL; int r, opt; int i, gain = AUTO_GAIN; /* tenths of a dB */ int dev_index = 0; int dev_given = 0; int ppm_error = 0; int custom_ppm = 0; int left_freq = 161975000; int right_freq = 162025000; int sample_rate = 12000; int output_rate = 48000; int dongle_freq, dongle_rate, delta; int edge = 0; pthread_cond_init(&ready, NULL); pthread_mutex_init(&ready_m, NULL); while ((opt = getopt(argc, argv, "l:r:s:o:EODd:g:p:h")) != -1) { switch (opt) { case 'l': left_freq = (int)atofs(optarg); break; case 'r': right_freq = (int)atofs(optarg); break; case 's': sample_rate = (int)atofs(optarg); break; case 'o': output_rate = (int)atofs(optarg); break; case 'E': edge = !edge; break; case 'D': dc_filter = !dc_filter; break; case 'O': oversample = !oversample; break; case 'd': dev_index = verbose_device_search(optarg); dev_given = 1; break; case 'g': gain = (int)(atof(optarg) * 10); break; case 'p': ppm_error = atoi(optarg); custom_ppm = 1; break; case 'h': default: usage(); return 2; } } if (argc <= optind) { filename = "-"; } else { filename = argv[optind]; } if (left_freq > right_freq) { usage(); return 2; } /* precompute rates */ dongle_freq = left_freq/2 + right_freq/2; if (edge) { dongle_freq -= sample_rate/2;} delta = right_freq - left_freq; if (delta > 1.2e6) { fprintf(stderr, "Frequencies may be at most 1.2MHz apart."); exit(1); } if (delta < 0) { fprintf(stderr, "Left channel must be lower than right channel."); exit(1); } i = (int)log2(2.4e6 / delta); dongle_rate = delta * (1<<i); both.rate_in = dongle_rate; both.rate_out = delta * 2; i = (int)log2(both.rate_in/both.rate_out); both.downsample_passes = i; both.downsample = 1 << i; left.rate_in = both.rate_out; i = (int)log2(left.rate_in / sample_rate); left.downsample_passes = i; left.downsample = 1 << i; left.rate_out = left.rate_in / left.downsample; right.rate_in = left.rate_in; right.rate_out = left.rate_out; right.downsample = left.downsample; right.downsample_passes = left.downsample_passes; if (left.rate_out > output_rate) { fprintf(stderr, "Channel bandwidth too high or output bandwidth too low."); exit(1); } stereo.rate = output_rate; if (edge) { fprintf(stderr, "Edge tuning enabled.\n"); } else { fprintf(stderr, "Edge tuning disabled.\n"); } if (dc_filter) { fprintf(stderr, "DC filter enabled.\n"); } else { fprintf(stderr, "DC filter disabled.\n"); } fprintf(stderr, "Buffer size: %0.2f mS\n", 1000 * (double)DEFAULT_BUF_LENGTH / (double)dongle_rate); fprintf(stderr, "Downsample factor: %i\n", both.downsample * left.downsample); fprintf(stderr, "Low pass: %i Hz\n", left.rate_out); fprintf(stderr, "Output: %i Hz\n", output_rate); /* precompute lengths */ both.len_in = DEFAULT_BUF_LENGTH; both.len_out = both.len_in / both.downsample; left.len_in = both.len_out; right.len_in = both.len_out; left.len_out = left.len_in / left.downsample; right.len_out = right.len_in / right.downsample; left_demod.buf_len = left.len_out; left_demod.result_len = left_demod.buf_len / 2; right_demod.buf_len = left_demod.buf_len; right_demod.result_len = left_demod.result_len; stereo.bl_len = (int)((long)(DEFAULT_BUF_LENGTH/2) * (long)output_rate / (long)dongle_rate); stereo.br_len = stereo.bl_len; stereo.result_len = stereo.br_len * 2; stereo.rate = output_rate; if (!dev_given) { dev_index = verbose_device_search("0"); } if (dev_index < 0) { exit(1); } downsample_init(&both); downsample_init(&left); downsample_init(&right); demod_init(&left_demod); demod_init(&right_demod); stereo_init(&stereo); r = rtlsdr_open(&dev, (uint32_t)dev_index); if (r < 0) { fprintf(stderr, "Failed to open rtlsdr device #%d.\n", dev_index); exit(1); } 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); if (strcmp(filename, "-") == 0) { /* Write samples to stdout */ file = stdout; setvbuf(stdout, NULL, _IONBF, 0); } else { file = fopen(filename, "wb"); if (!file) { fprintf(stderr, "Failed to open %s\n", filename); exit(1); } } /* Set the tuner gain */ if (gain == AUTO_GAIN) { verbose_auto_gain(dev); } else { gain = nearest_gain(dev, gain); verbose_gain_set(dev, gain); } if (!custom_ppm) { verbose_ppm_eeprom(dev, &ppm_error); } verbose_ppm_set(dev, ppm_error); //r = rtlsdr_set_agc_mode(dev, 1); /* Set the tuner frequency */ verbose_set_frequency(dev, dongle_freq); /* Set the sample rate */ verbose_set_sample_rate(dev, dongle_rate); /* Reset endpoint before we start reading from it (mandatory) */ verbose_reset_buffer(dev); pthread_create(&demod_thread, NULL, demod_thread_fn, (void *)(NULL)); rtlsdr_read_async(dev, rtlsdr_callback, (void *)(NULL), DEFAULT_ASYNC_BUF_NUMBER, DEFAULT_BUF_LENGTH); if (do_exit) { fprintf(stderr, "\nUser cancel, exiting...\n");} else { fprintf(stderr, "\nLibrary error %d, exiting...\n", r);} rtlsdr_cancel_async(dev); safe_cond_signal(&ready, &ready_m); pthread_cond_destroy(&ready); pthread_mutex_destroy(&ready_m); if (file != stdout) { fclose(file);} rtlsdr_close(dev); return r >= 0 ? r : -r; }
int main(int argc, char **argv) { #ifndef _WIN32 struct sigaction sigact; #endif char *filename = NULL; int n_read; int r, opt; int i, gain = 0; int sync_mode = 0; FILE *file; uint8_t *buffer; uint32_t dev_index = 0; uint32_t udp_port = 6666; uint32_t frequency = 100000000; uint32_t samp_rate = DEFAULT_SAMPLE_RATE; uint32_t out_block_size = DEFAULT_BUF_LENGTH; int device_count; char vendor[256], product[256], serial[256]; while ((opt = getopt(argc, argv, "d:p:f:g:s:b:n:S::")) != -1) { switch (opt) { case 'd': dev_index = atoi(optarg); break; case 'p': udp_port = atoi(optarg); break; case 'f': frequency = (uint32_t)atof(optarg); break; case 'g': gain = (int)(atof(optarg) * 10); /* tenths of a dB */ break; case 's': samp_rate = (uint32_t)atof(optarg); break; case 'b': out_block_size = (uint32_t)atof(optarg); break; case 'n': bytes_to_read = (uint32_t)atof(optarg) * 2; break; case 'S': sync_mode = 1; break; default: usage(); break; } } if (argc <= optind) { usage(); } else { filename = argv[optind]; } 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; } buffer = malloc(out_block_size * sizeof(uint8_t)); device_count = rtlsdr_get_device_count(); if (!device_count) { fprintf(stderr, "No supported devices found.\n"); exit(1); } 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)); //-------------------------------------------------- fd = socket(AF_INET,SOCK_DGRAM,0); if(fd==-1) { perror("socket"); exit(-1); } fprintf(stderr, "create socket OK!\n"); //create an send address addr.sin_family = AF_INET; addr.sin_port = htons(udp_port); addr.sin_addr.s_addr=inet_addr("127.0.0.1"); fprintf(stderr, "127.0.0.1:%u\n", udp_port); //-------------------------------------------------- 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"); /* Set the frequency */ r = rtlsdr_set_center_freq(dev, frequency); if (r < 0) fprintf(stderr, "WARNING: Failed to set center freq.\n"); else fprintf(stderr, "Tuned to %u Hz.\n", frequency); 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 { /* 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); } if(strcmp(filename, "-") == 0) { /* Write samples to stdout */ file = stdout; #ifdef _WIN32 _setmode(_fileno(stdin), _O_BINARY); #endif } else { file = fopen(filename, "wb"); if (!file) { fprintf(stderr, "Failed to open %s\n", filename); goto out; } } /* 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) { fprintf(stderr, "Reading samples in sync mode...\n"); 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, 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 (bytes_to_read > 0) bytes_to_read -= n_read; } } else { fprintf(stderr, "Reading samples in async mode...\n"); r = rtlsdr_read_async(dev, rtlsdr_callback, (void *)file, DEFAULT_ASYNC_BUF_NUMBER, out_block_size); } if (do_exit) fprintf(stderr, "\nUser cancel, exiting...\n"); else fprintf(stderr, "\nLibrary error %d, exiting...\n", r); if (file != stdout) fclose(file); rtlsdr_close(dev); free (buffer); close(fd); out: return r >= 0 ? r : -r; }
// read_async exists to avoid having to pass a void* for context when we really just want an integer. // Go's GC rules mean that there shouldn't be pointers in uintptr and vice versa in Go code. Find in C though. int read_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, intptr_t ctx, uint32_t buf_num, uint32_t buf_len) { return rtlsdr_read_async(dev, cb, (void*)ctx, buf_num, buf_len); }
int main(int argc, char **argv) { #ifndef _WIN32 struct sigaction sigact; #endif int n_read; int r, opt; int i, tuner_benchmark = 0; int sync_mode = 0; uint8_t *buffer; uint32_t dev_index = 0; uint32_t samp_rate = DEFAULT_SAMPLE_RATE; uint32_t out_block_size = DEFAULT_BUF_LENGTH; int device_count; int count; int gains[100]; int real_rate; int64_t ns; while ((opt = getopt(argc, argv, "d:s:b:tpS::")) != -1) { switch (opt) { case 'd': dev_index = atoi(optarg); break; case 's': samp_rate = (uint32_t)atof(optarg); break; case 'b': out_block_size = (uint32_t)atof(optarg); break; case 't': tuner_benchmark = 1; break; case 'p': ppm_benchmark = PPM_DURATION; break; case 'S': sync_mode = 1; break; default: usage(); break; } } 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; } buffer = malloc(out_block_size * sizeof(uint8_t)); device_count = rtlsdr_get_device_count(); if (!device_count) { fprintf(stderr, "No supported devices found.\n"); exit(1); } fprintf(stderr, "Found %d device(s):\n", device_count); for (i = 0; i < device_count; i++) fprintf(stderr, " %d: %s\n", i, rtlsdr_get_device_name(i)); 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 count = rtlsdr_get_tuner_gains(dev, NULL); fprintf(stderr, "Supported gain values (%d): ", count); count = rtlsdr_get_tuner_gains(dev, gains); for (i = 0; i < count; i++) fprintf(stderr, "%.1f ", gains[i] / 10.0); fprintf(stderr, "\n"); /* Set the sample rate */ r = rtlsdr_set_sample_rate(dev, samp_rate); if (r < 0) fprintf(stderr, "WARNING: Failed to set sample rate.\n"); if (tuner_benchmark) { if (rtlsdr_get_tuner_type(dev) == RTLSDR_TUNER_E4000) e4k_benchmark(); else fprintf(stderr, "No E4000 tuner found, aborting.\n"); goto exit; } /* Enable test mode */ r = rtlsdr_set_testmode(dev, 1); /* 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 (ppm_benchmark && !sync_mode) { fprintf(stderr, "Reporting PPM error measurement every %i seconds...\n", ppm_benchmark); fprintf(stderr, "Press ^C after a few minutes.\n"); #ifdef __APPLE__ gettimeofday(&tv, NULL); ppm_recent.tv_sec = tv.tv_sec; ppm_recent.tv_nsec = tv.tv_usec*1000; ppm_start.tv_sec = tv.tv_sec; ppm_start.tv_nsec = tv.tv_usec*1000; #elif __unix__ clock_gettime(CLOCK_REALTIME, &ppm_recent); clock_gettime(CLOCK_REALTIME, &ppm_start); #endif } if (!ppm_benchmark) { fprintf(stderr, "\nInfo: This tool will continuously" " read from the device, and report if\n" "samples get lost. If you observe no " "further output, everything is fine.\n\n"); } if (sync_mode) { fprintf(stderr, "Reading samples in sync mode...\n"); 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 ((uint32_t)n_read < out_block_size) { fprintf(stderr, "Short read, samples lost, exiting!\n"); break; } } } else { fprintf(stderr, "Reading samples in async mode...\n"); r = rtlsdr_read_async(dev, rtlsdr_callback, NULL, DEFAULT_ASYNC_BUF_NUMBER, out_block_size); } if (do_exit) { fprintf(stderr, "\nUser cancel, exiting...\n"); if (ppm_benchmark) { #ifndef _WIN32 ns = 1000000000L * (int64_t)(ppm_recent.tv_sec - ppm_start.tv_sec); ns += (int64_t)(ppm_recent.tv_nsec - ppm_start.tv_nsec); real_rate = (int)(ppm_total * 1000000000L / ns); printf("Cumulative PPM error: %i\n", (int)round((double)(1000000 * (real_rate - (int)samp_rate)) / (double)samp_rate)); #endif } } else fprintf(stderr, "\nLibrary error %d, exiting...\n", r); exit: rtlsdr_close(dev); free (buffer); return r >= 0 ? r : -r; }
int main (int argc, char **argv) { struct sigaction sigact; uint32_t dev_index = 0; int32_t device_count; int i,r; char vendor[256], product[256], serial[256]; uint32_t samp_rate = 2048000; int gain = AUTO_GAIN; dab_state dab; if (argc > 1) { dab.frequency = atoi(argv[1]); } else { //dab.frequency = 220352000; dab.frequency = 222064000; } //fprintf(stderr,"%i\n",dab.frequency); fprintf(stderr,"\n"); fprintf(stderr,"rtldab %s \n",VERSION); fprintf(stderr,"build: %s %s\n", __DATE__,__TIME__); fprintf(stderr,"\n"); fprintf(stderr," _____ _______ _ _____ ____ \n"); fprintf(stderr," | __ \\__ __| | | __ \\ /\\ | _ \\ \n"); fprintf(stderr," | |__) | | | | | | | | | / \\ | |_) |\n"); fprintf(stderr," | _ / | | | | | | | |/ /\\ \\ | _ < \n"); fprintf(stderr," | | \\ \\ | | | |____| |__| / ____ \\| |_) |\n"); fprintf(stderr," |_| \\_\\ |_| |______|_____/_/ \\_\\____/ \n"); fprintf(stderr,"\n"); fprintf(stderr,"\n\nrtl-dab Copyright (C) 2012 David May \n"); fprintf(stderr,"This program comes with ABSOLUTELY NO WARRANTY\n"); fprintf(stderr,"This is free software, and you are welcome to\n"); fprintf(stderr,"redistribute it under certain conditions\n\n\n"); fprintf(stderr,"--------------------------------\n"); fprintf(stderr,"Many thanks to the osmocom team!\n"); fprintf(stderr,"--------------------------------\n\n"); /*--------------------------------------------------- Looking for device and open connection ----------------------------------------------------*/ device_count = rtlsdr_get_device_count(); if (!device_count) { fprintf(stderr, "No supported devices found.\n"); exit(1); } 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); } /*------------------------------------------------- Set Frequency & Sample Rate --------------------------------------------------*/ /* Set the sample rate */ r = rtlsdr_set_sample_rate(dev, samp_rate); if (r < 0) fprintf(stderr, "WARNING: Failed to set sample rate.\n"); /* Set the frequency */ r = rtlsdr_set_center_freq(dev, dab.frequency); if (r < 0) fprintf(stderr, "WARNING: Failed to set center freq.\n"); else fprintf(stderr, "Tuned to %u Hz.\n", dab.frequency); /*------------------------------------------------ Setting gain -------------------------------------------------*/ if (gain == AUTO_GAIN) { r = rtlsdr_set_tuner_gain_mode(dev, 0); } else { r = rtlsdr_set_tuner_gain_mode(dev, 1); r = rtlsdr_set_tuner_gain(dev, gain); } if (r != 0) { fprintf(stderr, "WARNING: Failed to set tuner gain.\n"); } else if (gain == AUTO_GAIN) { fprintf(stderr, "Tuner gain set to automatic.\n"); } else { fprintf(stderr, "Tuner gain set to %0.2f dB.\n", gain/10.0); } /*----------------------------------------------- / Reset endpoint (mandatory) ------------------------------------------------*/ r = rtlsdr_reset_buffer(dev); /*----------------------------------------------- / Signal handler ------------------------------------------------*/ 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); /*----------------------------------------------- / start demod thread & rtl read -----------------------------------------------*/ dab_demod_init(&dab); dab_fic_parser_init(&sinfo); dab_analyzer_init(&ana); pthread_create(&demod_thread, NULL, demod_thread_fn, (void *)(&dab)); rtlsdr_read_async(dev, rtlsdr_callback, (void *)(&dab), DEFAULT_ASYNC_BUF_NUMBER, DEFAULT_BUF_LENGTH); if (do_exit) { fprintf(stderr, "\nUser cancel, exiting...\n");} else { fprintf(stderr, "\nLibrary error %d, exiting...\n", r);} rtlsdr_cancel_async(dev); //dab_demod_close(&dab); rtlsdr_close(dev); return 1; }
/* Thread for RX blocking function */ static void *rtlsdr_rx(void *arg) { /* Read & blocking call */ rtlsdr_read_async(rtl_device, rtlsdr_callback, NULL, 0, DEFAULT_BUF_LENGTH); exit(0); return 0; }
int main(int argc, char **argv) { #ifndef _WIN32 struct sigaction sigact; #endif struct fm_state fm; char *filename = NULL; int n_read; int r, opt; int i, gain = AUTO_GAIN; // tenths of a dB uint8_t *buffer; uint32_t dev_index = 0; int device_count; char vendor[256], product[256], serial[256]; fm.freqs[0] = 100000000; fm.sample_rate = DEFAULT_SAMPLE_RATE; fm.squelch_level = 150; fm.term_squelch_hits = 0; fm.freq_len = 0; fm.edge = 0; fm.fir_enable = 0; fm.prev_index = -1; fm.post_downsample = 1; // once this works, default = 4 fm.custom_atan = 0; sem_init(&data_ready, 0, 0); while ((opt = getopt(argc, argv, "d:f:g:s:b:l:o:t:EFA")) != -1) { switch (opt) { case 'd': dev_index = atoi(optarg); break; case 'f': fm.freqs[fm.freq_len] = (uint32_t)atof(optarg); fm.freq_len++; break; case 'g': gain = (int)(atof(optarg) * 10); break; case 'l': fm.squelch_level = (int)atof(optarg); break; case 's': fm.sample_rate = (uint32_t)atof(optarg); break; case 'o': fm.post_downsample = (int)atof(optarg); break; case 't': fm.term_squelch_hits = (int)atof(optarg); break; case 'E': fm.edge = 1; break; case 'F': fm.fir_enable = 1; break; case 'A': fm.custom_atan = 1; break; default: usage(); break; } } /* quadruple sample_rate to limit to Δθ to ±π/2 */ fm.sample_rate *= fm.post_downsample; if (argc <= optind) { usage(); } else { filename = argv[optind]; } buffer = malloc(DEFAULT_BUF_LENGTH * sizeof(uint8_t)); device_count = rtlsdr_get_device_count(); if (!device_count) { fprintf(stderr, "No supported devices found.\n"); exit(1); } 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 optimal_settings(&fm, 0, 0); build_fir(&fm); /* Set the tuner gain */ if (gain == AUTO_GAIN) { r = rtlsdr_set_tuner_gain_mode(dev, 0); } else { r = rtlsdr_set_tuner_gain_mode(dev, 1); r = rtlsdr_set_tuner_gain(dev, gain); } if (r != 0) { fprintf(stderr, "WARNING: Failed to set tuner gain.\n"); } else if (gain == AUTO_GAIN) { fprintf(stderr, "Tuner gain set to automatic.\n"); } else { fprintf(stderr, "Tuner gain set to %0.2f dB.\n", gain/10.0); } if (strcmp(filename, "-") == 0) { /* Write samples to stdout */ fm.file = stdout; } else { fm.file = fopen(filename, "wb"); if (!fm.file) { fprintf(stderr, "Failed to open %s\n", filename); exit(1); } } /* 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");} pthread_create(&demod_thread, NULL, demod_thread_fn, (void *)(&fm)); rtlsdr_read_async(dev, rtlsdr_callback, (void *)(&fm), DEFAULT_ASYNC_BUF_NUMBER, DEFAULT_BUF_LENGTH); if (do_exit) { fprintf(stderr, "\nUser cancel, exiting...\n");} else { fprintf(stderr, "\nLibrary error %d, exiting...\n", r);} rtlsdr_cancel_async(dev); if (fm.file != stdout) fclose(fm.file); rtlsdr_close(dev); free (buffer); return r >= 0 ? r : -r; }
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; }
static void *dongle_thread_fn(void *arg) { CRtlSdr *s = (CRtlSdr*)arg; rtlsdr_read_async(s->dongle.dev, rtlsdr_callback, (void*)arg, 0, s->dongle.buf_len); return 0; }
int main(int argc, char **argv) { #ifndef _WIN32 struct sigaction sigact; #endif int n_read, r, opt, i; int sync_mode = 0; uint8_t *buffer; int dev_index = 0; int dev_given = 0; uint32_t out_block_size = DEFAULT_BUF_LENGTH; int count; int gains[100]; while ((opt = getopt(argc, argv, "d:s:b:tp::Sh")) != -1) { switch (opt) { case 'd': dev_index = verbose_device_search(optarg); dev_given = 1; break; case 's': samp_rate = (uint32_t)atof(optarg); break; case 'b': out_block_size = (uint32_t)atof(optarg); break; case 't': test_mode = TUNER_BENCHMARK; break; case 'p': test_mode = PPM_BENCHMARK; if (optarg) ppm_duration = atoi(optarg); break; case 'S': sync_mode = 1; break; case 'h': default: usage(); break; } } 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; } buffer = malloc(out_block_size * sizeof(uint8_t)); if (!dev_given) { dev_index = verbose_device_search("0"); } if (dev_index < 0) { exit(1); } r = rtlsdr_open(&dev, (uint32_t)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 count = rtlsdr_get_tuner_gains(dev, NULL); fprintf(stderr, "Supported gain values (%d): ", count); count = rtlsdr_get_tuner_gains(dev, gains); for (i = 0; i < count; i++) fprintf(stderr, "%.1f ", gains[i] / 10.0); fprintf(stderr, "\n"); /* Set the sample rate */ verbose_set_sample_rate(dev, samp_rate); if (test_mode == TUNER_BENCHMARK) { tuner_benchmark(); goto exit; } /* Enable test mode */ r = rtlsdr_set_testmode(dev, 1); /* Reset endpoint before we start reading from it (mandatory) */ verbose_reset_buffer(dev); if ((test_mode == PPM_BENCHMARK) && !sync_mode) { fprintf(stderr, "Reporting PPM error measurement every %i seconds...\n", ppm_duration); fprintf(stderr, "Press ^C after a few minutes.\n"); } if (test_mode == NO_BENCHMARK) { fprintf(stderr, "\nInfo: This tool will continuously" " read from the device, and report if\n" "samples get lost. If you observe no " "further output, everything is fine.\n\n"); } if (sync_mode) { fprintf(stderr, "Reading samples in sync mode...\n"); fprintf(stderr, "(Samples are being lost but not reported.)\n"); 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 ((uint32_t)n_read < out_block_size) { fprintf(stderr, "Short read, samples lost, exiting!\n"); break; } underrun_test(buffer, n_read, 1); } } else { fprintf(stderr, "Reading samples in async mode...\n"); r = rtlsdr_read_async(dev, rtlsdr_callback, NULL, 0, out_block_size); } if (do_exit) { fprintf(stderr, "\nUser cancel, exiting...\n"); fprintf(stderr, "Samples per million lost (minimum): %i\n", (int)(1000000L * dropped_samples / total_samples)); } else fprintf(stderr, "\nLibrary error %d, exiting...\n", r); exit: rtlsdr_close(dev); free (buffer); return r >= 0 ? r : -r; }
static int do_sdr_decode(struct dab_state_t* dab, int frequency, int gain) { struct sigaction sigact; uint32_t dev_index = 0; int32_t device_count; int i,r; char vendor[256], product[256], serial[256]; uint32_t samp_rate = 2048000; memset(&sdr,0,sizeof(struct sdr_state_t)); sdr.frequency = frequency; //fprintf(stderr,"%i\n",sdr.frequency); /*--------------------------------------------------- Looking for device and open connection ----------------------------------------------------*/ device_count = rtlsdr_get_device_count(); if (!device_count) { fprintf(stderr, "No supported devices found.\n"); exit(1); } 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); } int gains[100]; int count = rtlsdr_get_tuner_gains(dev, gains); fprintf(stderr, "Supported gain values (%d): ", count); for (i = 0; i < count; i++) fprintf(stderr, "%.1f ", gains[i] / 10.0); fprintf(stderr, "\n"); /*------------------------------------------------- Set Frequency & Sample Rate --------------------------------------------------*/ /* Set the sample rate */ r = rtlsdr_set_sample_rate(dev, samp_rate); if (r < 0) fprintf(stderr, "WARNING: Failed to set sample rate.\n"); /* Set the frequency */ r = rtlsdr_set_center_freq(dev, sdr.frequency); if (r < 0) fprintf(stderr, "WARNING: Failed to set center freq.\n"); else fprintf(stderr, "Tuned to %u Hz.\n", sdr.frequency); /*------------------------------------------------ Setting gain -------------------------------------------------*/ if (gain == AUTO_GAIN) { r = rtlsdr_set_tuner_gain_mode(dev, 0); } else { r = rtlsdr_set_tuner_gain_mode(dev, 1); r = rtlsdr_set_tuner_gain(dev, gain); } if (r != 0) { fprintf(stderr, "WARNING: Failed to set tuner gain.\n"); } else if (gain == AUTO_GAIN) { fprintf(stderr, "Tuner gain set to automatic.\n"); } else { fprintf(stderr, "Tuner gain set to %0.2f dB.\n", gain/10.0); } /*----------------------------------------------- / Reset endpoint (mandatory) ------------------------------------------------*/ r = rtlsdr_reset_buffer(dev); /*----------------------------------------------- / Signal handler ------------------------------------------------*/ 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); /*----------------------------------------------- / start demod thread & rtl read -----------------------------------------------*/ fprintf(stderr,"Waiting for sync...\n"); sdr_init(&sdr); //dab_fic_parser_init(&sinfo); //dab_analyzer_init(&ana); pthread_create(&demod_thread, NULL, demod_thread_fn, (void *)(dab)); rtlsdr_read_async(dev, rtlsdr_callback, (void *)(&sdr), DEFAULT_ASYNC_BUF_NUMBER, DEFAULT_BUF_LENGTH); if (do_exit) { fprintf(stderr, "\nUser cancel, exiting...\n");} else { fprintf(stderr, "\nLibrary error %d, exiting...\n", r);} rtlsdr_cancel_async(dev); //dab_demod_close(&dab); rtlsdr_close(dev); return 1; }
// tz this is the thread where actual device reads take place // well actually they happen in the callback // static void *dongle_thread_fn(void *arg) { struct dongle_state *s = arg; rtlsdr_read_async(s->dev, rtlsdr_callback, s, 0, s->buf_len); return 0; }
static int do_sdr_decode(struct dab_state_t* dab, int frequency, int gain) { struct sigaction sigact; uint32_t dev_index = 0; int32_t device_count; int i,r; char vendor[256], product[256], serial[256]; uint32_t samp_rate = 2048000; memset(&sdr,0,sizeof(struct sdr_state_t)); sdr.frequency = frequency; //fprintf(stderr,"%i\n",sdr.frequency); /*--------------------------------------------------- Looking for device and open connection ----------------------------------------------------*/ if (dab->device_type == DAB_DEVICE_RTLSDR) { sdr.convert_unsigned = 1; device_count = rtlsdr_get_device_count(); if (!device_count) { fprintf(stderr, "No supported devices found.\n"); exit(1); } 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); } int gains[100]; int count = rtlsdr_get_tuner_gains(dev, gains); fprintf(stderr, "Supported gain values (%d): ", count); for (i = 0; i < count; i++) fprintf(stderr, "%.1f ", gains[i] / 10.0); fprintf(stderr, "\n"); } else if (dab->device_type == DAB_DEVICE_HACKRF) { sdr.convert_unsigned = 0; r = hackrf_init(); if( r != HACKRF_SUCCESS ) { hackrf_err("hackrf_init() failed", r); return EXIT_FAILURE; } const char* serial_number = nullptr; r = hackrf_open_by_serial(serial_number, &hackrf); if( r != HACKRF_SUCCESS ) { hackrf_err("hackrf_open() failed", r); return EXIT_FAILURE; } } else { r = -1; return EXIT_FAILURE; } /*------------------------------------------------- Set Frequency & Sample Rate --------------------------------------------------*/ if (dab->device_type == DAB_DEVICE_RTLSDR) { /* Set the sample rate */ r = rtlsdr_set_sample_rate(dev, samp_rate); if (r < 0) fprintf(stderr, "WARNING: Failed to set sample rate.\n"); /* Set the frequency */ r = rtlsdr_set_center_freq(dev, sdr.frequency); if (r < 0) fprintf(stderr, "WARNING: Failed to set center freq.\n"); else fprintf(stderr, "Tuned to %u Hz.\n", sdr.frequency); /*------------------------------------------------ Setting gain -------------------------------------------------*/ if (gain == AUTO_GAIN) { r = rtlsdr_set_tuner_gain_mode(dev, 0); } else { r = rtlsdr_set_tuner_gain_mode(dev, 1); r = rtlsdr_set_tuner_gain(dev, gain); } if (r != 0) { fprintf(stderr, "WARNING: Failed to set tuner gain.\n"); } else if (gain == AUTO_GAIN) { fprintf(stderr, "Tuner gain set to automatic.\n"); } else { fprintf(stderr, "Tuner gain set to %0.2f dB.\n", gain/10.0); } /*----------------------------------------------- / Reset endpoint (mandatory) ------------------------------------------------*/ r = rtlsdr_reset_buffer(dev); } else if (dab->device_type == DAB_DEVICE_HACKRF) { int sample_rate_hz = samp_rate; fprintf(stderr, "call hackrf_sample_rate_set(%u Hz/%.03f MHz)\n", sample_rate_hz, (sample_rate_hz/1e6)); int r = hackrf_set_sample_rate_manual(hackrf, sample_rate_hz, 1); if( r != HACKRF_SUCCESS ) { hackrf_err("hackrf_sample_rate_set() failed", r); return EXIT_FAILURE; } /* possible settings 1.75/2.5/3.5/5/5.5/6/7/8/9/10/12/14/15/20/24/28 */ int baseband_filter_bw_hz = 2500000; fprintf(stderr, "call hackrf_baseband_filter_bandwidth_set(%d Hz/%.03f MHz)\n", baseband_filter_bw_hz, ((float)baseband_filter_bw_hz/1e6)); r = hackrf_set_baseband_filter_bandwidth(hackrf, baseband_filter_bw_hz); if( r != HACKRF_SUCCESS ) { hackrf_err("hackrf_baseband_filter_bandwidth_set()", r); return EXIT_FAILURE; } r = hackrf_set_vga_gain(hackrf, hackrf_vga_gain); r |= hackrf_set_lna_gain(hackrf, hackrf_lna_gain); if( r != HACKRF_SUCCESS ) { hackrf_err("hackrf_vga gain/lna gain", r); return EXIT_FAILURE; } r = hackrf_set_freq(hackrf, sdr.frequency); if( r != HACKRF_SUCCESS ) { hackrf_err("hackrf_set_freq()", r); return EXIT_FAILURE; } } /*----------------------------------------------- / Signal handler ------------------------------------------------*/ 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); /*----------------------------------------------- / start demod thread & rtl read -----------------------------------------------*/ fprintf(stderr,"Waiting for sync...\n"); sdr_init(&sdr); //dab_fic_parser_init(&sinfo); //dab_analyzer_init(&ana); pthread_create(&demod_thread, NULL, demod_thread_fn, (void *)(dab)); if (dab->device_type == DAB_DEVICE_RTLSDR) { rtlsdr_read_async(dev, rtlsdr_callback, (void *)(&sdr), DEFAULT_ASYNC_BUF_NUMBER, DEFAULT_BUF_LENGTH); } else if (dab->device_type == DAB_DEVICE_HACKRF) { r = hackrf_start_rx(hackrf, hackrf_callback, (void *)(&sdr)); if( r != HACKRF_SUCCESS ) { hackrf_err("hackrf_start_x()", r); return EXIT_FAILURE; } while( ((r=hackrf_is_streaming(hackrf)) == HACKRF_TRUE) && (do_exit == false) ) { sleep(1); fprintf(stderr, "samples: low: %02.2f%%, saturating: %02.2f%%\n", num_low_power * 100.0 / DEFAULT_BUF_LENGTH, num_saturated * 100.0 / DEFAULT_BUF_LENGTH); } hackrf_err("hackrf_is_streaming", r); } if (do_exit) { fprintf(stderr, "\nUser cancel, exiting...\n");} else { fprintf(stderr, "\nLibrary error %d, exiting...\n", r);} if (dab->device_type == DAB_DEVICE_RTLSDR) { rtlsdr_cancel_async(dev); //dab_demod_close(&dab); rtlsdr_close(dev); } else if (dab->device_type == DAB_DEVICE_HACKRF) { if (hackrf != NULL) { r = hackrf_stop_rx(hackrf); if( r != HACKRF_SUCCESS ) { hackrf_err("hackrf_stop_rx() failed", r); } else { fprintf(stderr, "hackrf_stop_rx() done\n"); } r = hackrf_close(hackrf); if( r != HACKRF_SUCCESS ) { hackrf_err("hackrf_close() failed", r); } else { fprintf(stderr, "hackrf_close() done\n"); } } hackrf_exit(); } return 1; }