diff options
-rw-r--r-- | src/amps/amps_tacs_main.c | 12 | ||||
-rw-r--r-- | src/anetz/main.c | 10 | ||||
-rw-r--r-- | src/bnetz/main.c | 10 | ||||
-rw-r--r-- | src/cnetz/main.c | 10 | ||||
-rw-r--r-- | src/common/Makefile.am | 1 | ||||
-rw-r--r-- | src/common/call.c | 4 | ||||
-rw-r--r-- | src/common/call.h | 2 | ||||
-rw-r--r-- | src/common/main_mobile.c | 263 | ||||
-rw-r--r-- | src/common/main_mobile.h | 10 | ||||
-rw-r--r-- | src/common/sdr.c | 404 | ||||
-rw-r--r-- | src/common/sdr.h | 3 | ||||
-rw-r--r-- | src/common/sdr_config.c | 262 | ||||
-rw-r--r-- | src/common/sdr_config.h | 32 | ||||
-rw-r--r-- | src/common/sender.c | 4 | ||||
-rw-r--r-- | src/common/sender.h | 4 | ||||
-rw-r--r-- | src/common/sound.h | 2 | ||||
-rw-r--r-- | src/common/sound_alsa.c | 2 | ||||
-rw-r--r-- | src/nmt/main.c | 10 | ||||
-rw-r--r-- | src/r2000/main.c | 10 |
19 files changed, 589 insertions, 466 deletions
diff --git a/src/amps/amps_tacs_main.c b/src/amps/amps_tacs_main.c index eee7dcc..3065e7d 100644 --- a/src/amps/amps_tacs_main.c +++ b/src/amps/amps_tacs_main.c @@ -45,9 +45,9 @@ int tolerant = 0; void print_help(const char *arg0) { if (!tacs) - print_help_common(arg0, "-p -d -F yes | no [-S sid=<sid>] "); + main_mobile_print_help(arg0, "-p -d -F yes | no [-S sid=<sid>] "); else - print_help_common(arg0, "-p -d -F yes | no [-S aid=<aid>] "); + main_mobile_print_help(arg0, "-p -d -F yes | no [-S aid=<aid>] "); /* - - */ printf(" -T --channel-type <channel type> | list\n"); printf(" Give channel type, use 'list' to get a list. (default = '%s')\n", chan_type_short_name(chan_type[0])); @@ -102,7 +102,7 @@ void print_help(const char *arg0) printf(" Be more tolerant when hunting for sync sequence\n"); printf("\nstation-id: Give 10 digit station-id, you don't need to enter it for every\n"); printf(" start of this program.\n"); - print_hotkeys_common(); + main_mobile_print_hotkeys(); } static int handle_options(int argc, char **argv) @@ -121,7 +121,7 @@ static int handle_options(int argc, char **argv) {0, 0, 0, 0} }; - set_options_common("T:F:P:D:S:O", long_options_special); + main_mobile_set_options("T:F:P:D:S:O", long_options_special); while (1) { int option_index = 0, c; @@ -238,7 +238,7 @@ static int handle_options(int argc, char **argv) skip_args += 1; break; default: - opt_switch_common(c, argv[0], &skip_args); + main_mobile_opt_switch(c, argv[0], &skip_args); } } @@ -258,6 +258,8 @@ int main_amps_tacs(int argc, char *argv[]) /* override default */ samplerate = 96000; + main_mobile_init(); + skip_args = handle_options(argc, argv); argc -= skip_args; argv += skip_args; diff --git a/src/anetz/main.c b/src/anetz/main.c index 43b55e6..2a5b333 100644 --- a/src/anetz/main.c +++ b/src/anetz/main.c @@ -43,7 +43,7 @@ double lossdetect = 0; void print_help(const char *arg0) { - print_help_common(arg0, "[-V 12] "); + main_mobile_print_help(arg0, "[-V 12] "); /* - - */ printf(" -G --geo <lat>,<lon>\n"); printf(" Give your coordinates of your location, to find closest base station.\n"); @@ -60,7 +60,7 @@ void print_help(const char *arg0) printf(" percent. (disabled by default)\n"); printf("\nstation-id: Give (last) 5 digits of station-id, you don't need to enter it\n"); printf(" for every start of this program.\n"); - print_hotkeys_common(); + main_mobile_print_hotkeys(); } static int handle_options(int argc, char **argv) @@ -77,7 +77,7 @@ static int handle_options(int argc, char **argv) {0, 0, 0, 0} }; - set_options_common("G:V:P:L:", long_options_special); + main_mobile_set_options("G:V:P:L:", long_options_special); while (1) { int option_index = 0, c; @@ -114,7 +114,7 @@ static int handle_options(int argc, char **argv) skip_args += 2; break; default: - opt_switch_common(c, argv[0], &skip_args); + main_mobile_opt_switch(c, argv[0], &skip_args); } } @@ -137,6 +137,8 @@ int main(int argc, char *argv[]) init_freiton(); init_besetzton(); + main_mobile_init(); + skip_args = handle_options(argc, argv); argc -= skip_args; argv += skip_args; diff --git a/src/bnetz/main.c b/src/bnetz/main.c index 7fa1ce5..96271bd 100644 --- a/src/bnetz/main.c +++ b/src/bnetz/main.c @@ -43,7 +43,7 @@ double lossdetect = 0; void print_help(const char *arg0) { - print_help_common(arg0, "[-G <gfs>] "); + main_mobile_print_help(arg0, "[-G <gfs>] "); /* - - */ printf(" -G --gfs <gruppenfreisignal> | <lat>,<lon>\n"); printf(" Gruppenfreisignal\" 1..9 | 19 | 10..18 (default = '%d')\n", gfs); @@ -75,7 +75,7 @@ void print_help(const char *arg0) printf(" percent. (disabled by default)\n"); printf("\nstation-id: Give 5 digit station-id, you don't need to enter it for every\n"); printf(" start of this program.\n"); - print_hotkeys_common(); + main_mobile_print_hotkeys(); } static int handle_options(int argc, char **argv) @@ -91,7 +91,7 @@ static int handle_options(int argc, char **argv) {0, 0, 0, 0}, }; - set_options_common("G:M:P:L:", long_options_special); + main_mobile_set_options("G:M:P:L:", long_options_special); while (1) { int option_index = 0, c; @@ -128,7 +128,7 @@ static int handle_options(int argc, char **argv) skip_args += 2; break; default: - opt_switch_common(c, argv[0], &skip_args); + main_mobile_opt_switch(c, argv[0], &skip_args); } } @@ -147,6 +147,8 @@ int main(int argc, char *argv[]) init_besetzton(); init_ansage(); + main_mobile_init(); + skip_args = handle_options(argc, argv); argc -= skip_args; argv += skip_args; diff --git a/src/cnetz/main.c b/src/cnetz/main.c index ff5f291..7180df1 100644 --- a/src/cnetz/main.c +++ b/src/cnetz/main.c @@ -71,7 +71,7 @@ int metering = 20; void print_help(const char *arg0) { - print_help_common(arg0, "[-M] -S <rx ppm>,<tx ppm> -p -d "); + main_mobile_print_help(arg0, "[-M] -S <rx ppm>,<tx ppm> -p -d "); /* - - */ printf(" -T --channel-type <channel type> | list\n"); printf(" Give channel type, use 'list' to get a list. (default = '%s')\n", chan_type_short_name(chan_type[0])); @@ -192,7 +192,7 @@ void print_help(const char *arg0) printf(" input. (default = '%s')\n", (demod == FSK_DEMOD_LEVEL) ? "level" : (demod == FSK_DEMOD_SLOPE) ? "slope" : "auto"); printf("\nstation-id: Give 7 digit station-id, you don't need to enter it for every\n"); printf(" start of this program.\n"); - print_hotkeys_common(); + main_mobile_print_hotkeys(); printf("Press 'i' key to dump list of currently attached subscribers.\n"); } @@ -238,7 +238,7 @@ static int handle_options(int argc, char **argv) {0, 0, 0, 0} }; - set_options_common("T:MC:F:P:AQ:G:S:D:", long_options_special); + main_mobile_set_options("T:MC:F:P:AQ:G:S:D:", long_options_special); while (1) { int option_index = 0, c; @@ -396,7 +396,7 @@ static int handle_options(int argc, char **argv) skip_args += 2; break; default: - opt_switch_common(c, argv[0], &skip_args); + main_mobile_opt_switch(c, argv[0], &skip_args); } } @@ -421,6 +421,8 @@ int main(int argc, char *argv[]) init_besetzton(); init_ansage(); + main_mobile_init(); + skip_args = handle_options(argc, argv); argc -= skip_args; argv += skip_args; diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 6378f4f..e69bb57 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -35,6 +35,7 @@ if HAVE_SDR AM_CPPFLAGS += -DHAVE_SDR libcommon_a_SOURCES += \ + sdr_config.c \ sdr.c \ display_iq.c \ display_spectrum.c diff --git a/src/common/call.c b/src/common/call.c index 54e52d5..e3067f3 100644 --- a/src/common/call.c +++ b/src/common/call.c @@ -528,14 +528,14 @@ error: return rc; } -int call_open_audio(void) +int call_open_audio(int latspl) { if (!call.audiodev[0]) return 0; /* open sound device for call control */ /* use factor 1.4 of speech level for complete range of sound card */ - call.sound = sound_open(call.audiodev, NULL, NULL, 1, 0.0, call.samplerate, 1.4, 4000.0); + call.sound = sound_open(call.audiodev, NULL, NULL, 1, 0.0, call.samplerate, latspl, 1.4, 4000.0); if (!call.sound) { PDEBUG(DSENDER, DEBUG_ERROR, "No sound device!\n"); return -EIO; diff --git a/src/common/call.h b/src/common/call.h index e3c7964..78c0577 100644 --- a/src/common/call.h +++ b/src/common/call.h @@ -11,7 +11,7 @@ enum number_type { int call_init(const char *station_id, const char *audiodev, int samplerate, int latency, int dial_digits, int loopback, int use_mncc_sock, int send_patterns, int release_on_disconnect); void call_cleanup(void); -int call_open_audio(void); +int call_open_audio(int latspl); int call_start_audio(void); void process_call(int c); void clear_console_text(void); diff --git a/src/common/main_mobile.c b/src/common/main_mobile.c index 7598788..eb281c8 100644 --- a/src/common/main_mobile.c +++ b/src/common/main_mobile.c @@ -28,6 +28,7 @@ #include <math.h> #include <termios.h> #include <errno.h> +#include <getopt.h> #include "sample.h" #include "main_mobile.h" #include "debug.h" @@ -37,13 +38,17 @@ #include "mncc_sock.h" #ifdef HAVE_SDR #include "sdr.h" +#include "sdr_config.h" #endif -/* common settings */ +static int got_init = 0; + +/* common mobile settings */ int num_kanal = 0; int kanal[MAX_SENDER]; int num_audiodev = 0; const char *audiodev[MAX_SENDER] = { "hw:0,0" }; +int use_sdr = 0; const char *call_audiodev = ""; int samplerate = 48000; int call_samplerate = 48000; @@ -63,25 +68,16 @@ const char *write_tx_wave = NULL; const char *write_rx_wave = NULL; const char *read_tx_wave = NULL; const char *read_rx_wave = NULL; -int use_sdr = 0; -int sdr_channel = 0; -static const char *sdr_device_args = "", *sdr_stream_args = "", *sdr_tune_args = ""; -static int sdr_samplerate = 0; -static double sdr_bandwidth = 0.0; + +void main_mobile_init(void) +{ + got_init = 1; #ifdef HAVE_SDR -static int sdr_uhd = 0; -static int sdr_soapy = 0; + sdr_config_init(); #endif -double sdr_tx_gain = 0, sdr_rx_gain = 0; -const char *sdr_tx_antenna = "", *sdr_rx_antenna = ""; -const char *write_iq_tx_wave = NULL; -const char *write_iq_rx_wave = NULL; -const char *read_iq_tx_wave = NULL; -const char *read_iq_rx_wave = NULL; -int sdr_swap_links = 0; -int sdr_uhd_tx_timestamps = 0; - -void print_help_common(const char *arg0, const char *ext_usage) +} + +void main_mobile_print_help(const char *arg0, const char *ext_usage) { printf("Usage: %s -k <kanal/channel> %s[options] [station-id]\n", arg0, ext_usage); printf("\nGlobal options:\n"); @@ -144,55 +140,12 @@ void print_help_common(const char *arg0, const char *ext_usage) printf(" --read-tx-wave <file>\n"); printf(" Replace transmitted audio by given wave file.\n"); #ifdef HAVE_SDR - printf("\nSDR options:\n"); - /* - - */ -#ifdef HAVE_UHD - printf(" --sdr-uhd\n"); - printf(" Force UHD driver\n"); -#endif -#ifdef HAVE_SOAPY - printf(" --sdr-soapy\n"); - printf(" Force SoapySDR driver\n"); -#endif - printf(" --sdr-channel <channel #>\n"); - printf(" Give channel number for multi channel SDR device (default = %d)\n", sdr_channel); - printf(" --sdr-device-args <args>\n"); - printf(" --sdr-stream-args <args>\n"); - printf(" --sdr-tune-args <args>\n"); - printf(" Optional SDR device arguments, seperated by comma\n"); - printf(" e.g. --sdr-device-args <key>=<value>[,<key>=<value>[,...]]\n"); - printf(" --sdr-samplerate <samplerate>\n"); - printf(" Sample rate to use with SDR. By default it equals the regular sample\n"); - printf(" rate.\n"); - printf(" --sdr-bandwidth <bandwidth>\n"); - printf(" Give IF filter bandwidth to use. If not, sample rate is used.\n"); - printf(" --sdr-rx-antenna <name>\n"); - printf(" SDR device's RX antenna name, use 'list' to get a list\n"); - printf(" --sdr-tx-antenna <name>\n"); - printf(" SDR device's TX antenna name, use 'list' to get a list\n"); - printf(" --sdr-rx-gain <gain>\n"); - printf(" SDR device's RX gain in dB (default = %.1f)\n", sdr_rx_gain); - printf(" --sdr-tx-gain <gain>\n"); - printf(" SDR device's TX gain in dB (default = %.1f)\n", sdr_tx_gain); - printf(" --write-iq-rx-wave <file>\n"); - printf(" Write received IQ data to given wave file.\n"); - printf(" --write-iq-tx-wave <file>\n"); - printf(" Write transmitted IQ data to given wave file.\n"); - printf(" --read-iq-rx-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"); - printf(" --sdr-swap-links\n"); - printf(" Swap RX and TX frequencies for loopback tests over the air.r\n"); -#ifdef HAVE_UHD - printf(" --sdr-uhd-tx-timestamps\n"); - printf(" Use TX timestamps on UHD device. (May not work with some devices!)\n"); -#endif + sdr_config_print_help(); #endif printf("\nNetwork specific options:\n"); } -void print_hotkeys_common(void) +void main_mobile_print_hotkeys(void) { printf("\n"); printf("Press digits '0'..'9' and then 'd' key to dial towards mobile station\n"); @@ -200,8 +153,7 @@ void print_hotkeys_common(void) printf("Press 'w' key to toggle display of RX wave form.\n"); printf("Press 'c' key to toggle display of channel status.\n"); #ifdef HAVE_SDR - printf("Press 'i' key to toggle display of RX I/Q vector.\n"); - printf("Press 's' key to toggle display of RX spectrum.\n"); + sdr_config_print_hotkeys(); #endif } @@ -213,26 +165,7 @@ void print_hotkeys_common(void) #define OPT_CALL_SAMPLERATE 1005 #define OPT_MNCC_NAME 1006 -#define OPT_SDR_UHD 1100 -#define OPT_SDR_SOAPY 1101 -#define OPT_SDR_CHANNEL 1102 -#define OPT_SDR_DEVICE_ARGS 1103 -#define OPT_SDR_STREAM_ARGS 1104 -#define OPT_SDR_TUNE_ARGS 1105 -#define OPT_SDR_RX_ANTENNA 1106 -#define OPT_SDR_TX_ANTENNA 1107 -#define OPT_SDR_RX_GAIN 1108 -#define OPT_SDR_TX_GAIN 1109 -#define OPT_SDR_SAMPLERATE 1110 -#define OPT_SDR_BANDWIDTH 1111 -#define OPT_WRITE_IQ_RX_WAVE 1112 -#define OPT_WRITE_IQ_TX_WAVE 1113 -#define OPT_READ_IQ_RX_WAVE 1114 -#define OPT_READ_IQ_TX_WAVE 1115 -#define OPT_SDR_SWAP_LINKS 1116 -#define OPT_SDR_UHD_TX_TS 1117 - -static struct option long_options_common[] = { +static struct option main_mobile_long_options[] = { {"help", 0, 0, 'h'}, {"debug", 1, 0, 'v'}, {"kanal", 1, 0, 'k'}, @@ -255,28 +188,10 @@ static struct option long_options_common[] = { {"write-tx-wave", 1, 0, OPT_WRITE_TX_WAVE}, {"read-rx-wave", 1, 0, OPT_READ_RX_WAVE}, {"read-tx-wave", 1, 0, OPT_READ_TX_WAVE}, - {"sdr-uhd", 0, 0, OPT_SDR_UHD}, - {"sdr-soapy", 0, 0, OPT_SDR_SOAPY}, - {"sdr-channel", 1, 0, OPT_SDR_CHANNEL}, - {"sdr-device-args", 1, 0, OPT_SDR_DEVICE_ARGS}, - {"sdr-stream-args", 1, 0, OPT_SDR_STREAM_ARGS}, - {"sdr-tune-args", 1, 0, OPT_SDR_TUNE_ARGS}, - {"sdr-samplerate", 1, 0, OPT_SDR_SAMPLERATE}, - {"sdr-bandwidth", 1, 0, OPT_SDR_BANDWIDTH}, - {"sdr-rx-antenna", 1, 0, OPT_SDR_RX_ANTENNA}, - {"sdr-tx-antenna", 1, 0, OPT_SDR_TX_ANTENNA}, - {"sdr-rx-gain", 1, 0, OPT_SDR_RX_GAIN}, - {"sdr-tx-gain", 1, 0, OPT_SDR_TX_GAIN}, - {"write-iq-rx-wave", 1, 0, OPT_WRITE_IQ_RX_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-tx-wave", 1, 0, OPT_READ_IQ_TX_WAVE}, - {"sdr-swap-links", 0, 0, OPT_SDR_SWAP_LINKS}, - {"sdr-uhd-tx-timestamps", 0, 0, OPT_SDR_UHD_TX_TS}, {0, 0, 0, 0} }; -const char *optstring_common = "hv:k:a:s:i:b:pdg:mc:t:l:r:"; +static const char *main_mobile_optstring = "hv:k:a:s:i:b:pdg:mc:t:l:r:"; struct option *long_options; char *optstring; @@ -293,28 +208,42 @@ static void check_duplicate_option(int num, struct option *option) } } -void set_options_common(const char *optstring_special, struct option *long_options_special) +void main_mobile_set_options(const char *optstring_special, struct option *long_options_special) { - int i; + int i = 0, j; - long_options = calloc(sizeof(*long_options), 100); - for (i = 0; long_options_common[i].name; i++) { - check_duplicate_option(i, &long_options_common[i]); - memcpy(&long_options[i], &long_options_common[i], sizeof(*long_options)); + long_options = calloc(sizeof(*long_options), 256); + for (j = 0; main_mobile_long_options[j].name; i++, j++) { + check_duplicate_option(i, &main_mobile_long_options[j]); + memcpy(&long_options[i], &main_mobile_long_options[j], sizeof(*long_options)); } +#ifdef HAVE_SDR + for (j = 0; sdr_config_long_options[j].name; i++, j++) { + check_duplicate_option(i, &sdr_config_long_options[j]); + memcpy(&long_options[i], &sdr_config_long_options[j], sizeof(*long_options)); + } +#endif for (; long_options_special->name; i++) { check_duplicate_option(i, long_options_special); memcpy(&long_options[i], long_options_special++, sizeof(*long_options)); } - optstring = calloc(strlen(optstring_common) + strlen(optstring_special) + 1, 1); - strcpy(optstring, optstring_common); + optstring = calloc(256, 2); + strcpy(optstring, main_mobile_optstring); +#ifdef HAVE_SDR + strcat(optstring, sdr_config_optstring); +#endif strcat(optstring, optstring_special); } -void opt_switch_common(int c, char *arg0, int *skip_args) +void print_help(const char *arg0); + +void main_mobile_opt_switch(int c, char *arg0, int *skip_args) { double gain_db; +#ifdef HAVE_SDR + int rc; +#endif switch (c) { case 'h': @@ -424,92 +353,14 @@ void opt_switch_common(int c, char *arg0, int *skip_args) read_tx_wave = strdup(optarg); *skip_args += 2; break; - case OPT_SDR_UHD: -#ifdef HAVE_SDR - use_sdr = 1; - sdr_uhd = 1; -#else - fprintf(stderr, "UHD SDR support not compiled in!\n"); - exit(0); -#endif - *skip_args += 1; - break; - case OPT_SDR_SOAPY: + default: #ifdef HAVE_SDR - use_sdr = 1; - sdr_soapy = 1; -#else - fprintf(stderr, "SoapySDR support not compiled in!\n"); - exit(0); + rc = sdr_config_opt_switch(c, skip_args); + if (rc < 0) + exit (0); + #endif - *skip_args += 1; - break; - case OPT_SDR_CHANNEL: - sdr_channel = atoi(optarg); - *skip_args += 2; - break; - case OPT_SDR_DEVICE_ARGS: - sdr_device_args = strdup(optarg); - *skip_args += 2; break; - case OPT_SDR_STREAM_ARGS: - sdr_stream_args = strdup(optarg); - *skip_args += 2; - break; - case OPT_SDR_TUNE_ARGS: - sdr_tune_args = strdup(optarg); - *skip_args += 2; - break; - case OPT_SDR_SAMPLERATE: - sdr_samplerate = atoi(optarg); - *skip_args += 2; - break; - case OPT_SDR_BANDWIDTH: - sdr_bandwidth = atof(optarg); - *skip_args += 2; - break; - case OPT_SDR_RX_ANTENNA: - sdr_rx_antenna = strdup(optarg); - *skip_args += 2; - break; - case OPT_SDR_TX_ANTENNA: - sdr_tx_antenna = strdup(optarg); - *skip_args += 2; - break; - case OPT_SDR_RX_GAIN: - sdr_rx_gain = atof(optarg); - *skip_args += 2; - break; - case OPT_SDR_TX_GAIN: - sdr_tx_gain = atof(optarg); - *skip_args += 2; - break; - case OPT_WRITE_IQ_RX_WAVE: - write_iq_rx_wave = strdup(optarg); - *skip_args += 2; - break; - case OPT_WRITE_IQ_TX_WAVE: - write_iq_tx_wave = strdup(optarg); - *skip_args += 2; - break; - case OPT_READ_IQ_RX_WAVE: - read_iq_rx_wave = strdup(optarg); - *skip_args += 2; - break; - case OPT_READ_IQ_TX_WAVE: - read_iq_tx_wave = strdup(optarg); - *skip_args += 2; - break; - case OPT_SDR_SWAP_LINKS: - sdr_swap_links = 1; - *skip_args += 1; - break; - case OPT_SDR_UHD_TX_TS: - sdr_uhd_tx_timestamps = 1; - *skip_args += 1; - break; - default: - exit (0); } } @@ -556,6 +407,11 @@ void main_mobile(int *quit, int latency, int interval, void (*myhandler)(void), int c; int rc; + if (!got_init) { + fprintf(stderr, "main_mobile_init was not called, please fix!\n"); + abort(); + } + /* latency of send buffer in samples */ latspl = samplerate * latency / 1000; @@ -582,24 +438,15 @@ void main_mobile(int *quit, int latency, int interval, void (*myhandler)(void), } #ifdef HAVE_SDR - if ((sdr_uhd == 1 && sdr_soapy == 1)) { - fprintf(stderr, "You must choose which one you want: --sdr-uhd or --sdr-soapy\n"); - return; - } - - if (sdr_samplerate == 0.0) - sdr_samplerate = samplerate; - if (sdr_bandwidth == 0.0) - sdr_bandwidth = sdr_samplerate; - rc = sdr_init(sdr_uhd, sdr_soapy, sdr_channel, sdr_device_args, sdr_stream_args, sdr_tune_args, sdr_tx_antenna, sdr_rx_antenna, sdr_tx_gain, sdr_rx_gain, sdr_samplerate, sdr_bandwidth, write_iq_tx_wave, write_iq_rx_wave, read_iq_tx_wave, read_iq_rx_wave, latspl, sdr_swap_links, sdr_uhd_tx_timestamps); + rc = sdr_configure(samplerate); if (rc < 0) return; #endif /* open audio */ - if (sender_open_audio()) + if (sender_open_audio(latspl)) return; - if (call_open_audio()) + if (call_open_audio(latspl)) return; /* real time priority */ diff --git a/src/common/main_mobile.h b/src/common/main_mobile.h index 45210fb..85503bf 100644 --- a/src/common/main_mobile.h +++ b/src/common/main_mobile.h @@ -22,13 +22,13 @@ extern const char *write_tx_wave; extern const char *read_rx_wave; extern const char *read_tx_wave; -void print_help(const char *arg0); -void print_help_common(const char *arg0, const char *ext_usage); -void print_hotkeys_common(void); +void main_mobile_init(void); +void main_mobile_print_help(const char *arg0, const char *ext_usage); +void main_mobile_print_hotkeys(void); extern struct option *long_options; extern char *optstring; -void set_options_common(const char *optstring_special, struct option *long_options_special); -void opt_switch_common(int c, char *arg0, int *skip_args); +void main_mobile_set_options(const char *optstring_special, struct option *long_options_special); +void main_mobile_opt_switch(int c, char *arg0, int *skip_args); #define OPT_ARRAY(num_name, name, value) \ { \ diff --git a/src/common/sdr.c b/src/common/sdr.c index d4c2e88..a8459c4 100644 --- a/src/common/sdr.c +++ b/src/common/sdr.c @@ -17,19 +17,25 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +enum paging_signal; + #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h> #include <errno.h> #include <math.h> +#include <getopt.h> #define __USE_GNU #include <pthread.h> #include <unistd.h> #include "sample.h" #include "fm_modulation.h" -#include "sender.h" #include "timer.h" +#include "wave.h" +#include "display.h" +#include "sdr_config.h" +#include "sdr.h" #ifdef HAVE_UHD #include "uhd.h" #endif @@ -41,6 +47,17 @@ /* enable to debug buffer handling */ //#define DEBUG_BUFFER +typedef struct sdr_thread { + int use; + volatile int running, exit; /* flags to control exit of threads */ + int buffer_size; + volatile float *buffer; + float *buffer2; + volatile int in, out; /* in and out pointers (atomic, so no locking required) */ + int max_fill; /* measure maximum buffer fill */ + double max_fill_timer; /* timer to display/reset maximum fill */ +} sdr_thread_t; + typedef struct sdr_chan { double tx_frequency; /* frequency used */ double rx_frequency; /* frequency used */ @@ -49,12 +66,17 @@ typedef struct sdr_chan { } sdr_chan_t; typedef struct sdr { + int threads; /* use threads */ + int oversample; /* oversample IQ rate */ + sdr_thread_t thread_read, + thread_write; sdr_chan_t *chan; /* settings for all channels */ int paging_channel; /* if set, points to paging channel */ sdr_chan_t paging_chan; /* settings for extra paging channel */ int channels; /* number of frequencies */ double amplitude; /* amplitude of each carrier */ int samplerate; /* sample rate of audio data */ + int latspl; /* latency in audio samples */ wave_rec_t wave_rx_rec; wave_rec_t wave_tx_rec; wave_play_t wave_rx_play; @@ -66,65 +88,10 @@ typedef struct sdr { sample_t *wavespl1; } sdr_t; -typedef struct sdr_thread { - int use; - volatile int running, exit; /* flags to control exit of threads */ - int buffer_size; - volatile float *buffer; - float *buffer2; - volatile int in, out; /* in and out pointers (atomic, so no locking required) */ - int max_fill; /* measure maximum buffer fill */ - double max_fill_timer; /* timer to display/reset maximum fill */ -} sdr_thread_t; - -/* preferences */ -static int sdr_use_uhd, sdr_use_soapy; -static int sdr_channel; -static const char *sdr_device_args, *sdr_stream_args, *sdr_tune_args; -static const char *sdr_rx_antenna, *sdr_tx_antenna; -static double sdr_rx_gain, sdr_tx_gain; -static const char *sdr_write_iq_rx_wave, *sdr_write_iq_tx_wave, *sdr_read_iq_rx_wave, *sdr_read_iq_tx_wave; -static int sdr_samplerate; /* sample rate of IQ data */ -static double sdr_bandwidth; -static int sdr_oversample; -static int sdr_latspl; -static int sdr_threads; -static sdr_thread_t sdr_thread_read, sdr_thread_write; -static int sdr_swap_links; -static int sdr_uhd_tx_timestamps; - -int sdr_init(int sdr_uhd, int sdr_soapy, int channel, const char *device_args, const char *stream_args, const char *tune_args, const char *tx_antenna, const char *rx_antenna, double tx_gain, double rx_gain, int samplerate, double bandwidth, const char *write_iq_tx_wave, const char *write_iq_rx_wave, const char *read_iq_tx_wave, const char *read_iq_rx_wave, int latspl, int swap_links, int uhd_tx_timestamps) -{ - PDEBUG(DSDR, DEBUG_DEBUG, "Init SDR\n"); - - sdr_threads = 0; /* only requried for oversampling */ - sdr_use_uhd = sdr_uhd; - sdr_use_soapy = sdr_soapy; - sdr_channel = channel; - sdr_device_args = strdup(device_args); - sdr_stream_args = strdup(stream_args); - sdr_tune_args = strdup(tune_args); - sdr_tx_antenna = strdup(tx_antenna); - sdr_rx_antenna = strdup(rx_antenna); - sdr_tx_gain = tx_gain; - sdr_rx_gain = rx_gain; - sdr_bandwidth = bandwidth; - sdr_write_iq_tx_wave = write_iq_tx_wave; - sdr_write_iq_rx_wave = write_iq_rx_wave; - sdr_read_iq_tx_wave = read_iq_tx_wave; - sdr_read_iq_rx_wave = read_iq_rx_wave; - sdr_samplerate = samplerate; - sdr_oversample = 1; - sdr_latspl = latspl; - sdr_swap_links = swap_links; - sdr_uhd_tx_timestamps = uhd_tx_timestamps; - - return 0; -} - -void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_frequency, double *rx_frequency, int channels, double paging_frequency, int samplerate, double max_deviation, double max_modulation) +void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_frequency, double *rx_frequency, int channels, double paging_frequency, int samplerate, int latspl, double max_deviation, double max_modulation) { sdr_t *sdr; + int threads = 1, oversample = 1; /* always use threads */ double bandwidth; double tx_center_frequency = 0.0, rx_center_frequency = 0.0; int rc; @@ -132,48 +99,19 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq PDEBUG(DSDR, DEBUG_DEBUG, "Open SDR device\n"); - if (sdr_samplerate != samplerate) { - if (samplerate > sdr_samplerate) { + 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_samplerate, samplerate); + PDEBUG(DSDR, DEBUG_ERROR, "You selected an SDR rate of %d and an audio rate of %d.\n", sdr_config->samplerate, samplerate); return NULL; } - if ((sdr_samplerate % samplerate)) { + 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_samplerate, samplerate); - return NULL; - } - sdr_oversample = sdr_samplerate / samplerate; - sdr_threads = 1; - } - - if (sdr_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 = calloc(sdr_thread_read.buffer_size, sizeof(*sdr_thread_read.buffer)); - if (!sdr_thread_read.buffer) { - PDEBUG(DSDR, DEBUG_ERROR, "No mem!\n"); + PDEBUG(DSDR, DEBUG_ERROR, "You selected an SDR rate of %d and an audio rate of %d.\n", sdr_config->samplerate, samplerate); return NULL; } - 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"); - return NULL; - } - sdr_thread_read.in = sdr_thread_read.out = 0; - memset(&sdr_thread_write, 0, sizeof(sdr_thread_write)); - sdr_thread_write.buffer_size = sdr_latspl * 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"); - return NULL; - } - 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"); - return NULL; - } - sdr_thread_write.in = sdr_thread_write.out = 0; + oversample = sdr_config->samplerate / samplerate; + threads = 1; } display_iq_init(samplerate); @@ -195,29 +133,61 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq sdr->channels = channels; sdr->amplitude = 1.0 / (double)channels; sdr->samplerate = samplerate; + sdr->latspl = latspl; + sdr->threads = threads; /* always requried, 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 = calloc(sdr->thread_read.buffer_size, sizeof(*sdr->thread_read.buffer)); + if (!sdr->thread_read.buffer) { + PDEBUG(DSDR, DEBUG_ERROR, "No mem!\n"); + return NULL; + } + 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"); + return NULL; + } + sdr->thread_read.in = sdr->thread_read.out = 0; + memset(&sdr->thread_write, 0, sizeof(sdr->thread_write)); + sdr->thread_write.buffer_size = sdr->latspl * 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"); + return NULL; + } + 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"); + return NULL; + } + sdr->thread_write.in = sdr->thread_write.out = 0; + } /* alloc fm modulation buffers */ - sdr->modbuff = calloc(sdr_latspl * 2, sizeof(*sdr->modbuff)); + sdr->modbuff = calloc(sdr->latspl * 2, sizeof(*sdr->modbuff)); if (!sdr->modbuff) { PDEBUG(DSDR, DEBUG_ERROR, "NO MEM!\n"); goto error; } - sdr->modbuff_I = calloc(sdr_latspl, sizeof(*sdr->modbuff_I)); + sdr->modbuff_I = calloc(sdr->latspl, sizeof(*sdr->modbuff_I)); if (!sdr->modbuff_I) { PDEBUG(DSDR, DEBUG_ERROR, "NO MEM!\n"); goto error; } - sdr->modbuff_Q = calloc(sdr_latspl, sizeof(*sdr->modbuff_Q)); + sdr->modbuff_Q = calloc(sdr->latspl, sizeof(*sdr->modbuff_Q)); if (!sdr->modbuff_Q) { PDEBUG(DSDR, DEBUG_ERROR, "NO MEM!\n"); goto error; } - sdr->wavespl0 = calloc(sdr_latspl, sizeof(*sdr->wavespl0)); + sdr->wavespl0 = calloc(sdr->latspl, sizeof(*sdr->wavespl0)); if (!sdr->wavespl0) { PDEBUG(DSDR, DEBUG_ERROR, "NO MEM!\n"); goto error; } - sdr->wavespl1 = calloc(sdr_latspl, sizeof(*sdr->wavespl1)); + sdr->wavespl1 = calloc(sdr->latspl, sizeof(*sdr->wavespl1)); if (!sdr->wavespl1) { PDEBUG(DSDR, DEBUG_ERROR, "NO MEM!\n"); goto error; @@ -291,17 +261,17 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq goto error; } /* show gain */ - PDEBUG(DSDR, DEBUG_INFO, "Using gain: TX %.1f dB\n", sdr_tx_gain); + PDEBUG(DSDR, DEBUG_INFO, "Using gain: TX %.1f dB\n", sdr_config->tx_gain); /* open wave */ - if (sdr_write_iq_tx_wave) { - rc = wave_create_record(&sdr->wave_tx_rec, sdr_write_iq_tx_wave, samplerate, 2, 1.0); + 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"); goto error; } } - if (sdr_read_iq_tx_wave) { - rc = wave_create_playback(&sdr->wave_tx_play, sdr_read_iq_tx_wave, samplerate, 2, 1.0); + if (sdr_config->read_iq_tx_wave) { + rc = wave_create_playback(&sdr->wave_tx_play, sdr_config->read_iq_tx_wave, samplerate, 2, 1.0); if (rc < 0) { PDEBUG(DSDR, DEBUG_ERROR, "Failed to create WAVE playback instance!\n"); goto error; @@ -344,17 +314,17 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq goto error; } /* show gain */ - PDEBUG(DSDR, DEBUG_INFO, "Using gain: RX %.1f dB\n", sdr_rx_gain); + PDEBUG(DSDR, DEBUG_INFO, "Using gain: RX %.1f dB\n", sdr_config->rx_gain); /* open wave */ - if (sdr_write_iq_rx_wave) { - rc = wave_create_record(&sdr->wave_rx_rec, sdr_write_iq_rx_wave, samplerate, 2, 1.0); + 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"); goto error; } } - if (sdr_read_iq_rx_wave) { - rc = wave_create_playback(&sdr->wave_rx_play, sdr_read_iq_rx_wave, samplerate, 2, 1.0); + if (sdr_config->read_iq_rx_wave) { + rc = wave_create_playback(&sdr->wave_rx_play, sdr_config->read_iq_rx_wave, samplerate, 2, 1.0); if (rc < 0) { PDEBUG(DSDR, DEBUG_ERROR, "Failed to create WAVE playback instance!\n"); goto error; @@ -362,7 +332,7 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq } } - if (sdr_swap_links) { + if (sdr_config->swap_links) { double temp; PDEBUG(DSDR, DEBUG_NOTICE, "Sapping RX and TX frequencies!\n"); temp = rx_center_frequency; @@ -371,16 +341,16 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq } #ifdef HAVE_UHD - if (sdr_use_uhd) { - rc = uhd_open(sdr_channel, sdr_device_args, sdr_stream_args, sdr_tune_args, sdr_tx_antenna, sdr_rx_antenna, tx_center_frequency, rx_center_frequency, sdr_samplerate, sdr_tx_gain, sdr_rx_gain, sdr_bandwidth, sdr_uhd_tx_timestamps); + 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, tx_center_frequency, rx_center_frequency, sdr_config->samplerate, sdr_config->tx_gain, sdr_config->rx_gain, sdr_config->bandwidth, sdr_config->uhd_tx_timestamps); if (rc) goto error; } #endif #ifdef HAVE_SOAPY - if (sdr_use_soapy) { - rc = soapy_open(sdr_channel, sdr_device_args, sdr_stream_args, sdr_tune_args, sdr_tx_antenna, sdr_rx_antenna, tx_center_frequency, rx_center_frequency, sdr_samplerate, sdr_tx_gain, sdr_rx_gain, sdr_bandwidth); + 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, tx_center_frequency, rx_center_frequency, sdr_config->samplerate, sdr_config->tx_gain, sdr_config->rx_gain, sdr_config->bandwidth); if (rc) goto error; } @@ -393,25 +363,25 @@ error: return NULL; } -static void *sdr_write_child(void __attribute__((__unused__)) *arg) +static void *sdr_write_child(void *arg) { sdr_t *sdr = (sdr_t *)arg; int num; int fill, out; int s, ss, o; - while (sdr_thread_write.running) { + while (sdr->thread_write.running) { /* write to SDR */ - fill = (sdr_thread_write.in - sdr_thread_write.out + sdr_thread_write.buffer_size) % sdr_thread_write.buffer_size; - if (fill > sdr_thread_write.max_fill) - sdr_thread_write.max_fill = fill; - if (sdr_thread_write.max_fill_timer == 0.0) - sdr_thread_write.max_fill_timer = get_time(); - if (get_time() - sdr_thread_write.max_fill_timer > 1.0) { + fill = (sdr->thread_write.in - sdr->thread_write.out + sdr->thread_write.buffer_size) % sdr->thread_write.buffer_size; + if (fill > sdr->thread_write.max_fill) + sdr->thread_write.max_fill = fill; + if (sdr->thread_write.max_fill_timer == 0.0) + sdr->thread_write.max_fill_timer = get_time(); + if (get_time() - sdr->thread_write.max_fill_timer > 1.0) { double delay; - 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; + 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); } num = fill / 2; @@ -419,23 +389,23 @@ static void *sdr_write_child(void __attribute__((__unused__)) *arg) #ifdef DEBUG_BUFFER printf("Thread found %d samples in write buffer and forwards them to SDR.\n", num); #endif - out = sdr_thread_write.out; + out = sdr->thread_write.out; for (s = 0, ss = 0; s < num; s++) { - for (o = 0; o < sdr_oversample; o++) { - sdr_thread_write.buffer2[ss++] = sdr_thread_write.buffer[out]; - sdr_thread_write.buffer2[ss++] = sdr_thread_write.buffer[out + 1]; + for (o = 0; o < sdr->oversample; o++) { + sdr->thread_write.buffer2[ss++] = sdr->thread_write.buffer[out]; + sdr->thread_write.buffer2[ss++] = sdr->thread_write.buffer[out + 1]; } - out = (out + 2) % sdr_thread_write.buffer_size; + out = (out + 2) % sdr->thread_write.buffer_size; } #ifdef HAVE_UHD - if (sdr_use_uhd) - uhd_send(sdr_thread_write.buffer2, num * sdr_oversample); + if (sdr_config->uhd) + uhd_send(sdr->thread_write.buffer2, num * sdr->oversample); #endif #ifdef HAVE_SOAPY - if (sdr_use_soapy) - soapy_send(sdr_thread_write.buffer2, num * sdr_oversample); + if (sdr_config->soapy) + soapy_send(sdr->thread_write.buffer2, num * sdr->oversample); #endif - sdr_thread_write.out = out; + sdr->thread_write.out = out; } /* delay some time */ @@ -443,41 +413,41 @@ static void *sdr_write_child(void __attribute__((__unused__)) *arg) } PDEBUG(DSDR, DEBUG_DEBUG, "Thread received exit!\n"); - sdr_thread_write.exit = 1; + sdr->thread_write.exit = 1; return NULL; } -static void *sdr_read_child(void __attribute__((__unused__)) *arg) +static void *sdr_read_child(void *arg) { -// sdr_t *sdr = (sdr_t *)arg; + sdr_t *sdr = (sdr_t *)arg; int num, count = 0; int space, in; int s, ss; - while (sdr_thread_read.running) { + while (sdr->thread_read.running) { /* read from SDR */ - space = (sdr_thread_read.out - sdr_thread_read.in - 2 + sdr_thread_read.buffer_size) % sdr_thread_read.buffer_size; + space = (sdr->thread_read.out - sdr->thread_read.in - 2 + sdr->thread_read.buffer_size) % sdr->thread_read.buffer_size; num = space / 2; if (num) { #ifdef HAVE_UHD - if (sdr_use_uhd) - count = uhd_receive(sdr_thread_read.buffer2, num); + if (sdr_config->uhd) + count = uhd_receive(sdr->thread_read.buffer2, num); #endif #ifdef HAVE_SOAPY - if (sdr_use_soapy) - count = soapy_receive(sdr_thread_read.buffer2, num); + if (sdr_config->soapy) + count = soapy_receive(sdr->thread_read.buffer2, num); #endif if (count > 0) { #ifdef DEBUG_BUFFER printf("Thread read %d samples from SDR and writes them to read buffer.\n", count); #endif - in = sdr_thread_read.in; + in = sdr->thread_read.in; for (s = 0, ss = 0; s < count; s++) { - sdr_thread_read.buffer[in++] = sdr_thread_read.buffer2[ss++]; - sdr_thread_read.buffer[in++] = sdr_thread_read.buffer2[ss++]; - in %= sdr_thread_read.buffer_size; + sdr->thread_read.buffer[in++] = sdr->thread_read.buffer2[ss++]; + sdr->thread_read.buffer[in++] = sdr->thread_read.buffer2[ss++]; + in %= sdr->thread_read.buffer_size; } - sdr_thread_read.in = in; + sdr->thread_read.in = in; } } @@ -486,38 +456,38 @@ static void *sdr_read_child(void __attribute__((__unused__)) *arg) } PDEBUG(DSDR, DEBUG_DEBUG, "Thread received exit!\n"); - sdr_thread_read.exit = 1; + sdr->thread_read.exit = 1; return NULL; } /* start streaming */ -int sdr_start(void __attribute__((__unused__)) *inst) +int sdr_start(void *inst) { -// sdr_t *sdr = (sdr_t *)inst; + sdr_t *sdr = (sdr_t *)inst; int rc = -EINVAL; #ifdef HAVE_UHD - if (sdr_use_uhd) + if (sdr_config->uhd) rc = uhd_start(); #endif #ifdef HAVE_SOAPY - if (sdr_use_soapy) + if (sdr_config->soapy) rc = soapy_start(); #endif if (rc < 0) return rc; - if (sdr_threads) { + if (sdr->threads) { int rc; pthread_t tid; char tname[64]; PDEBUG(DSDR, DEBUG_DEBUG, "Create threads!\n"); - sdr_thread_write.running = 1; - sdr_thread_write.exit = 0; + 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; + sdr->thread_write.running = 0; PDEBUG(DSDR, DEBUG_ERROR, "Failed to create thread!\n"); return rc; } @@ -525,11 +495,11 @@ int sdr_start(void __attribute__((__unused__)) *inst) strncat(tname, "-sdr_tx", sizeof(tname)); tname[sizeof(tname) - 1] = '\0'; pthread_setname_np(tid, tname); - sdr_thread_read.running = 1; - sdr_thread_read.exit = 0; + sdr->thread_read.running = 1; + sdr->thread_read.exit = 0; rc = pthread_create(&tid, NULL, sdr_read_child, inst); if (rc < 0) { - sdr_thread_read.running = 0; + sdr->thread_read.running = 0; PDEBUG(DSDR, DEBUG_ERROR, "Failed to create thread!\n"); return rc; } @@ -548,37 +518,37 @@ void sdr_close(void *inst) PDEBUG(DSDR, DEBUG_DEBUG, "Close SDR device\n"); - if (sdr_threads) { - if (sdr_thread_write.running) { + if (sdr->threads) { + if (sdr->thread_write.running) { PDEBUG(DSDR, DEBUG_DEBUG, "Thread sending exit!\n"); - sdr_thread_write.running = 0; - while (sdr_thread_write.exit == 0) + sdr->thread_write.running = 0; + while (sdr->thread_write.exit == 0) usleep(1000); } - if (sdr_thread_read.running) { + if (sdr->thread_read.running) { PDEBUG(DSDR, DEBUG_DEBUG, "Thread sending exit!\n"); - sdr_thread_read.running = 0; - while (sdr_thread_read.exit == 0) + sdr->thread_read.running = 0; + while (sdr->thread_read.exit == 0) usleep(1000); } } - if (sdr_thread_read.buffer) - free((void *)sdr_thread_read.buffer); - if (sdr_thread_read.buffer2) - free((void *)sdr_thread_read.buffer2); - if (sdr_thread_write.buffer) - free((void *)sdr_thread_write.buffer); - if (sdr_thread_write.buffer2) - free((void *)sdr_thread_write.buffer2); + if (sdr->thread_read.buffer) + free((void *)sdr->thread_read.buffer); + if (sdr->thread_read.buffer2) + free((void *)sdr->thread_read.buffer2); + if (sdr->thread_write.buffer) + free((void *)sdr->thread_write.buffer); + if (sdr->thread_write.buffer2) + free((void *)sdr->thread_write.buffer2); #ifdef HAVE_UHD - if (sdr_use_uhd) + if (sdr_config->uhd) uhd_close(); #endif #ifdef HAVE_SOAPY - if (sdr_use_soapy) + if (sdr_config->soapy) soapy_close(); #endif @@ -615,7 +585,7 @@ 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) { + if (num > sdr->latspl) { fprintf(stderr, "exceeding maximum size given by sdr_latspl, please fix!\n"); abort(); } @@ -656,11 +626,11 @@ int sdr_write(void *inst, sample_t **samples, uint8_t **power, int num, enum pag } } - if (sdr_threads) { + if (sdr->threads) { /* store data towards SDR in ring buffer */ int space, in; - space = (sdr_thread_write.out - sdr_thread_write.in - 2 + sdr_thread_write.buffer_size) % sdr_thread_write.buffer_size; + space = (sdr->thread_write.out - sdr->thread_write.in - 2 + sdr->thread_write.buffer_size) % sdr->thread_write.buffer_size; if (space < num * 2) { PDEBUG(DSDR, DEBUG_ERROR, "Write SDR buffer overflow!\n"); num = space / 2; @@ -668,21 +638,21 @@ int sdr_write(void *inst, sample_t **samples, uint8_t **power, int num, enum pag #ifdef DEBUG_BUFFER printf("Writing %d samples to write buffer.\n", num); #endif - in = sdr_thread_write.in; + in = sdr->thread_write.in; for (s = 0, ss = 0; s < num; s++) { - sdr_thread_write.buffer[in++] = buff[ss++]; - sdr_thread_write.buffer[in++] = buff[ss++]; - in %= sdr_thread_write.buffer_size; + sdr->thread_write.buffer[in++] = buff[ss++]; + sdr->thread_write.buffer[in++] = buff[ss++]; + in %= sdr->thread_write.buffer_size; } - sdr_thread_write.in = in; + sdr->thread_write.in = in; sent = num; } else { #ifdef HAVE_UHD - if (sdr_use_uhd) + if (sdr_config->uhd) sent = uhd_send(buff, num); #endif #ifdef HAVE_SOAPY - if (sdr_use_soapy) + if (sdr_config->soapy) sent = soapy_send(buff, num); #endif if (sent < 0) @@ -699,7 +669,7 @@ int sdr_read(void *inst, sample_t **samples, int num, int channels) int count = 0; int c, s, ss; - if (num > sdr_latspl) { + if (num > sdr->latspl) { fprintf(stderr, "exceeding maximum size given by sdr_latspl, please fix!\n"); abort(); } @@ -710,42 +680,42 @@ int sdr_read(void *inst, sample_t **samples, int num, int channels) buff = (float *)samples; } - if (sdr_threads) { + if (sdr->threads) { /* load data from SDR out of ring buffer */ int fill, out; - fill = (sdr_thread_read.in - sdr_thread_read.out + sdr_thread_read.buffer_size) % sdr_thread_read.buffer_size; - if (fill > sdr_thread_read.max_fill) - sdr_thread_read.max_fill = fill; - if (sdr_thread_read.max_fill_timer == 0.0) - sdr_thread_read.max_fill_timer = get_time(); - if (get_time() - sdr_thread_read.max_fill_timer > 1.0) { + fill = (sdr->thread_read.in - sdr->thread_read.out + sdr->thread_read.buffer_size) % sdr->thread_read.buffer_size; + if (fill > sdr->thread_read.max_fill) + sdr->thread_read.max_fill = fill; + if (sdr->thread_read.max_fill_timer == 0.0) + sdr->thread_read.max_fill_timer = get_time(); + if (get_time() - sdr->thread_read.max_fill_timer > 1.0) { double delay; - delay = (double)sdr_thread_read.max_fill / 2.0 / (double)sdr_samplerate; - sdr_thread_read.max_fill = 0; - sdr_thread_read.max_fill_timer += 1.0; + 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); } - if (fill / 2 / sdr_oversample < num) - num = fill / 2 / sdr_oversample; + if (fill / 2 / sdr->oversample < num) + num = fill / 2 / sdr->oversample; #ifdef DEBUG_BUFFER printf("Reading %d samples from read buffer.\n", num); #endif - out = sdr_thread_read.out; + out = sdr->thread_read.out; for (s = 0, ss = 0; s < num; s++) { - buff[ss++] = sdr_thread_read.buffer[out]; - buff[ss++] = sdr_thread_read.buffer[out + 1]; - out = (out + 2 * sdr_oversample) % sdr_thread_read.buffer_size; + buff[ss++] = sdr->thread_read.buffer[out]; + buff[ss++] = sdr->thread_read.buffer[out + 1]; + out = (out + 2 * sdr->oversample) % sdr->thread_read.buffer_size; } - sdr_thread_read.out = out; + sdr->thread_read.out = out; count = num; } else { #ifdef HAVE_UHD - if (sdr_use_uhd) + if (sdr_config->uhd) count = uhd_receive(buff, num); #endif #ifdef HAVE_SOAPY - if (sdr_use_soapy) + if (sdr_config->soapy) count = soapy_receive(buff, num); #endif if (count <= 0) @@ -780,28 +750,28 @@ int sdr_read(void *inst, sample_t **samples, int num, int channels) } /* how much do we need to send (in audio sample duration) to get the target delay (latspl) */ -int sdr_get_tosend(void __attribute__((__unused__)) *inst, int latspl) +int sdr_get_tosend(void *inst, int latspl) { -// sdr_t *sdr = (sdr_t *)inst; + sdr_t *sdr = (sdr_t *)inst; int count = 0; #ifdef HAVE_UHD - if (sdr_use_uhd) - count = uhd_get_tosend(latspl * sdr_oversample); + if (sdr_config->uhd) + count = uhd_get_tosend(latspl * sdr->oversample); #endif #ifdef HAVE_SOAPY - if (sdr_use_soapy) - count = soapy_get_tosend(latspl * sdr_oversample); + if (sdr_config->soapy) + count = soapy_get_tosend(latspl * sdr->oversample); #endif if (count < 0) return count; - count /= sdr_oversample; + count /= sdr->oversample; - if (sdr_threads) { + if (sdr->threads) { /* substract what we have in write buffer, because this is not jent 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; + fill = (sdr->thread_write.in - sdr->thread_write.out + sdr->thread_write.buffer_size) % sdr->thread_write.buffer_size; count -= fill / 2; if (count < 0) count = 0; diff --git a/src/common/sdr.h b/src/common/sdr.h index dc95bc9..1bbfa7b 100644 --- a/src/common/sdr.h +++ b/src/common/sdr.h @@ -1,7 +1,6 @@ -int sdr_init(int sdr_uhd, int sdr_soapy, int channel, const char *device_args, const char *stream_args, const char *tune_args, const char *tx_antenna, const char *rx_antenna, double tx_gain, double rx_gain, int samplerate, double bandwidth, const char *write_iq_tx_wave, const char *write_iq_rx_wave, const char *read_iq_tx_wave, const char *read_iq_rx_wave, int latspl, int swap_links, int uhd_tx_timestamps); 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, int latspl, double bandwidth, double sample_deviation); void sdr_close(void *inst); int sdr_write(void *inst, sample_t **samples, uint8_t **power, int num, enum paging_signal *paging_signal, int *on, int channels); int sdr_read(void *inst, sample_t **samples, int num, int channels); diff --git a/src/common/sdr_config.c b/src/common/sdr_config.c new file mode 100644 index 0000000..c4cae55 --- /dev/null +++ b/src/common/sdr_config.c @@ -0,0 +1,262 @@ +/* Config for SDR + * + * (C) 2017 by Andreas Eversberg <jolly@eversberg.eu> + * All Rights Reserved + * + * 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/>. + */ + +enum paging_signal; + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> +#include <getopt.h> +#include "sample.h" +#include "sdr.h" +#include "sdr_config.h" + +static int got_init = 0; +extern int use_sdr; +sdr_config_t *sdr_config = NULL; + +void sdr_config_init(void) +{ + sdr_config = calloc(1, sizeof(*sdr_config)); + memset(sdr_config, 0, sizeof(*sdr_config)); + sdr_config->device_args = ""; + sdr_config->stream_args = ""; + sdr_config->tune_args = ""; + + got_init = 1; +} + +void sdr_config_print_help(void) +{ + printf("\nSDR options:\n"); + /* - - */ +#ifdef HAVE_UHD + printf(" --sdr-uhd\n"); + printf(" Force UHD driver\n"); +#endif +#ifdef HAVE_SOAPY + printf(" --sdr-soapy\n"); + printf(" Force SoapySDR driver\n"); +#endif + printf(" --sdr-channel <channel #>\n"); + printf(" Give channel number for multi channel SDR device (default = %d)\n", sdr_config->channel); + printf(" --sdr-device-args <args>\n"); + printf(" --sdr-stream-args <args>\n"); + printf(" --sdr-tune-args <args>\n"); + printf(" Optional SDR device arguments, seperated by comma\n"); + printf(" e.g. --sdr-device-args <key>=<value>[,<key>=<value>[,...]]\n"); + printf(" --sdr-samplerate <samplerate>\n"); + printf(" Sample rate to use with SDR. By default it equals the regular sample\n"); + printf(" rate.\n"); + printf(" --sdr-bandwidth <bandwidth>\n"); + printf(" Give IF filter bandwidth to use. If not, sample rate is used.\n"); + printf(" --sdr-rx-antenna <name>\n"); + printf(" SDR device's RX antenna name, use 'list' to get a list\n"); + printf(" --sdr-tx-antenna <name>\n"); + printf(" SDR device's TX antenna name, use 'list' to get a list\n"); + printf(" --sdr-rx-gain <gain>\n"); + printf(" SDR device's RX gain in dB (default = %.1f)\n", sdr_config->rx_gain); + printf(" --sdr-tx-gain <gain>\n"); + printf(" SDR device's TX gain in dB (default = %.1f)\n", sdr_config->tx_gain); + printf(" --write-iq-rx-wave <file>\n"); + printf(" Write received IQ data to given wave file.\n"); + printf(" --write-iq-tx-wave <file>\n"); + printf(" Write transmitted IQ data to given wave file.\n"); + printf(" --read-iq-rx-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"); + printf(" --sdr-swap-links\n"); + printf(" Swap RX and TX frequencies for loopback tests over the air.\n"); +#ifdef HAVE_UHD + printf(" --sdr-uhd-tx-timestamps\n"); + printf(" Use TX timestamps on UHD device. (May not work with some devices!)\n"); +#endif +} + +void sdr_config_print_hotkeys(void) +{ + printf("Press 'i' key to toggle display of RX I/Q vector.\n"); + printf("Press 's' key to toggle display of RX spectrum.\n"); +} + +#define OPT_SDR_UHD 1500 +#define OPT_SDR_SOAPY 1501 +#define OPT_SDR_CHANNEL 1502 +#define OPT_SDR_DEVICE_ARGS 1503 +#define OPT_SDR_STREAM_ARGS 1504 +#define OPT_SDR_TUNE_ARGS 1505 +#define OPT_SDR_RX_ANTENNA 1506 +#define OPT_SDR_TX_ANTENNA 1507 +#define OPT_SDR_RX_GAIN 1508 +#define OPT_SDR_TX_GAIN 1509 +#define OPT_SDR_SAMPLERATE 1510 +#define OPT_SDR_BANDWIDTH 1511 +#define OPT_WRITE_IQ_RX_WAVE 1512 +#define OPT_WRITE_IQ_TX_WAVE 1513 +#define OPT_READ_IQ_RX_WAVE 1514 +#define OPT_READ_IQ_TX_WAVE 1515 +#define OPT_SDR_SWAP_LINKS 1516 +#define OPT_SDR_UHD_TX_TS 1517 + +struct option sdr_config_long_options[] = { + {"sdr-uhd", 0, 0, OPT_SDR_UHD}, + {"sdr-soapy", 0, 0, OPT_SDR_SOAPY}, + {"sdr-channel", 1, 0, OPT_SDR_CHANNEL}, + {"sdr-device-args", 1, 0, OPT_SDR_DEVICE_ARGS}, + {"sdr-stream-args", 1, 0, OPT_SDR_STREAM_ARGS}, + {"sdr-tune-args", 1, 0, OPT_SDR_TUNE_ARGS}, + {"sdr-samplerate", 1, 0, OPT_SDR_SAMPLERATE}, + {"sdr-bandwidth", 1, 0, OPT_SDR_BANDWIDTH}, + {"sdr-rx-antenna", 1, 0, OPT_SDR_RX_ANTENNA}, + {"sdr-tx-antenna", 1, 0, OPT_SDR_TX_ANTENNA}, + {"sdr-rx-gain", 1, 0, OPT_SDR_RX_GAIN}, + {"sdr-tx-gain", 1, 0, OPT_SDR_TX_GAIN}, + {"write-iq-rx-wave", 1, 0, OPT_WRITE_IQ_RX_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-tx-wave", 1, 0, OPT_READ_IQ_TX_WAVE}, + {"sdr-swap-links", 0, 0, OPT_SDR_SWAP_LINKS}, + {"sdr-uhd-tx-timestamps", 0, 0, OPT_SDR_UHD_TX_TS}, + {0, 0, 0, 0} +}; + +const char *sdr_config_optstring = ""; + +int sdr_config_opt_switch(int c, int *skip_args) +{ + switch (c) { + case OPT_SDR_UHD: +#ifdef HAVE_UHD + sdr_config->uhd = 1; + use_sdr = 1; +#else + fprintf(stderr, "UHD SDR support not compiled in!\n"); + exit(0); +#endif + *skip_args += 1; + break; + case OPT_SDR_SOAPY: +#ifdef HAVE_SOAPY + sdr_config->soapy = 1; + use_sdr = 1; +#else + fprintf(stderr, "SoapySDR support not compiled in!\n"); + exit(0); +#endif + *skip_args += 1; + break; + case OPT_SDR_CHANNEL: + sdr_config->channel = atoi(optarg); + *skip_args += 2; + break; + case OPT_SDR_DEVICE_ARGS: + sdr_config->device_args = strdup(optarg); + *skip_args += 2; + break; + case OPT_SDR_STREAM_ARGS: + sdr_config->stream_args = strdup(optarg); + *skip_args += 2; + break; + case OPT_SDR_TUNE_ARGS: + sdr_config->tune_args = strdup(optarg); + *skip_args += 2; + break; + case OPT_SDR_SAMPLERATE: + sdr_config->samplerate = atoi(optarg); + *skip_args += 2; + break; + case OPT_SDR_BANDWIDTH: + sdr_config->bandwidth = atof(optarg); + *skip_args += 2; + break; + case OPT_SDR_RX_ANTENNA: + sdr_config->rx_antenna = strdup(optarg); + *skip_args += 2; + break; + case OPT_SDR_TX_ANTENNA: + sdr_config->tx_antenna = strdup(optarg); + *skip_args += 2; + break; + case OPT_SDR_RX_GAIN: + sdr_config->rx_gain = atof(optarg); + *skip_args += 2; + break; + case OPT_SDR_TX_GAIN: + sdr_config->tx_gain = atof(optarg); + *skip_args += 2; + break; + case OPT_WRITE_IQ_RX_WAVE: + sdr_config->write_iq_rx_wave = strdup(optarg); + *skip_args += 2; + break; + case OPT_WRITE_IQ_TX_WAVE: + sdr_config->write_iq_tx_wave = strdup(optarg); + *skip_args += 2; + break; + case OPT_READ_IQ_RX_WAVE: + sdr_config->read_iq_rx_wave = strdup(optarg); + *skip_args += 2; + break; + case OPT_READ_IQ_TX_WAVE: + sdr_config->read_iq_tx_wave = strdup(optarg); + *skip_args += 2; + break; + case OPT_SDR_SWAP_LINKS: + sdr_config->swap_links = 1; + *skip_args += 1; + break; + case OPT_SDR_UHD_TX_TS: + sdr_config->uhd_tx_timestamps = 1; + *skip_args += 1; + break; + default: + return -1; + } + + return 0; +} + +int sdr_configure(int samplerate) +{ + if (!got_init) { + fprintf(stderr, "sdr_config_init was not called, please fix!\n"); + abort(); + } + + /* no sdr selected -> return 0 */ + if (!sdr_config->uhd && !sdr_config->soapy) + return 0; + + if ((sdr_config->uhd == 1 && sdr_config->soapy == 1)) { + fprintf(stderr, "You must choose which one you want: --sdr-uhd or --sdr-soapy\n"); + exit(0); + } + + if (sdr_config->samplerate == 0) + sdr_config->samplerate = samplerate; + if (sdr_config->bandwidth == 0.0) + sdr_config->bandwidth = (double)sdr_config->samplerate; + + /* sdr selected -> return 1 */ + return 1; +} + + diff --git a/src/common/sdr_config.h b/src/common/sdr_config.h new file mode 100644 index 0000000..b64424d --- /dev/null +++ b/src/common/sdr_config.h @@ -0,0 +1,32 @@ + +typedef struct sdr_config { + int uhd, /* select UHD API */ + soapy; /* select Soapy SDR API */ + int channel; /* channel number */ + const char *device_args, /* arguments */ + *stream_args, + *tune_args; + int samplerate; /* ADC/DAC sample rate */ + double bandwidth; /* IF bandwidth */ + double tx_gain, /* gain */ + rx_gain; + const char *tx_antenna, /* list/override antennas */ + *rx_antenna; + const char *write_iq_tx_wave; /* wave recording and playback */ + const char *write_iq_rx_wave; + const char *read_iq_tx_wave; + const char *read_iq_rx_wave; + int swap_links; /* swap DL and UL frequency */ + int uhd_tx_timestamps; /* use UHD time stamps */ +} sdr_config_t; + +extern sdr_config_t *sdr_config; + +void sdr_config_init(void); +void sdr_config_print_help(void); +void sdr_config_print_hotkeys(void); +extern struct option sdr_config_long_options[]; +extern const char *sdr_config_optstring; +int sdr_config_opt_switch(int c, int *skip_args); +int sdr_configure(int samplerate); + diff --git a/src/common/sender.c b/src/common/sender.c index 823fd5c..4d1b54e 100644 --- a/src/common/sender.c +++ b/src/common/sender.c @@ -153,7 +153,7 @@ error: return rc; } -int sender_open_audio(void) +int sender_open_audio(int latspl) { sender_t *master, *inst; int channels; @@ -212,7 +212,7 @@ int sender_open_audio(void) } /* open device */ - master->audio = master->audio_open(master->audiodev, tx_f, rx_f, channels, paging_frequency, master->samplerate, master->max_deviation, master->max_modulation); + master->audio = master->audio_open(master->audiodev, tx_f, rx_f, channels, paging_frequency, master->samplerate, latspl, master->max_deviation, master->max_modulation); if (!master->audio) { PDEBUG(DSENDER, DEBUG_ERROR, "No audio device!\n"); return -EIO; diff --git a/src/common/sender.h b/src/common/sender.h index 2cd0b9e..3a3136b 100644 --- a/src/common/sender.h +++ b/src/common/sender.h @@ -41,7 +41,7 @@ typedef struct sender { /* audio */ void *audio; char audiodev[64]; /* audio device name (alsa or sdr) */ - void *(*audio_open)(const char *, double *, double *, int, double, int, double, double); + void *(*audio_open)(const char *, double *, double *, int, double, int, int, double, double); int (*audio_start)(void *); void (*audio_close)(void *); int (*audio_write)(void *, sample_t **, uint8_t **, int, enum paging_signal *, int *, int); @@ -93,7 +93,7 @@ extern int cant_recover; int sender_create(sender_t *sender, int kanal, double sendefrequenz, double empfangsfrequenz, const char *audiodev, int use_sdr, int samplerate, double rx_gain, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, const char *read_tx_wave, int loopback, double loss_volume, enum paging_signal paging_signal); void sender_destroy(sender_t *sender); void sender_set_fm(sender_t *sender, double max_deviation, double max_modulation, double dBm0_deviation, double max_display); -int sender_open_audio(void); +int sender_open_audio(int latspl); int sender_start_audio(void); void process_sender_audio(sender_t *sender, int *quit, int latspl); void sender_send(sender_t *sender, sample_t *samples, uint8_t *power, int count); diff --git a/src/common/sound.h b/src/common/sound.h index 40c813f..f5ac621 100644 --- a/src/common/sound.h +++ b/src/common/sound.h @@ -1,7 +1,7 @@ enum paging_signal; -void *sound_open(const char *audiodev, double *tx_frequency, double *rx_frequency, int channels, double paging_frequency, int samplerate, double bandwidth, double sample_deviation); +void *sound_open(const char *audiodev, double *tx_frequency, double *rx_frequency, int channels, double paging_frequency, int samplerate, int latspl, double bandwidth, double sample_deviation); int sound_start(void *inst); void sound_close(void *inst); int sound_write(void *inst, sample_t **samples, uint8_t **power, int num, enum paging_signal *paging_signal, int *on, int channels); diff --git a/src/common/sound_alsa.c b/src/common/sound_alsa.c index ca71551..2719d07 100644 --- a/src/common/sound_alsa.c +++ b/src/common/sound_alsa.c @@ -128,7 +128,7 @@ static int sound_prepare(sound_t *sound) return 0; } -void *sound_open(const char *audiodev, double __attribute__((unused)) *tx_frequency, double __attribute__((unused)) *rx_frequency, int channels, double __attribute__((unused)) paging_frequency, int samplerate, double max_deviation, double __attribute__((unused)) max_modulation) +void *sound_open(const char *audiodev, double __attribute__((unused)) *tx_frequency, double __attribute__((unused)) *rx_frequency, int channels, double __attribute__((unused)) paging_frequency, int samplerate, int __attribute((unused)) latspl, double max_deviation, double __attribute__((unused)) max_modulation) { sound_t *sound; int rc; diff --git a/src/nmt/main.c b/src/nmt/main.c index e0fbadb..1302124 100644 --- a/src/nmt/main.c +++ b/src/nmt/main.c @@ -59,7 +59,7 @@ int send_callerid = 0; void print_help(const char *arg0) { - print_help_common(arg0, "[-N 900] -Y <traffic area> | list [-I 1] [-0 1] "); + main_mobile_print_help(arg0, "[-N 900] -Y <traffic area> | list [-I 1] [-0 1] "); /* - - */ printf(" -N --nmt-system 450/900\n"); printf(" Give NMT type as first paramer. (default = '%d')\n", nmt_system); @@ -94,7 +94,7 @@ void print_help(const char *arg0) printf(" If set, the caller ID is sent while ringing the phone. (default = '%d')\n", send_callerid); printf("\nstation-id: Give 7 digits of station-id, you don't need to enter it\n"); printf(" for every start of this program.\n"); - print_hotkeys_common(); + main_mobile_print_hotkeys(); } static int handle_options(int argc, char **argv) @@ -116,7 +116,7 @@ static int handle_options(int argc, char **argv) {0, 0, 0, 0} }; - set_options_common("N:T:P:Y:A:C:0:S:I:", long_options_special); + main_mobile_set_options("N:T:P:Y:A:C:0:S:I:", long_options_special); while (1) { int option_index = 0, c, rc; @@ -224,7 +224,7 @@ error_ta: skip_args += 2; break; default: - opt_switch_common(c, argv[0], &skip_args); + main_mobile_opt_switch(c, argv[0], &skip_args); } first_option = 0; } @@ -290,6 +290,8 @@ int main(int argc, char *argv[]) init_nmt_tones(); init_announcement(); + main_mobile_init(); + skip_args = handle_options(argc, argv); argc -= skip_args; argv += skip_args; diff --git a/src/r2000/main.c b/src/r2000/main.c index fc89194..684e893 100644 --- a/src/r2000/main.c +++ b/src/r2000/main.c @@ -52,7 +52,7 @@ enum r2000_chan_type chan_type[MAX_SENDER] = { CHAN_TYPE_CC_TC }; void print_help(const char *arg0) { - print_help_common(arg0, "-R <relais number> [option] "); + main_mobile_print_help(arg0, "-R <relais number> [option] "); /* - - */ printf(" -B --band <number> | list\n"); printf(" -B --bande <number> | list\n"); @@ -96,7 +96,7 @@ void print_help(const char *arg0) printf("\nstation-id: Give 1 digit of station mobile type + 3 digits of home relais ID\n"); printf(" + 5 digits of mobile ID.\n"); printf(" (e.g. 103200819 = type 1, relais ID 32, mobile ID 819)\n"); - print_hotkeys_common(); + main_mobile_print_hotkeys(); } #define OPT_BANDE 256 @@ -124,7 +124,7 @@ static int handle_options(int argc, char **argv) {0, 0, 0, 0} }; - set_options_common("B:T:R:I:P:C:N:S", long_options_special); + main_mobile_set_options("B:T:R:I:P:C:N:S", long_options_special); while (1) { int option_index = 0, c, rc; @@ -264,7 +264,7 @@ static int handle_options(int argc, char **argv) skip_args += 1; break; default: - opt_switch_common(c, argv[0], &skip_args); + main_mobile_opt_switch(c, argv[0], &skip_args); } } @@ -284,6 +284,8 @@ int main(int argc, char *argv[]) /* init tones */ init_radiocom_tones(); + main_mobile_init(); + skip_args = handle_options(argc, argv); argc -= skip_args; argv += skip_args; |