static void *dongle_f(void *arg) { struct dongle_struct *ds = arg; rtlsdr_dev_t *dev = NULL; fprintf(stderr, "Initializing %d\n", ds->id); #ifdef PURKKA1 CHECK1(rtlsdr_open(&dev, (ds->id + 1) % 3)); #define trigger_id 2 #else CHECK1(rtlsdr_open(&dev, ds->id)); #define trigger_id 0 #endif ds->dev = dev; CHECK1(rtlsdr_set_sample_rate(dev, samprate)); CHECK1(rtlsdr_set_dithering(dev, 0)); CHECK1(rtlsdr_set_center_freq(dev, frequency)); CHECK1(rtlsdr_set_tuner_gain_mode(dev, 1)); CHECK1(rtlsdr_set_tuner_gain(dev, gain)); CHECK1(rtlsdr_reset_buffer(dev)); fprintf(stderr, "Initialized %d\n", ds->id); donglesok++; for(;;) { int task; pthread_mutex_lock(&dongle_m); if(dongle_task == DONGLE_EXIT) break; sem_post(&dongle_sem); pthread_cond_wait(&dongle_c, &dongle_m); task = dongle_task; pthread_mutex_unlock(&dongle_m); if(task == DONGLE_READ) { int ret; int blocksize = ds->blocksize, n_read = 0; n_read = 0; errno = 0; CHECK2(ret = rtlsdr_read_sync(dev, ds->buffer, blocksize, &n_read)); if(ret < 0) { } else if(n_read < blocksize) { fprintf(stderr, "Short read %d: %d/%d\n", ds->id, n_read, blocksize); } else if(coherent_debug) { fprintf(stderr, "Read %d\n", ds->id); } } else if(task == DONGLE_EXIT) break; } donglesok--; err: fprintf(stderr, "Exiting %d\n", ds->id); if(dev) CHECK2(rtlsdr_close(dev)); sem_post(&dongle_sem); return NULL; }
rtl rtl_create(int device_index) { int status; // create object rtl r = (rtl) malloc(sizeof(struct rtl_s)); if (device_index < 0) { device_index = _rtl_search_for_device("0"); if (device_index < 0) { exit(1); } } status = rtlsdr_open( & r->device, device_index); if (status < 0) { ERROR("Failed to open rtlsdr device %d.\n", device_index); exit(1); } r->sample_rate = RTL_DEFAULT_SAMPLE_RATE; r->state = RTL_HALTED; pthread_mutex_init( & r->buffer_m, NULL); pthread_mutex_init( & r->state_m, NULL); return r; }
bool opensdr(struct rtlsdrstruct* sdr, struct liquidobjects* dsp) { sdr->device_index = 0; int status; status = rtlsdr_open(&sdr->device, sdr->device_index); if (status < 0) { printf("Failed to open rtlsdr device %d.\n", sdr->device_index); exit(1); } // rtlsdr_set_center_freq(sdr->device, 97900000); // rtlsdr_set_sample_rate(sdr->device, 2000000); tune_sdr(sdr, 97900000, dsp); setsamplingrate_sdr(sdr, 2000000, dsp); rtlsdr_set_tuner_gain_mode(sdr->device, 0); // printf("Gain mode set= %d\n",retval); // rtlsdr_set_tuner_gain(sdr->device, 390); // printf("Set gain= %d\n",retval); rtlsdr_reset_buffer(sdr->device); return true; }
void modesInitRTLSDR(void) { int j; int device_count; char vendor[256], product[256], serial[256]; device_count = rtlsdr_get_device_count(); if (!device_count) { fprintf(stderr, "[dvbt][e]No supported RTLSDR devices found.\n"); exit(1); } fprintf(stderr, "[dvbt][i]Found %d device(s):\n", device_count); for (j = 0; j < device_count; j++) { rtlsdr_get_device_usb_strings(j, vendor, product, serial); fprintf(stderr, "[dvbt][i]%d: %s, %s, SN: %s %s\n", j, vendor, product, serial, (j == Modes.dev_index) ? "(currently selected)" : ""); } if (rtlsdr_open(&Modes.dev, Modes.dev_index) < 0) { fprintf(stderr, "[dvbt][e]Error opening the RTLSDR device: %s\n", strerror(errno)); exit(1); } /* Set gain, frequency, sample rate, and reset the device. */ rtlsdr_set_tuner_gain_mode(Modes.dev, (Modes.gain == MODES_AUTO_GAIN) ? 0 : 1); if (Modes.gain != MODES_AUTO_GAIN) { if (Modes.gain == MODES_MAX_GAIN) { /* Find the maximum gain available. */ int numgains; int gains[100]; numgains = rtlsdr_get_tuner_gains(Modes.dev, gains); Modes.gain = gains[numgains-1]; fprintf(stderr, "[dvbt][i]Max available gain is: %.2f\n", Modes.gain/10.0); } rtlsdr_set_tuner_gain(Modes.dev, Modes.gain); fprintf(stderr, "[dvbt][i]Setting gain to: %.2f\n", Modes.gain/10.0); } else { fprintf(stderr, "[dvbt][i]Using automatic gain control.\n"); } if( Modes.ppm_error != 0) { fprintf(stderr, "[dvbt][i]Setting ppm error to: %d\n", Modes.ppm_error); } rtlsdr_set_freq_correction(Modes.dev, Modes.ppm_error); if (Modes.enable_agc) rtlsdr_set_agc_mode(Modes.dev, 1); rtlsdr_set_center_freq(Modes.dev, Modes.freq); rtlsdr_set_sample_rate(Modes.dev, MODES_DEFAULT_RATE); rtlsdr_reset_buffer(Modes.dev); fprintf(stderr, "[dvbt][i]Gain reported by device: %.2f\n", rtlsdr_get_tuner_gain(Modes.dev)/10.0); }
/* rtlsdr initialization ------------------------------------------------------- * search front end and initialization * args : none * return : int status 0:okay -1:failure *-----------------------------------------------------------------------------*/ extern int rtlsdr_init(void) { int ret,dev_index=0;; /* open rtlsdr */ dev_index=verbose_device_search("0"); ret=rtlsdr_open(&dev, (uint32_t)dev_index); if (ret<0) { SDRPRINTF("error: failed to open rtlsdr device #%d.\n",dev_index); return -1; } /* set configuration */ ret=rtlsdr_initconf(); if (ret<0) { SDRPRINTF("error: failed to initialize rtlsdr\n"); return -1; } return 0; }
int main(int argc, char** argv) { uint32_t opt; int32_t rtl_result; int32_t rtl_count; char rtl_vendor[256], rtl_product[256], rtl_serial[256]; initrx_options(); initDecoder_options(); /* RX buffer allocation */ rx_state.iSamples=malloc(sizeof(float)*SIGNAL_LENGHT*SIGNAL_SAMPLE_RATE); rx_state.qSamples=malloc(sizeof(float)*SIGNAL_LENGHT*SIGNAL_SAMPLE_RATE); /* Stop condition setup */ rx_state.exit_flag = false; rx_state.decode_flag = false; uint32_t nLoop = 0; if (argc <= 1) usage(); while ((opt = getopt(argc, argv, "f:c:l:g:a:o:p:u:d:n:i:H:Q:S")) != -1) { switch (opt) { case 'f': // Frequency rx_options.dialfreq = (uint32_t)atofs(optarg); break; case 'c': // Callsign sprintf(dec_options.rcall, "%.12s", optarg); break; case 'l': // Locator / Grid sprintf(dec_options.rloc, "%.6s", optarg); break; case 'g': // Small signal amplifier gain rx_options.gain = atoi(optarg); if (rx_options.gain < 0) rx_options.gain = 0; if (rx_options.gain > 49) rx_options.gain = 49; rx_options.gain *= 10; break; case 'a': // Auto gain rx_options.autogain = atoi(optarg); if (rx_options.autogain < 0) rx_options.autogain = 0; if (rx_options.autogain > 1) rx_options.autogain = 1; break; case 'o': // Fine frequency correction rx_options.shift = atoi(optarg); break; case 'p': rx_options.ppm = atoi(optarg); break; case 'u': // Upconverter frequency rx_options.upconverter = (uint32_t)atofs(optarg); break; case 'd': // Direct Sampling rx_options.directsampling = (uint32_t)atofs(optarg); break; case 'n': // Stop after n iterations rx_options.maxloop = (uint32_t)atofs(optarg); break; case 'i': // Select the device to use rx_options.device = (uint32_t)atofs(optarg); break; case 'H': // Decoder option, use a hastable dec_options.usehashtable = 1; break; case 'Q': // Decoder option, faster dec_options.quickmode = 1; break; case 'S': // Decoder option, single pass mode (same as original wsprd) dec_options.subtraction = 0; dec_options.npasses = 1; break; default: usage(); break; } } if (rx_options.dialfreq == 0) { fprintf(stderr, "Please specify a dial frequency.\n"); fprintf(stderr, " --help for usage...\n"); exit(1); } if (dec_options.rcall[0] == 0) { fprintf(stderr, "Please specify your callsign.\n"); fprintf(stderr, " --help for usage...\n"); exit(1); } if (dec_options.rloc[0] == 0) { fprintf(stderr, "Please specify your locator.\n"); fprintf(stderr, " --help for usage...\n"); exit(1); } /* Calcule shift offset */ rx_options.realfreq = rx_options.dialfreq + rx_options.shift + rx_options.upconverter; /* Store the frequency used for the decoder */ dec_options.freq = rx_options.dialfreq; /* If something goes wrong... */ signal(SIGINT, &sigint_callback_handler); signal(SIGTERM, &sigint_callback_handler); signal(SIGILL, &sigint_callback_handler); signal(SIGFPE, &sigint_callback_handler); signal(SIGSEGV, &sigint_callback_handler); signal(SIGABRT, &sigint_callback_handler); /* Init & parameter the device */ rtl_count = rtlsdr_get_device_count(); if (!rtl_count) { fprintf(stderr, "No supported devices found\n"); return EXIT_FAILURE; } fprintf(stderr, "Found %d device(s):\n", rtl_count); for (uint32_t i=0; i<rtl_count; i++) { rtlsdr_get_device_usb_strings(i, rtl_vendor, rtl_product, rtl_serial); fprintf(stderr, " %d: %s, %s, SN: %s\n", i, rtl_vendor, rtl_product, rtl_serial); } fprintf(stderr, "\nUsing device %d: %s\n", rx_options.device, rtlsdr_get_device_name(rx_options.device)); rtl_result = rtlsdr_open(&rtl_device, rx_options.device); if (rtl_result < 0) { fprintf(stderr, "ERROR: Failed to open rtlsdr device #%d.\n", rx_options.device); return EXIT_FAILURE; } if (rx_options.directsampling) { rtl_result = rtlsdr_set_direct_sampling(rtl_device, rx_options.directsampling); if (rtl_result < 0) { fprintf(stderr, "ERROR: Failed to set direct sampling\n"); rtlsdr_close(rtl_device); return EXIT_FAILURE; } } rtl_result = rtlsdr_set_sample_rate(rtl_device, SAMPLING_RATE); if (rtl_result < 0) { fprintf(stderr, "ERROR: Failed to set sample rate\n"); rtlsdr_close(rtl_device); return EXIT_FAILURE; } rtl_result = rtlsdr_set_tuner_gain_mode(rtl_device, 1); if (rtl_result < 0) { fprintf(stderr, "ERROR: Failed to enable manual gain\n"); rtlsdr_close(rtl_device); return EXIT_FAILURE; } if (rx_options.autogain) { rtl_result = rtlsdr_set_tuner_gain_mode(rtl_device, 0); if (rtl_result != 0) { fprintf(stderr, "ERROR: Failed to set tuner gain\n"); rtlsdr_close(rtl_device); return EXIT_FAILURE; } } else { rtl_result = rtlsdr_set_tuner_gain(rtl_device, rx_options.gain); if (rtl_result != 0) { fprintf(stderr, "ERROR: Failed to set tuner gain\n"); rtlsdr_close(rtl_device); return EXIT_FAILURE; } } if (rx_options.ppm != 0) { rtl_result = rtlsdr_set_freq_correction(rtl_device, rx_options.ppm); if (rtl_result < 0) { fprintf(stderr, "ERROR: Failed to set ppm error\n"); rtlsdr_close(rtl_device); return EXIT_FAILURE; } } rtl_result = rtlsdr_set_center_freq(rtl_device, rx_options.realfreq + FS4_RATE + 1500); if (rtl_result < 0) { fprintf(stderr, "ERROR: Failed to set frequency\n"); rtlsdr_close(rtl_device); return EXIT_FAILURE; } rtl_result = rtlsdr_reset_buffer(rtl_device); if (rtl_result < 0) { fprintf(stderr, "ERROR: Failed to reset buffers.\n"); rtlsdr_close(rtl_device); return EXIT_FAILURE; } /* Print used parameter */ time_t rawtime; time ( &rawtime ); struct tm *gtm = gmtime(&rawtime); printf("\nStarting rtlsdr-wsprd (%04d-%02d-%02d, %02d:%02dz) -- Version 0.2\n", gtm->tm_year + 1900, gtm->tm_mon + 1, gtm->tm_mday, gtm->tm_hour, gtm->tm_min); printf(" Callsign : %s\n", dec_options.rcall); printf(" Locator : %s\n", dec_options.rloc); printf(" Dial freq. : %d Hz\n", rx_options.dialfreq); printf(" Real freq. : %d Hz\n", rx_options.realfreq); printf(" PPM factor : %d\n", rx_options.ppm); if(rx_options.autogain) printf(" Auto gain : enable\n"); else printf(" Gain : %d dB\n", rx_options.gain/10); /* Time alignment stuff */ struct timeval lTime; gettimeofday(&lTime, NULL); uint32_t sec = lTime.tv_sec % 120; uint32_t usec = sec * 1000000 + lTime.tv_usec; uint32_t uwait = 120000000 - usec; printf("Wait for time sync (start in %d sec)\n\n", uwait/1000000); /* Prepare a low priority param for the decoder thread */ struct sched_param param; pthread_attr_init(&dec.tattr); pthread_attr_setschedpolicy(&dec.tattr, SCHED_RR); pthread_attr_getschedparam(&dec.tattr, ¶m); param.sched_priority = 90; // = sched_get_priority_min(); pthread_attr_setschedparam(&dec.tattr, ¶m); /* Create a thread and stuff for separate decoding Info : https://computing.llnl.gov/tutorials/pthreads/ */ pthread_rwlock_init(&dec.rw, NULL); pthread_cond_init(&dec.ready_cond, NULL); pthread_mutex_init(&dec.ready_mutex, NULL); pthread_create(&dongle.thread, NULL, rtlsdr_rx, NULL); pthread_create(&dec.thread, &dec.tattr, wsprDecoder, NULL); /* Main loop : Wait, read, decode */ while (!rx_state.exit_flag && !(rx_options.maxloop && (nLoop >= rx_options.maxloop))) { /* Wait for time Sync on 2 mins */ gettimeofday(&lTime, NULL); sec = lTime.tv_sec % 120; usec = sec * 1000000 + lTime.tv_usec; uwait = 120000000 - usec + 10000; // Adding 10ms, to be sure to reach this next minute usleep(uwait); //printf("SYNC! RX started\n"); /* Use the Store the date at the begin of the frame */ time ( &rawtime ); gtm = gmtime(&rawtime); sprintf(rx_options.date,"%02d%02d%02d", gtm->tm_year - 100, gtm->tm_mon + 1, gtm->tm_mday); sprintf(rx_options.uttime,"%02d%02d", gtm->tm_hour, gtm->tm_min); /* Start to store the samples */ initSampleStorage(); while( (rx_state.exit_flag == false) && (rx_state.iqIndex < (SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE) ) ) { usleep(250000); } nLoop++; } /* Stop the RX and free the blocking function */ rtlsdr_cancel_async(rtl_device); /* Close the RTL device */ rtlsdr_close(rtl_device); printf("Bye!\n"); /* Wait the thread join (send a signal before to terminate the job) */ pthread_mutex_lock(&dec.ready_mutex); pthread_cond_signal(&dec.ready_cond); pthread_mutex_unlock(&dec.ready_mutex); pthread_join(dec.thread, NULL); pthread_join(dongle.thread, NULL); /* Destroy the lock/cond/thread */ pthread_rwlock_destroy(&dec.rw); pthread_cond_destroy(&dec.ready_cond); pthread_mutex_destroy(&dec.ready_mutex); pthread_exit(NULL); return EXIT_SUCCESS; }
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; }
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(){ printf("samplerate: %d\nbuflen:%d\n", SAMPLERATE, BUFLEN); rtlsdr_dev_t *dev = NULL; int devindex = verbose_device_search("0"); int r = rtlsdr_open(&dev, devindex); if(r){printf("err %d opening device\n", r);} verbose_set_sample_rate(dev, SAMPLERATE); verbose_set_frequency(dev, 90000000);//357000); //verbose_gain_set(dev, 496); verbose_gain_set(dev, 200); //verbose_auto_gain(dev); verbose_reset_buffer(dev); char *buf = calloc(BUFLEN,1); //char *buf = malloc((1<<16)*8);//[(1<<16)*8] = {0}; int howmany = 0; rtlsdr_read_sync(dev, buf, BUFLEN, &howmany); printf("read %d of %d\n", howmany, BUFLEN); FILE *testfile = fopen("test.dat", "w"); //fprintf(testfile, "[\n"); int i; for(i=0;i<howmany/2;i++){ fprintf(testfile, "%d %d\n", i, (int)((unsigned short*)buf)[i] - 0xffff/2); } fwrite(buf, 1, howmany,testfile); fclose(testfile); double *inbuf = calloc(BUFLEN/2, sizeof(double)); fftw_complex *outbuf = calloc(BUFLEN/2, sizeof(fftw_complex)); fftw_plan plan = fftw_plan_dft_r2c_1d(BUFLEN/2, inbuf, outbuf, FFTW_ESTIMATE); for(i=0;i<howmany/2;i++){ inbuf[i] = (double)((int)((unsigned short*)buf)[i] - 0xffff/2); } fftw_execute(plan); testfile = fopen("testdft.dat", "w"); for(i=1/*ignore first component (dc?)*/;i<howmany/2/2;i++){ fprintf(testfile, "%d %f\n", i, log10(abs(outbuf[i][0]))-log10(DBL_MAX));//this math is probably/definitely all wrong } fclose(testfile); //free(buf); #ifdef BIGDFT testfile = fopen("bigdft.dat", "w"); int freq; //for(freq=2000000;freq<1000000000;freq += 2048000){ //for(freq=80000000;freq<100000000;freq += SAMPLERATE/*BUFLEN/2*/){ for(freq=40000000;freq<1000000000;freq += SAMPLERATE/*BUFLEN/2*/){ verbose_set_frequency(dev, freq);//357000); verbose_reset_buffer(dev); rtlsdr_read_sync(dev, buf, BUFLEN, &howmany); for(i=0;i<howmany/2;i++){ inbuf[i] = (double)((int)((unsigned short*)buf)[i] - 0xffff/2); } fftw_execute(plan); for(i=1;i<howmany/2/2;i+= 1){//50){ //fprintf(testfile, "%d %f\n", i*(SAMPLERATE/(howmany/2/2))+freq, (outbuf[i][0]));//this math is probably/definitely all wrong fprintf(testfile, "%d %f\n", i*(SAMPLERATE/(howmany/2/2))+freq, log10(abs(outbuf[i][0]))-log10(DBL_MAX));//this math is probably/definitely all wrong } printf("%d\n", freq); } fclose(testfile); #endif rtlsdr_close(dev); return 0; }
bool CRtlSdr::open() { if (device_count == 0) { qDebug() << "No supported device found to open rtlsdr device " << dongle.dev_index << "\n"; power = false; return false; } Initialize(&dongle,&demod); dongle.dev_index = 0; if (dongle.dev_index < 0) { power = false; return false; } int r = rtlsdr_open(&dongle.dev, (uint32_t)dongle.dev_index); if (r < 0) { qDebug() << "Failed to open rtlsdr device " << dongle.dev_index << "\n"; power = false; return false; } r = rtlsdr_set_tuner_gain_mode(dongle.dev,dongle.gain); if (r < 0) { qDebug() << "Failed to set gain to " << dongle.gain << "\n"; power = false; return false; } r = rtlsdr_set_tuner_gain(dongle.dev,20); if (r < 0) { qDebug() << "Failed to set gain to " << dongle.gain << "\n"; power = false; return false; } r = rtlsdr_reset_buffer(dongle.dev); if (r < 0) { qDebug() << "WARNING: Failed to reset buffers.\n"; } r = rtlsdr_set_sample_rate(dongle.dev,dongle.rate); if (r < 0) { qDebug() << "Failed to set sample rate to " << dongle.rate << "\n"; power = false; return false; } r = rtlsdr_set_freq_correction(dongle.dev,43); if (r < 0) { qDebug() << "Failed to set ppm rate to " << 43 << "\n"; power = false; return false; } qDebug() << "Dongle sample rate " << rtlsdr_get_sample_rate(dongle.dev); // Build a data reader thead pthread_create(&dongle.thread, NULL, dongle_thread_fn, (void *)(this)); power = true; log_t.isConnected = true; return true; }
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; }
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; }
int main(int argc, char **argv) { // setup window glut_init(argc,argv); /// // init radio /// int 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); uint32_t dev_index = 0; fprintf(stderr, "Using device %d: %s\n", dev_index, rtlsdr_get_device_name(dev_index)); int r = rtlsdr_open(&dev, dev_index); if (r < 0) { fprintf(stderr, "Failed to open rtlsdr device #%d.\n", dev_index); exit(1); } /* Set the sample rate */ uint32_t samp_rate = DEFAULT_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 */ frequency = 100000000; if(argv[1]) frequency = (uint32_t)atof(argv[1]) * (uint32_t)1e6; if(frequency < 1e6) { fprintf(stderr, "WARNING: Center frequency should be in range, setting to 100MHz\n"); frequency = 100000000; } r = rtlsdr_set_center_freq(dev, frequency); if (r < 0) fprintf(stderr, "WARNING: Failed to set center freq.\n"); else fprintf(stderr, "Tuned to %f MHz.\n", frequency/1e6); sprintf(strFreq,"%4.0f",frequency/1e6); /* Set the gain */ int gain = 0; if(argv[2]) gain = atoi(argv[2]); if (!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"); fprintf(stderr, "Valid values for e4000 are: -10, 15, 40, 65, 90, 115, 140, 165, 190, 215, 240, 290, 340, 420, 430, 450, 470, 490\n"); fprintf(stderr, "Valid values for r820t are: 9, 14, 27, 37, 77, 87, 125, 144, 157, 166, 197, 207, 229, 254, 280, 297,\n\t328, 338, 364, 372, 386, 402, 421, 434, 439, 445, 480, 496\n"); fprintf(stderr, "Gain values are in tenths of dB, e.g. 115 means 11.5 dB.\n"); } else fprintf(stderr, "Tuner gain set to %f dB.\n", gain/10.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"); /// // setup fftw /// uint32_t out_block_size = DEFAULT_BUF_LENGTH; buffer = malloc(out_block_size * sizeof(uint8_t)); fftw_in = fftw_malloc ( sizeof ( fftw_complex ) * out_block_size/2 ); fftw_out = fftw_malloc ( sizeof ( fftw_complex ) * out_block_size/2 ); // put the plan on FFTW_MEASURE to calculate the optimal fft plan (takes a few seconds). // If performance of FFTW_ESTIMATE is good enough use that one //fftw_p = fftw_plan_dft_1d ( out_block_size/2, fftw_in, fftw_out, FFTW_FORWARD, FFTW_MEASURE ); fftw_p = fftw_plan_dft_1d ( out_block_size/2, fftw_in, fftw_out, FFTW_FORWARD, FFTW_ESTIMATE ); /* start reading samples */ fprintf(stderr, "Update frequency is %.2fHz.\n",((double)DEFAULT_SAMPLE_RATE / (double)DEFAULT_BUF_LENGTH)); fprintf(stderr, "Press [q,w] to change frequency, [a,z] to adjust waterfall color sensitivity, ESC to quit.\n"); pwr_max = 0.0f; pwr_diff = 1.0f; glutTimerFunc(0,readData,0); glutMainLoop(); return 0; }
int main(int argc, char **argv) { #ifndef _WIN32 struct sigaction sigact; #endif char *filename = NULL; int i, length, n_read, r, opt, wb_mode = 0; int f_set = 0; int gain = AUTO_GAIN; // tenths of a dB uint8_t *buffer; uint32_t dev_index = 0; int device_count; int ppm_error = 0; int interval = 10; int fft_threads = 1; int smoothing = 0; int single = 0; double crop = 0.0; char vendor[256], product[256], serial[256]; char *freq_optarg; time_t next_tick; time_t time_now; time_t exit_time = 0; char t_str[50]; struct tm *cal_time; double (*window_fn)(int, int) = rectangle; freq_optarg = ""; while ((opt = getopt(argc, argv, "f:i:s:t:d:g:p:e:w:c:1Fh")) != -1) { switch (opt) { case 'f': // lower:upper:bin_size freq_optarg = strdup(optarg); f_set = 1; break; case 'd': dev_index = atoi(optarg); break; case 'g': gain = (int)(atof(optarg) * 10); break; case 'c': crop = atofp(optarg); break; case 'i': interval = (int)round(atoft(optarg)); break; case 'e': exit_time = (time_t)((int)round(atoft(optarg))); break; case 's': if (strcmp("avg", optarg) == 0) { smoothing = 0;} if (strcmp("iir", optarg) == 0) { smoothing = 1;} break; case 'w': if (strcmp("rectangle", optarg) == 0) { window_fn = rectangle;} if (strcmp("hamming", optarg) == 0) { window_fn = hamming;} if (strcmp("blackman", optarg) == 0) { window_fn = blackman;} if (strcmp("blackman-harris", optarg) == 0) { window_fn = blackman_harris;} if (strcmp("hann-poisson", optarg) == 0) { window_fn = hann_poisson;} if (strcmp("youssef", optarg) == 0) { window_fn = youssef;} if (strcmp("kaiser", optarg) == 0) { window_fn = kaiser;} if (strcmp("bartlett", optarg) == 0) { window_fn = bartlett;} break; case 't': fft_threads = atoi(optarg); break; case 'p': ppm_error = atoi(optarg); break; case '1': single = 1; break; case 'F': boxcar = 0; break; case 'h': default: usage(); break; } } if (!f_set) { fprintf(stderr, "No frequency range provided.\n"); exit(1); } if ((crop < 0.0) || (crop > 1.0)) { fprintf(stderr, "Crop value outside of 0 to 1.\n"); exit(1); } frequency_range(freq_optarg, crop); if (tune_count == 0) { usage();} if (argc <= optind) { filename = "-"; } else { filename = argv[optind]; } if (interval < 1) { interval = 1;} fprintf(stderr, "Reporting every %i seconds\n", interval); 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 /* 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); gain = nearest_gain(gain); 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 log to stdout */ file = stdout; #ifdef _WIN32 // Is this necessary? Output is ascii. _setmode(_fileno(file), _O_BINARY); #endif } else { file = fopen(filename, "wb"); if (!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");} /* actually do stuff */ rtlsdr_set_sample_rate(dev, (uint32_t)tunes[0].rate); sine_table(tunes[0].bin_e); next_tick = time(NULL) + interval; if (exit_time) { exit_time = time(NULL) + exit_time;} fft_buf = malloc(tunes[0].buf_len * sizeof(int16_t)); length = 1 << tunes[0].bin_e; window_coefs = malloc(length * sizeof(int)); for (i=0; i<length; i++) { window_coefs[i] = (int)(256*window_fn(i, length)); } while (!do_exit) { scanner(); time_now = time(NULL); if (time_now < next_tick) { continue;} // time, Hz low, Hz high, Hz step, samples, dbm, dbm, ... cal_time = localtime(&time_now); strftime(t_str, 50, "%Y-%m-%d, %H:%M:%S", cal_time); for (i=0; i<tune_count; i++) { fprintf(file, "%s, ", t_str); csv_dbm(&tunes[i]); } fflush(file); while (time(NULL) >= next_tick) { next_tick += interval;} if (single) { do_exit = 1;} if (exit_time && time(NULL) >= exit_time) { do_exit = 1;} } /* clean up */ 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(fft_buf); free(window_coefs); //for (i=0; i<tune_count; i++) { // free(tunes[i].avg); // free(tunes[i].buf8); //} 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; }
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; }
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; }
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; }
// main program int main (int argc, char **argv) { // command-line options int verbose = 1; int ppm_error = 0; int gain = 0; unsigned int nfft = 64; float offset = -65.0f; float scale = 5.0f; float fft_rate = 10.0f; float rx_resamp_rate; float bandwidth = 800e3f; unsigned int logsize = 4096; char filename[256] = "rtl_asgram.dat"; int r, n_read; uint32_t frequency = 100000000; uint32_t samp_rate = DEFAULT_SAMPLE_RATE; uint32_t out_block_size = DEFAULT_BUF_LENGTH; uint8_t *buffer; int dev_index = 0; int dev_given = 0; struct sigaction sigact; normalizer_t *norm; // int d; while ((d = getopt(argc,argv,"hf:b:B:G:n:p:s:o:r:L:F:")) != EOF) { switch (d) { case 'h': usage(); return 0; case 'f': frequency = atof(optarg); break; case 'b': bandwidth = atof(optarg); break; case 'B': out_block_size = (uint32_t)atof(optarg); break; case 'G': gain = (int)(atof(optarg) * 10); break; case 'n': nfft = atoi(optarg); break; case 'o': offset = atof(optarg); break; case 'p': ppm_error = atoi(optarg); break; case 's': samp_rate = (uint32_t)atofs(optarg); break; case 'r': fft_rate = atof(optarg); break; case 'L': logsize = atoi(optarg); break; case 'F': strncpy(filename,optarg,255); break; case 'd': dev_index = verbose_device_search(optarg); dev_given = 1; break; default: usage(); return 1; } } // validate parameters if (fft_rate <= 0.0f || fft_rate > 100.0f) { fprintf(stderr,"error: %s, fft rate must be in (0, 100) Hz\n", argv[0]); exit(1); } 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); } 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); /* Set the sample rate */ verbose_set_sample_rate(dev, samp_rate); /* 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); rx_resamp_rate = bandwidth/samp_rate; printf("frequency : %10.4f [MHz]\n", frequency*1e-6f); printf("bandwidth : %10.4f [kHz]\n", bandwidth*1e-3f); printf("sample rate : %10.4f kHz = %10.4f kHz * %8.6f\n", samp_rate * 1e-3f, bandwidth * 1e-3f, 1.0f / rx_resamp_rate); printf("verbosity : %s\n", (verbose?"enabled":"disabled")); unsigned int i; // add arbitrary resampling component msresamp_crcf resamp = msresamp_crcf_create(rx_resamp_rate, 60.0f); assert(resamp); // create buffer for sample logging windowcf log = windowcf_create(logsize); // create ASCII spectrogram object float maxval; float maxfreq; char ascii[nfft+1]; ascii[nfft] = '\0'; // append null character to end of string asgram q = asgram_create(nfft); asgram_set_scale(q, offset, scale); // assemble footer unsigned int footer_len = nfft + 16; char footer[footer_len+1]; for (i=0; i<footer_len; i++) footer[i] = ' '; footer[1] = '['; footer[nfft/2 + 3] = '+'; footer[nfft + 4] = ']'; sprintf(&footer[nfft+6], "%8.3f MHz", frequency*1e-6f); unsigned int msdelay = 1000 / fft_rate; // create/initialize Hamming window float w[nfft]; for (i=0; i<nfft; i++) w[i] = hamming(i,nfft); //allocate recv buffer buffer = malloc(out_block_size * sizeof(uint8_t)); assert(buffer); // create buffer for arbitrary resamper output int b_len = ((int)(out_block_size * rx_resamp_rate) + 64) >> 1; complex float buffer_resamp[b_len]; debug("resamp_buffer_len: %d", b_len); // timer to control asgram output timer t1 = timer_create(); timer_tic(t1); norm = normalizer_create(); verbose_reset_buffer(dev); while (!do_exit) { // grab data from device 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; } // push data through arbitrary resampler and give to frame synchronizer // TODO : apply bandwidth-dependent gain for (i=0; i<n_read/2; i++) { // grab sample from usrp buffer complex float rtlsdr_sample = normalizer_normalize(norm, *((uint16_t*)buffer+i)); // push through resampler (one at a time) unsigned int nw; msresamp_crcf_execute(resamp, &rtlsdr_sample, 1, buffer_resamp, &nw); // push resulting samples into asgram object asgram_push(q, buffer_resamp, nw); // write samples to log windowcf_write(log, buffer_resamp, nw); } 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; if (timer_toc(t1) > msdelay*1e-3f) { // reset timer timer_tic(t1); // run the spectrogram asgram_execute(q, ascii, &maxval, &maxfreq); // print the spectrogram printf(" > %s < pk%5.1fdB [%5.2f]\n", ascii, maxval, maxfreq); printf("%s\r", footer); fflush(stdout); } } // try to write samples to file FILE * fid = fopen(filename,"w"); if (fid != NULL) { // write header fprintf(fid, "# %s : auto-generated file\n", filename); fprintf(fid, "#\n"); fprintf(fid, "# num_samples : %u\n", logsize); fprintf(fid, "# frequency : %12.8f MHz\n", frequency*1e-6f); fprintf(fid, "# bandwidth : %12.8f kHz\n", bandwidth*1e-3f); // save results to file complex float * rc; // read pointer windowcf_read(log, &rc); for (i=0; i<logsize; i++) fprintf(fid, "%12.4e %12.4e\n", crealf(rc[i]), cimagf(rc[i])); // close it up fclose(fid); printf("results written to '%s'\n", filename); } else { fprintf(stderr,"error: %s, could not open '%s' for writing\n", argv[0], filename); } // destroy objects normalizer_destroy(&norm); msresamp_crcf_destroy(resamp); windowcf_destroy(log); asgram_destroy(q); timer_destroy(t1); rtlsdr_close(dev); free (buffer); return 0; }
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; 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; }
// Initilizes and Opens the RTL Dongle void Init_Device(int mode) { int r; int i = 0; int gain = 496; //496;//0;//125;//386; /* { 0, 9, 14, 27, 37, 77, 87, 125, 144, 157, 166, 197, 207, 229, 254, 280, 297, 328, 338, 364, 372, 386, 402, 421, 434, 439, 445, 480, 496 }; */ uint32_t dev_index = 0; uint32_t frequency = (d1.freq + d1.freqcorr) * 1e6; //1433170000;//1420400000;//1409246000;//1407630000;//34000000;//1420400000;//1421550000;//99500000;//100000000; uint32_t samp_rate = 2.4 * 1e6 + 0.5; //1400000;//2400000;//DEFAULT_SAMPLE_RATE; int device_count; char vendor[256], product[256], serial[256]; d1.dongle = 1; if (mode) { /* Set the frequency */ r = rtlsdr_set_center_freq(dev, frequency); if (r < 0) fprintf(stderr, "WARNING: Failed to set center freq.\n"); else if (d1.printout) printf("Tuned to %u Hz.\n", frequency); return; } device_count = rtlsdr_get_device_count(); if (!device_count) { fprintf(stderr, "No supported devices found.\n"); exit(1); } if (d1.printout) printf("Found %d device(s):\n", device_count); for (i = 0; i < device_count; i++) { rtlsdr_get_device_usb_strings(i, vendor, product, serial); if (d1.printout) printf(" %d: %s, %s, SN: %s\n", i, vendor, product, serial); } if (d1.printout) printf("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 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 if (d1.printout) printf("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 */// doesn't set gain to gain value - uses R828_Arry[0] = (R828_Arry[0] & 0xF0) | 0x0F;//0x06;//gLNA;//lna_index r = rtlsdr_set_tuner_gain(dev, gain); if (r < 0) fprintf(stderr, "WARNING: Failed to set tuner gain.\n"); } r = rtlsdr_reset_buffer(dev); // printf("Reset Status: %u \n", r); }
// main program int main (int argc, char **argv) { // command-line options int verbose = 1; int ppm_error = 0; int gain = 0; float rx_resamp_rate; float bandwidth = 800e3f; int r, n_read; uint32_t frequency = 100000000; uint32_t samp_rate = DEFAULT_SAMPLE_RATE; uint32_t out_block_size = DEFAULT_BUF_LENGTH; uint8_t *buffer; complex float *buffer_norm; int dev_index = 0; int dev_given = 0; struct sigaction sigact; normalizer_t *norm; float kf = 0.1f; // modulation factor liquid_freqdem_type type = LIQUID_FREQDEM_DELAYCONJ; // int d; while ((d = getopt(argc,argv,"hf:b:B:G:p:s:")) != EOF) { switch (d) { case 'h': usage(); return 0; case 'f': frequency = atof(optarg); break; case 'b': bandwidth = atof(optarg); break; case 'B': out_block_size = (uint32_t)atof(optarg); break; case 'G': gain = (int)(atof(optarg) * 10); break; case 'p': ppm_error = atoi(optarg); break; case 's': samp_rate = (uint32_t)atofs(optarg); break; case 'd': dev_index = verbose_device_search(optarg); dev_given = 1; break; default: usage(); return 1; } } 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); } 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); /* Set the sample rate */ verbose_set_sample_rate(dev, samp_rate); /* 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); rx_resamp_rate = bandwidth/samp_rate; printf("frequency : %10.4f [MHz]\n", frequency*1e-6f); printf("bandwidth : %10.4f [kHz]\n", bandwidth*1e-3f); printf("sample rate : %10.4f kHz = %10.4f kHz * %8.6f\n", samp_rate * 1e-3f, bandwidth * 1e-3f, 1.0f / rx_resamp_rate); printf("verbosity : %s\n", (verbose?"enabled":"disabled")); unsigned int i,j; // add arbitrary resampling component msresamp_crcf resamp = msresamp_crcf_create(rx_resamp_rate, 60.0f); assert(resamp); //allocate recv buffer buffer = malloc(out_block_size * sizeof(uint8_t)); assert(buffer); buffer_norm = malloc(out_block_size * sizeof(complex float)); assert(buffer_norm); // create buffer for arbitrary resamper output int b_len = ((int)(out_block_size * rx_resamp_rate) + 64) >> 1; complex float buffer_resamp[b_len]; int16_t buffer_demod[b_len]; debug("resamp_buffer_len: %d\n", b_len); norm = normalizer_create(); verbose_reset_buffer(dev); freqdem dem = freqdem_create(kf,type); while (!do_exit) { // grab data from device 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; } // push data through arbitrary resampler and give to frame synchronizer // TODO : apply bandwidth-dependent gain for (i=0; i<n_read/2; i++) { // grab sample from usrp buffer buffer_norm[i] = normalizer_normalize(norm, *((uint16_t*)buffer+i)); } // push through resampler (one at a time) unsigned int nw; float demod; msresamp_crcf_execute(resamp, buffer_norm, n_read/2, buffer_resamp, &nw); for(j=0;j<nw;j++) { freqdem_demodulate(dem, buffer_resamp[j], &demod); buffer_demod[j] = to_int16(demod); } if (fwrite(buffer_demod, 2, nw, stdout) != (size_t)nw) { 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; } // destroy objects freqdem_destroy(dem); normalizer_destroy(&norm); msresamp_crcf_destroy(resamp); rtlsdr_close(dev); free (buffer); return 0; }
// // =============================== RTLSDR handling ========================== // int modesInitRTLSDR(void) { int j; int device_count, dev_index = 0; char vendor[256], product[256], serial[256]; if (Modes.dev_name) { if ( (dev_index = verbose_device_search(Modes.dev_name)) < 0 ) return -1; } device_count = rtlsdr_get_device_count(); if (!device_count) { fprintf(stderr, "No supported RTLSDR devices found.\n"); return -1; } fprintf(stderr, "Found %d device(s):\n", device_count); for (j = 0; j < device_count; j++) { rtlsdr_get_device_usb_strings(j, vendor, product, serial); fprintf(stderr, "%d: %s, %s, SN: %s %s\n", j, vendor, product, serial, (j == dev_index) ? "(currently selected)" : ""); } if (rtlsdr_open(&Modes.dev, dev_index) < 0) { fprintf(stderr, "Error opening the RTLSDR device: %s\n", strerror(errno)); return -1; } // Set gain, frequency, sample rate, and reset the device rtlsdr_set_tuner_gain_mode(Modes.dev, (Modes.gain == MODES_AUTO_GAIN) ? 0 : 1); if (Modes.gain != MODES_AUTO_GAIN) { int *gains; int numgains; numgains = rtlsdr_get_tuner_gains(Modes.dev, NULL); if (numgains <= 0) { fprintf(stderr, "Error getting tuner gains\n"); return -1; } gains = malloc(numgains * sizeof(int)); if (rtlsdr_get_tuner_gains(Modes.dev, gains) != numgains) { fprintf(stderr, "Error getting tuner gains\n"); free(gains); return -1; } if (Modes.gain == MODES_MAX_GAIN) { int highest = -1; int i; for (i = 0; i < numgains; ++i) { if (gains[i] > highest) highest = gains[i]; } Modes.gain = highest; fprintf(stderr, "Max available gain is: %.2f dB\n", Modes.gain/10.0); } else { int closest = -1; int i; for (i = 0; i < numgains; ++i) { if (closest == -1 || abs(gains[i] - Modes.gain) < abs(closest - Modes.gain)) closest = gains[i]; } if (closest != Modes.gain) { Modes.gain = closest; fprintf(stderr, "Closest available gain: %.2f dB\n", Modes.gain/10.0); } } free(gains); fprintf(stderr, "Setting gain to: %.2f dB\n", Modes.gain/10.0); if (rtlsdr_set_tuner_gain(Modes.dev, Modes.gain) < 0) { fprintf(stderr, "Error setting tuner gains\n"); return -1; } } else { fprintf(stderr, "Using automatic gain control.\n"); } rtlsdr_set_freq_correction(Modes.dev, Modes.ppm_error); if (Modes.enable_agc) rtlsdr_set_agc_mode(Modes.dev, 1); rtlsdr_set_center_freq(Modes.dev, Modes.freq); rtlsdr_set_sample_rate(Modes.dev, (unsigned)Modes.sample_rate); rtlsdr_reset_buffer(Modes.dev); fprintf(stderr, "Gain reported by device: %.2f dB\n", rtlsdr_get_tuner_gain(Modes.dev)/10.0); return 0; }
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; }
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_cond_init(&data_ready, NULL); pthread_rwlock_init(&data_rw, NULL); pthread_mutex_init(&data_mutex, NULL); while ((opt = getopt(argc, argv, "d:f:g:s:b:l:o:t:r:p:EFA:NWMULRDCh")) != -1) { switch (opt) { case 'd': dev_index = atoi(optarg); break; case 'f': if (fm.freq_len >= FREQUENCIES_LIMIT) { break;} 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; case 'h': 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 >= FREQUENCIES_LIMIT) { fprintf(stderr, "Too many channels, maximum %i.\n", FREQUENCIES_LIMIT); exit(1); } if (fm.freq_len > 1 && fm.squelch_level == 0) { fprintf(stderr, "Please specify a squelch level. Required for scanning multiple frequencies.\n"); exit(1); } if (fm.freq_len > 1) { fm.terminate_on_squelch = 0; } if (argc <= optind) { filename = "-"; } else { filename = argv[optind]; } ACTUAL_BUF_LENGTH = lcm_post[fm.post_downsample] * DEFAULT_BUF_LENGTH; buffer = malloc(ACTUAL_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 */ // I really should loop over everything // but you are more wrong for scanning broadcast FM 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); gain = nearest_gain(gain); 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, ACTUAL_BUF_LENGTH);*/ while (!do_exit) { sync_read(buffer, ACTUAL_BUF_LENGTH, &fm); } while (!do_exit) { sync_read(buffer, ACTUAL_BUF_LENGTH, &fm); } 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(&data_ready, &data_mutex); pthread_join(demod_thread, NULL); pthread_cond_destroy(&data_ready); pthread_rwlock_destroy(&data_rw); pthread_mutex_destroy(&data_mutex); if (fm.file != stdout) { fclose(fm.file);} rtlsdr_close(dev); free (buffer); return r >= 0 ? r : -r; }
int start_the_radio(int device_index, long freq_hz, long output_SR, int gain_db10) { // post("inside start_the_radio()" ); // int err = 0; // tz for usage call int r; int dev_given = 0; // gets set on, if user passes in device index arg (-d) // int custom_ppm = 0; // gets set on, if users specifies freq correction arg (-p) char device_index_str[10] = "0"; // initialization dongle_init(&dongle); demod_init(&demod); output_init(&output); controller_init(&controller); buffer_init(); // tz reset index pointers // handle device index if(device_index != 0) { sprintf(device_index_str,"%d", device_index); dongle.dev_index = verbose_device_search(device_index_str); dev_given = 1; } // set gain // tz - note that when passing this param from Max/Pd it gets passed in // db * 10 format - so we don't need extra multiplier // this is done to allow setting to AUTOGAIN // dongle.gain = gain_db10 ; // set sample rate demod.rate_in = (uint32_t) output_SR; demod.rate_out = (uint32_t) output_SR; // set frequency controller.freqs[controller.freq_len] = (uint32_t) freq_hz; controller.freq_len++; // note: here is how dongle ppm error correction was set in rtl_fm // dongle.ppm_error = atoi(optarg); // custom_ppm = 1; // do initial setup // tz this was for resampling and can be removed output.rate = demod.rate_out; // tz this can get cleaned up too... // set buffer length - would need to increase if downsample rate increased // ACTUAL_BUF_LENGTH = DEFAULT_BUF_LENGTH; // if user specied a device number, use it - otherwise default to 0 if (!dev_given) { dongle.dev_index = verbose_device_search("0"); } if (dongle.dev_index < 0) { return(1); } // open device r = rtlsdr_open(&dongle.dev, (uint32_t)dongle.dev_index); if (r < 0) { // sprintf(errmesg, "Failed to open rtlsdr device #%d.\n", dongle.dev_index); sprintf(errmesg, "Failed to open rtlsdr device #%d.\n", dongle.dev_index); post(errmesg, 0); return(1); } set_tuner_gain(&dongle); // do freq error correction verbose_ppm_set(dongle.dev, dongle.ppm_error); //r = rtlsdr_set_testmode(dongle.dev, 1); /* Reset endpoint before we start reading from it (mandatory) */ verbose_reset_buffer(dongle.dev); // tz these threads all get running in parallel here // int errx; // for debugging - not really used now errx = pthread_create(&controller.thread, NULL, controller_thread_fn, (void *)(&controller)); usleep(100000); errx = pthread_create(&dongle.thread, NULL, dongle_thread_fn, (void *)(&dongle)); radio_running = 1; return(0); }