aboutsummaryrefslogtreecommitdiffstats
path: root/src/libsdr/sdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsdr/sdr.c')
-rw-r--r--src/libsdr/sdr.c280
1 files changed, 174 insertions, 106 deletions
diff --git a/src/libsdr/sdr.c b/src/libsdr/sdr.c
index 73107c0..e322b5e 100644
--- a/src/libsdr/sdr.c
+++ b/src/libsdr/sdr.c
@@ -31,7 +31,7 @@ enum paging_signal;
#include "../libsample/sample.h"
#include "../libfm/fm.h"
#include "../libam/am.h"
-#include "../libtimer/timer.h"
+#include <osmocom/core/timer.h>
#include "../libmobile/sender.h"
#include "sdr_config.h"
#include "sdr.h"
@@ -41,7 +41,7 @@ enum paging_signal;
#ifdef HAVE_SOAPY
#include "soapy.h"
#endif
-#include "../libdebug/debug.h"
+#include "../liblogging/logging.h"
/* enable to debug buffer handling */
//#define DEBUG_BUFFER
@@ -93,7 +93,8 @@ typedef struct sdr {
int channels; /* number of frequencies */
double amplitude; /* amplitude of each carrier */
int samplerate; /* sample rate of audio data */
- int latspl; /* latency in audio samples */
+ int buffer_size; /* buffer in audio samples */
+ double interval; /* how often to process the loop */
wave_rec_t wave_rx_rec;
wave_rec_t wave_tx_rec;
wave_play_t wave_rx_play;
@@ -129,14 +130,14 @@ static void show_spectrum(const char *direction, double halfbandwidth, double ce
text[x] = 'P';
}
- PDEBUG(DSDR, DEBUG_INFO, "%s Spectrum:\n%s\n---------------------------------------+---------------------------------------\n", direction, text);
+ LOGP(DSDR, LOGL_INFO, "%s Spectrum:\n%s\n---------------------------------------+---------------------------------------\n", direction, text);
for (i = 0; i < num; i++)
- PDEBUG(DSDR, DEBUG_INFO, "Frequency %c = %.4f MHz\n", '1' + i, frequency[i] / 1e6);
+ LOGP(DSDR, LOGL_INFO, "Frequency %c = %.4f MHz\n", '1' + i, frequency[i] / 1e6);
if (paging_frequency)
- PDEBUG(DSDR, DEBUG_INFO, "Frequency P = %.4f MHz (Paging Frequency)\n", paging_frequency / 1e6);
+ LOGP(DSDR, LOGL_INFO, "Frequency P = %.4f MHz (Paging Frequency)\n", paging_frequency / 1e6);
}
-void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_frequency, double *rx_frequency, int *am, int channels, double paging_frequency, int samplerate, int latspl, double max_deviation, double max_modulation, double modulation_index)
+void *sdr_open(int __attribute__((__unused__)) direction, const char __attribute__((__unused__)) *device, double *tx_frequency, double *rx_frequency, int *am, int channels, double paging_frequency, int samplerate, int buffer_size, double interval, double max_deviation, double max_modulation, double modulation_index)
{
sdr_t *sdr;
int threads = 1, oversample = 1; /* always use threads */
@@ -145,17 +146,17 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq
int rc;
int c;
- PDEBUG(DSDR, DEBUG_DEBUG, "Open SDR device\n");
+ LOGP(DSDR, LOGL_DEBUG, "Open SDR device\n");
if (sdr_config->samplerate != samplerate) {
if (samplerate > sdr_config->samplerate) {
- PDEBUG(DSDR, DEBUG_ERROR, "SDR sample rate must be greater than audio sample rate!\n");
- PDEBUG(DSDR, DEBUG_ERROR, "You selected an SDR rate of %d and an audio rate of %d.\n", sdr_config->samplerate, samplerate);
+ LOGP(DSDR, LOGL_ERROR, "SDR sample rate must be greater than audio sample rate!\n");
+ LOGP(DSDR, LOGL_ERROR, "You selected an SDR rate of %d and an audio rate of %d.\n", sdr_config->samplerate, samplerate);
return NULL;
}
if ((sdr_config->samplerate % samplerate)) {
- PDEBUG(DSDR, DEBUG_ERROR, "SDR sample rate must be a multiple of audio sample rate!\n");
- PDEBUG(DSDR, DEBUG_ERROR, "You selected an SDR rate of %d and an audio rate of %d.\n", sdr_config->samplerate, samplerate);
+ LOGP(DSDR, LOGL_ERROR, "SDR sample rate must be a multiple of audio sample rate!\n");
+ LOGP(DSDR, LOGL_ERROR, "You selected an SDR rate of %d and an audio rate of %d.\n", sdr_config->samplerate, samplerate);
return NULL;
}
oversample = sdr_config->samplerate / samplerate;
@@ -164,36 +165,32 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq
bandwidth = 2.0 * (max_deviation + max_modulation);
if (bandwidth)
- PDEBUG(DSDR, DEBUG_INFO, "Require bandwidth of each channel is 2 * (%.1f deviation + %.1f modulation) = %.1f KHz\n", max_deviation / 1e3, max_modulation / 1e3, bandwidth / 1e3);
-
- if (channels < 1) {
- PDEBUG(DSDR, DEBUG_ERROR, "No channel given, please fix!\n");
- abort();
- }
+ LOGP(DSDR, LOGL_INFO, "Require bandwidth of each channel is 2 * (%.1f deviation + %.1f modulation) = %.1f KHz\n", max_deviation / 1e3, max_modulation / 1e3, bandwidth / 1e3);
sdr = calloc(sizeof(*sdr), 1);
if (!sdr) {
- PDEBUG(DSDR, DEBUG_ERROR, "NO MEM!\n");
+ LOGP(DSDR, LOGL_ERROR, "NO MEM!\n");
goto error;
}
sdr->channels = channels;
sdr->amplitude = 1.0 / (double)channels;
sdr->samplerate = samplerate;
- sdr->latspl = latspl;
+ sdr->buffer_size = buffer_size;
+ sdr->interval = interval;
sdr->threads = threads; /* always required, because write may block */
sdr->oversample = oversample;
if (threads) {
memset(&sdr->thread_read, 0, sizeof(sdr->thread_read));
- sdr->thread_read.buffer_size = sdr->latspl * 2 * sdr->oversample + 2;
+ sdr->thread_read.buffer_size = sdr->buffer_size * 2 * sdr->oversample + 2;
sdr->thread_read.buffer = calloc(sdr->thread_read.buffer_size, sizeof(*sdr->thread_read.buffer));
if (!sdr->thread_read.buffer) {
- PDEBUG(DSDR, DEBUG_ERROR, "No mem!\n");
+ LOGP(DSDR, LOGL_ERROR, "No mem!\n");
goto error;
}
sdr->thread_read.buffer2 = calloc(sdr->thread_read.buffer_size, sizeof(*sdr->thread_read.buffer2));
if (!sdr->thread_read.buffer2) {
- PDEBUG(DSDR, DEBUG_ERROR, "No mem!\n");
+ LOGP(DSDR, LOGL_ERROR, "No mem!\n");
goto error;
}
sdr->thread_read.in = sdr->thread_read.out = 0;
@@ -202,15 +199,15 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq
iir_lowpass_init(&sdr->thread_read.lp[1], samplerate / 2.0, sdr_config->samplerate, 2);
}
memset(&sdr->thread_write, 0, sizeof(sdr->thread_write));
- sdr->thread_write.buffer_size = sdr->latspl * 2 + 2;
+ sdr->thread_write.buffer_size = sdr->buffer_size * 2 + 2;
sdr->thread_write.buffer = calloc(sdr->thread_write.buffer_size, sizeof(*sdr->thread_write.buffer));
if (!sdr->thread_write.buffer) {
- PDEBUG(DSDR, DEBUG_ERROR, "No mem!\n");
+ LOGP(DSDR, LOGL_ERROR, "No mem!\n");
goto error;
}
sdr->thread_write.buffer2 = calloc(sdr->thread_write.buffer_size * sdr->oversample, sizeof(*sdr->thread_write.buffer2));
if (!sdr->thread_write.buffer2) {
- PDEBUG(DSDR, DEBUG_ERROR, "No mem!\n");
+ LOGP(DSDR, LOGL_ERROR, "No mem!\n");
goto error;
}
sdr->thread_write.in = sdr->thread_write.out = 0;
@@ -221,34 +218,34 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq
}
/* alloc fm modulation buffers */
- sdr->modbuff = calloc(sdr->latspl * 2, sizeof(*sdr->modbuff));
+ sdr->modbuff = calloc(sdr->buffer_size * 2, sizeof(*sdr->modbuff));
if (!sdr->modbuff) {
- PDEBUG(DSDR, DEBUG_ERROR, "NO MEM!\n");
+ LOGP(DSDR, LOGL_ERROR, "NO MEM!\n");
goto error;
}
- sdr->modbuff_I = calloc(sdr->latspl, sizeof(*sdr->modbuff_I));
+ sdr->modbuff_I = calloc(sdr->buffer_size, sizeof(*sdr->modbuff_I));
if (!sdr->modbuff_I) {
- PDEBUG(DSDR, DEBUG_ERROR, "NO MEM!\n");
+ LOGP(DSDR, LOGL_ERROR, "NO MEM!\n");
goto error;
}
- sdr->modbuff_Q = calloc(sdr->latspl, sizeof(*sdr->modbuff_Q));
+ sdr->modbuff_Q = calloc(sdr->buffer_size, sizeof(*sdr->modbuff_Q));
if (!sdr->modbuff_Q) {
- PDEBUG(DSDR, DEBUG_ERROR, "NO MEM!\n");
+ LOGP(DSDR, LOGL_ERROR, "NO MEM!\n");
goto error;
}
- sdr->modbuff_carrier = calloc(sdr->latspl, sizeof(*sdr->modbuff_carrier));
+ sdr->modbuff_carrier = calloc(sdr->buffer_size, sizeof(*sdr->modbuff_carrier));
if (!sdr->modbuff_carrier) {
- PDEBUG(DSDR, DEBUG_ERROR, "NO MEM!\n");
+ LOGP(DSDR, LOGL_ERROR, "NO MEM!\n");
goto error;
}
- sdr->wavespl0 = calloc(sdr->latspl, sizeof(*sdr->wavespl0));
+ sdr->wavespl0 = calloc(sdr->buffer_size, sizeof(*sdr->wavespl0));
if (!sdr->wavespl0) {
- PDEBUG(DSDR, DEBUG_ERROR, "NO MEM!\n");
+ LOGP(DSDR, LOGL_ERROR, "NO MEM!\n");
goto error;
}
- sdr->wavespl1 = calloc(sdr->latspl, sizeof(*sdr->wavespl1));
+ sdr->wavespl1 = calloc(sdr->buffer_size, sizeof(*sdr->wavespl1));
if (!sdr->wavespl1) {
- PDEBUG(DSDR, DEBUG_ERROR, "NO MEM!\n");
+ LOGP(DSDR, LOGL_ERROR, "NO MEM!\n");
goto error;
}
@@ -259,13 +256,26 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq
}
/* create list of channel states */
- sdr->chan = calloc(sizeof(*sdr->chan), channels + (sdr->paging_channel != 0));
- if (!sdr->chan) {
- PDEBUG(DSDR, DEBUG_ERROR, "NO MEM!\n");
- goto error;
+ if (channels) {
+ sdr->chan = calloc(sizeof(*sdr->chan), channels + (sdr->paging_channel != 0));
+ if (!sdr->chan) {
+ LOGP(DSDR, LOGL_ERROR, "NO MEM!\n");
+ goto error;
+ }
}
- if (tx_frequency) {
+ /* swap links, if required */
+ if (sdr_config->swap_links) {
+ double *temp;
+ LOGP(DSDR, LOGL_NOTICE, "Sapping RX and TX frequencies!\n");
+ temp = rx_frequency;
+ rx_frequency = tx_frequency;
+ tx_frequency = temp;
+ }
+
+ if (tx_frequency && !channels)
+ tx_center_frequency = tx_frequency[0];
+ if (tx_frequency && channels) {
/* calculate required bandwidth (IQ rate) */
double tx_low_frequency = 0.0, tx_high_frequency = 0.0;
@@ -285,6 +295,57 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq
}
tx_center_frequency = (tx_high_frequency + tx_low_frequency) / 2.0;
+ /* prevent channel bandwidth from overlapping with the center frequency */
+ if (channels == 1 && !sdr->paging_channel) {
+ /* simple: just move off the center by two times half of the bandwidth */
+ tx_center_frequency -= 2.0 * bandwidth / 2.0;
+ /* Note: tx_low_frequency is kept at old center.
+ Calculation of 'low_side' will become 0.
+ This is correct, since there is no bandwidth
+ below new center frequency.
+ */
+ LOGP(DSDR, LOGL_INFO, "We shift center frequency %.0f KHz down (half bandwidth), to prevent channel from overlap with DC level.\n", bandwidth / 2.0 / 1e3);
+ } else {
+ /* find two channels that are aside the center */
+ double low_dist = 0, high_dist = 0, dist;
+ int low_c = -1, high_c = -1;
+ for (c = 0; c < channels; c++) {
+ dist = fabs(tx_center_frequency - sdr->chan[c].tx_frequency);
+ if (round(sdr->chan[c].tx_frequency) >= round(tx_center_frequency)) {
+ if (high_c < 0 || dist < high_dist) {
+ high_dist = dist;
+ high_c = c;
+ }
+ } else {
+ if (low_c < 0 || dist < low_dist) {
+ low_dist = dist;
+ low_c = c;
+ }
+ }
+ }
+ if (sdr->paging_channel) {
+ dist = fabs(tx_center_frequency - sdr->chan[sdr->paging_channel].tx_frequency);
+ if (round(sdr->chan[sdr->paging_channel].tx_frequency) >= round(tx_center_frequency)) {
+ if (high_c < 0 || dist < high_dist) {
+ high_dist = dist;
+ high_c = sdr->paging_channel;
+ }
+ } else {
+ if (low_c < 0 || dist < low_dist) {
+ low_dist = dist;
+ low_c = sdr->paging_channel;
+ }
+ }
+ }
+ /* new center = center of the two frequencies aside old center */
+ if (low_c >= 0 && high_c >= 0) {
+ tx_center_frequency =
+ ((sdr->chan[low_c].tx_frequency) +
+ (sdr->chan[high_c].tx_frequency)) / 2.0;
+ LOGP(DSDR, LOGL_INFO, "We move center freqeuency between the two channels in the middle, to prevent them from overlap with DC level.\n");
+ }
+ }
+
/* show spectrum */
show_spectrum("TX", (double)samplerate / 2.0, tx_center_frequency, tx_frequency, paging_frequency, channels);
@@ -293,20 +354,20 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq
low_side = (tx_center_frequency - tx_low_frequency) + bandwidth / 2.0;
high_side = (tx_high_frequency - tx_center_frequency) + bandwidth / 2.0;
range = ((low_side > high_side) ? low_side : high_side) * 2.0;
- PDEBUG(DSDR, DEBUG_INFO, "Total bandwidth (two side bands) for all TX Frequencies: %.0f Hz\n", range);
+ LOGP(DSDR, LOGL_INFO, "Total bandwidth (two side bands) for all TX Frequencies: %.0f Hz\n", range);
if (range > samplerate * USABLE_BANDWIDTH) {
- PDEBUG(DSDR, DEBUG_NOTICE, "*******************************************************************************\n");
- PDEBUG(DSDR, DEBUG_NOTICE, "The required bandwidth of %.0f Hz exceeds %.0f%% of the sample rate.\n", range, USABLE_BANDWIDTH * 100.0);
- PDEBUG(DSDR, DEBUG_NOTICE, "Please increase samplerate!\n");
- PDEBUG(DSDR, DEBUG_NOTICE, "*******************************************************************************\n");
+ LOGP(DSDR, LOGL_NOTICE, "*******************************************************************************\n");
+ LOGP(DSDR, LOGL_NOTICE, "The required bandwidth of %.0f Hz exceeds %.0f%% of the sample rate.\n", range, USABLE_BANDWIDTH * 100.0);
+ LOGP(DSDR, LOGL_NOTICE, "Please increase samplerate!\n");
+ LOGP(DSDR, LOGL_NOTICE, "*******************************************************************************\n");
goto error;
}
- PDEBUG(DSDR, DEBUG_INFO, "Using center frequency: TX %.6f MHz\n", tx_center_frequency / 1e6);
+ LOGP(DSDR, LOGL_INFO, "Using center frequency: TX %.6f MHz\n", tx_center_frequency / 1e6);
/* set offsets to center frequency */
for (c = 0; c < channels; c++) {
double tx_offset;
tx_offset = sdr->chan[c].tx_frequency - tx_center_frequency;
- PDEBUG(DSDR, DEBUG_DEBUG, "Frequency #%d: TX offset: %.6f MHz\n", c, tx_offset / 1e6);
+ LOGP(DSDR, LOGL_DEBUG, "Frequency #%d: TX offset: %.6f MHz\n", c, tx_offset / 1e6);
sdr->chan[c].am = am[c];
if (am[c]) {
double gain, bias;
@@ -321,18 +382,18 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq
if (sdr->paging_channel) {
double tx_offset;
tx_offset = sdr->chan[sdr->paging_channel].tx_frequency - tx_center_frequency;
- PDEBUG(DSDR, DEBUG_DEBUG, "Paging Frequency: TX offset: %.6f MHz\n", tx_offset / 1e6);
+ LOGP(DSDR, LOGL_DEBUG, "Paging Frequency: TX offset: %.6f MHz\n", tx_offset / 1e6);
rc = fm_mod_init(&sdr->chan[sdr->paging_channel].fm_mod, samplerate, tx_offset, sdr->amplitude);
if (rc < 0)
goto error;
}
/* show gain */
- PDEBUG(DSDR, DEBUG_INFO, "Using gain: TX %.1f dB\n", sdr_config->tx_gain);
+ LOGP(DSDR, LOGL_INFO, "Using gain: TX %.1f dB\n", sdr_config->tx_gain);
/* open wave */
if (sdr_config->write_iq_tx_wave) {
rc = wave_create_record(&sdr->wave_tx_rec, sdr_config->write_iq_tx_wave, samplerate, 2, 1.0);
if (rc < 0) {
- PDEBUG(DSDR, DEBUG_ERROR, "Failed to create WAVE recoding instance!\n");
+ LOGP(DSDR, LOGL_ERROR, "Failed to create WAVE recoding instance!\n");
goto error;
}
}
@@ -340,13 +401,15 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq
int two = 2;
rc = wave_create_playback(&sdr->wave_tx_play, sdr_config->read_iq_tx_wave, &samplerate, &two, 1.0);
if (rc < 0) {
- PDEBUG(DSDR, DEBUG_ERROR, "Failed to create WAVE playback instance!\n");
+ LOGP(DSDR, LOGL_ERROR, "Failed to create WAVE playback instance!\n");
goto error;
}
}
}
- if (rx_frequency) {
+ if (rx_frequency && !channels)
+ rx_center_frequency = rx_frequency[0];
+ if (rx_frequency && channels) {
/* calculate required bandwidth (IQ rate) */
double rx_low_frequency = 0.0, rx_high_frequency = 0.0;
for (c = 0; c < channels; c++) {
@@ -367,7 +430,7 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq
This is correct, since there is no bandwidth
below new center frequency.
*/
- PDEBUG(DSDR, DEBUG_INFO, "We shift center frequency %.0f KHz down (half bandwidth), to prevent channel from overlap with DC level.\n", bandwidth / 2.0 / 1e3);
+ LOGP(DSDR, LOGL_INFO, "We shift center frequency %.0f KHz down (half bandwidth), to prevent channel from overlap with DC level.\n", bandwidth / 2.0 / 1e3);
} else {
/* find two channels that are aside the center */
double low_dist, high_dist, dist;
@@ -391,7 +454,7 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq
rx_center_frequency =
((sdr->chan[low_c].rx_frequency) +
(sdr->chan[high_c].rx_frequency)) / 2.0;
- PDEBUG(DSDR, DEBUG_INFO, "We move center freqeuency between the two channels in the middle, to prevent them from overlap with DC level.\n");
+ LOGP(DSDR, LOGL_INFO, "We move center freqeuency between the two channels in the middle, to prevent them from overlap with DC level.\n");
}
}
@@ -403,35 +466,35 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq
low_side = (rx_center_frequency - rx_low_frequency) + bandwidth / 2.0;
high_side = (rx_high_frequency - rx_center_frequency) + bandwidth / 2.0;
range = ((low_side > high_side) ? low_side : high_side) * 2.0;
- PDEBUG(DSDR, DEBUG_INFO, "Total bandwidth (two side bands) for all RX Frequencies: %.0f Hz\n", range);
+ LOGP(DSDR, LOGL_INFO, "Total bandwidth (two side bands) for all RX Frequencies: %.0f Hz\n", range);
if (range > samplerate * USABLE_BANDWIDTH) {
- PDEBUG(DSDR, DEBUG_NOTICE, "*******************************************************************************\n");
- PDEBUG(DSDR, DEBUG_NOTICE, "The required bandwidth of %.0f Hz exceeds %.0f%% of the sample rate.\n", range, USABLE_BANDWIDTH * 100.0);
- PDEBUG(DSDR, DEBUG_NOTICE, "Please increase samplerate!\n");
- PDEBUG(DSDR, DEBUG_NOTICE, "*******************************************************************************\n");
+ LOGP(DSDR, LOGL_NOTICE, "*******************************************************************************\n");
+ LOGP(DSDR, LOGL_NOTICE, "The required bandwidth of %.0f Hz exceeds %.0f%% of the sample rate.\n", range, USABLE_BANDWIDTH * 100.0);
+ LOGP(DSDR, LOGL_NOTICE, "Please increase samplerate!\n");
+ LOGP(DSDR, LOGL_NOTICE, "*******************************************************************************\n");
goto error;
}
- PDEBUG(DSDR, DEBUG_INFO, "Using center frequency: RX %.6f MHz\n", rx_center_frequency / 1e6);
+ LOGP(DSDR, LOGL_INFO, "Using center frequency: RX %.6f MHz\n", rx_center_frequency / 1e6);
/* set offsets to center frequency */
for (c = 0; c < channels; c++) {
double rx_offset;
rx_offset = sdr->chan[c].rx_frequency - rx_center_frequency;
- PDEBUG(DSDR, DEBUG_DEBUG, "Frequency #%d: RX offset: %.6f MHz\n", c, rx_offset / 1e6);
+ LOGP(DSDR, LOGL_DEBUG, "Frequency #%d: RX offset: %.6f MHz\n", c, rx_offset / 1e6);
sdr->chan[c].am = am[c];
if (am[c])
- rc = am_demod_init(&sdr->chan[c].am_demod, samplerate, rx_offset, bandwidth, 1.0 / modulation_index);
+ rc = am_demod_init(&sdr->chan[c].am_demod, samplerate, rx_offset, bandwidth / 2.0, 1.0 / modulation_index); /* bandwidth is only one side band */
else
- rc = fm_demod_init(&sdr->chan[c].fm_demod, samplerate, rx_offset, bandwidth / 2.0);
+ rc = fm_demod_init(&sdr->chan[c].fm_demod, samplerate, rx_offset, bandwidth); /* bandwidth are deviation and both side bands */
if (rc < 0)
goto error;
}
/* show gain */
- PDEBUG(DSDR, DEBUG_INFO, "Using gain: RX %.1f dB\n", sdr_config->rx_gain);
+ LOGP(DSDR, LOGL_INFO, "Using gain: RX %.1f dB\n", sdr_config->rx_gain);
/* open wave */
if (sdr_config->write_iq_rx_wave) {
rc = wave_create_record(&sdr->wave_rx_rec, sdr_config->write_iq_rx_wave, samplerate, 2, 1.0);
if (rc < 0) {
- PDEBUG(DSDR, DEBUG_ERROR, "Failed to create WAVE recoding instance!\n");
+ LOGP(DSDR, LOGL_ERROR, "Failed to create WAVE recoding instance!\n");
goto error;
}
}
@@ -439,7 +502,7 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq
int two = 2;
rc = wave_create_playback(&sdr->wave_rx_play, sdr_config->read_iq_rx_wave, &samplerate, &two, 1.0);
if (rc < 0) {
- PDEBUG(DSDR, DEBUG_ERROR, "Failed to create WAVE playback instance!\n");
+ LOGP(DSDR, LOGL_ERROR, "Failed to create WAVE playback instance!\n");
goto error;
}
}
@@ -456,22 +519,14 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq
}
}
- if (sdr_config->swap_links) {
- double temp;
- PDEBUG(DSDR, DEBUG_NOTICE, "Sapping RX and TX frequencies!\n");
- temp = rx_center_frequency;
- rx_center_frequency = tx_center_frequency;
- tx_center_frequency = temp;
- }
-
display_iq_init(samplerate);
display_spectrum_init(samplerate, rx_center_frequency);
- PDEBUG(DSDR, DEBUG_INFO, "Using local oscillator offseet: %.0f Hz\n", sdr_config->lo_offset);
+ LOGP(DSDR, LOGL_INFO, "Using local oscillator offseet: %.0f Hz\n", sdr_config->lo_offset);
#ifdef HAVE_UHD
if (sdr_config->uhd) {
- rc = uhd_open(sdr_config->channel, sdr_config->device_args, sdr_config->stream_args, sdr_config->tune_args, sdr_config->tx_antenna, sdr_config->rx_antenna, sdr_config->clock_source, tx_center_frequency, rx_center_frequency, sdr_config->lo_offset, sdr_config->samplerate, sdr_config->tx_gain, sdr_config->rx_gain, sdr_config->bandwidth, sdr_config->uhd_tx_timestamps);
+ rc = uhd_open(sdr_config->channel, sdr_config->device_args, sdr_config->stream_args, sdr_config->tune_args, sdr_config->tx_antenna, sdr_config->rx_antenna, sdr_config->clock_source, tx_center_frequency, rx_center_frequency, sdr_config->lo_offset, sdr_config->samplerate, sdr_config->tx_gain, sdr_config->rx_gain, sdr_config->bandwidth, sdr_config->timestamps);
if (rc)
goto error;
}
@@ -479,7 +534,7 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq
#ifdef HAVE_SOAPY
if (sdr_config->soapy) {
- rc = soapy_open(sdr_config->channel, sdr_config->device_args, sdr_config->stream_args, sdr_config->tune_args, sdr_config->tx_antenna, sdr_config->rx_antenna, sdr_config->clock_source, tx_center_frequency, rx_center_frequency, sdr_config->lo_offset, sdr_config->samplerate, sdr_config->tx_gain, sdr_config->rx_gain, sdr_config->bandwidth);
+ rc = soapy_open(sdr_config->channel, sdr_config->device_args, sdr_config->stream_args, sdr_config->tune_args, sdr_config->tx_antenna, sdr_config->rx_antenna, sdr_config->clock_source, tx_center_frequency, rx_center_frequency, sdr_config->lo_offset, sdr_config->samplerate, sdr_config->tx_gain, sdr_config->rx_gain, sdr_config->bandwidth, sdr_config->timestamps);
if (rc)
goto error;
}
@@ -515,7 +570,7 @@ static void sdr_bias(float *buffer, int count)
if (bias_count >= sdr_config->samplerate) {
bias_I /= bias_count;
bias_Q /= bias_count;
- PDEBUG(DSDR, DEBUG_INFO, "DC bias calibration finished.\n");
+ LOGP(DSDR, LOGL_INFO, "DC bias calibration finished.\n");
}
} else {
for (i = 0; i < count; i++) {
@@ -567,10 +622,10 @@ static void *sdr_write_child(void *arg)
}
/* delay some time */
- usleep(1000);
+ usleep(sdr->interval * 1000.0);
}
- PDEBUG(DSDR, DEBUG_DEBUG, "Thread received exit!\n");
+ LOGP(DSDR, LOGL_DEBUG, "Thread received exit!\n");
sdr->thread_write.exit = 1;
return NULL;
}
@@ -619,10 +674,10 @@ static void *sdr_read_child(void *arg)
}
/* delay some time */
- usleep(1000);
+ usleep(sdr->interval * 1000.0);
}
- PDEBUG(DSDR, DEBUG_DEBUG, "Thread received exit!\n");
+ LOGP(DSDR, LOGL_DEBUG, "Thread received exit!\n");
sdr->thread_read.exit = 1;
return NULL;
}
@@ -649,13 +704,13 @@ int sdr_start(void *inst)
pthread_t tid;
char tname[64];
- PDEBUG(DSDR, DEBUG_DEBUG, "Create threads!\n");
+ LOGP(DSDR, LOGL_DEBUG, "Create threads!\n");
sdr->thread_write.running = 1;
sdr->thread_write.exit = 0;
rc = pthread_create(&tid, NULL, sdr_write_child, inst);
if (rc < 0) {
sdr->thread_write.running = 0;
- PDEBUG(DSDR, DEBUG_ERROR, "Failed to create thread!\n");
+ LOGP(DSDR, LOGL_ERROR, "Failed to create thread!\n");
return rc;
}
pthread_getname_np(tid, tname, sizeof(tname));
@@ -667,7 +722,7 @@ int sdr_start(void *inst)
rc = pthread_create(&tid, NULL, sdr_read_child, inst);
if (rc < 0) {
sdr->thread_read.running = 0;
- PDEBUG(DSDR, DEBUG_ERROR, "Failed to create thread!\n");
+ LOGP(DSDR, LOGL_ERROR, "Failed to create thread!\n");
return rc;
}
pthread_getname_np(tid, tname, sizeof(tname));
@@ -683,17 +738,17 @@ void sdr_close(void *inst)
{
sdr_t *sdr = (sdr_t *)inst;
- PDEBUG(DSDR, DEBUG_DEBUG, "Close SDR device\n");
+ LOGP(DSDR, LOGL_DEBUG, "Close SDR device\n");
if (sdr->threads) {
if (sdr->thread_write.running) {
- PDEBUG(DSDR, DEBUG_DEBUG, "Thread sending exit!\n");
+ LOGP(DSDR, LOGL_DEBUG, "Thread sending exit!\n");
sdr->thread_write.running = 0;
while (sdr->thread_write.exit == 0)
usleep(1000);
}
if (sdr->thread_read.running) {
- PDEBUG(DSDR, DEBUG_DEBUG, "Thread sending exit!\n");
+ LOGP(DSDR, LOGL_DEBUG, "Thread sending exit!\n");
sdr->thread_read.running = 0;
while (sdr->thread_read.exit == 0)
usleep(1000);
@@ -750,6 +805,15 @@ void sdr_close(void *inst)
display_spectrum_exit();
}
+static double get_time(void)
+{
+ static struct timespec tv;
+
+ clock_gettime(CLOCK_REALTIME, &tv);
+
+ return (double)tv.tv_sec + (double)tv.tv_nsec / 1000000000.0;
+}
+
int sdr_write(void *inst, sample_t **samples, uint8_t **power, int num, enum paging_signal __attribute__((unused)) *paging_signal, int *on, int channels)
{
sdr_t *sdr = (sdr_t *)inst;
@@ -757,12 +821,12 @@ int sdr_write(void *inst, sample_t **samples, uint8_t **power, int num, enum pag
int c, s, ss;
int sent = 0;
- if (num > sdr->latspl) {
- fprintf(stderr, "exceeding maximum size given by sdr_latspl, please fix!\n");
+ if (num > sdr->buffer_size) {
+ fprintf(stderr, "exceeding maximum size given by sdr->buffer_size, please fix!\n");
abort();
}
if (channels != sdr->channels && channels != 0) {
- PDEBUG(DSDR, DEBUG_ERROR, "Invalid number of channels, please fix!\n");
+ LOGP(DSDR, LOGL_ERROR, "Invalid number of channels, please fix!\n");
abort();
}
@@ -817,11 +881,11 @@ int sdr_write(void *inst, sample_t **samples, uint8_t **power, int num, enum pag
delay = (double)sdr->thread_write.max_fill / 2.0 / (double)sdr->samplerate;
sdr->thread_write.max_fill = 0;
sdr->thread_write.max_fill_timer += 1.0;
- PDEBUG(DSDR, DEBUG_DEBUG, "write delay = %.3f ms\n", delay * 1000.0);
+ LOGP(DSDR, LOGL_DEBUG, "write delay = %.3f ms\n", delay * 1000.0);
}
if (space < num * 2) {
- PDEBUG(DSDR, DEBUG_ERROR, "Write SDR buffer overflow!\n");
+ LOGP(DSDR, LOGL_ERROR, "Write SDR buffer overflow!\n");
num = space / 2;
}
#ifdef DEBUG_BUFFER
@@ -858,8 +922,8 @@ int sdr_read(void *inst, sample_t **samples, int num, int channels, double *rf_l
int count = 0;
int c, s, ss;
- if (num > sdr->latspl) {
- fprintf(stderr, "exceeding maximum size given by sdr_latspl, please fix!\n");
+ if (num > sdr->buffer_size) {
+ fprintf(stderr, "exceeding maximum size given by sdr->buffer_size, please fix!\n");
abort();
}
@@ -885,7 +949,7 @@ int sdr_read(void *inst, sample_t **samples, int num, int channels, double *rf_l
delay = (double)sdr->thread_read.max_fill / 2.0 / (double)sdr_config->samplerate;
sdr->thread_read.max_fill = 0;
sdr->thread_read.max_fill_timer += 1.0;
- PDEBUG(DSDR, DEBUG_DEBUG, "read delay = %.3f ms\n", delay * 1000.0);
+ LOGP(DSDR, LOGL_DEBUG, "read delay = %.3f ms\n", delay * 1000.0);
}
if (fill / 2 / sdr->oversample < num)
@@ -917,7 +981,7 @@ int sdr_read(void *inst, sample_t **samples, int num, int channels, double *rf_l
}
if (sdr_rx_overflow) {
- PDEBUG(DSDR, DEBUG_ERROR, "SDR RX overflow!\n");
+ LOGP(DSDR, LOGL_ERROR, "SDR RX overflow!\n");
sdr_rx_overflow = 0;
}
@@ -942,6 +1006,8 @@ int sdr_read(void *inst, sample_t **samples, int num, int channels, double *rf_l
if (channels) {
for (c = 0; c < channels; c++) {
+ if (rf_level_db)
+ rf_level_db[c] = NAN;
if (sdr->chan[c].am)
am_demodulate_complex(&sdr->chan[c].am_demod, samples[c], count, buff, sdr->modbuff_I, sdr->modbuff_Q, sdr->modbuff_carrier);
else
@@ -958,7 +1024,8 @@ int sdr_read(void *inst, sample_t **samples, int num, int channels, double *rf_l
avg = sqrt(avg /(double)count); /* RMS */
avg = log10(avg) * 20;
display_measurements_update(sdr->chan[c].dmp_rf_level, avg, 0.0);
- rf_level_db[c] = avg;
+ if (rf_level_db)
+ rf_level_db[c] = avg;
if (!sdr->chan[c].am) {
min = 0.0;
max = 0.0;
@@ -981,26 +1048,27 @@ int sdr_read(void *inst, sample_t **samples, int num, int channels, double *rf_l
return count;
}
-/* how much do we need to send (in audio sample duration) to get the target delay (latspl) */
-int sdr_get_tosend(void *inst, int latspl)
+/* how much do we need to send (in audio sample duration) to get the target delay (buffer size) */
+int sdr_get_tosend(void *inst, int buffer_size)
{
sdr_t *sdr = (sdr_t *)inst;
int count = 0;
#ifdef HAVE_UHD
if (sdr_config->uhd)
- count = uhd_get_tosend(latspl * sdr->oversample);
+ count = uhd_get_tosend(buffer_size * sdr->oversample);
#endif
#ifdef HAVE_SOAPY
if (sdr_config->soapy)
- count = soapy_get_tosend(latspl * sdr->oversample);
+ count = soapy_get_tosend(buffer_size * sdr->oversample);
#endif
if (count < 0)
return count;
+ /* rounding down, so we never overfill */
count /= sdr->oversample;
if (sdr->threads) {
- /* subtract what we have in write buffer, because this is not jent sent to the SDR */
+ /* subtract what we have in write buffer, because this is not jet sent to the SDR */
int fill;
fill = (sdr->thread_write.in - sdr->thread_write.out + sdr->thread_write.buffer_size) % sdr->thread_write.buffer_size;