diff options
| author | Felix Erckenbrecht <dg1yfe@stus-disco.de> | 2022-03-25 08:52:32 +0100 | 
|---|---|---|
| committer | Felix Erckenbrecht <dg1yfe@stus-disco.de> | 2022-03-25 08:52:32 +0100 | 
| commit | 8a99e6b24664a775c4038714193d147171fd5afd (patch) | |
| tree | 3e7f6bf293da1c75928fcb6f6010dc63a27511c4 | |
| parent | 3f05271da3e6f4a4561e440c4c8a0cdce3636f73 (diff) | |
| download | osmo-fl2k-8a99e6b24664a775c4038714193d147171fd5afd.tar.gz osmo-fl2k-8a99e6b24664a775c4038714193d147171fd5afd.tar.bz2 osmo-fl2k-8a99e6b24664a775c4038714193d147171fd5afd.zip | |
Cleanup - only build ampliphase binary
| -rw-r--r-- | src/CMakeLists.txt | 59 | ||||
| -rw-r--r-- | src/fl2k_ampliphase.c (renamed from src/fl2k_iq.c) | 0 | ||||
| -rw-r--r-- | src/fl2k_file.c | 215 | ||||
| -rw-r--r-- | src/fl2k_fm.c | 621 | ||||
| -rw-r--r-- | src/fl2k_garage.c | 545 | ||||
| -rw-r--r-- | src/fl2k_tcp.c | 256 | ||||
| -rw-r--r-- | src/fl2k_test.c | 308 | ||||
| -rw-r--r-- | src/rds_mod.c | 302 | ||||
| -rw-r--r-- | src/rds_waveforms.c | 153 | 
9 files changed, 6 insertions, 2453 deletions
| diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 543226e..f4ec556 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -75,69 +75,22 @@ endif()  ########################################################################  # Build utility  ######################################################################## -add_executable(fl2k_file fl2k_file.c) -add_executable(fl2k_tcp fl2k_tcp.c) -add_executable(fl2k_test fl2k_test.c) -add_executable(fl2k_fm fl2k_fm.c rds_waveforms.c rds_mod.c) -add_executable(fl2k_garage fl2k_garage.c) -add_executable(fl2k_iq fl2k_iq.c) -set(INSTALL_TARGETS libosmo-fl2k_shared libosmo-fl2k_static fl2k_file fl2k_tcp fl2k_test fl2k_fm fl2k_garage fl2k_iq) +add_executable(fl2k_ampliphase fl2k_ampliphase.c) +set(INSTALL_TARGETS libosmo-fl2k_shared libosmo-fl2k_static fl2k_ampliphase) -target_link_libraries(fl2k_file libosmo-fl2k_shared -    ${LIBUSB_LIBRARIES} -    ${CMAKE_THREAD_LIBS_INIT} -) - -target_link_libraries(fl2k_tcp libosmo-fl2k_shared -    ${LIBUSB_LIBRARIES} -    ${CMAKE_THREAD_LIBS_INIT} -) - -target_link_libraries(fl2k_test libosmo-fl2k_shared -    ${LIBUSB_LIBRARIES} -    ${CMAKE_THREAD_LIBS_INIT} -) - -target_link_libraries(fl2k_fm libosmo-fl2k_shared -    ${LIBUSB_LIBRARIES} -    ${CMAKE_THREAD_LIBS_INIT} -) - -target_link_libraries(fl2k_garage libosmo-fl2k_shared -    ${LIBUSB_LIBRARIES} -    ${CMAKE_THREAD_LIBS_INIT} -) - -target_link_libraries(fl2k_iq libosmo-fl2k_shared +target_link_libraries(fl2k_ampliphase libosmo-fl2k_shared      ${LIBUSB_LIBRARIES}      ${CMAKE_THREAD_LIBS_INIT}  )  if(UNIX) -target_link_libraries(fl2k_test m) -target_link_libraries(fl2k_fm m) -target_link_libraries(fl2k_garage m) -target_link_libraries(fl2k_iq m) +target_link_libraries(fl2k_ampliphase m)  endif()  if(WIN32 AND NOT MINGW) -target_link_libraries(fl2k_file libgetopt_static) -target_link_libraries(fl2k_tcp ws2_32 libgetopt_static) -target_link_libraries(fl2k_test libgetopt_static) -target_link_libraries(fl2k_fm libgetopt_static) -target_link_libraries(fl2k_garage libgetopt_static) -target_link_libraries(fl2k_iq libgetopt_static) -set_property(TARGET fl2k_file APPEND PROPERTY COMPILE_DEFINITIONS "libosmo-fl2k_STATIC" ) -set_property(TARGET fl2k_tcp APPEND PROPERTY COMPILE_DEFINITIONS "libosmo-fl2k_STATIC" ) -set_property(TARGET fl2k_test APPEND PROPERTY COMPILE_DEFINITIONS "libosmo-fl2k_STATIC" ) -set_property(TARGET fl2k_fm APPEND PROPERTY COMPILE_DEFINITIONS "libosmo-fl2k_STATIC" ) -set_property(TARGET fl2k_garage APPEND PROPERTY COMPILE_DEFINITIONS "libosmo-fl2k_STATIC" ) -set_property(TARGET fl2k_iq APPEND PROPERTY COMPILE_DEFINITIONS "libosmo-fl2k_STATIC" ) -endif() - -if(MINGW) -target_link_libraries(fl2k_tcp ws2_32) +target_link_libraries(fl2k_ampliphase libgetopt_static) +set_property(TARGET fl2k_ampliphase APPEND PROPERTY COMPILE_DEFINITIONS "libosmo-fl2k_STATIC" )  endif()  ######################################################################## diff --git a/src/fl2k_iq.c b/src/fl2k_ampliphase.c index db8d7bf..db8d7bf 100644 --- a/src/fl2k_iq.c +++ b/src/fl2k_ampliphase.c diff --git a/src/fl2k_file.c b/src/fl2k_file.c deleted file mode 100644 index 5ae199b..0000000 --- a/src/fl2k_file.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * osmo-fl2k, turns FL2000-based USB 3.0 to VGA adapters into - * low cost DACs - * - * Copyright (C) 2016-2018 by Steve Markgraf <steve@steve-m.de> - * - * SPDX-License-Identifier: GPL-2.0+ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -#include <errno.h> -#include <signal.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> - -#ifndef _WIN32 -#include <unistd.h> -#define sleep_ms(ms)	usleep(ms*1000) -#else -#include <windows.h> -#include <io.h> -#include <fcntl.h> -#include "getopt/getopt.h" -#define sleep_ms(ms)	Sleep(ms) -#endif - -#include "osmo-fl2k.h" - -static fl2k_dev_t *dev = NULL; - -static volatile int do_exit = 0; -static volatile int repeat = 1; -FILE *file; -char *txbuf = NULL; - -void usage(void) -{ -	fprintf(stderr, -		"fl2k_file, a sample player for FL2K VGA dongles\n\n" -		"Usage:\n" -		"\t[-d device_index (default: 0)]\n" -		"\t[-r repeat file (default: 1)]\n" -		"\t[-s samplerate (default: 100 MS/s)]\n" -		"\tfilename (use '-' to read from stdin)\n\n" -	); -	exit(1); -} - -#ifdef _WIN32 -BOOL WINAPI -sighandler(int signum) -{ -	if (CTRL_C_EVENT == signum) { -		fprintf(stderr, "Signal caught, exiting!\n"); -		fl2k_stop_tx(dev); -		do_exit = 1; -		return TRUE; -	} -	return FALSE; -} -#else -static void sighandler(int signum) -{ -	fprintf(stderr, "Signal caught, exiting!\n"); -	fl2k_stop_tx(dev); -	do_exit = 1; -} -#endif - -void fl2k_callback(fl2k_data_info_t *data_info) -{ -	int r, left = FL2K_BUF_LEN; -	static uint32_t repeat_cnt = 0; - -	if (data_info->device_error) { -		fprintf(stderr, "Device error, exiting.\n"); -		do_exit = 1; -		return; -	} - -	data_info->sampletype_signed = 1; -	data_info->r_buf = txbuf; - -	while (!do_exit && (left > 0)) { -		r = fread(txbuf + (FL2K_BUF_LEN - left), 1, left, file); - -		if (ferror(file)) -			fprintf(stderr, "File Error\n"); - -		if (feof(file)) { -			if (repeat && (r > 0)) { -				repeat_cnt++; -				fprintf(stderr, "repeat %d\n", repeat_cnt); -				rewind(file); -			} else { -				fl2k_stop_tx(dev); -				do_exit = 1; -			} -		} - -		if (r > 0) -			left -= r; -	} -} - -int main(int argc, char **argv) -{ -#ifndef _WIN32 -	struct sigaction sigact, sigign; -#endif -	int r, opt, i; -	uint32_t samp_rate = 100000000; -	uint32_t buf_num = 0; -	int dev_index = 0; -	void *status; -	char *filename = NULL; - -	while ((opt = getopt(argc, argv, "d:r:s:")) != -1) { -		switch (opt) { -		case 'd': -			dev_index = (uint32_t)atoi(optarg); -			break; -		case 'r': -			repeat = (int)atoi(optarg); -			break; -		case 's': -			samp_rate = (uint32_t)atof(optarg); -			break; -		default: -			usage(); -			break; -		} -	} - -	if (argc <= optind) -		usage(); -	else -		filename = argv[optind]; - -	if (dev_index < 0) -		exit(1); - -	if (strcmp(filename, "-") == 0) { /* Read samples from stdin */ -		file = stdin; -#ifdef _WIN32 -		_setmode(_fileno(stdin), _O_BINARY); -#endif -	} else { -		file = fopen(filename, "rb"); -		if (!file) { -			fprintf(stderr, "Failed to open %s\n", filename); -			return -ENOENT; -		} -	} - -	txbuf = malloc(FL2K_BUF_LEN); -	if (!txbuf) { -		fprintf(stderr, "malloc error!\n"); -		goto out; -	} - -	fl2k_open(&dev, (uint32_t)dev_index); -	if (NULL == dev) { -		fprintf(stderr, "Failed to open fl2k device #%d.\n", dev_index); -		goto out; -	} - -	r = fl2k_start_tx(dev, fl2k_callback, NULL, 0); - -	/* Set the sample rate */ -	r = fl2k_set_sample_rate(dev, samp_rate); -	if (r < 0) -		fprintf(stderr, "WARNING: Failed to set sample rate.\n"); - - -#ifndef _WIN32 -	sigact.sa_handler = sighandler; -	sigemptyset(&sigact.sa_mask); -	sigact.sa_flags = 0; -	sigign.sa_handler = SIG_IGN; -	sigaction(SIGINT, &sigact, NULL); -	sigaction(SIGTERM, &sigact, NULL); -	sigaction(SIGQUIT, &sigact, NULL); -	sigaction(SIGPIPE, &sigign, NULL); -#else -	SetConsoleCtrlHandler( (PHANDLER_ROUTINE) sighandler, TRUE ); -#endif - -	while (!do_exit) -		sleep_ms(500); - -	fl2k_close(dev); - -out: -	if (txbuf) -		free(txbuf); - -	if (file && (file != stdin)) -		fclose(file); - -	return 0; -} diff --git a/src/fl2k_fm.c b/src/fl2k_fm.c deleted file mode 100644 index b22efcd..0000000 --- a/src/fl2k_fm.c +++ /dev/null @@ -1,621 +0,0 @@ -/* - * osmo-fl2k, turns FL2000-based USB 3.0 to VGA adapters into - * low cost DACs - * - * Copyright (C) 2016-2018 by Steve Markgraf <steve@steve-m.de> - * - * based on FM modulator code from VGASIG: - * Copyright (C) 2009 by Bartek Kania <mbk@gnarf.org> - * - * SPDX-License-Identifier: GPL-2.0+ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <signal.h> -#include <string.h> -#include <errno.h> - -#ifndef _WIN32 -#include <unistd.h> -#include <fcntl.h> -#include <getopt.h> -#else -#include <windows.h> -#include <io.h> -#include <fcntl.h> -#include "getopt/getopt.h" -#endif - -#include <math.h> -#include <pthread.h> - -#include "osmo-fl2k.h" -#include "rds_mod.h" - -#define BUFFER_SAMPLES_SHIFT	16 -#define BUFFER_SAMPLES		(1 << BUFFER_SAMPLES_SHIFT) -#define BUFFER_SAMPLES_MASK	((1 << BUFFER_SAMPLES_SHIFT)-1) - -#define AUDIO_BUF_SIZE		1024 - -fl2k_dev_t *dev = NULL; -int do_exit = 0; - -pthread_t fm_thread; -pthread_mutex_t cb_mutex; -pthread_mutex_t fm_mutex; -pthread_cond_t cb_cond; -pthread_cond_t fm_cond; - -FILE *file; -int8_t *txbuf = NULL; -int8_t *fmbuf = NULL; -int8_t *buf1 = NULL; -int8_t *buf2 = NULL; - -uint32_t samp_rate = 100000000; - -/* default signal parameters */ -#define PILOT_FREQ	19000	/* In Hz */ -#define STEREO_CARRIER	38000	/* In Hz */ - -int deviation = 75000; -int carrier_freq = 97000000; -int carrier_per_signal; -int input_freq = 44100; -int stereo_flag = 0; -int rds_flag = 0; - -double *freqbuf;  -double *slopebuf;  -int writepos, readpos; - -void usage(void) -{ -	fprintf(stderr, -		"fl2k_fm, an FM modulator for FL2K VGA dongles\n\n" -		"Usage:" -		"\t[-d device index (default: 0)]\n" -		"\t[-c carrier frequency (default: 9.7 MHz)]\n" -		"\t[-f FM deviation (default: 75000 Hz, WBFM)]\n" -		"\t[-i input audio sample rate (default: 44100 Hz for mono FM)]\n" -		"\t[-s samplerate in Hz (default: 100 MS/s)]\n" -		"\t[--rds (enables RDS, forces audio sample rate to 228 kHz)]\n" -		"\t[--stereo (enables stereo, requires audio sample rate >= 114 kHz)]\n" -		"\tfilename (use '-' to read from stdin)\n\n" -	); -	exit(1); -} - -#ifdef _WIN32 -BOOL WINAPI -sighandler(int signum) -{ -	if (CTRL_C_EVENT == signum) { -		fprintf(stderr, "Signal caught, exiting!\n"); -		fl2k_stop_tx(dev); -		do_exit = 1; -		pthread_cond_signal(&fm_cond); -		return TRUE; -	} -	return FALSE; -} -#else -static void sighandler(int signum) -{ -	fprintf(stderr, "Signal caught, exiting!\n"); -	fl2k_stop_tx(dev); -	do_exit = 1; -	pthread_cond_signal(&fm_cond); -} -#endif - -/* DDS Functions */ - -#ifndef M_PI -# define M_PI		3.14159265358979323846	/* pi */ -# define M_PI_2		1.57079632679489661923	/* pi/2 */ -# define M_PI_4		0.78539816339744830962	/* pi/4 */ -# define M_1_PI		0.31830988618379067154	/* 1/pi */ -# define M_2_PI		0.63661977236758134308	/* 2/pi */ -#endif -#define DDS_2PI		(M_PI * 2)		/* 2 * Pi */ -#define DDS_3PI2	(M_PI_2 * 3)		/* 3/2 * pi */ - -#define SIN_TABLE_ORDER	8 -#define SIN_TABLE_SHIFT	(32 - SIN_TABLE_ORDER) -#define SIN_TABLE_LEN	(1 << SIN_TABLE_ORDER) -#define ANG_INCR	(0xffffffff / DDS_2PI) - -int8_t sine_table[SIN_TABLE_LEN]; -int sine_table_init = 0; - -typedef struct { -	double sample_freq; -	double freq; -	double fslope; -	unsigned long int phase; -	unsigned long int phase_step; -	unsigned long int phase_slope; -} dds_t; - -static inline void dds_setphase(dds_t *dds, double phase) -{ -	dds->phase = phase * ANG_INCR; -} - -static inline double dds_getphase(dds_t *dds) -{ -	return dds->phase / ANG_INCR; -} - -static inline void dds_set_freq(dds_t *dds, double freq, double fslope) -{ -	dds->fslope = fslope; -	dds->phase_step = (freq / dds->sample_freq) * 2 * M_PI * ANG_INCR; - -	/* The slope parameter is used with the FM modulator to create -	 * a simple but very fast and effective interpolation filter. -	 * See the fm modulator for details */ -	dds->freq = freq; -	dds->phase_slope = (fslope / dds->sample_freq) * 2 * M_PI * ANG_INCR; -} - -dds_t dds_init(double sample_freq, double freq, double phase) -{ -	dds_t dds; -	int i; - -	dds.sample_freq = sample_freq; -	dds.phase = phase * ANG_INCR; -	dds_set_freq(&dds, freq, 0); - -	/* Initialize sine table, prescaled for 8 bit signed integer */ -	if (!sine_table_init) { -		double incr = 1.0 / (double)SIN_TABLE_LEN; -		for (i = 0; i < SIN_TABLE_LEN; i++) -			sine_table[i] = sin(incr * i * DDS_2PI) * 127; - -		sine_table_init = 1; -	} - -	return dds; -} - -static inline int8_t dds_real(dds_t *dds) -{ -	int tmp; - -	tmp = dds->phase >> SIN_TABLE_SHIFT; -	dds->phase += dds->phase_step; -	dds->phase &= 0xffffffff; - -	dds->phase_step += dds->phase_slope; - -	return sine_table[tmp]; -} - -static inline void dds_real_buf(dds_t *dds, int8_t *buf, int count) -{ -	int i; -	for (i = 0; i < count; i++) -		buf[i] = dds_real(dds); -} - -/* Signal generation and some helpers */ - -/* Generate the radio signal using the pre-calculated frequency information - * in the freq buffer */ -static void *fm_worker(void *arg) -{ -	register double freq; -	register double tmp; -	dds_t carrier; -	int8_t *tmp_ptr; -	uint32_t len = 0; -	uint32_t readlen, remaining; -	int buf_prefilled = 0; - -	/* Prepare the oscillators */ -	carrier = dds_init(samp_rate, carrier_freq, 0); - -	while (!do_exit) { -		dds_set_freq(&carrier, freqbuf[readpos], slopebuf[readpos]); -		readpos++; -		readpos &= BUFFER_SAMPLES_MASK; - -		/* check if we reach the end of the buffer */ -		if ((len + carrier_per_signal) > FL2K_BUF_LEN) { -			readlen = FL2K_BUF_LEN - len; -			remaining = carrier_per_signal - readlen; -			dds_real_buf(&carrier, &fmbuf[len], readlen); - -			if (buf_prefilled) { -				/* swap buffers */ -				tmp_ptr = fmbuf; -				fmbuf = txbuf; -				txbuf = tmp_ptr; -				pthread_cond_wait(&cb_cond, &cb_mutex); -			} - -			dds_real_buf(&carrier, fmbuf, remaining); -			len = remaining; - -			buf_prefilled = 1; -		} else { -			dds_real_buf(&carrier, &fmbuf[len], carrier_per_signal); -			len += carrier_per_signal; -		} - -		pthread_cond_signal(&fm_cond); -	} - -	pthread_exit(NULL); -} - -static inline int writelen(int maxlen) -{ -	int rp = readpos; -	int len; -	int r; - -	if (rp < writepos) -		rp += BUFFER_SAMPLES; - -	len = rp - writepos; - -	r = len > maxlen ? maxlen : len; - -	return r; -} - -static inline double modulate_sample(int lastwritepos, double lastfreq, double sample) -{ -	double freq, slope; - -	/* Calculate modulator frequency at this point to lessen -	 * the calculations needed in the signal generator */ -	freq = sample * deviation; -	freq += carrier_freq; - -	/* What we do here is calculate a linear "slope" from -	the previous sample to this one. This is then used by -	the modulator to gently increase/decrease the frequency -	with each sample without the need to recalculate -	the dds parameters. In fact this gives us a very -	efficient and pretty good interpolation filter. */ -	slope = freq - lastfreq; -	slope /= carrier_per_signal; -	slopebuf[lastwritepos] = slope; -	freqbuf[writepos] = freq; - -	return freq; -} - -void fm_modulator_mono(int use_rds) -{ -	unsigned int i; -	size_t len; -	double freq; -	double lastfreq = carrier_freq; -	int16_t audio_buf[AUDIO_BUF_SIZE]; -	uint32_t lastwritepos = writepos; -	double sample; -	double rds_samples[AUDIO_BUF_SIZE]; - -	while (!do_exit) { -		len = writelen(AUDIO_BUF_SIZE); -		if (len > 1) { -			len = fread(audio_buf, 2, len, file); - -			if (len == 0) -				do_exit = 1; - -			if (use_rds) -				get_rds_samples(rds_samples, len); - -			for (i = 0; i < len; i++) { -				sample = audio_buf[i] / 32767.0; - -				if (use_rds) { -					sample *= 4; -					sample += rds_samples[i]; -					sample /= 5; -				} - -				/* Modulate and buffer the sample */ -				lastfreq = modulate_sample(lastwritepos, lastfreq, sample); -				lastwritepos = writepos++; -				writepos %= BUFFER_SAMPLES; -			} -		} else { -			pthread_cond_wait(&fm_cond, &fm_mutex); -		} -	} -} - -void fm_modulator_stereo(int use_rds) -{ -	unsigned int i; -	size_t len, sample_cnt; -	double freq; -	double lastfreq = carrier_freq; -	int16_t audio_buf[AUDIO_BUF_SIZE]; -	uint32_t lastwritepos = writepos; - -	dds_t pilot, stereo; -	double L, R, LpR, LmR, sample; -	double rds_samples[AUDIO_BUF_SIZE]; - -	/* Prepare stereo carriers */ -	pilot = dds_init(input_freq, PILOT_FREQ, 0); -	stereo = dds_init(input_freq, STEREO_CARRIER, 0); - -	while (!do_exit) { -		len = writelen(AUDIO_BUF_SIZE); -		if (len > 1 && !(len % 2)) { -			len = fread(audio_buf, 2, len, file); - -			if (len == 0) -				do_exit = 1; - -			/* stereo => two audio samples per baseband sample */ -			sample_cnt = len/2; - -			if (use_rds) -				get_rds_samples(rds_samples, sample_cnt); - -			for (i = 0; i < sample_cnt; i++) { -				/* Get samples for both channels, and calculate the  -				* mono (L+R) and the difference signal used to recreate -				* the stereo data (L-R). */ -				L = audio_buf[i*2] / 32767.0; -				R = audio_buf[i*2+1] / 32767.0; -				LpR = (L + R) / 2; -				LmR = (L - R) / 2; - -				/* Create a composite sample consisting of the mono -				* signal at baseband, a 19kHz pilot and a the difference -				* signal DSB-SC modulated on a 38kHz carrier */ -				sample = 4.05 * LpR;					/* Mono signal */ -				sample += 0.9 * (dds_real(&pilot)/127.0);		/* Pilot */ -				sample += 4.05 * LmR * (dds_real(&stereo)/127.0);	/* DSB-SC stereo */ - -				if (use_rds) { -					/* add RDS signal */ -					sample += rds_samples[i]; - -					/* Normalize so we get the signal within [-1, 1] */ -					sample /= 10; -				} else { -					sample /= 9; -				} - -				lastfreq = modulate_sample(lastwritepos, lastfreq, sample); - -				lastwritepos = writepos++; -				writepos %= BUFFER_SAMPLES; -			} -		} else { -			pthread_cond_wait(&fm_cond, &fm_mutex); -		} -	} -} - -void fl2k_callback(fl2k_data_info_t *data_info) -{ -	if (data_info->device_error) { -		fprintf(stderr, "Device error, exiting.\n"); -		do_exit = 1; -		pthread_cond_signal(&fm_cond); -	} - -	pthread_cond_signal(&cb_cond); - -	data_info->sampletype_signed = 1; -	data_info->r_buf = (char *)txbuf; -} - -int main(int argc, char **argv) -{ -	int r, opt; -	uint32_t buf_num = 0; -	int dev_index = 0; -	pthread_attr_t attr; -	char *filename = NULL; -	int option_index = 0; -	int input_freq_specified = 0; - -#ifndef _WIN32 -	struct sigaction sigact, sigign; -#endif - -	static struct option long_options[] = -	{ -		{"stereo", no_argument, &stereo_flag, 1}, -		{"rds",    no_argument, &rds_flag,    1}, -		{0, 0, 0, 0} -	}; - -	while (1) { -		opt = getopt_long(argc, argv, "d:c:f:i:s:", long_options, &option_index); - -		/* end of options reached */ -		if (opt == -1) -			break; - -		switch (opt) { -		case 0: -			break; -		case 'd': -			dev_index = (uint32_t)atoi(optarg); -			break; -		case 'c': -			carrier_freq = (uint32_t)atof(optarg); -			break; -		case 'f': -			deviation = (uint32_t)atof(optarg); -			break; -		case 'i': -			input_freq = (uint32_t)atof(optarg); -			input_freq_specified = 1; -			break; -		case 's': -			samp_rate = (uint32_t)atof(optarg); -			break; -		default: -			usage(); -			break; -		} -	} - -	if (argc <= optind) { -		usage(); -	} else { -		filename = argv[optind]; -	} - -	if (dev_index < 0) { -		exit(1); -	} - -	if (rds_flag && input_freq_specified) { -		if (input_freq != RDS_MODULATOR_RATE) { -			fprintf(stderr, "RDS modulator only works with " -					"228 kHz audio sample rate!\n"); -			exit(1); -		} -	} else if (rds_flag && !input_freq_specified) { -		input_freq = RDS_MODULATOR_RATE; -	} - -	if (stereo_flag && input_freq < (RDS_MODULATOR_RATE/2)) { -		fprintf(stderr, "Audio sample rate needs to be at least " -				"114 kHz for stereo FM!\n"); -		exit(1); -	} - - -	if (strcmp(filename, "-") == 0) { /* Read samples from stdin */ -		file = stdin; -#ifdef _WIN32 -		_setmode(_fileno(stdin), _O_BINARY); -#endif -	} else { -		file = fopen(filename, "rb"); -		if (!file) { -			fprintf(stderr, "Failed to open %s\n", filename); -			return -ENOENT; -		} -	} - -	/* allocate buffer */ -	buf1 = malloc(FL2K_BUF_LEN); -	buf2 = malloc(FL2K_BUF_LEN); -	if (!buf1 || !buf2) { -		fprintf(stderr, "malloc error!\n"); -		exit(1); -	} - -	fmbuf = buf1; -	txbuf = buf2; - -	/* Decoded audio */ -	freqbuf = malloc(BUFFER_SAMPLES * sizeof(double)); -	slopebuf = malloc(BUFFER_SAMPLES * sizeof(double)); -	readpos = 0; -	writepos = 1; - -	fprintf(stderr, "Samplerate:\t%3.2f MHz\n", (double)samp_rate/1000000); -	fprintf(stderr, "Carrier:\t%3.2f MHz\n", (double)carrier_freq/1000000); -	fprintf(stderr, "Frequencies:\t%3.2f MHz, %3.2f MHz\n",  -					(double)((samp_rate - carrier_freq) / 1000000.0), -					(double)((samp_rate + carrier_freq) / 1000000.0)); - -	pthread_mutex_init(&cb_mutex, NULL); -	pthread_mutex_init(&fm_mutex, NULL); -	pthread_cond_init(&cb_cond, NULL); -	pthread_cond_init(&fm_cond, NULL); -	pthread_attr_init(&attr); - -	fl2k_open(&dev, (uint32_t)dev_index); -	if (NULL == dev) { -		fprintf(stderr, "Failed to open fl2k device #%d.\n", dev_index); -		goto out; -	} - -	r = pthread_create(&fm_thread, &attr, fm_worker, NULL); -	if (r < 0) { -		fprintf(stderr, "Error spawning FM worker thread!\n"); -		goto out; -	} - -	pthread_attr_destroy(&attr); -	r = fl2k_start_tx(dev, fl2k_callback, NULL, 0); - -	/* Set the sample rate */ -	r = fl2k_set_sample_rate(dev, samp_rate); -	if (r < 0) -		fprintf(stderr, "WARNING: Failed to set sample rate. %d\n", r); - -	/* read back actual frequency */ -	samp_rate = fl2k_get_sample_rate(dev); - -	/* Calculate needed constants */ -	carrier_per_signal = samp_rate / input_freq; - -	/* Set RDS parameters */ -	set_rds_pi(0x0dac); -	set_rds_ps("fl2k_fm"); -	set_rds_rt("VGA FM transmitter"); - -#ifndef _WIN32 -	sigact.sa_handler = sighandler; -	sigemptyset(&sigact.sa_mask); -	sigact.sa_flags = 0; -	sigign.sa_handler = SIG_IGN; -	sigaction(SIGINT, &sigact, NULL); -	sigaction(SIGTERM, &sigact, NULL); -	sigaction(SIGQUIT, &sigact, NULL); -	sigaction(SIGPIPE, &sigign, NULL); -#else -	SetConsoleCtrlHandler( (PHANDLER_ROUTINE) sighandler, TRUE ); -#endif - -	if (stereo_flag) { -		fm_modulator_stereo(rds_flag); -	} else { -		if (rds_flag) -			fprintf(stderr, "Warning: RDS with mono (without 19 kHz pilot" -					" tone) doesn't work with all receivers!\n"); - -		fm_modulator_mono(rds_flag); -	} - -out: -	fl2k_close(dev); - -	if (file != stdin) -		fclose(file); - -	free(freqbuf); -	free(slopebuf); -	free(buf1); -	free(buf2); - -	return 0; -} diff --git a/src/fl2k_garage.c b/src/fl2k_garage.c deleted file mode 100644 index d50922e..0000000 --- a/src/fl2k_garage.c +++ /dev/null @@ -1,545 +0,0 @@ -/* - * osmo-fl2k, turns FL2000-based USB 3.0 to VGA adapters into - * low cost DACs - * - * Copyright (C) 2019 by Felix Erckenbrecht <eligs@eligs.de> - * - * based on fl2k_fm code by: - * Copyright (C) 2016-2018 by Steve Markgraf <steve@steve-m.de> - * - * based on FM modulator code from VGASIG: - * Copyright (C) 2009 by Bartek Kania <mbk@gnarf.org> - * - * SPDX-License-Identifier: GPL-2.0+ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <signal.h> -#include <string.h> -#include <errno.h> -#include <stdint.h> - -#ifndef _WIN32 -#include <unistd.h> -#include <fcntl.h> -#include <getopt.h> -#else -#include <windows.h> -#include <io.h> -#include <fcntl.h> -#include "getopt/getopt.h" -#endif - -#include <math.h> -#include <pthread.h> - -#include "osmo-fl2k.h" -#include "rds_mod.h" - -#define BUFFER_SAMPLES_SHIFT	16 -#define BUFFER_SAMPLES		(1 << BUFFER_SAMPLES_SHIFT) -#define BUFFER_SAMPLES_MASK	((1 << BUFFER_SAMPLES_SHIFT)-1) - -#define AUDIO_BUF_SIZE		4096 - -#define BASEBAND_SAMPLES_PER_CHIP 3 -#define BASEBAND_WORD_BITS 12 -#define BASEBAND_CHIPS_PER_BIT 3 -#define BASEBAND_CHIPS_PER_WORD (BASEBAND_WORD_BITS * BASEBAND_CHIPS_PER_BIT) -#define BASEBAND_CHIPS_PER_SPACE BASEBAND_CHIPS_PER_WORD -#define BASEBAND_SPACE_HIGH_CHIPS 1 -#define BASEBAND_SPACE_LOW_CHIPS (BASEBAND_CHIPS_PER_SPACE - BASEBAND_SPACE_HIGH_CHIPS) -#define BASEBAND_CHIPS_TOTAL (BASEBAND_CHIPS_PER_SPACE + BASEBAND_CHIPS_PER_WORD) - -fl2k_dev_t *dev = NULL; -int do_exit = 0; - -pthread_t am_thread; -pthread_mutex_t cb_mutex; -pthread_mutex_t am_mutex; -pthread_cond_t cb_cond; -pthread_cond_t am_cond; - -int16_t *sample_buf; -int sample_buf_size; - -int8_t *txbuf = NULL; -int8_t *ambuf = NULL; -int8_t *buf1 = NULL; -int8_t *buf2 = NULL; - -uint32_t samp_rate = 100000000; - -double mod_index = 0.9; -int carrier_freq = 40685000; -int carrier_per_signal; - -double *ampbuf; -double *slopebuf; -int writepos, readpos; - -void usage(void) -{ -	fprintf(stderr, -		"fl2k_garage, a garage door opener for FL2K VGA dongles\n\n" -		"Usage:" -		"\t[-d device index (default: 0)]\n" -		"\t[-f carrier frequency (default: 40.685 MHz)]\n" -		"\t[-c garage door code (12 Bit)]\n" -		"\t[-b chip period in us (default 320 us)]\n" -		"\t[-s samplerate in Hz (default: 100 MS/s)]\n" -	); -	exit(1); -} - -#ifdef _WIN32 -BOOL WINAPI -sighandler(int signum) -{ -	if (CTRL_C_EVENT == signum) { -		fprintf(stderr, "Signal caught, exiting!\n"); -		fl2k_stop_tx(dev); -		do_exit = 1; -		pthread_cond_signal(&am_cond); -		return TRUE; -	} -	return FALSE; -} -#else -static void sighandler(int signum) -{ -	fprintf(stderr, "Signal caught, exiting!\n"); -	fl2k_stop_tx(dev); -	do_exit = 1; -	pthread_cond_signal(&am_cond); -} -#endif - -/* DDS Functions */ - -#ifndef M_PI -# define M_PI		3.14159265358979323846	/* pi */ -# define M_PI_2		1.57079632679489661923	/* pi/2 */ -# define M_PI_4		0.78539816339744830962	/* pi/4 */ -# define M_1_PI		0.31830988618379067154	/* 1/pi */ -# define M_2_PI		0.63661977236758134308	/* 2/pi */ -#endif -#define DDS_2PI		(M_PI * 2)		/* 2 * Pi */ -#define DDS_3PI2	(M_PI_2 * 3)		/* 3/2 * pi */ - -#define SIN_TABLE_ORDER	8 -#define SIN_TABLE_SHIFT	(32 - SIN_TABLE_ORDER) -#define SIN_TABLE_LEN	(1 << SIN_TABLE_ORDER) -#define ANG_INCR	(0xffffffff / DDS_2PI) - -int16_t sine_table[SIN_TABLE_LEN]; -int sine_table_init = 0; - -typedef struct { -	double sample_freq; -	double freq; -	unsigned long int phase; -	unsigned long int phase_step; -	double amplitude; -	double ampslope; -} dds_t; - -static inline void dds_set_freq(dds_t *dds, double freq) -{ -	dds->freq = freq; -	dds->phase_step = (freq / dds->sample_freq) * 2 * M_PI * ANG_INCR; -} - -static inline void dds_set_amp(dds_t *dds, double amplitude, double ampslope) -{ -	dds->amplitude = amplitude; -	dds->ampslope  = ampslope; -} - -dds_t dds_init(double sample_freq, double freq, double phase, double amp) -{ -	dds_t dds; -	int i; - -	dds.sample_freq = sample_freq; -	dds.phase = phase * ANG_INCR; -	dds_set_freq(&dds, freq); -	dds_set_amp(&dds, amp, 0); -	/* Initialize sine table, prescaled for 16 bit signed integer */ -	if (!sine_table_init) { -		double incr = 1.0 / (double)SIN_TABLE_LEN; -		for (i = 0; i < SIN_TABLE_LEN; i++) -			sine_table[i] = sin(incr * i * DDS_2PI) * 32767; - -		sine_table_init = 1; -	} - -	return dds; -} - -static inline int8_t dds_real(dds_t *dds) -{ -	int tmp; -	int32_t amp; - -	// advance dds generator -	tmp = dds->phase >> SIN_TABLE_SHIFT; -	dds->phase += dds->phase_step; -	dds->phase &= 0xffffffff; - -	amp = (int32_t)(dds->amplitude * 255) * sine_table[tmp]; -	dds->amplitude += dds->ampslope; - -	return (int8_t)(amp >> 16) ; -} - -static inline void dds_real_buf(dds_t *dds, int8_t *buf, int count) -{ -	int i; -	for (i = 0; i < count; i++) -		buf[i] = dds_real(dds); -} - -/* Signal generation and some helpers */ - -/* Generate the radio signal using the pre-calculated amplitude information - * in the amp buffer */ -static void *am_worker(void *arg) -{ -	register double freq; -	register double tmp; -	dds_t carrier; -	int8_t *tmp_ptr; -	uint32_t len = 0; -	uint32_t readlen, remaining; -	int buf_prefilled = 0; - -	/* Prepare the oscillators */ -	carrier = dds_init(samp_rate, carrier_freq, 1, 0); - -	while (!do_exit) { -		dds_set_amp(&carrier, ampbuf[readpos], slopebuf[readpos]); -		readpos++; -		readpos &= BUFFER_SAMPLES_MASK; - -		/* check if we reach the end of the buffer */ -		if ((len + carrier_per_signal) > FL2K_BUF_LEN) { -			readlen = FL2K_BUF_LEN - len; -			remaining = carrier_per_signal - readlen; -			dds_real_buf(&carrier, &ambuf[len], readlen); - -			if (buf_prefilled) { -				/* swap buffers */ -				tmp_ptr = ambuf; -				ambuf = txbuf; -				txbuf = tmp_ptr; -				pthread_cond_wait(&cb_cond, &cb_mutex); -			} - -			dds_real_buf(&carrier, ambuf, remaining); -			len = remaining; - -			buf_prefilled = 1; -		} else { -			dds_real_buf(&carrier, &ambuf[len], carrier_per_signal); -			len += carrier_per_signal; -		} - -		pthread_cond_signal(&am_cond); -	} - -	pthread_exit(NULL); -} - -static inline int writelen(int maxlen) -{ -	int rp = readpos; -	int len; -	int r; - -	if (rp < writepos) -		rp += BUFFER_SAMPLES; - -	len = rp - writepos; - -	r = len > maxlen ? maxlen : len; - -	return r; -} - -static inline int32_t modulate_sample_am(int lastwritepos, double lastamp, int16_t sample) -{ -	double amp, slope; - -	/* Calculate modulator amplitude at this point to lessen -	 * the calculations needed in the signal generator */ -	amp = 1 - ((double)sample * mod_index); - -	/* What we do here is calculate a linear "slope" from -	the previous sample to this one. This is then used by -	the modulator to gently increase/decrease the amplitude -	with each sample without the need to recalculate -	the dds parameters. In fact this gives us a very -	efficient and pretty good interpolation filter. */ -	slope = amp - lastamp; -	slope /= carrier_per_signal; -	slopebuf[lastwritepos] = slope; -	ampbuf[writepos]       = amp; - -	return amp; -} - -void am_modulator(const int code_input) -{ -	int counter = 0; -	int code; -	unsigned int i; -	unsigned int b = 0; -	size_t len; -	int32_t lastamp = 0; -	uint32_t lastwritepos = writepos; -	int16_t sample = 0; -	int samplebuf_pos = 0; - -	/* -	 *  3*640 us = 1,92 ms pro Symbol -	 *  12 Symbole Daten (12 Bit) -	 *  11 Symbole Pause, 1 Symbol 1 (synch) -	 * -	 *  1 = __- -	 *  0 = _-- -	 */ -	while (!do_exit) { -		len = writelen(AUDIO_BUF_SIZE); -		if (len > 1) { -			if (len == 0) -				do_exit = 1; - -			for (i = 0; i < len; i++) { -				/* Modulate and buffer the sample */ -				sample = sample_buf[samplebuf_pos++]; -				if(samplebuf_pos >= BASEBAND_SAMPLES_PER_CHIP * BASEBAND_CHIPS_TOTAL){ -					samplebuf_pos = 0; -				} -				lastamp = modulate_sample_am(lastwritepos, lastamp, sample); -				lastwritepos = writepos++; -				writepos %= BUFFER_SAMPLES; -			} -		} else { -			pthread_cond_wait(&am_cond, &am_mutex); -		} -	} -} - -void prepare_baseband(const int code_input, int16_t * sbuf){ -	int counter; -	int b; -	int sample_no; -	int16_t sample; -	int msb_first_code; - -	msb_first_code = 0; -	// change to msb first and invert -	for(b = 0;b<12;b++){ -		msb_first_code <<= 1; -		msb_first_code |= code_input & (1<<b) ? 0 : 1; -	} - -	sample_no = 0; -	for(counter=0;counter < (BASEBAND_CHIPS_PER_SPACE + BASEBAND_CHIPS_PER_WORD) ; counter++){ -		for(b=0 ; b<BASEBAND_SAMPLES_PER_CHIP ; b++){ -			if(counter < (BASEBAND_SPACE_LOW_CHIPS)){ -				sample = 0; -			} -			else if(counter < (BASEBAND_CHIPS_PER_SPACE)){ -				// synch symbol -				sample = 1; -			} -			else{ -				int m; -				m = counter % BASEBAND_CHIPS_PER_BIT; -				if(m == 0){ -					sample = 0; -				} -				else if(m == 1){ -					sample = (msb_first_code & 1); -				} -				else{ -					sample = 1; -					if(b == BASEBAND_SAMPLES_PER_CHIP-1){ -						msb_first_code >>= 1; -					} -				} -			} -			sbuf[counter * BASEBAND_SAMPLES_PER_CHIP + b] = sample; -		} -	} -} - -void fl2k_callback(fl2k_data_info_t *data_info) -{ -	if (data_info->device_error) { -		fprintf(stderr, "Device error, exiting.\n"); -		do_exit = 1; -		pthread_cond_signal(&am_cond); -	} - -	pthread_cond_signal(&cb_cond); - -	data_info->sampletype_signed = 1; -	data_info->r_buf = (char *)txbuf; -} - -int main(int argc, char **argv) -{ -	int r, opt; -	uint32_t buf_num = 0; -	int dev_index = 0; -	pthread_attr_t attr; -	char *filename = NULL; -	int option_index = 0; -	int code = 0; -	int chiptime_us = 320; - -#ifndef _WIN32 -	struct sigaction sigact, sigign; -#endif - -	static struct option long_options[] = -	{ -		{0, 0, 0, 0} -	}; - -	while (1) { -		opt = getopt_long(argc, argv, "b:c:f:m:s:", long_options, &option_index); -		/* end of options reached */ -		if (opt == -1) -			break; - -		switch (opt) { -		case 0: -			break; -		case 'b': -			chiptime_us = atoi(optarg); -			break; -		case 'c': -			code = atoi(optarg); -			code &= 4095; -			break; -		case 'f': -			carrier_freq = (uint32_t)atof(optarg); -			break; -		case 'm': -			mod_index = atof(optarg); -			break; -		case 's': -			samp_rate = (uint32_t)atof(optarg); -			break; -		default: -			usage(); -			break; -		} -	} - -	if (argc < optind) { -		usage(); -	} - -	/* allocate buffer */ -	buf1 = malloc(FL2K_BUF_LEN); -	buf2 = malloc(FL2K_BUF_LEN); -	if (!buf1 || !buf2) { -		fprintf(stderr, "malloc error!\n"); -		exit(1); -	} - -	ambuf = buf1; -	txbuf = buf2; - -	/* Decoded audio */ -	slopebuf 	= malloc(BUFFER_SAMPLES * sizeof(double)); -	ampbuf  	= malloc(BUFFER_SAMPLES * sizeof(double)); -	slopebuf    = malloc(BUFFER_SAMPLES * sizeof(double)); -	sample_buf  = malloc((BASEBAND_SAMPLES_PER_CHIP * BASEBAND_CHIPS_TOTAL) * sizeof(int16_t)); -	readpos 	= 0; -	writepos 	= 1; - -	fprintf(stderr, "Samplerate:\t%3.2f MHz\n", (double)samp_rate/1000000); -	fprintf(stderr, "Carrier:\t%3.3f MHz\n", (double)carrier_freq/1000000); -	fprintf(stderr, "Mod Index:\t%3.1f %%\n", -					(double)(mod_index * 100)); -	fprintf(stderr, "Chip period:\t%d us\n", chiptime_us); - -	pthread_mutex_init(&cb_mutex, NULL); -	pthread_mutex_init(&am_mutex, NULL); -	pthread_cond_init(&cb_cond, NULL); -	pthread_cond_init(&am_cond, NULL); -	pthread_attr_init(&attr); - -	prepare_baseband(code, sample_buf); - -	fl2k_open(&dev, (uint32_t)dev_index); -	if (NULL == dev) { -		fprintf(stderr, "Failed to open fl2k device #%d.\n", dev_index); -		goto out; -	} - -	r = pthread_create(&am_thread, &attr, am_worker, NULL); -	if (r < 0) { -		fprintf(stderr, "Error spawning AM worker thread!\n"); -		goto out; -	} - -	pthread_attr_destroy(&attr); -	r = fl2k_start_tx(dev, fl2k_callback, NULL, 0); - -	/* Set the sample rate */ -	r = fl2k_set_sample_rate(dev, samp_rate); -	if (r < 0) -		fprintf(stderr, "WARNING: Failed to set sample rate. %d\n", r); - -	/* read back actual frequency */ -	samp_rate = fl2k_get_sample_rate(dev); - -	/* Calculate needed constants */ -	carrier_per_signal = (int)((double) samp_rate * chiptime_us/(1000000*BASEBAND_SAMPLES_PER_CHIP) + 0.5); -	printf("Cps :\t%d\n", carrier_per_signal); -#ifndef _WIN32 -	sigact.sa_handler = sighandler; -	sigemptyset(&sigact.sa_mask); -	sigact.sa_flags = 0; -	sigign.sa_handler = SIG_IGN; -	sigaction(SIGINT, &sigact, NULL); -	sigaction(SIGTERM, &sigact, NULL); -	sigaction(SIGQUIT, &sigact, NULL); -	sigaction(SIGPIPE, &sigign, NULL); -#else -	SetConsoleCtrlHandler( (PHANDLER_ROUTINE) sighandler, TRUE ); -#endif - -	am_modulator(code); - -out: -	fl2k_close(dev); - -	free(ampbuf); -	free(slopebuf); -	free(buf1); -	free(buf2); - -	return 0; -} diff --git a/src/fl2k_tcp.c b/src/fl2k_tcp.c deleted file mode 100644 index 871ac26..0000000 --- a/src/fl2k_tcp.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * osmo-fl2k, turns FL2000-based USB 3.0 to VGA adapters into - * low cost DACs - * - * Copyright (C) 2016-2018 by Steve Markgraf <steve@steve-m.de> - * - * SPDX-License-Identifier: GPL-2.0+ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -#include <errno.h> -#include <signal.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> - -#ifndef _WIN32 -#include <unistd.h> -#include <arpa/inet.h> -#include <sys/socket.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/time.h> -#include <netinet/in.h> -#include <netinet/tcp.h> /* for TCP_NODELAY */ -#include <fcntl.h> -#define sleep_ms(ms)	usleep(ms*1000) -#else -#include <windows.h> -#include <winsock2.h> -#include "getopt/getopt.h" -#define sleep_ms(ms)	Sleep(ms) -#endif - -#include "osmo-fl2k.h" - -#ifdef _WIN32 -#pragma comment(lib, "ws2_32.lib") - -typedef int socklen_t; - -#else -#define closesocket close -#define SOCKADDR struct sockaddr -#define SOCKET int -#define SOCKET_ERROR -1 -#endif - -static SOCKET s; -static fl2k_dev_t *dev = NULL; -static volatile int do_exit = 0; -static volatile int connected = 0; -static char *txbuf = NULL; -static fd_set readfds; -static SOCKET sock; - -void usage(void) -{ -	fprintf(stderr, -		"fl2k_tcp, a spectrum client for FL2K VGA dongles\n\n" -		"Usage:\t[-a server address]\n" -		"\t[-d device index (default: 0)]\n" -		"\t[-p port (default: 1234)]\n" -		"\t[-s samplerate in Hz (default: 100 MS/s)]\n" -		"\t[-b number of buffers (default: 4)]\n" -	); -	exit(1); -} - -#ifdef _WIN32 -BOOL WINAPI -sighandler(int signum) -{ -	if (CTRL_C_EVENT == signum) { -		fprintf(stderr, "Signal caught, exiting!\n"); -		fl2k_stop_tx(dev); -		do_exit = 1; -		return TRUE; -	} -	return FALSE; -} -#else -static void sighandler(int signum) -{ -	fprintf(stderr, "Signal caught, exiting!\n"); -	do_exit = 1; -	fl2k_stop_tx(dev); -} -#endif - -void fl2k_callback(fl2k_data_info_t *data_info) -{ -	int left = FL2K_BUF_LEN; -	int received; -	int r; -	struct timeval tv = { 1, 0 }; - -	if (data_info->device_error) { -		fprintf(stderr, "Device error, exiting.\n"); -		do_exit = 1; -		return; -	} - -	if (!connected) -		return; - -	data_info->sampletype_signed = 1; -	data_info->r_buf = txbuf; - -	while (!do_exit && (left > 0)) { -		FD_ZERO(&readfds); -		FD_SET(sock, &readfds); -		tv.tv_sec = 1; -		tv.tv_usec = 0; -		r = select(sock + 1, &readfds, NULL, NULL, &tv); - -		if (r) { -			received = recv(sock, txbuf + (FL2K_BUF_LEN - left), left, 0); -			if (!received) { -				fprintf(stderr, "Connection was closed!\n"); -				fl2k_stop_tx(dev); -				do_exit = 1; -			} - -			left -= received; -		} -	} -} - -int main(int argc, char **argv) -{ -	int r, opt, i; -	char *addr = "127.0.0.1"; -	int port = 1234; -	uint32_t samp_rate = 100000000; -	struct sockaddr_in local, remote; -	uint32_t buf_num = 0; -	int dev_index = 0; -	int dev_given = 0; -	int flag = 1; - -#ifdef _WIN32 -	WSADATA wsd; -	i = WSAStartup(MAKEWORD(2,2), &wsd); -#else -	struct sigaction sigact, sigign; -#endif - -	while ((opt = getopt(argc, argv, "d:s:a:p:b:")) != -1) { -		switch (opt) { -		case 'd': -			dev_index = (uint32_t)atoi(optarg); -			dev_given = 1; -			break; -		case 's': -			samp_rate = (uint32_t)atof(optarg); -			break; -		case 'a': -			addr = optarg; -			break; -		case 'p': -			port = atoi(optarg); -			break; -		case 'b': -			buf_num = atoi(optarg); -			break; -		default: -			usage(); -			break; -		} -	} - -	if (argc < optind) -		usage(); - -	if (dev_index < 0) { -		exit(1); -	} - -	txbuf = malloc(FL2K_BUF_LEN); - -	if (!txbuf) { -		fprintf(stderr, "malloc error!\n"); -		exit(1); -	} - -	fl2k_open(&dev, (uint32_t)dev_index); -	if (NULL == dev) { -		fprintf(stderr, "Failed to open fl2k device #%d.\n", dev_index); -		exit(1); -	} - -	r = fl2k_start_tx(dev, fl2k_callback, NULL, buf_num); - -	/* Set the sample rate */ -	r = fl2k_set_sample_rate(dev, samp_rate); -	if (r < 0) -		fprintf(stderr, "WARNING: Failed to set sample rate.\n"); - -#ifndef _WIN32 -	sigact.sa_handler = sighandler; -	sigemptyset(&sigact.sa_mask); -	sigact.sa_flags = 0; -	sigign.sa_handler = SIG_IGN; -	sigaction(SIGINT, &sigact, NULL); -	sigaction(SIGTERM, &sigact, NULL); -	sigaction(SIGQUIT, &sigact, NULL); -	sigaction(SIGPIPE, &sigact, NULL); -#else -	SetConsoleCtrlHandler( (PHANDLER_ROUTINE) sighandler, TRUE ); -#endif - -	sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - -	memset(&remote, 0, sizeof(remote)); - -	remote.sin_family = AF_INET; -	remote.sin_port = htons(port); -	remote.sin_addr.s_addr = inet_addr(addr); - -	fprintf(stderr, "Connecting to %s:%d...\n", addr, port); -	while (connect(sock, (struct sockaddr *)&remote, sizeof(remote)) != 0) { -		sleep_ms(500); -		if (do_exit) -			goto out; -	} - -	setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&flag,sizeof(flag)); -	fprintf(stderr, "Connected\n"); -	connected = 1; - -	while (!do_exit) -		sleep_ms(500); - -out: -	fl2k_close(dev); -	free(txbuf); -	closesocket(s); -#ifdef _WIN32 -	WSACleanup(); -#endif - -	return 0; -} diff --git a/src/fl2k_test.c b/src/fl2k_test.c deleted file mode 100644 index b166dda..0000000 --- a/src/fl2k_test.c +++ /dev/null @@ -1,308 +0,0 @@ -/* - * osmo-fl2k, turns FL2000-based USB 3.0 to VGA adapters into - * low cost DACs - * - * Copyright (C) 2016-2018 by Steve Markgraf <steve@steve-m.de> - * - * based on rtl_test: - *  - * Copyright (C) 2012-2014 by Steve Markgraf <steve@steve-m.de> - * Copyright (C) 2012-2014 by Kyle Keen <keenerd@gmail.com> - * Copyright (C) 2014 by Michael Tatarinov <kukabu@gmail.com> - * - * SPDX-License-Identifier: GPL-2.0+ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -#include <errno.h> -#include <signal.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <math.h> - -#ifdef __APPLE__ -#include <sys/time.h> -#else -#include <time.h> -#endif - -#ifndef _WIN32 -#include <unistd.h> -#define sleep_ms(ms)	usleep(ms*1000) -#else -#include <windows.h> -#include "getopt/getopt.h" -#define sleep_ms(ms)	Sleep(ms) -#endif - -#include "osmo-fl2k.h" - -#define DEFAULT_SAMPLE_RATE		100000000 -#define PPM_DURATION			10 -#define PPM_DUMP_TIME			1 - -struct time_generic -	/* holds all the platform specific values */ -{ -#ifndef _WIN32 -	time_t tv_sec; -	long tv_nsec; -#else -	long tv_sec; -	long tv_nsec; -	int init; -	LARGE_INTEGER frequency; -	LARGE_INTEGER ticks; -#endif -}; - -static int do_exit = 0; -static fl2k_dev_t *dev = NULL; - -static uint32_t samp_rate = DEFAULT_SAMPLE_RATE; -static unsigned int ppm_duration = PPM_DURATION; - -static char *buffer; -static int cb_cnt = 0; - -void usage(void) -{ -	fprintf(stderr, -		"fl2k_test, clock accuracy test for FL2K VGA dongles,\n" -		"also outputs a square wave at fs/2\n\n" -		"Usage:\n" -		"\t[-d device_index (default: 0)]\n" -		"\t[-s samplerate (default: 100 MS/s)]\n" -	); -	exit(1); -} - -#ifdef _WIN32 -BOOL WINAPI -sighandler(int signum) -{ -	if (CTRL_C_EVENT == signum) { -		fprintf(stderr, "Signal caught, exiting!\n"); -		fl2k_stop_tx(dev); -		do_exit = 1; -		return TRUE; -	} -	return FALSE; -} -#else -static void sighandler(int signum) -{ -	fprintf(stderr, "Signal caught, exiting!\n"); -	fl2k_stop_tx(dev); -	do_exit = 1; -} -#endif - -#ifndef _WIN32 -static int ppm_gettime(struct time_generic *tg) -{ -	int rv = ENOSYS; -	struct timespec ts; - -#ifdef __unix__ -	rv = clock_gettime(CLOCK_MONOTONIC, &ts); -	tg->tv_sec = ts.tv_sec; -	tg->tv_nsec = ts.tv_nsec; -#elif __APPLE__ -	struct timeval tv; - -	rv = gettimeofday(&tv, NULL); -	tg->tv_sec = tv.tv_sec; -	tg->tv_nsec = tv.tv_usec * 1000; -#endif -	return rv; -} -#endif - -#ifdef _WIN32 -static int ppm_gettime(struct time_generic *tg) -{ -	int rv; -	int64_t frac; -	if (!tg->init) { -		QueryPerformanceFrequency(&tg->frequency); -		tg->init = 1; -	} -	rv = QueryPerformanceCounter(&tg->ticks); -	tg->tv_sec = tg->ticks.QuadPart / tg->frequency.QuadPart; -	frac = (int64_t)(tg->ticks.QuadPart - (tg->tv_sec * tg->frequency.QuadPart)); -	tg->tv_nsec = (long)(frac * 1000000000L / (int64_t)tg->frequency.QuadPart); -	return !rv; -} -#endif - -static int ppm_report(uint64_t nsamples, uint64_t interval) -{ -	double real_rate, ppm; - -	real_rate = nsamples * 1e9 / interval; -	ppm = 1e6 * (real_rate / (double)samp_rate - 1.); -	return (int)round(ppm); -} - -static void ppm_test(uint32_t len) -{ -	static uint64_t nsamples = 0; -	static uint64_t interval = 0; -	static uint64_t nsamples_total = 0; -	static uint64_t interval_total = 0; -	static struct time_generic ppm_now; -	static struct time_generic ppm_recent; - -	static enum { -		PPM_INIT_NO, -		PPM_INIT_DUMP, -		PPM_INIT_RUN -	} ppm_init = PPM_INIT_NO; - -	ppm_gettime(&ppm_now); - -	if (ppm_init != PPM_INIT_RUN) { -		/* -		* Kyle Keen wrote: -		* PPM_DUMP_TIME throws out the first N seconds of data. -		* The dongle's PPM is usually very bad when first starting up, -		* typically incorrect by more than twice the final value. -		* Discarding the first few seconds allows the value to stabilize much faster. -		*/ -		if (ppm_init == PPM_INIT_NO) { -			ppm_recent.tv_sec = ppm_now.tv_sec + PPM_DUMP_TIME; -			ppm_init = PPM_INIT_DUMP; -			return; -		} -		if (ppm_init == PPM_INIT_DUMP && ppm_recent.tv_sec < ppm_now.tv_sec) -			return; -		ppm_recent = ppm_now; -		ppm_init = PPM_INIT_RUN; -		return; -	} -	nsamples += (uint64_t)len; -	interval = (uint64_t)(ppm_now.tv_sec - ppm_recent.tv_sec); -	if (interval < ppm_duration) -		return; -	interval *= 1000000000UL; -	interval += (int64_t)(ppm_now.tv_nsec - ppm_recent.tv_nsec); - -	nsamples_total += nsamples; -	interval_total += interval; -	printf("real sample rate: %i current PPM: %i cumulative PPM: %i\n", -		(int)((1000000000UL * nsamples) / interval), -		ppm_report(nsamples, interval), -		ppm_report(nsamples_total, interval_total)); -	ppm_recent = ppm_now; -	nsamples = 0; -} - -void fl2k_callback(fl2k_data_info_t *data_info) -{ -	if (data_info->device_error) { -		fprintf(stderr, "Device error, exiting.\n"); -		do_exit = 1; -		return; -	} - -	/* drop first couple of callbacks until everything is settled */ -	if (cb_cnt > 20) { -		ppm_test(FL2K_BUF_LEN); -	} else { -		/* as data is repetitive, it only needs to be handed -		 * over until all transfer buffers contain the data */ -		data_info->r_buf = buffer; -		cb_cnt++; -	} -} - -int main(int argc, char **argv) -{ -#ifndef _WIN32 -	struct sigaction sigact; -#endif -	int r, opt, i; -	uint32_t dev_index = 0; - -	while ((opt = getopt(argc, argv, "d:s:p::h")) != -1) { -		switch (opt) { -		case 'd': -			dev_index = (uint32_t)atoi(optarg); -			break; -		case 's': -			samp_rate = (uint32_t)atof(optarg); -			break; -		case 'p': -			if (optarg) -				ppm_duration = atoi(optarg); -			break; -		case 'h': -		default: -			usage(); -			break; -		} -	} - -	buffer = malloc(FL2K_BUF_LEN); -	if (!buffer) -		goto exit; - -	fl2k_open(&dev, (uint32_t)dev_index); -	if (NULL == dev) { -	fprintf(stderr, "Failed to open fl2k 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 - -	/* initialize buffer with rect signal */ -	for (i = 0; i < FL2K_BUF_LEN; i += 2) { -		buffer[i] = 0x00; -		buffer[i+1] = 0xff; -	} - -	r = fl2k_start_tx(dev, fl2k_callback, NULL, 0); - -	/* Set the sample rate */ -	r = fl2k_set_sample_rate(dev, samp_rate); -	if (r < 0) -		fprintf(stderr, "WARNING: Failed to set sample rate.\n"); - -	samp_rate = fl2k_get_sample_rate(dev); - -	fprintf(stderr, "Reporting PPM error measurement every %u seconds...\n", ppm_duration); -	fprintf(stderr, "Press ^C after a few minutes.\n"); - -	while (!do_exit) -		sleep_ms(500); - -exit: -	fl2k_close(dev); -	free(buffer); - -	return 0; -} diff --git a/src/rds_mod.c b/src/rds_mod.c deleted file mode 100644 index 687aa65..0000000 --- a/src/rds_mod.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - * RDS Modulator from: - * PiFmRds - FM/RDS transmitter for the Raspberry Pi - * https://github.com/ChristopheJacquet/PiFmRds - *  - * Copyright (C) 2014 by Christophe Jacquet, F8FTK - * - * adapted for use with fl2k_fm: - * Copyright (C) 2018 by Steve Markgraf <steve@steve-m.de> - * - * SPDX-License-Identifier: GPL-3.0+ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. -*/ - -#include <stdint.h> -#include <string.h> -#include <time.h> -#include <stdlib.h> - -#define RT_LENGTH	64 -#define PS_LENGTH	8 -#define GROUP_LENGTH	4 - -extern double waveform_biphase[576]; - -struct { -	uint16_t pi; -	int ta; -	char ps[PS_LENGTH+1]; -	char rt[RT_LENGTH+1]; -} rds_params = { 0 }; - -/* The RDS error-detection code generator polynomial is -   x^10 + x^8 + x^7 + x^5 + x^4 + x^3 + x^0 -*/ -#define POLY		0x1B9 -#define POLY_DEG	10 -#define MSB_BIT		(1 << 15) -#define BLOCK_SIZE	16 - -#define BITS_PER_GROUP (GROUP_LENGTH * (BLOCK_SIZE+POLY_DEG)) -#define SAMPLES_PER_BIT 192 -#define FILTER_SIZE (sizeof(waveform_biphase)/sizeof(double)) -#define SAMPLE_BUFFER_SIZE (SAMPLES_PER_BIT + FILTER_SIZE) - - -uint16_t offset_words[] = { 0x0FC, 0x198, 0x168, 0x1B4 }; -// We don't handle offset word C' here for the sake of simplicity - -/* Classical CRC computation */ -uint16_t crc(uint16_t block) -{ -	uint16_t crc = 0; -	int i, bit, msb; - -	for (i = 0; i < BLOCK_SIZE; i++) { -		bit = (block & MSB_BIT) != 0; -		block <<= 1; - -		msb = (crc >> (POLY_DEG-1)) & 1; -		crc <<= 1; - -		if ((msb ^ bit) != 0) -			crc = crc ^ POLY; -	} - -	return crc; -} - -/* Possibly generates a CT (clock time) group if the minute has just changed -   Returns 1 if the CT group was generated, 0 otherwise -*/ -int get_rds_ct_group(uint16_t *blocks) -{ -	static int latest_minutes = -1; -	int l, mjd, offset; - -	// Check time -	time_t now; -	struct tm *utc; - -	now = time(NULL); -	utc = gmtime(&now); - -	if(utc->tm_min != latest_minutes) { -		// Generate CT group -		latest_minutes = utc->tm_min; - -		l = utc->tm_mon <= 1 ? 1 : 0; -		mjd = 14956 + utc->tm_mday +  -		      (int)((utc->tm_year - l) * 365.25) + -		      (int)((utc->tm_mon + 2 + l*12) * 30.6001); - -		blocks[1] = 0x4400 | (mjd>>15); -		blocks[2] = (mjd<<1) | (utc->tm_hour>>4); -		blocks[3] = (utc->tm_hour & 0xF)<<12 | utc->tm_min<<6; - -		utc = localtime(&now); - -		//'struct tm' has no member named 'tm_gmtoff' on Windows+MinGW -		#if defined(__APPLE__) || defined(__FreeBSD__) -		offset = utc->tm_gmtoff / (30 * 60); -		#else -		offset = time(NULL) / (30 * 60); -		#endif - -		blocks[3] |= abs(offset); -		if (offset < 0) -			blocks[3] |= 0x20; - -		return 1; -	} else { -		return 0; -	} -} - -/* Creates an RDS group. This generates sequences of the form 0A, 0A, 0A, 0A, 2A, etc. -   The pattern is of length 5, the variable 'state' keeps track of where we are in the -   pattern. 'ps_state' and 'rt_state' keep track of where we are in the PS (0A) sequence -   or RT (2A) sequence, respectively. -*/ -void get_rds_group(int *buffer) -{ -	static int state = 0; -	static int ps_state = 0; -	static int rt_state = 0; -	uint16_t blocks[GROUP_LENGTH] = { rds_params.pi, 0, 0, 0 }; -	uint16_t block, check; -	int i, j; - -	// Generate block content -	if (!get_rds_ct_group(blocks)) { // CT (clock time) has priority on other group types -		if (state < 4) { -			blocks[1] = 0x0400 | ps_state; - -			if (rds_params.ta) -				blocks[1] |= 0x0010; - -			blocks[2] = 0xCDCD;	 // no AF -			blocks[3] = rds_params.ps[ps_state*2] << 8 | rds_params.ps[ps_state*2+1]; -			ps_state++; - -			if (ps_state >= 4) -				ps_state = 0; -		} else { // state == 5 -			blocks[1] = 0x2400 | rt_state; -			blocks[2] = rds_params.rt[rt_state*4+0] << 8 | rds_params.rt[rt_state*4+1]; -			blocks[3] = rds_params.rt[rt_state*4+2] << 8 | rds_params.rt[rt_state*4+3]; -			rt_state++; -			if (rt_state >= 16) -				rt_state = 0; -		} - -		state++; -		if (state >= 5) -			state = 0; -	} -	 -	// Calculate the checkword for each block and emit the bits -	for (i = 0; i < GROUP_LENGTH; i++) { -		block = blocks[i]; -		check = crc(block) ^ offset_words[i]; -		for (j = 0; j < BLOCK_SIZE; j++) { -			*buffer++ = ((block & (1 << (BLOCK_SIZE-1))) != 0); -			block <<= 1; -		} -		for (j = 0; j < POLY_DEG; j++) { -			*buffer++ = ((check & (1 << (POLY_DEG-1))) != 0); -			check <<= 1; -		} -	} -} - -/* Get a number of RDS samples. This generates the envelope of the waveform using -   pre-generated elementary waveform samples, and then it amplitude-modulates the  -   envelope with a 57 kHz carrier, which is very efficient as 57 kHz is 4 times the -   sample frequency we are working at (228 kHz). - */ -void get_rds_samples(double *buffer, uint32_t count) -{ -	static int bit_buffer[BITS_PER_GROUP]; -	static int bit_pos = BITS_PER_GROUP; -	static double sample_buffer[SAMPLE_BUFFER_SIZE] = {0}; - -	static int prev_output = 0; -	static int cur_output = 0; -	static int cur_bit = 0; -	static int sample_count = SAMPLES_PER_BIT; -	static int inverting = 0; -	static int phase = 0; - -	static unsigned int in_sample_index = 0; -	static unsigned int out_sample_index = SAMPLE_BUFFER_SIZE-1; - -	unsigned int i, j, idx; -	double val, sample; -	double *src; - -	for (i = 0; i < count; i++) { -		if (sample_count >= SAMPLES_PER_BIT) { -			if (bit_pos >= BITS_PER_GROUP) { -				get_rds_group(bit_buffer); -				bit_pos = 0; -			} - -			// do differential encoding -			cur_bit = bit_buffer[bit_pos]; -			prev_output = cur_output; -			cur_output = prev_output ^ cur_bit; - -			inverting = (cur_output == 1); - -			src = waveform_biphase; -			idx = in_sample_index; - -			for (j = 0; j < FILTER_SIZE; j++) { -				val = *src++; -				if (inverting) -					val = -val; - -				sample_buffer[idx++] += val; - -				if (idx >= SAMPLE_BUFFER_SIZE) -					idx = 0; -			} - -			in_sample_index += SAMPLES_PER_BIT; -			if (in_sample_index >= SAMPLE_BUFFER_SIZE) -				in_sample_index -= SAMPLE_BUFFER_SIZE; - -			bit_pos++; -			sample_count = 0; -		} - -		sample = sample_buffer[out_sample_index]; -		sample_buffer[out_sample_index] = 0; -		out_sample_index++; -		if (out_sample_index >= SAMPLE_BUFFER_SIZE) -			out_sample_index = 0; - -		// modulate at 57 kHz -		// use phase for this -		switch (phase) { -			case 0: -			case 2: sample = 0; break; -			case 1: break; -			case 3: sample = -sample; break; -		} -		phase++; -		if (phase >= 4) -			phase = 0; - -		*buffer++ = sample; -		sample_count++; -	} -} - -void set_rds_pi(uint16_t pi_code) -{ -	rds_params.pi = pi_code; -} - -void set_rds_rt(char *rt) -{ -	int i; - -	strncpy(rds_params.rt, rt, 64); - -	for (i = 0; i < 64; i++) { -		if (rds_params.rt[i] == 0) -			rds_params.rt[i] = 32; -	} -} - -void set_rds_ps(char *ps) -{ -	int i; - -	strncpy(rds_params.ps, ps, 8); - -	for (i = 0; i < 8; i++) { -		if (rds_params.ps[i] == 0) -			rds_params.ps[i] = 32; -	} -} - -void set_rds_ta(int ta) -{ -	rds_params.ta = ta; -} diff --git a/src/rds_waveforms.c b/src/rds_waveforms.c deleted file mode 100644 index d508449..0000000 --- a/src/rds_waveforms.c +++ /dev/null @@ -1,153 +0,0 @@ -/* This file was automatically generated by "generate_waveforms.py" from - * https://github.com/ChristopheJacquet/PiFmRds/ - * - * (C) 2014 Christophe Jacquet. - * Released under the GNU GPL v3 license. -*/ - -double waveform_biphase[] = { - 0.00253265133022,  0.00255504491037,  0.00256667102126,  0.00256723854970, - 0.00255649674667,  0.00253423716573,  0.00250029547253,  0.00245455311551, - 0.00239693884806,  0.00232743009314,  0.00224605414143,  0.00215288917468, - 0.00204806510656,  0.00193176423352,  0.00180422168917,  0.00166572569587, - 0.00151661760823,  0.00135729174364,  0.00118819499588,  0.00100982622839, - 0.00082273544470,  0.00062752273428,  0.00042483699288,  0.00021537441720, --0.00000012322530, -0.00022087054977, -0.00044604072817, -0.00067476788077, --0.00090614968071, -0.00113925016637, -0.00137310275567, -0.00160671345499, --0.00183906425517, -0.00206911670572, -0.00229581565752, -0.00251809316382, --0.00273487252813, -0.00294507248686, -0.00314761151410, -0.00334141223473, --0.00352540593170, -0.00369853713255, -0.00385976825946, -0.00400808432674, --0.00414249766903, -0.00426205268297, -0.00436583056466, -0.00445295402495, --0.00452259196407, -0.00457396408696, -0.00460634544047, -0.00461907085337, --0.00461153926002, -0.00458321788861, -0.00453364629481, -0.00446244022186, --0.00436929526830, -0.00425399034471, -0.00411639090130, -0.00395645190841, --0.00377422057251, -0.00356983877090, -0.00334354518872, -0.00309567714275, --0.00282667207705, -0.00253706871632, -0.00222750786389, -0.00189873283191, --0.00155158949247, -0.00118702593940, -0.00080609175162, -0.00040993684994, - 0.00000019005938,  0.00042294345989,  0.00085688342327,  0.00130047843362, - 0.00175210863919,  0.00221006953169,  0.00267257605183,  0.00313776711824, - 0.00360371057560,  0.00406840855594,  0.00452980324611,  0.00498578305229, - 0.00543418915128,  0.00587282241677,  0.00629945070701,  0.00671181649912, - 0.00710764485348,  0.00748465169059,  0.00784055236082,  0.00817307048659, - 0.00847994705483,  0.00875894973632,  0.00900788240743,  0.00922459484812, - 0.00940699258958,  0.00955304688301,  0.00966080476069,  0.00972839915915, - 0.00975405907344,  0.00973611971083,  0.00967303261139,  0.00956337570235, - 0.00940586325271,  0.00919935569384,  0.00894286927184,  0.00863558549687, - 0.00827686035476,  0.00786623324593,  0.00740343561706,  0.00688839925073, - 0.00632126417893,  0.00570238618641,  0.00503234387065,  0.00431194522560, - 0.00354223371723,  0.00272449381977,  0.00186025598240,  0.00095130099727, --0.00000033625901, -0.00099236373728, -0.00202222980620, -0.00308712154498, --0.00418396376074, -0.00530941875093, -0.00645988682960, -0.00763150763453, --0.00882016223000, -0.01002147601830, -0.01123082247100, -0.01244332768770, --0.01365387579080, -0.01485711515770, -0.01604746549480, -0.01721912575140, --0.01836608287050, -0.01948212137170, -0.02056083375870, -0.02159563173920, --0.02257975824610, -0.02350630024450, -0.02436820230520, -0.02515828092590, --0.02586923957590, -0.02649368443980, -0.02702414083260, -0.02745307025480, --0.02777288805630, -0.02797598167370, -0.02805472940410, -0.02800151967640, --0.02780877077830, -0.02746895099680, -0.02697459912600, -0.02631834529620, --0.02549293207490, -0.02449123579000, -0.02330628802350, -0.02193129722250, --0.02035967037330, -0.01858503468320, -0.01660125921430, -0.01440247641080, --0.01198310346410, -0.00933786345535, -0.00646180621834, -0.00335032886310, - 0.00000080409844,  0.00359544108347,  0.00743702428450,  0.01152857108890, - 0.01587265612930,  0.02047139402060,  0.02532642284170,  0.03043888841330, - 0.03580942942790,  0.04143816348300,  0.04732467406730,  0.05346799854990, - 0.05986661721770,  0.06651844340760,  0.07342081477420,  0.08057048573450, - 0.08796362112670,  0.09559579111960,  0.10346196740200,  0.11155652068800, - 0.11987321955300,  0.12840523064300,  0.13714512025400,  0.14608485732300, - 0.15521581782400,  0.16452879059300,  0.17401398458500,  0.18366103756000, - 0.19345902621300,  0.20339647772800,  0.21346138276100,  0.22364120983400, - 0.23392292112600,  0.24429298964900,  0.25473741777900,  0.26524175712200, - 0.27579112968500,  0.28637025030900,  0.29696345035600,  0.30755470256700, - 0.31812764709700,  0.32866561863200,  0.33915167458400,  0.34956862427200, - 0.35989905906300,  0.37012538339000,  0.38022984661400,  0.39019457563000, - 0.40000160819100,  0.40963292682000,  0.41907049336100,  0.42829628390300, - 0.43729232419900,  0.44604072538100,  0.45452371993000,  0.46272369782900, - 0.47062324279700,  0.47820516854900,  0.48545255496600,  0.49234878413200, - 0.49887757611800,  0.50502302444800,  0.51076963117100,  0.51610234143400, - 0.52100657748800,  0.52546827205100,  0.52947390092900,  0.53301051483100, - 0.53606577028900,  0.53862795962200,  0.54068603984100,  0.54222966045900, - 0.54324919009800,  0.54373574185300,  0.54368119733200,  0.54307822931100, - 0.54192032294800,  0.54020179549500,  0.53791781445300,  0.53506441412200, - 0.53163851050000,  0.52763791447900,  0.52306134330900,  0.51790843029000, - 0.51217973265200,  0.50587673761100,  0.49900186656100,  0.49155847739800, - 0.48355086494200,  0.47498425946700,  0.46586482332000,  0.45619964562500, - 0.44599673508500,  0.43526501088000,  0.42401429168100,  0.41225528278300, - 0.39999956139700,  0.38725956008100,  0.37404854845100,  0.36038061302100, - 0.34627063539800,  0.33173426875400,  0.31678791267100,  0.30144868639300, - 0.28573440054000,  0.26966352734900,  0.25325516949400,  0.23652902755300, - 0.21950536619500,  0.20220497914700,  0.18464915302200,  0.16685963008900, - 0.14885857004900,  0.13066851092000,  0.11231232909100,  0.09381319865270, - 0.07519455007850,  0.05648002834940,  0.03769345061440,  0.01885876347700, - 0.00000000000000, -0.01885876347700, -0.03769345061440, -0.05648002834940, --0.07519455007850, -0.09381319865270, -0.11231232909100, -0.13066851092000, --0.14885857004900, -0.16685963008900, -0.18464915302200, -0.20220497914700, --0.21950536619500, -0.23652902755300, -0.25325516949400, -0.26966352734900, --0.28573440054000, -0.30144868639300, -0.31678791267100, -0.33173426875400, --0.34627063539800, -0.36038061302100, -0.37404854845100, -0.38725956008100, --0.39999956139700, -0.41225528278300, -0.42401429168100, -0.43526501088000, --0.44599673508500, -0.45619964562500, -0.46586482332000, -0.47498425946700, --0.48355086494200, -0.49155847739800, -0.49900186656100, -0.50587673761100, --0.51217973265200, -0.51790843029000, -0.52306134330900, -0.52763791447900, --0.53163851050000, -0.53506441412200, -0.53791781445300, -0.54020179549500, --0.54192032294800, -0.54307822931100, -0.54368119733200, -0.54373574185300, --0.54324919009800, -0.54222966045900, -0.54068603984100, -0.53862795962200, --0.53606577028900, -0.53301051483100, -0.52947390092900, -0.52546827205100, --0.52100657748800, -0.51610234143400, -0.51076963117100, -0.50502302444800, --0.49887757611800, -0.49234878413200, -0.48545255496600, -0.47820516854900, --0.47062324279700, -0.46272369782900, -0.45452371993000, -0.44604072538100, --0.43729232419900, -0.42829628390300, -0.41907049336100, -0.40963292682000, --0.40000160819100, -0.39019457563000, -0.38022984661400, -0.37012538339000, --0.35989905906300, -0.34956862427200, -0.33915167458400, -0.32866561863200, --0.31812764709700, -0.30755470256700, -0.29696345035600, -0.28637025030900, --0.27579112968500, -0.26524175712200, -0.25473741777900, -0.24429298964900, --0.23392292112600, -0.22364120983400, -0.21346138276100, -0.20339647772800, --0.19345902621300, -0.18366103756000, -0.17401398458500, -0.16452879059300, --0.15521581782400, -0.14608485732300, -0.13714512025400, -0.12840523064300, --0.11987321955300, -0.11155652068800, -0.10346196740200, -0.09559579111960, --0.08796362112670, -0.08057048573450, -0.07342081477420, -0.06651844340760, --0.05986661721770, -0.05346799854990, -0.04732467406730, -0.04143816348300, --0.03580942942790, -0.03043888841330, -0.02532642284170, -0.02047139402060, --0.01587265612930, -0.01152857108890, -0.00743702428450, -0.00359544108347, --0.00000080409844,  0.00335032886310,  0.00646180621834,  0.00933786345535, - 0.01198310346410,  0.01440247641080,  0.01660125921430,  0.01858503468320, - 0.02035967037330,  0.02193129722250,  0.02330628802350,  0.02449123579000, - 0.02549293207490,  0.02631834529620,  0.02697459912600,  0.02746895099680, - 0.02780877077830,  0.02800151967640,  0.02805472940410,  0.02797598167370, - 0.02777288805630,  0.02745307025480,  0.02702414083260,  0.02649368443980, - 0.02586923957590,  0.02515828092590,  0.02436820230520,  0.02350630024450, - 0.02257975824610,  0.02159563173920,  0.02056083375870,  0.01948212137170, - 0.01836608287050,  0.01721912575140,  0.01604746549480,  0.01485711515770, - 0.01365387579080,  0.01244332768770,  0.01123082247100,  0.01002147601830, - 0.00882016223000,  0.00763150763453,  0.00645988682960,  0.00530941875093, - 0.00418396376074,  0.00308712154498,  0.00202222980620,  0.00099236373728, - 0.00000033625901, -0.00095130099727, -0.00186025598240, -0.00272449381977, --0.00354223371723, -0.00431194522560, -0.00503234387065, -0.00570238618641, --0.00632126417893, -0.00688839925073, -0.00740343561706, -0.00786623324593, --0.00827686035476, -0.00863558549687, -0.00894286927184, -0.00919935569384, --0.00940586325271, -0.00956337570235, -0.00967303261139, -0.00973611971083, --0.00975405907344, -0.00972839915915, -0.00966080476069, -0.00955304688301, --0.00940699258958, -0.00922459484812, -0.00900788240743, -0.00875894973632, --0.00847994705483, -0.00817307048659, -0.00784055236082, -0.00748465169059, --0.00710764485348, -0.00671181649912, -0.00629945070701, -0.00587282241677, --0.00543418915128, -0.00498578305229, -0.00452980324611, -0.00406840855594, --0.00360371057560, -0.00313776711824, -0.00267257605183, -0.00221006953169, --0.00175210863919, -0.00130047843362, -0.00085688342327, -0.00042294345989, --0.00000019005938,  0.00040993684994,  0.00080609175162,  0.00118702593940, - 0.00155158949247,  0.00189873283191,  0.00222750786389,  0.00253706871632, - 0.00282667207705,  0.00309567714275,  0.00334354518872,  0.00356983877090, - 0.00377422057251,  0.00395645190841,  0.00411639090130,  0.00425399034471, - 0.00436929526830,  0.00446244022186,  0.00453364629481,  0.00458321788861, - 0.00461153926002,  0.00461907085337,  0.00460634544047,  0.00457396408696, - 0.00452259196407,  0.00445295402495,  0.00436583056466,  0.00426205268297, - 0.00414249766903,  0.00400808432674,  0.00385976825946,  0.00369853713255, - 0.00352540593170,  0.00334141223473,  0.00314761151410,  0.00294507248686, - 0.00273487252813,  0.00251809316382,  0.00229581565752,  0.00206911670572, - 0.00183906425517,  0.00160671345499,  0.00137310275567,  0.00113925016637, - 0.00090614968071,  0.00067476788077,  0.00044604072817,  0.00022087054977, - 0.00000012322530, -0.00021537441720, -0.00042483699288, -0.00062752273428, --0.00082273544470, -0.00100982622839, -0.00118819499588, -0.00135729174364, --0.00151661760823, -0.00166572569587, -0.00180422168917, -0.00193176423352, --0.00204806510656, -0.00215288917468, -0.00224605414143, -0.00232743009314, --0.00239693884806, -0.00245455311551, -0.00250029547253, -0.00253423716573, --0.00255649674667, -0.00256723854970, -0.00256667102126, -0.00255504491037, -}; | 
