aboutsummaryrefslogtreecommitdiffstats
path: root/src/Utils.cpp
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2023-11-21 22:12:14 +0100
committerMatthias P. Braendli <matthias.braendli@mpb.li>2023-11-21 22:12:14 +0100
commit5fe36a627405b8fc65bdb212a6d505b9a6c8e489 (patch)
tree8646d654e0467be8603c5ad37fb6cd89656dfd26 /src/Utils.cpp
parent477ac4639a7c7f74f07a6164096fc7de102528ff (diff)
parentf84065c3cc6fff0edb771f85190f7228f4d740b6 (diff)
downloaddabmod-5fe36a627405b8fc65bdb212a6d505b9a6c8e489.tar.gz
dabmod-5fe36a627405b8fc65bdb212a6d505b9a6c8e489.tar.bz2
dabmod-5fe36a627405b8fc65bdb212a6d505b9a6c8e489.zip
Merge branch 'dexter' into next
Diffstat (limited to 'src/Utils.cpp')
-rw-r--r--src/Utils.cpp163
1 files changed, 145 insertions, 18 deletions
diff --git a/src/Utils.cpp b/src/Utils.cpp
index f39c4c9..788d125 100644
--- a/src/Utils.cpp
+++ b/src/Utils.cpp
@@ -3,7 +3,7 @@
Her Majesty the Queen in Right of Canada (Communications Research
Center Canada)
- Copyright (C) 2018
+ Copyright (C) 2023
Matthias P. Braendli, matthias.braendli@mpb.li
http://opendigitalradio.org
@@ -25,6 +25,8 @@
along with ODR-DabMod. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <ctime>
+#include <sstream>
#include "Utils.h"
#include "GainControl.h"
#if defined(HAVE_PRCTL)
@@ -62,10 +64,6 @@ static void printHeader()
"SSE " <<
#endif
"\n";
-
-#if defined(BUILD_FOR_EASYDABV3)
- std::cerr << " This is a build for the EasyDABv3 board" << std::endl;
-#endif
}
void printUsage(const char* progName)
@@ -77,13 +75,8 @@ void printUsage(const char* progName)
fprintf(out, "Usage with command line options:\n");
fprintf(out, "\t%s"
" input"
-#if defined(BUILD_FOR_EASYDABV3)
- " -f filename -F format"
-#else
" (-f filename -F format | -u uhddevice -F frequency)"
-#endif
" [-o offset]"
-#if !defined(BUILD_FOR_EASYDABV3)
"\n\t"
" [-G txgain]"
" [-T filter_taps_file]"
@@ -93,14 +86,12 @@ void printUsage(const char* progName)
" [-g gainMode]"
" [-m dabMode]"
" [-r samplingRate]"
-#endif
" [-l]"
" [-h]"
"\n", progName);
fprintf(out, "Where:\n");
fprintf(out, "input: ETI input filename (default: stdin), or\n");
fprintf(out, " tcp://source:port for ETI-over-TCP input, or\n");
- fprintf(out, " zmq+tcp://source:port for ZMQ input.\n");
fprintf(out, " udp://:port for EDI input.\n");
fprintf(out, "-f name: Use file output with given filename. (use /dev/stdout for standard output)\n");
fprintf(out, "-F format: Set the output format (see doc/example.ini for formats) for the file output.\n");
@@ -108,7 +99,6 @@ void printUsage(const char* progName)
fprintf(out, " Specifying this option has two implications: It enables synchronous transmission,\n"
" requiring an external REFCLK and PPS signal and frames that do not contain a valid timestamp\n"
" get muted.\n\n");
-#if !defined(BUILD_FOR_EASYDABV3)
fprintf(out, "-u device: Use UHD output with given device string. (use "" for default device)\n");
fprintf(out, "-F frequency: Set the transmit frequency when using UHD output. (mandatory option when using UHD)\n");
fprintf(out, "-G txgain: Set the transmit gain for the UHD driver (default: 0)\n");
@@ -119,7 +109,6 @@ void printUsage(const char* progName)
fprintf(out, "-g gainmode: Set computation gain mode: fix, max or var\n");
fprintf(out, "-m mode: Set DAB mode: (0: auto, 1-4: force).\n");
fprintf(out, "-r rate: Set output sampling rate (default: 2048000).\n\n");
-#endif
fprintf(out, "-l: Loop file when reach end of file.\n");
fprintf(out, "-h: Print this help.\n");
}
@@ -132,7 +121,7 @@ void printVersion(void)
" ODR-DabMod is copyright (C) Her Majesty the Queen in Right of Canada,\n"
" 2005 -- 2012 Communications Research Centre (CRC),\n"
" and\n"
- " Copyright (C) 2018 Matthias P. Braendli, matthias.braendli@mpb.li\n"
+ " Copyright (C) 2023 Matthias P. Braendli, matthias.braendli@mpb.li\n"
"\n"
" http://opendigitalradio.org\n"
"\n"
@@ -157,6 +146,87 @@ void printStartupInfo()
printHeader();
}
+void printModSettings(const mod_settings_t& mod_settings)
+{
+ std::stringstream ss;
+ // Print settings
+ ss << "Input\n";
+ ss << " Type: " << mod_settings.inputTransport << "\n";
+ ss << " Source: " << mod_settings.inputName << "\n";
+
+ ss << "Output\n";
+
+ if (mod_settings.useFileOutput) {
+ ss << " Name: " << mod_settings.outputName << "\n";
+ }
+#if defined(HAVE_OUTPUT_UHD)
+ else if (mod_settings.useUHDOutput) {
+ ss << " UHD\n" <<
+ " Device: " << mod_settings.sdr_device_config.device << "\n" <<
+ " Subdevice: " <<
+ mod_settings.sdr_device_config.subDevice << "\n" <<
+ " master_clock_rate: " <<
+ mod_settings.sdr_device_config.masterClockRate << "\n" <<
+ " refclk: " <<
+ mod_settings.sdr_device_config.refclk_src << "\n" <<
+ " pps source: " <<
+ mod_settings.sdr_device_config.pps_src << "\n";
+ }
+#endif
+#if defined(HAVE_SOAPYSDR)
+ else if (mod_settings.useSoapyOutput) {
+ ss << " SoapySDR\n"
+ " Device: " << mod_settings.sdr_device_config.device << "\n" <<
+ " master_clock_rate: " <<
+ mod_settings.sdr_device_config.masterClockRate << "\n";
+ }
+#endif
+#if defined(HAVE_DEXTER)
+ else if (mod_settings.useDexterOutput) {
+ ss << " PrecisionWave DEXTER\n";
+ }
+#endif
+#if defined(HAVE_LIMESDR)
+ else if (mod_settings.useLimeOutput) {
+ ss << " LimeSDR\n"
+ " Device: " << mod_settings.sdr_device_config.device << "\n" <<
+ " master_clock_rate: " <<
+ mod_settings.sdr_device_config.masterClockRate << "\n";
+ }
+#endif
+#if defined(HAVE_BLADERF)
+ else if (mod_settings.useBladeRFOutput) {
+ ss << " BladeRF\n"
+ " Device: " << mod_settings.sdr_device_config.device << "\n" <<
+ " refclk: " << mod_settings.sdr_device_config.refclk_src << "\n";
+ }
+#endif
+ else if (mod_settings.useZeroMQOutput) {
+ ss << " ZeroMQ\n" <<
+ " Listening on: " << mod_settings.outputName << "\n" <<
+ " Socket type : " << mod_settings.zmqOutputSocketType << "\n";
+ }
+
+ ss << " Sampling rate: ";
+ if (mod_settings.outputRate > 1000) {
+ if (mod_settings.outputRate > 1000000) {
+ ss << std::fixed << std::setprecision(4) <<
+ mod_settings.outputRate / 1000000.0 <<
+ " MHz\n";
+ }
+ else {
+ ss << std::fixed << std::setprecision(4) <<
+ mod_settings.outputRate / 1000.0 <<
+ " kHz\n";
+ }
+ }
+ else {
+ ss << std::fixed << std::setprecision(4) <<
+ mod_settings.outputRate << " Hz\n";
+ }
+ fprintf(stderr, "%s", ss.str().c_str());
+}
+
int set_realtime_prio(int prio)
{
// Set thread priority to realtime
@@ -174,7 +244,7 @@ void set_thread_name(const char *name)
#endif
}
-double parseChannel(const std::string& chan)
+double parse_channel(const std::string& chan)
{
double freq;
if (chan == "5A") freq = 174928000;
@@ -216,12 +286,59 @@ double parseChannel(const std::string& chan)
else if (chan == "13E") freq = 237488000;
else if (chan == "13F") freq = 239200000;
else {
- std::cerr << " soapy output: channel " << chan << " does not exist in table\n";
- throw std::out_of_range("soapy channel selection error");
+ std::cerr << "Channel " << chan << " does not exist in table\n";
+ throw std::out_of_range("channel out of range");
}
return freq;
}
+std::optional<std::string> convert_frequency_to_channel(double frequency)
+{
+ const int freq = round(frequency);
+ std::string chan;
+ if (freq == 174928000) chan = "5A";
+ else if (freq == 176640000) chan = "5B";
+ else if (freq == 178352000) chan = "5C";
+ else if (freq == 180064000) chan = "5D";
+ else if (freq == 181936000) chan = "6A";
+ else if (freq == 183648000) chan = "6B";
+ else if (freq == 185360000) chan = "6C";
+ else if (freq == 187072000) chan = "6D";
+ else if (freq == 188928000) chan = "7A";
+ else if (freq == 190640000) chan = "7B";
+ else if (freq == 192352000) chan = "7C";
+ else if (freq == 194064000) chan = "7D";
+ else if (freq == 195936000) chan = "8A";
+ else if (freq == 197648000) chan = "8B";
+ else if (freq == 199360000) chan = "8C";
+ else if (freq == 201072000) chan = "8D";
+ else if (freq == 202928000) chan = "9A";
+ else if (freq == 204640000) chan = "9B";
+ else if (freq == 206352000) chan = "9C";
+ else if (freq == 208064000) chan = "9D";
+ else if (freq == 209936000) chan = "10A";
+ else if (freq == 211648000) chan = "10B";
+ else if (freq == 213360000) chan = "10C";
+ else if (freq == 215072000) chan = "10D";
+ else if (freq == 216928000) chan = "11A";
+ else if (freq == 218640000) chan = "11B";
+ else if (freq == 220352000) chan = "11C";
+ else if (freq == 222064000) chan = "11D";
+ else if (freq == 223936000) chan = "12A";
+ else if (freq == 225648000) chan = "12B";
+ else if (freq == 227360000) chan = "12C";
+ else if (freq == 229072000) chan = "12D";
+ else if (freq == 230784000) chan = "13A";
+ else if (freq == 232496000) chan = "13B";
+ else if (freq == 234208000) chan = "13C";
+ else if (freq == 235776000) chan = "13D";
+ else if (freq == 237488000) chan = "13E";
+ else if (freq == 239200000) chan = "13F";
+ else { return std::nullopt; }
+
+ return chan;
+}
+
std::chrono::milliseconds transmission_frame_duration(unsigned int dabmode)
{
using namespace std::chrono;
@@ -235,3 +352,13 @@ std::chrono::milliseconds transmission_frame_duration(unsigned int dabmode)
}
}
+
+time_t get_clock_realtime_seconds()
+{
+ struct timespec t;
+ if (clock_gettime(CLOCK_REALTIME, &t) != 0) {
+ throw std::runtime_error(std::string("Failed to retrieve CLOCK_REALTIME") + strerror(errno));
+ }
+
+ return t.tv_sec;
+}