aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt59
-rw-r--r--src/fl2k_ampliphase.c (renamed from src/fl2k_iq.c)0
-rw-r--r--src/fl2k_file.c215
-rw-r--r--src/fl2k_fm.c621
-rw-r--r--src/fl2k_garage.c545
-rw-r--r--src/fl2k_tcp.c256
-rw-r--r--src/fl2k_test.c308
-rw-r--r--src/rds_mod.c302
-rw-r--r--src/rds_waveforms.c153
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,
-};