示例#1
0
void retune(rtlsdr_dev_t *d, int freq)
{
    uint8_t dump[BUFFER_DUMP];
    int n_read;

//  // NB: time scan pass
//  struct timeval stop, start;
//
//  // Record start time
//  gettimeofday(&start, NULL);

    rtlsdr_set_center_freq(d, (uint32_t)freq);

    /* wait for settling and flush buffer */
    usleep(5000);

    rtlsdr_read_sync(d, &dump, BUFFER_DUMP, &n_read);
    if (n_read != BUFFER_DUMP) {
        fprintf(stderr, "Error: bad retune.\n");}

//  // Compute scan time
//  gettimeofday(&stop, NULL);
//
//  long startTime = start.tv_sec * 1000000 + start.tv_usec;
//  long stopTime = stop.tv_sec * 1000000 + stop.tv_usec;
//  printf("Retune took %ld micros\n", stopTime - startTime);

}
示例#2
0
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;
}
示例#3
0
void full_demod(struct fm_state *fm)
{
	int i, sr, freq_next, hop = 0;
	//    pthread_mutex_lock(&data_ready);

	static unsigned char tmpBuf[DEFAULT_BUF_LENGTH];
	while(ringbuffer_is_empty((ringbuffer*)fm->buf))
    	{
        	usleep(100000);
	}
	ringbuffer_read((ringbuffer*)fm->buf, tmpBuf);
	//fprintf(stderr, "data!\n");

	rotate_90(tmpBuf, sizeof(tmpBuf));
	if (fm->fir_enable) {
        	low_pass_fir(fm, tmpBuf, sizeof(tmpBuf));
	} else {
        	low_pass(fm, tmpBuf, sizeof(tmpBuf));
	}
	//    pthread_mutex_unlock(&data_write);
	fm->mode_demod(fm);
        if (fm->mode_demod == &raw_demod) {
		fwrite(fm->signal2, 2, fm->signal2_len, fm->file);
		return;
	}
	sr = post_squelch(fm);
	if (!sr && fm->squelch_hits > fm->conseq_squelch) {
		if (fm->terminate_on_squelch) {
			fm->exit_flag = 1;}
		if (fm->freq_len == 1) {  /* mute */
			for (i=0; i<fm->signal_len; i++) {
				fm->signal2[i] = 0;}
		}
		else {
			hop = 1;}
	}
	if (fm->post_downsample > 1) {
		fm->signal2_len = low_pass_simple(fm->signal2, fm->signal2_len, fm->post_downsample);}
	if (fm->output_rate > 0) {
		low_pass_real(fm);
	}
	if (fm->deemph) {
		deemph_filter(fm);}
	if (fm->dc_block) {
		dc_block_filter(fm);}
	/* ignore under runs for now */
	fwrite(fm->signal2, 2, fm->signal2_len, fm->file);
	if (hop && ringbuffer_is_empty((ringbuffer*)fm->buf)) { // Making sure the buffer is empty before tuning
		freq_next = (fm->freq_now + 1) % fm->freq_len;
		optimal_settings(fm, freq_next, 1);
		fm->squelch_hits = fm->conseq_squelch + 1;  /* hair trigger */
		/* wait for settling and flush buffer */
		usleep(5000);
		rtlsdr_read_sync(dev, NULL, 4096, NULL);
	}
}
示例#4
0
void retune(rtlsdr_dev_t *d, int freq)
{
	uint8_t dump[BUFFER_DUMP];
	int n_read;
	rtlsdr_set_center_freq(d, (uint32_t)freq);
	/* wait for settling and flush buffer */
	usleep(5000);
	rtlsdr_read_sync(d, &dump, BUFFER_DUMP, &n_read);
	if (n_read != BUFFER_DUMP) {
		fprintf(stderr, "Error: bad retune.\n");}
}
示例#5
0
void full_demod(struct fm_state *fm)
{
	uint8_t dump[BUFFER_DUMP];
	int i, sr, freq_next, n_read, hop = 0;
	pthread_rwlock_wrlock(&data_rw);
	rotate_90(fm->buf, fm->buf_len);
	if (fm->fir_enable) {
		low_pass_fir(fm, fm->buf, fm->buf_len);
	} else {
		low_pass(fm, fm->buf, fm->buf_len);
	}
	pthread_rwlock_unlock(&data_rw);
	fm->mode_demod(fm);
	if (fm->mode_demod == &raw_demod) {
		fwrite(fm->signal2, 2, fm->signal2_len, fm->file);
		return;
	}
	sr = post_squelch(fm);
	if (!sr && fm->squelch_hits > fm->conseq_squelch) {
		if (fm->terminate_on_squelch) {
			fm->exit_flag = 1;}
		if (fm->freq_len == 1) {  /* mute */
			for (i=0; i<fm->signal_len; i++) {
				fm->signal2[i] = 0;}
		}
		else {
			hop = 1;}
	}
	if (fm->post_downsample > 1) {
		fm->signal2_len = low_pass_simple(fm->signal2, fm->signal2_len, fm->post_downsample);}
	if (fm->output_rate > 0) {
		low_pass_real(fm);
	}
	if (fm->deemph) {
		deemph_filter(fm);}
	if (fm->dc_block) {
		dc_block_filter(fm);}
	/* ignore under runs for now */
	fwrite(fm->signal2, 2, fm->signal2_len, fm->file);
	if (hop) {
		freq_next = (fm->freq_now + 1) % fm->freq_len;
		optimal_settings(fm, freq_next, 1);
		fm->squelch_hits = fm->conseq_squelch + 1;  /* hair trigger */
		/* wait for settling and flush buffer */
		usleep(5000);
		rtlsdr_read_sync(dev, &dump, BUFFER_DUMP, &n_read);
		if (n_read != BUFFER_DUMP) {
			fprintf(stderr, "Error: bad retune.\n");}
	}
}
示例#6
0
static void sync_read(unsigned char *buf, uint32_t len, struct fm_state *fm)
{
	int r, n_read;
	r = rtlsdr_read_sync(dev, buf, len, &n_read);
	if (r < 0) {
		fprintf(stderr, "WARNING: sync read failed.\n");
		return;
	}
	pthread_rwlock_wrlock(&data_rw);
	memcpy(fm->buf, buf, len);
	fm->buf_len = len;
	pthread_rwlock_unlock(&data_rw);
	safe_cond_signal(&data_ready, &data_mutex);
	//full_demod(fm);
}
示例#7
0
void scanner(void)
{
	int i, j, j2, n_read, offset, bin_e, bin_len, buf_len, ds, ds_p;
	int32_t w;
	struct tuning_state *ts;
	int16_t *fft_buf;
	bin_e = tunes[0].bin_e;
	bin_len = 1 << bin_e;
	buf_len = tunes[0].buf_len;
	for (i=0; i<tune_count; i++) {
		if (do_exit >= 2)
			{return;}
		ts = &tunes[i];
		fft_buf = ts->fft_buf;
		regain(dev, ts->gain);
		rerate(dev, ts->rate);
		retune(dev, ts->freq);
		rtlsdr_read_sync(dev, ts->buf8, buf_len, &n_read);
		if (n_read != buf_len) {
			fprintf(stderr, "Error: dropped samples.\n");}
		/* rms */
		if (bin_len == 1) {
			rms_power(ts);
			continue;
		}
		/* prep for fft */
		for (j=0; j<buf_len; j++) {
			fft_buf[j] = (int16_t)ts->buf8[j] - 127;
		}
		ds = ts->downsample;
		ds_p = ts->downsample_passes;
		if (ds_p) {  /* recursive */
			for (j=0; j < ds_p; j++) {
				downsample_iq(fft_buf, buf_len >> j);
			}
			/* droop compensation */
			if (ts->comp_fir_size == 9 && ds_p <= CIC_TABLE_MAX) {
				generic_fir(fft_buf, buf_len >> j, cic_9_tables[ds_p]);
				generic_fir(fft_buf+1, (buf_len >> j)-1, cic_9_tables[ds_p]);
			}
		} else if (ds > 1) {  /* boxcar */
示例#8
0
文件: sdr.c 项目: jprince14/en525.743
void sdr_work(struct rtlsdrstruct* sdr) {
	//if the size of the data read off the SDR is too large then the demod function
	//takes too long which makes the output audio low quality
	int x = rtlsdr_read_sync(sdr->device, sdr->buffer, 1 * 1024, &sdr->receivesize);
//	usleep(1000);
	if (x < 0) {
		printf("Samples read: %d\n", sdr->receivesize);
		printf("Error reading from SDR\n");
		exit(0);
	}
//	if (sdr->receivesize == 0) {
//		printf("ERROR reading data off SDR, # Samples read: %d\n", sdr->receivesize);
//	}

#if SDR_WRITE == 0
	printf("sdr->receivesize = %d\n", sdr->receivesize);
//	printf("Sampling rate set to %d\n", rtlsdr_get_sample_rate(sdr->device));
	fwrite(sdr->buffer, sizeof(uint8_t), sdr->receivesize, sdr->filewrite);
#endif

}
示例#9
0
void full_demod(unsigned char *buf, uint32_t len, struct fm_state *fm)
{
	int sr, freq_next;
	rotate_90(buf, len);
	if (fm->fir_enable) {
		low_pass_fir(fm, buf, len);
	} else {
		low_pass(fm, buf, len);
	}
	fm_demod(fm);
	sr = post_squelch(fm);
	if (fm->post_downsample > 1) {
		fm->signal_len = low_pass_simple(fm->signal2, fm->signal_len/2, fm->post_downsample)*2;}
	/* ignore under runs for now */
	fwrite(fm->signal2, 2, fm->signal_len/2, fm->file);
	if (fm->freq_len > 1 && !sr && fm->squelch_hits > CONSEQ_SQUELCH) {
		freq_next = (fm->freq_now + 1) % fm->freq_len;
		optimal_settings(fm, freq_next, 1);
		fm->squelch_hits = CONSEQ_SQUELCH + 1;  /* hair trigger */
		/* wait for settling and dump buffer */
		usleep(5000);
		rtlsdr_read_sync(dev, NULL, 4096, NULL);
	}
}
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;
}
示例#11
0
文件: rtl_test.c 项目: 9nut/rtl-sdr
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;
}
示例#12
0
int main(int argc, char **argv)
{
#ifndef _WIN32
	struct sigaction sigact;
#endif
	int n_read, r, opt, i;
	int sync_mode = 0;
	uint8_t *buffer;
	int dev_index = 0;
	int dev_given = 0;
	uint32_t out_block_size = DEFAULT_BUF_LENGTH;
	int count;
	int gains[100];

	while ((opt = getopt(argc, argv, "d:s:b:tp::Sh")) != -1) {
		switch (opt) {
		case 'd':
			dev_index = verbose_device_search(optarg);
			dev_given = 1;
			break;
		case 's':
			samp_rate = (uint32_t)atof(optarg);
			break;
		case 'b':
			out_block_size = (uint32_t)atof(optarg);
			break;
		case 't':
			test_mode = TUNER_BENCHMARK;
			break;
		case 'p':
			test_mode = PPM_BENCHMARK;
			if (optarg)
				ppm_duration = atoi(optarg);
			break;
		case 'S':
			sync_mode = 1;
			break;
		case 'h':
		default:
			usage();
			break;
		}
	}

	if(out_block_size < MINIMAL_BUF_LENGTH ||
	   out_block_size > MAXIMAL_BUF_LENGTH ){
		fprintf(stderr,
			"Output block size wrong value, falling back to default\n");
		fprintf(stderr,
			"Minimal length: %u\n", MINIMAL_BUF_LENGTH);
		fprintf(stderr,
			"Maximal length: %u\n", MAXIMAL_BUF_LENGTH);
		out_block_size = DEFAULT_BUF_LENGTH;
	}

	buffer = malloc(out_block_size * sizeof(uint8_t));

	if (!dev_given) {
		dev_index = verbose_device_search("0");
	}

	if (dev_index < 0) {
		exit(1);
	}

	r = rtlsdr_open(&dev, (uint32_t)dev_index);
	if (r < 0) {
		fprintf(stderr, "Failed to open rtlsdr device #%d.\n", dev_index);
		exit(1);
	}
#ifndef _WIN32
	sigact.sa_handler = sighandler;
	sigemptyset(&sigact.sa_mask);
	sigact.sa_flags = 0;
	sigaction(SIGINT, &sigact, NULL);
	sigaction(SIGTERM, &sigact, NULL);
	sigaction(SIGQUIT, &sigact, NULL);
	sigaction(SIGPIPE, &sigact, NULL);
#else
	SetConsoleCtrlHandler( (PHANDLER_ROUTINE) sighandler, TRUE );
#endif
	count = rtlsdr_get_tuner_gains(dev, NULL);
	fprintf(stderr, "Supported gain values (%d): ", count);

	count = rtlsdr_get_tuner_gains(dev, gains);
	for (i = 0; i < count; i++)
		fprintf(stderr, "%.1f ", gains[i] / 10.0);
	fprintf(stderr, "\n");

	/* Set the sample rate */
	verbose_set_sample_rate(dev, samp_rate);

	if (test_mode == TUNER_BENCHMARK) {
		tuner_benchmark();
		goto exit;
	}

	/* Enable test mode */
	r = rtlsdr_set_testmode(dev, 1);

	/* Reset endpoint before we start reading from it (mandatory) */
	verbose_reset_buffer(dev);

	if ((test_mode == PPM_BENCHMARK) && !sync_mode) {
		fprintf(stderr, "Reporting PPM error measurement every %i seconds...\n", ppm_duration);
		fprintf(stderr, "Press ^C after a few minutes.\n");
	}

	if (test_mode == NO_BENCHMARK) {
		fprintf(stderr, "\nInfo: This tool will continuously"
				" read from the device, and report if\n"
				"samples get lost. If you observe no "
				"further output, everything is fine.\n\n");
	}

	if (sync_mode) {
		fprintf(stderr, "Reading samples in sync mode...\n");
		fprintf(stderr, "(Samples are being lost but not reported.)\n");
		while (!do_exit) {
			r = rtlsdr_read_sync(dev, buffer, out_block_size, &n_read);
			if (r < 0) {
				fprintf(stderr, "WARNING: sync read failed.\n");
				break;
			}

			if ((uint32_t)n_read < out_block_size) {
				fprintf(stderr, "Short read, samples lost, exiting!\n");
				break;
			}
			underrun_test(buffer, n_read, 1);
		}
	} else {
		fprintf(stderr, "Reading samples in async mode...\n");
		r = rtlsdr_read_async(dev, rtlsdr_callback, NULL,
				      0, out_block_size);
	}

	if (do_exit) {
		fprintf(stderr, "\nUser cancel, exiting...\n");
		fprintf(stderr, "Samples per million lost (minimum): %i\n", (int)(1000000L * dropped_samples / total_samples));
	}
	else
		fprintf(stderr, "\nLibrary error %d, exiting...\n", r);

exit:
	rtlsdr_close(dev);
	free (buffer);

	return r >= 0 ? r : -r;
}
示例#13
0
文件: rtl_433.c 项目: dducret/rtl_433
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(&timestamp);
          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;
}
示例#14
0
void vspectra(void)
{

    int i, j, k, kk, num, numm, i4, maxi, r;
    int m, mm, blsiz, blsiz2, nsam, n_read;
    double avsig, av, max, min, noise, wid;
    uint8_t *bufferRead = malloc((NSAM) * sizeof(uint8_t));
    static double vspec[NSPEC];
    static int wtt[NSPEC];
    static double re[NSPEC * 2], am[NSPEC * 2];
    double smax;
    fftwf_plan p0;
    float *reamin0, *reamout0;


    blsiz = NSPEC * 2;
    blsiz2 = blsiz / 2;
    d1.bw = 2.4;                // fixed 2.4 for TV dongle 10 MHz for ADC card
    if (d1.fbw == 0.0)
        d1.fbw = 2.0;           //  use bandwidth default if not set in srt.cat
    d1.f1 = 0.5 - (d1.fbw / d1.bw) * 0.5;
    d1.f2 = 0.5 + (d1.fbw / d1.bw) * 0.5;
    d1.fc = (d1.f1 + d1.f2) * 0.5;
    d1.lofreq = 0;              // not used but needs to be set to zero to flag the use of the dongle 
    d1.efflofreq = d1.freq - d1.bw * 0.5;

    if (!d1.fftsim) {
        fft_init(blsiz2, &p0, &reamin0, &reamout0);
    }

    num = d1.nblk;              //was 20   // was 100
    nsam = NSAM;
    d1.nsam = NSAM * num;
    avsig = 0;
    numm = 0;
    smax = 0;
    max = -1e99;
    min = 1e99;
    for (i = 0; i < blsiz2; i++)
        vspec[i] = 0.0;
    for (k = 0; k < num; k++) {
        if (!d1.radiosim)
// Read the raw data from the RTL Dongle
            r = rtlsdr_read_sync(dev, bufferRead, nsam, &n_read);
        else {
            av = 5.0;
            if (d1.elnow < 5.0)
                av = av * (d1.tsys + d1.tcal) / d1.tsys;
            if (strstr(soutrack, "Sun")) {
                av = sqrt(d1.eloff * d1.eloff +
                          d1.azoff * d1.azoff * cos(d1.elnow * PI / 180.0) * cos(d1.elnow * PI / 180.0) +
                          1e-6);
                if (av > d1.beamw)
                    av = d1.beamw;
                av = 5.0 + 25.0 * cos(av * PI * 0.5 / d1.beamw) * cos(av * PI * 0.5 / d1.beamw);
            }
            for (i = 0; i < nsam; i++)
                bufferRead[i] = (uint8_t) (sqrt(av) * gauss() + 127.397 + 0.5 + 0 * sin(2.0 * PI * 0.5 * (i / 2) / d1.bw)); // simulate data
        }

//   for(i=0;i<nsam;i+=0x10000)  printf("%d %f\n",i,(double)(bufferRead[i]-127.397));
        for (kk = 0; kk < nsam / blsiz; kk++) {
            if (d1.fftsim)
                for (i = 0; i < blsiz2; i++) {
                    re[i] = (double) (bufferRead[2 * i + kk * blsiz] - 127.397);
                    am[i] = (double) (bufferRead[2 * i + 1 + kk * blsiz] - 127.397);
                    if (re[i] > smax)
                        smax = re[i];
            } else
                for (i = 0; i < blsiz2; i++) {
                    reamin0[2 * i] = (float) (bufferRead[2 * i + kk * blsiz] - 127.397);
                    reamin0[2 * i + 1] = (float) (bufferRead[2 * i + 1 + kk * blsiz] - 127.397);
                    if (reamin0[2 * i] > smax)
                        smax = reamin0[2 * i];
                }

            if (d1.fftsim)
                Four(re, am, blsiz2);
            else {
                cfft(&p0);
                for (i = 0; i < blsiz2; i++) {
                    re[i] = reamout0[2 * i];
                    am[i] = reamout0[2 * i + 1];
                }
            }
// for(i = 0; i < blsiz2; i++) if(re[i] > max) max=re[i];
// for(i = 0; i < blsiz2; i++) if(re[i] < min) min=re[i];
            for (i = 0; i < blsiz2; i++) {
                if (i < blsiz2 / 2)
                    j = i + blsiz2 / 2;
                else
                    j = i - blsiz2 / 2;
                vspec[j] += re[i] * re[i] + am[i] * am[i];
                numm++;
            }
        }
    }
//   printf("max %f min %f\n",max,min);
    max = av = 0;
    maxi = 0;
    for (i = 0; i < blsiz2; i++)
        wtt[i] = 1;
    if (numm > 0) {
        if (d1.nfreq == blsiz2) {
            for (i = 0; i < blsiz2; i++) {
                if (i > 10)
                    spec[i] = vspec[i] / (double) numm;
                else
                    spec[i] = 0;
            }
        } else {
            m = blsiz2 / d1.nfreq;
            for (i = 0; i < d1.nrfi; i++) {
                i4 = (d1.rfi[i] - d1.freq + d1.bw * 0.5) * blsiz2 / d1.bw + 0.5; // index of rfi MHz 
                wid = 0.5 * d1.rfiwid[i] / (d1.bw / NSPEC);
                for (j = -wid; j <= wid; j++)
                    if ((i4 + j) >= 0 && (i4 + j) < blsiz2)
                        wtt[i4 + j] = 0;
            }
            for (j = 0; j < d1.nfreq; j++) {
                av = mm = 0;
                for (i = j * m - m / 2; i <= j * m + m / 2; i++) {
                    if (i > 10 && i < blsiz2 && wtt[i]) { // wtt=0 removal of spurs
                        av += vspec[i] / (double) numm;
                        if (vspec[i] > max) {
                            max = vspec[i];
                            maxi = i;
                        }
                        mm++;
                    }
                }
                if (mm > 0)
                    spec[j] = av / mm;
                else {
                    spec[j] = 0;
                    if (j > 10)
                        printf("check RFI settings in srt.cat data deleted at %8.3f\n",
                               j * d1.bw / d1.nfreq + d1.freq - d1.bw * 0.5);
                }
            }
            max = max / (double) numm;
            noise = spec[maxi / m] * sqrt(2.0 * blsiz2 / (double) d1.nsam);
            if (max > spec[maxi / m] + d1.rfisigma * noise && d1.printout) // rfisigma sigma
                printf("check for RFI at %8.4f MHz max %5.0e av %5.0e smax %5.0f %3.0f sigma\n",
                       maxi * d1.bw / blsiz2 + d1.freq - d1.bw * 0.5, max, spec[maxi / m], smax,
                       (max - spec[maxi / m]) / noise);
        }
    }
    d1.smax = smax;
    if (!d1.fftsim)
        fft_free(&p0, &reamin0, &reamout0);
    free(bufferRead);
}
示例#15
0
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;
}
示例#16
0
文件: rtl_asgram.c 项目: EQ4/sdr_rec
// 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;
}
示例#17
0
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;
}
示例#18
0
文件: rtl_demod.c 项目: EQ4/sdr_rec
// 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;
}
示例#19
0
void scanner(void)
{
	int i, j, j2, f, n_read, offset, bin_e, bin_len, buf_len, ds, ds_p;
	int32_t w;
	struct tuning_state *ts;
	bin_e = tunes[0].bin_e;
	bin_len = 1 << bin_e;
	buf_len = tunes[0].buf_len;
	for (i=0; i<tune_count; i++) {
		if (do_exit >= 2)
			{return;}
		ts = &tunes[i];
		f = (int)rtlsdr_get_center_freq(dev);
		if (f != ts->freq) {
			retune(dev, ts->freq);}
		rtlsdr_read_sync(dev, ts->buf8, buf_len, &n_read);
		if (n_read != buf_len) {
			fprintf(stderr, "Error: dropped samples.\n");}
		/* rms */
		if (bin_len == 1) {
			rms_power(ts);
			continue;
		}
		/* prep for fft */
		for (j=0; j<buf_len; j++) {
			fft_buf[j] = (int16_t)ts->buf8[j] - 127;
		}
		ds = ts->downsample;
		ds_p = ts->downsample_passes;
		if (boxcar && ds > 1) {
			j=2, j2=0;
			while (j < buf_len) {
				fft_buf[j2]   += fft_buf[j];
				fft_buf[j2+1] += fft_buf[j+1];
				fft_buf[j] = 0;
				fft_buf[j+1] = 0;
				j += 2;
				if (j % (ds*2) == 0) {
					j2 += 2;}
			}
		} else if (ds_p) {  /* recursive */
			for (j=0; j < ds_p; j++) {
				downsample_iq(fft_buf, buf_len >> j);
			}
			/* droop compensation */
			if (comp_fir_size == 9 && ds_p <= CIC_TABLE_MAX) {
				generic_fir(fft_buf, buf_len >> j, cic_9_tables[ds_p]);
				generic_fir(fft_buf+1, (buf_len >> j)-1, cic_9_tables[ds_p]);
			}
		}
		remove_dc(fft_buf, buf_len / ds);
		remove_dc(fft_buf+1, (buf_len / ds) - 1);
		/* window function and fft */
		for (offset=0; offset<(buf_len/ds); offset+=(2*bin_len)) {
			// todo, let rect skip this
			for (j=0; j<bin_len; j++) {
				w =  (int32_t)fft_buf[offset+j*2];
				w *= (int32_t)(window_coefs[j]);
				//w /= (int32_t)(ds);
				fft_buf[offset+j*2]   = (int16_t)w;
				w =  (int32_t)fft_buf[offset+j*2+1];
				w *= (int32_t)(window_coefs[j]);
				//w /= (int32_t)(ds);
				fft_buf[offset+j*2+1] = (int16_t)w;
			}
			fix_fft(fft_buf+offset, bin_e);
			if (!peak_hold) {
				for (j=0; j<bin_len; j++) {
					ts->avg[j] += real_conj(fft_buf[offset+j*2], fft_buf[offset+j*2+1]);
				}
			} else {
				for (j=0; j<bin_len; j++) {
					ts->avg[j] = MAX(real_conj(fft_buf[offset+j*2], fft_buf[offset+j*2+1]), ts->avg[j]);
				}
			}
			ts->samples += ds;
		}
	}
示例#20
0
void readData(int line_idx)
{	
	// this also works without the /2, the fft only needs to be drawn in the texture once then
	// I'm not sure if this is supposed to work like that, maybe ask some GL expert?
	// use /2 for now, maybe test later for performance
	if(line_idx == GLUT_BUFSIZE/2)
	{
		offset = 0.0f;
		line_idx = 0;
	}
	else offset = -(float)(line_idx)/(float)GLUT_BUFSIZE;

	// scale colors every full round of the buffer
/*	if(line_idx==100)
	{
		pwr_diff = pwr_max;
		fprintf(stderr, "pwr_diff reset to %.2f\n", pwr_diff);
		pwr_max = 0.0f;
	}
*/	
	uint32_t out_block_size = DEFAULT_BUF_LENGTH;
	int n_read;
	int r = rtlsdr_read_sync(dev, buffer, out_block_size, &n_read);
	if (r < 0)
	{
		fprintf(stderr, "WARNING: sync read failed.\n");
		return;
	}
	
	if ((uint32_t)n_read < out_block_size)
	{
		fprintf(stderr, "Short read, samples lost, exiting!\n");
		return;
	}
	
	// calculate fft of buffer
	uint32_t N = out_block_size/2;
	int i;
	for(i = 0 ; i < N ; i++)
	{
		fftw_in[i][0] = (buffer[i*2] -127) * 0.008;		// adc is 8 bits, map (0,255) to (-1,1)
		fftw_in[i][1] = (buffer[i*2 +1] -127) * 0.008;
	}
	fftw_execute(fftw_p);
	//fprintf(stderr, "%d\n", n_read);
	//fprintf(stderr, "%3d: %d %d %d %d %d %d %d %d %d %d\n", line_idx, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], buffer[8], buffer[9] );
	//fprintf(stderr, "%3d: %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f\n", line_idx, fftw_in[0][0], fftw_in[0][1], fftw_in[1][0], fftw_in[1][1], fftw_in[2][0], fftw_in[2][1], fftw_in[3][0], fftw_in[3][1], fftw_in[4][0], fftw_in[4][1] );
	//fprintf(stderr, "%3d: %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f\n", line_idx, fftw_out[0][0], fftw_out[0][1], fftw_out[1][0], fftw_out[1][1], fftw_out[2][0], fftw_out[2][1], fftw_out[3][0], fftw_out[3][1], fftw_out[4][0], fftw_out[4][1] );

		
	// put fft on screen
	// x = index of pixel on screen, n_avg is number of fft bins that have to be averaged in one pixel
	int n_avg = N / GLUT_BUFSIZE;
	float pwr, color_idx, color_blue, color_green, color_red;
	int x, p;
	for(x = 0 ; x < GLUT_BUFSIZE ; x++)
	{
		pwr = 0.0f;
		for(p = 0 ; p < n_avg ; p++) pwr += (fftw_out[(x*n_avg) +p][0] * fftw_out[(x*n_avg) +p][0]) + (fftw_out[(x*n_avg) +p][1] * fftw_out[(x*n_avg) +p][1]);
		pwr /= (n_avg * (N/2));
		
		// scale colors to power in spectrum
		if(pwr > pwr_max) pwr_max = pwr;
		color_idx = pwr/pwr_diff;
		
		//color_idx = (float)x/(float)GLUT_BUFSIZE;
		if(color_idx < 1)
		{
			//color_blue = (sin((color_idx * 3.1415f) + 1.5708) +1)/2;
			//color_green = sin(color_idx * 3.1415f);
			//color_red = (sin((color_idx * 3.1415f) - 1.5708) +1)/2;
			color_blue = exp( -((color_idx - 0.1) / .3) * ((color_idx - 0.1) / .3) );
			color_green = exp( -((color_idx - 0.35) / .5) * ((color_idx - 0.35) / .5) );
			color_red = exp( -((color_idx - .95) / .3) * ((color_idx - .95) / .3) );
		}
		else
		{
			color_blue = 0.0f;
			color_green = 0.0f;
			color_red = 1.0f;
		}
		
		// negative frequencies are in [N/2,N] and positive in [0,N/2]
		int xN;
		if(x < (GLUT_BUFSIZE/2)) xN = x + GLUT_BUFSIZE/2;
		else xN = x - GLUT_BUFSIZE/2;
		texture[xN][GLUT_BUFSIZE-line_idx-1][0] = color_red;
		texture[xN][GLUT_BUFSIZE-line_idx-1][1] = color_green;
		texture[xN][GLUT_BUFSIZE-line_idx-1][2] = color_blue;
		
		// when using line_idx == GLUT_BUFSIZE/2 in the first if statement the fft should be drawn twice
		texture[xN][(GLUT_BUFSIZE/2)-line_idx-1][0] = color_red;
		texture[xN][(GLUT_BUFSIZE/2)-line_idx-1][1] = color_green;
		texture[xN][(GLUT_BUFSIZE/2)-line_idx-1][2] = color_blue;
	}
	//fprintf(stderr, "%.2f\n", pwr_max);

	glutPostRedisplay();
	glutTimerFunc(0,readData,++line_idx);
}