SDR: Add option to send (previously recorded) IQ data instead of TX data
This commit is contained in:
@@ -68,6 +68,7 @@ double sdr_rx_gain = 0, sdr_tx_gain = 0;
|
|||||||
const char *write_iq_rx_wave = NULL;
|
const char *write_iq_rx_wave = NULL;
|
||||||
const char *write_iq_tx_wave = NULL;
|
const char *write_iq_tx_wave = NULL;
|
||||||
const char *read_iq_rx_wave = NULL;
|
const char *read_iq_rx_wave = NULL;
|
||||||
|
const char *read_iq_tx_wave = NULL;
|
||||||
void print_help_common(const char *arg0, const char *ext_usage)
|
void print_help_common(const char *arg0, const char *ext_usage)
|
||||||
{
|
{
|
||||||
printf("Usage: %s -k <kanal/channel> %s[options] [station-id]\n", arg0, ext_usage);
|
printf("Usage: %s -k <kanal/channel> %s[options] [station-id]\n", arg0, ext_usage);
|
||||||
@@ -148,6 +149,8 @@ void print_help_common(const char *arg0, const char *ext_usage)
|
|||||||
printf(" Write transmitted IQ data to given wave file.\n");
|
printf(" Write transmitted IQ data to given wave file.\n");
|
||||||
printf(" --read-iq-rx-wave <file>\n");
|
printf(" --read-iq-rx-wave <file>\n");
|
||||||
printf(" Replace received IQ data by given wave file.\n");
|
printf(" Replace received IQ data by given wave file.\n");
|
||||||
|
printf(" --read-iq-tx-wave <file>\n");
|
||||||
|
printf(" Replace transmitted IQ data by given wave file.\n");
|
||||||
#endif
|
#endif
|
||||||
printf("\nNetwork specific options:\n");
|
printf("\nNetwork specific options:\n");
|
||||||
}
|
}
|
||||||
@@ -174,6 +177,7 @@ void print_hotkeys_common(void)
|
|||||||
#define OPT_WRITE_IQ_RX_WAVE 1105
|
#define OPT_WRITE_IQ_RX_WAVE 1105
|
||||||
#define OPT_WRITE_IQ_TX_WAVE 1106
|
#define OPT_WRITE_IQ_TX_WAVE 1106
|
||||||
#define OPT_READ_IQ_RX_WAVE 1107
|
#define OPT_READ_IQ_RX_WAVE 1107
|
||||||
|
#define OPT_READ_IQ_TX_WAVE 1108
|
||||||
|
|
||||||
static struct option long_options_common[] = {
|
static struct option long_options_common[] = {
|
||||||
{"help", 0, 0, 'h'},
|
{"help", 0, 0, 'h'},
|
||||||
@@ -204,6 +208,7 @@ static struct option long_options_common[] = {
|
|||||||
{"write-iq-rx-wave", 1, 0, OPT_WRITE_IQ_RX_WAVE},
|
{"write-iq-rx-wave", 1, 0, OPT_WRITE_IQ_RX_WAVE},
|
||||||
{"write-iq-tx-wave", 1, 0, OPT_WRITE_IQ_TX_WAVE},
|
{"write-iq-tx-wave", 1, 0, OPT_WRITE_IQ_TX_WAVE},
|
||||||
{"read-iq-rx-wave", 1, 0, OPT_READ_IQ_RX_WAVE},
|
{"read-iq-rx-wave", 1, 0, OPT_READ_IQ_RX_WAVE},
|
||||||
|
{"read-iq-tx-wave", 1, 0, OPT_READ_IQ_TX_WAVE},
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -379,6 +384,10 @@ void opt_switch_common(int c, char *arg0, int *skip_args)
|
|||||||
read_iq_rx_wave = strdup(optarg);
|
read_iq_rx_wave = strdup(optarg);
|
||||||
*skip_args += 2;
|
*skip_args += 2;
|
||||||
break;
|
break;
|
||||||
|
case OPT_READ_IQ_TX_WAVE:
|
||||||
|
read_iq_tx_wave = strdup(optarg);
|
||||||
|
*skip_args += 2;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
exit (0);
|
exit (0);
|
||||||
}
|
}
|
||||||
@@ -461,7 +470,7 @@ void main_common(int *quit, int latency, int interval, void (*myhandler)(void),
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_SDR
|
#ifdef HAVE_SDR
|
||||||
rc = sdr_init(sdr_uhd, sdr_soapy, sdr_args, sdr_rx_gain, sdr_tx_gain, write_iq_rx_wave, write_iq_tx_wave, read_iq_rx_wave);
|
rc = sdr_init(sdr_uhd, sdr_soapy, sdr_args, sdr_rx_gain, sdr_tx_gain, write_iq_rx_wave, write_iq_tx_wave, read_iq_rx_wave, read_iq_tx_wave);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
@@ -52,14 +52,15 @@ typedef struct sdr {
|
|||||||
wave_rec_t wave_rx_rec;
|
wave_rec_t wave_rx_rec;
|
||||||
wave_rec_t wave_tx_rec;
|
wave_rec_t wave_tx_rec;
|
||||||
wave_play_t wave_rx_play;
|
wave_play_t wave_rx_play;
|
||||||
|
wave_play_t wave_tx_play;
|
||||||
} sdr_t;
|
} sdr_t;
|
||||||
|
|
||||||
static int sdr_use_uhd, sdr_use_soapy;
|
static int sdr_use_uhd, sdr_use_soapy;
|
||||||
static const char *sdr_device_args;
|
static const char *sdr_device_args;
|
||||||
static double sdr_rx_gain, sdr_tx_gain;
|
static double sdr_rx_gain, sdr_tx_gain;
|
||||||
const char *sdr_write_iq_rx_wave, *sdr_write_iq_tx_wave, *sdr_read_iq_rx_wave;
|
const char *sdr_write_iq_rx_wave, *sdr_write_iq_tx_wave, *sdr_read_iq_rx_wave, *sdr_read_iq_tx_wave;
|
||||||
|
|
||||||
int sdr_init(int sdr_uhd, int sdr_soapy, const char *device_args, double rx_gain, double tx_gain, const char *write_iq_rx_wave, const char *write_iq_tx_wave, const char *read_iq_rx_wave)
|
int sdr_init(int sdr_uhd, int sdr_soapy, const char *device_args, double rx_gain, double tx_gain, const char *write_iq_rx_wave, const char *write_iq_tx_wave, const char *read_iq_rx_wave, const char *read_iq_tx_wave)
|
||||||
{
|
{
|
||||||
sdr_use_uhd = sdr_uhd;
|
sdr_use_uhd = sdr_uhd;
|
||||||
sdr_use_soapy = sdr_soapy;
|
sdr_use_soapy = sdr_soapy;
|
||||||
@@ -69,6 +70,7 @@ int sdr_init(int sdr_uhd, int sdr_soapy, const char *device_args, double rx_gain
|
|||||||
sdr_write_iq_rx_wave = write_iq_rx_wave;
|
sdr_write_iq_rx_wave = write_iq_rx_wave;
|
||||||
sdr_write_iq_tx_wave = write_iq_tx_wave;
|
sdr_write_iq_tx_wave = write_iq_tx_wave;
|
||||||
sdr_read_iq_rx_wave = read_iq_rx_wave;
|
sdr_read_iq_rx_wave = read_iq_rx_wave;
|
||||||
|
sdr_read_iq_tx_wave = read_iq_tx_wave;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -186,21 +188,28 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq
|
|||||||
if (sdr_write_iq_rx_wave) {
|
if (sdr_write_iq_rx_wave) {
|
||||||
rc = wave_create_record(&sdr->wave_rx_rec, sdr_write_iq_rx_wave, sdr->samplerate, 2, 1.0);
|
rc = wave_create_record(&sdr->wave_rx_rec, sdr_write_iq_rx_wave, sdr->samplerate, 2, 1.0);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
PDEBUG(DSENDER, DEBUG_ERROR, "Failed to create WAVE recoding instance!\n");
|
PDEBUG(DSDR, DEBUG_ERROR, "Failed to create WAVE recoding instance!\n");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sdr_write_iq_tx_wave) {
|
if (sdr_write_iq_tx_wave) {
|
||||||
rc = wave_create_record(&sdr->wave_tx_rec, sdr_write_iq_tx_wave, sdr->samplerate, 2, 1.0);
|
rc = wave_create_record(&sdr->wave_tx_rec, sdr_write_iq_tx_wave, sdr->samplerate, 2, 1.0);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
PDEBUG(DSENDER, DEBUG_ERROR, "Failed to create WAVE recoding instance!\n");
|
PDEBUG(DSDR, DEBUG_ERROR, "Failed to create WAVE recoding instance!\n");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sdr_read_iq_rx_wave) {
|
if (sdr_read_iq_rx_wave) {
|
||||||
rc = wave_create_playback(&sdr->wave_rx_play, sdr_read_iq_rx_wave, sdr->samplerate, 2, 1.0);
|
rc = wave_create_playback(&sdr->wave_rx_play, sdr_read_iq_rx_wave, sdr->samplerate, 2, 1.0);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
PDEBUG(DSENDER, DEBUG_ERROR, "Failed to create WAVE playback instance!\n");
|
PDEBUG(DSDR, DEBUG_ERROR, "Failed to create WAVE playback instance!\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sdr_read_iq_tx_wave) {
|
||||||
|
rc = wave_create_playback(&sdr->wave_tx_play, sdr_read_iq_tx_wave, sdr->samplerate, 2, 1.0);
|
||||||
|
if (rc < 0) {
|
||||||
|
PDEBUG(DSDR, DEBUG_ERROR, "Failed to create WAVE playback instance!\n");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -262,6 +271,7 @@ void sdr_close(void *inst)
|
|||||||
wave_destroy_record(&sdr->wave_rx_rec);
|
wave_destroy_record(&sdr->wave_rx_rec);
|
||||||
wave_destroy_record(&sdr->wave_tx_rec);
|
wave_destroy_record(&sdr->wave_tx_rec);
|
||||||
wave_destroy_playback(&sdr->wave_rx_play);
|
wave_destroy_playback(&sdr->wave_rx_play);
|
||||||
|
wave_destroy_playback(&sdr->wave_tx_play);
|
||||||
free(sdr->chan);
|
free(sdr->chan);
|
||||||
free(sdr);
|
free(sdr);
|
||||||
sdr = NULL;
|
sdr = NULL;
|
||||||
@@ -298,6 +308,14 @@ int sdr_write(void *inst, sample_t **samples, int num, enum paging_signal __attr
|
|||||||
}
|
}
|
||||||
wave_write(&sdr->wave_tx_rec, spl_list, num);
|
wave_write(&sdr->wave_tx_rec, spl_list, num);
|
||||||
}
|
}
|
||||||
|
if (sdr->wave_tx_play.fp) {
|
||||||
|
sample_t spl[2][num], *spl_list[2] = { spl[0], spl[1] };
|
||||||
|
wave_read(&sdr->wave_tx_play, spl_list, num);
|
||||||
|
for (s = 0, ss = 0; s < num; s++) {
|
||||||
|
buff[ss++] = spl[0][s];
|
||||||
|
buff[ss++] = spl[1][s];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_UHD
|
#ifdef HAVE_UHD
|
||||||
if (sdr_use_uhd)
|
if (sdr_use_uhd)
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
int sdr_init(int sdr_uhd, int sdr_soapy, const char *device_args, double rx_gain, double tx_gain, const char *write_iq_rx_wave, const char *write_iq_tx_wave, const char *read_iq_rx_wave);
|
int sdr_init(int sdr_uhd, int sdr_soapy, const char *device_args, double rx_gain, double tx_gain, const char *write_iq_rx_wave, const char *write_iq_tx_wave, const char *read_iq_rx_wave, const char *read_iq_tx_wave);
|
||||||
int sdr_start(void *inst);
|
int sdr_start(void *inst);
|
||||||
void *sdr_open(const char *audiodev, double *tx_frequency, double *rx_frequency, int channels, double paging_frequency, int samplerate, double bandwidth, double sample_deviation);
|
void *sdr_open(const char *audiodev, double *tx_frequency, double *rx_frequency, int channels, double paging_frequency, int samplerate, double bandwidth, double sample_deviation);
|
||||||
void sdr_close(void *inst);
|
void sdr_close(void *inst);
|
||||||
|
Reference in New Issue
Block a user