diff options
| -rw-r--r-- | ChangeLog | 4 | ||||
| -rw-r--r-- | INSTALL.md | 85 | ||||
| -rw-r--r-- | README.md | 24 | ||||
| -rw-r--r-- | TODO | 20 | ||||
| -rw-r--r-- | configure.ac | 2 | ||||
| -rw-r--r-- | doc/example.ini | 6 | ||||
| -rw-r--r-- | lib/Json.cpp | 4 | ||||
| -rw-r--r-- | lib/Json.h | 4 | ||||
| -rw-r--r-- | lib/Socket.cpp | 1 | ||||
| -rw-r--r-- | lib/Socket.h | 2 | ||||
| -rw-r--r-- | lib/ThreadsafeQueue.h | 2 | ||||
| -rw-r--r-- | lib/fec/decode_rs.h | 12 | ||||
| -rw-r--r-- | m4/ax_boost_base.m4 | 20 | ||||
| -rw-r--r-- | src/ConfigParser.cpp | 54 | ||||
| -rw-r--r-- | src/output/SDR.cpp | 13 | ||||
| -rw-r--r-- | src/output/SDRDevice.h | 2 |
16 files changed, 151 insertions, 104 deletions
@@ -1,6 +1,10 @@ This file contains information about the changes done to ODR-DabMod in this repository +2025-09-08: Matthias P. Braendli <matthias@mpb.li> + (v3.0.1): + Fix compilation on debian gcc-15. + 2025-02-26: Matthias P. Braendli <matthias@mpb.li> (v3.0.0): Add support for the PrecisionWave DEXTER Modulator. @@ -1,25 +1,22 @@ -You have 3 ways to install odr-dabmod on your host: +# Installation -# Using your linux distribution packaging system -`odr-dabmod` is available on the official repositories of several debian-based distributions, such as Debian -(from Debian 12), Ubuntu (from 24.10), Opensuse and Arch. +You have 2 ways to install odr-dabmod on your host: -If you are using Debian 12 (Bookworm), you will need to -[add the backports repository](https://backports.debian.org/Instructions/) +## Installing binary packages on some linux distributions + +[](https://repology.org/project/odr-dabmod/versions) **Notice**: this package does not include the web-based GUI and Digital Predistortion Computation engine -# Using installation scripts -If your linux distribution is debian-based, you can install odr-dabmod -as well as the other main components of the mmbTools set with the -[Opendigitalradio dab-scripts](https://github.com/opendigitalradio/dab-scripts.git) +## Compiling manually -# Compiling manually -Unlike the 2 previous options, this one allows you to compile odr-dabmod with the features you really need. +Unlike the previous option, this one allows you to compile odr-dabmod with the features you really need. -## Dependencies -### Debian Bullseye-based OS: -``` +### Dependencies + +#### Debian Bullseye-based OS + +```sh # Required packages ## C++11 compiler sudo apt-get install --yes build-essential automake libtool @@ -29,7 +26,7 @@ sudo apt-get install --yes libfftw3-dev # optional packages ## ZeroMQ http://www.zeromq.org -sudo apt-get install --yes libzmq3-dev libzmq5 +sudo apt-get install --yes libzmq3-dev ## UHD for USRP sudo apt-get install --yes libuhd-dev @@ -44,29 +41,37 @@ sudo apt-get install --yes libsoapysdr-dev sudo apt-get install --yes libbladerf-dev ``` -## Compilation +### Compilation + 1. Clone this repository: - ``` + + ```sh # stable version: git clone https://github.com/Opendigitalradio/ODR-DabMod.git # or development version (at your own risk): git clone https://github.com/Opendigitalradio/ODR-DabMod.git -b next ``` + 1. Configure the project - ``` + + ```sh cd ODR-DabMod - ./bootstrap + ./bootstrap.sh ./configure ``` + 1. Compile and install: - ``` + + ```sh make sudo make install ``` -### Configure options +#### Configure options + The configure script can be launched with a variety of options: + - Disable ZeroMQ input (to be used with ODR-DabMod), output and remotecontrol: `--disable-zeromq` - Disable the binding to the UHD driver for USRPs: `--disable-output-uhd` - Compile using the `-ffast-math` option that gives a substantial speedup at the cost of floating point correctness: `--enable-fast-math` @@ -79,45 +84,52 @@ The configure script can be launched with a variety of options: Create debugging files for each DSP block for data analysis: `--enable-trace` For more information, call: -``` + +```sh ./configure --help ``` -#### Performance optimisation +##### Performance optimisation + While the performance of modern systems is good enough in most cases to run ODR-DabMod, it is sometimes necessary to increase the compilation optimisation if all features are used or on slow systems. Tricks for best performance: -* Do not use `--disable-native` -* Use `--enable-fast-math` -* Add `-O3` to compiler flags -* Disable assertions with `-DNDEBUG` +- Do not use `--disable-native` +- Use `--enable-fast-math` +- Add `-O3` to compiler flags +- Disable assertions with `-DNDEBUG` Applying all together: -``` + +```sh ./configure CFLAGS="-O3 -DNDEBUG" CXXFLAGS="-O3 -DNDEBUG" --enable-fast-math ``` -#### Checking for memory usage issues +##### Checking for memory usage issues + If your compiler supports it, you can enable the address sanitizer to check for memory issues: -``` + +```sh ./configure CFLAGS="-fsanitize=address -g -O2" CXXFLAGS="-fsanitize=address -g -O2" ``` The resulting binary will be instrumented with additional memory checks, which have a measurable overhead. Please report if you get warnings or errors when using the sanitizer. -## SoapySDR support and required dependencies +### SoapySDR support and required dependencies + SoapySDR is a vendor-neutral library to drive SDR devices. It can be used to drive the HackRF and the LimeSDR among others. Required dependencies that need to be installed are, in order: -1. SoapySDR itself from https://github.com/pothosware/SoapySDR -1. The LimeSuite for the LimeSDR from https://github.com/myriadrf/LimeSuite -1. HackRF support for SoapySDR from https://github.com/pothosware/SoapyHackRF + +1. SoapySDR itself from <https://github.com/pothosware/SoapySDR> +1. The LimeSuite for the LimeSDR from <https://github.com/myriadrf/LimeSuite> +1. HackRF support for SoapySDR from <https://github.com/pothosware/SoapyHackRF> ODR-DabMod will automatically recognise if the SoapySDR library is installed on your system, and will print at the end of `./configure` if support is enabled or @@ -125,5 +137,6 @@ not. A configuration example is available in `doc/example.ini` -## BladeRF support +### BladeRF support + In order to use `--enable-bladerf`, you need to install the `libbladerf2` including the -dev package. @@ -1,5 +1,5 @@ -OVERVIEW -======== +# OVERVIEW + ODR-DabMod is a *DAB (Digital Audio Broadcasting)* modulator compliant to ETSI EN 300 401. It is the continuation of the work started by the Communications Research Center Canada, and is now pursued in the @@ -9,8 +9,7 @@ ODR-DabMod is part of the ODR-mmbTools tool-set. More information about the ODR-mmbTools is available in the *guide*, available on the [Opendigitalradio mmbTools page](http://www.opendigitalradio.org/mmbtools). -Features --------- +## Features - Reads ETI and EDI, outputs compliant COFDM I/Q - Supports native DAB sample rate and can also resample to other rates @@ -38,6 +37,7 @@ Features - ZeroMQ PUB and REP output, useful for sending IQ to GNURadio flowgraphs. Development has stalled on the following topics: + - Experimental prototype about digital predistortion for PA linearisation. - See `python/dpd/README.md` - A web GUI for control and supervision of modulator and predistortion engine. See `python/gui/README.md` @@ -53,18 +53,18 @@ ODR-DabMod. The `python/` directory contains a web-based graphical control interface and the digital predistortion project. -INSTALL -======= -See the `INSTALL.md` file for installation instructions. +## Install + +[Check the installation instructions.](INSTALL.md) + +## License -LICENCE -======= See the files `LICENCE` and `COPYING` -CONTACT -======= +## Contact + Matthias P. Braendli *matthias [at] mpb [dot] li* With thanks to other contributors listed in AUTHORS -http://opendigitalradio.org/ +<http://opendigitalradio.org/> @@ -1,25 +1,21 @@ +# To do + This TODO file lists ideas and features for future developments. Unless written, no activity has been started on the topics. - -Smaller things --------------- +## Smaller things Remove GuardIntervalInserter implementation for window==0, as it was shown both are equivalent. +## Resampler improvements -Resampler improvements ----------------------- - * Assess quality of window currently used. - * Evaluate usefulness of other windows. - * Distribute energy of Fs bin equally to both negative and positive - frequencies in the back buffer. +- Assess quality of window currently used. +- Evaluate usefulness of other windows. +- Distribute energy of Fs bin equally to both negative and positive frequencies in the back buffer. +## Review CicEq -Review CicEq ------------- The CIC Equaliser was used for the USRP1 to compensate for spectrum flatness. It is not documented, and its effect poorly explained. Review if still needed, and document appropriately. - diff --git a/configure.ac b/configure.ac index 46bbaf1..ccce564 100644 --- a/configure.ac +++ b/configure.ac @@ -19,7 +19,7 @@ # along with ODR-DabMod. If not, see <http://www.gnu.org/licenses/>. AC_PREREQ([2.69]) -AC_INIT([ODR-DabMod],[3.0.0],[matthias.braendli@mpb.li]) +AC_INIT([ODR-DabMod],[3.0.1],[matthias.braendli@mpb.li]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([m4]) AC_CANONICAL_TARGET diff --git a/doc/example.ini b/doc/example.ini index 0d0f8e3..a1129de 100644 --- a/doc/example.ini +++ b/doc/example.ini @@ -76,6 +76,12 @@ loop=0 ;transport=tcp ;source=localhost:9200 + +; 1 means that the output device will throttle the input rate. +; 0 means that frames will be dropped if the input is too fast. +; Default depends on the value of transport: 1 for file, 0 for network inputs +;backpressure_input=1 + [modulator] ; Mode 'fix' uses a fixed factor and is really not recommended. It is more ; useful on an academic perspective for people trying to understand the DAB diff --git a/lib/Json.cpp b/lib/Json.cpp index 361a149..ee33671 100644 --- a/lib/Json.cpp +++ b/lib/Json.cpp @@ -3,7 +3,7 @@ Her Majesty the Queen in Right of Canada (Communications Research Center Canada) - Copyright (C) 2023 + Copyright (C) 2025 Matthias P. Braendli, matthias.braendli@mpb.li http://www.opendigitalradio.org @@ -27,7 +27,7 @@ #include <sstream> #include <iomanip> #include <string> -#include <algorithm> +#include <stdexcept> #include "Json.h" @@ -3,7 +3,7 @@ Her Majesty the Queen in Right of Canada (Communications Research Center Canada) - Copyright (C) 2023 + Copyright (C) 2025 Matthias P. Braendli, matthias.braendli@mpb.li http://www.opendigitalradio.org @@ -34,10 +34,10 @@ #include <vector> #include <memory> #include <optional> -#include <stdexcept> #include <string> #include <unordered_map> #include <variant> +#include <cstdint> namespace json { diff --git a/lib/Socket.cpp b/lib/Socket.cpp index 5c920d7..33c9c73 100644 --- a/lib/Socket.cpp +++ b/lib/Socket.cpp @@ -1152,6 +1152,7 @@ void TCPDataDispatcher::process() std::vector<TCPConnection::stats_t> TCPDataDispatcher::get_stats() const { std::vector<TCPConnection::stats_t> s; + auto lock = unique_lock<mutex>(m_mutex); for (const auto& conn : m_connections) { s.push_back(conn.get_stats()); } diff --git a/lib/Socket.h b/lib/Socket.h index 29b618a..b9a40ee 100644 --- a/lib/Socket.h +++ b/lib/Socket.h @@ -298,7 +298,7 @@ class TCPDataDispatcher std::thread m_listener_thread; TCPSocket m_listener_socket; - std::mutex m_mutex; + mutable std::mutex m_mutex; std::deque<std::vector<uint8_t> > m_preroll_queue; std::list<TCPConnection> m_connections; }; diff --git a/lib/ThreadsafeQueue.h b/lib/ThreadsafeQueue.h index 13bc19e..a8d2e85 100644 --- a/lib/ThreadsafeQueue.h +++ b/lib/ThreadsafeQueue.h @@ -31,7 +31,7 @@ #include <functional> #include <mutex> #include <condition_variable> -#include <queue> +#include <deque> #include <utility> #include <cassert> diff --git a/lib/fec/decode_rs.h b/lib/fec/decode_rs.h index c165cf3..647b885 100644 --- a/lib/fec/decode_rs.h +++ b/lib/fec/decode_rs.h @@ -145,15 +145,15 @@ count++; } if (count != no_eras) { - printf("count = %d no_eras = %d\n lambda(x) is WRONG\n",count,no_eras); + fprintf(stderr, "count = %d no_eras = %d\n lambda(x) is WRONG\n",count,no_eras); count = -1; goto finish; } #if DEBUG >= 2 - printf("\n Erasure positions as determined by roots of Eras Loc Poly:\n"); + fprintf(stderr, "\n Erasure positions as determined by roots of Eras Loc Poly:\n"); for (i = 0; i < count; i++) - printf("%d ", loc[i]); - printf("\n"); + fprintf(stderr, "%d ", loc[i]); + fprintf(stderr, "\n"); #endif #endif } @@ -227,7 +227,7 @@ continue; /* Not a root */ /* store root (index-form) and error location number */ #if DEBUG>=2 - printf("count %d root %d loc %d\n",count,i,k); + fprintf(stderr, "count %d root %d loc %d\n",count,i,k); #endif root[count] = i; loc[count] = k; @@ -279,7 +279,7 @@ } #if DEBUG >= 1 if (den == 0) { - printf("\n ERROR: denominator = 0\n"); + fprintf(stderr, "\n ERROR: denominator = 0\n"); count = -1; goto finish; } diff --git a/m4/ax_boost_base.m4 b/m4/ax_boost_base.m4 index 7b8190a..9d5a08c 100644 --- a/m4/ax_boost_base.m4 +++ b/m4/ax_boost_base.m4 @@ -10,10 +10,10 @@ # # Test for the Boost C++ libraries of a particular version (or newer) # -# If no path to the installed boost library is given the macro searchs -# under /usr, /usr/local, /opt and /opt/local and evaluates the -# $BOOST_ROOT environment variable. Further documentation is available at -# <http://randspringer.de/boost/index.html>. +# If no path to the installed boost library is given the macro searches +# under /usr, /usr/local, /opt, /opt/local and /opt/homebrew and evaluates +# the $BOOST_ROOT environment variable. Further documentation is available +# at <http://randspringer.de/boost/index.html>. # # This macro calls: # @@ -33,7 +33,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 47 +#serial 55 # example boost program (need to pass version) m4_define([_AX_BOOST_BASE_PROGRAM], @@ -114,7 +114,7 @@ AC_DEFUN([_AX_BOOST_BASE_RUNDETECT],[ AS_CASE([${host_cpu}], [x86_64],[libsubdirs="lib64 libx32 lib lib64"], [mips*64*],[libsubdirs="lib64 lib32 lib lib64"], - [ppc64|powerpc64|s390x|sparc64|aarch64|ppc64le|powerpc64le|riscv64],[libsubdirs="lib64 lib lib64"], + [ppc64|powerpc64|s390x|sparc64|aarch64|ppc64le|powerpc64le|riscv64|e2k|loongarch64],[libsubdirs="lib64 lib lib64"], [libsubdirs="lib"] ) @@ -128,7 +128,7 @@ AC_DEFUN([_AX_BOOST_BASE_RUNDETECT],[ ) dnl first we check the system location for boost libraries - dnl this location ist chosen if boost libraries are installed with the --layout=system option + dnl this location is chosen if boost libraries are installed with the --layout=system option dnl or if you install boost with RPM AS_IF([test "x$_AX_BOOST_BASE_boost_path" != "x"],[ AC_MSG_CHECKING([for boostlib >= $1 ($WANT_BOOST_VERSION) includes in "$_AX_BOOST_BASE_boost_path/include"]) @@ -151,7 +151,7 @@ AC_DEFUN([_AX_BOOST_BASE_RUNDETECT],[ else search_libsubdirs="$multiarch_libsubdir $libsubdirs" fi - for _AX_BOOST_BASE_boost_path_tmp in /usr /usr/local /opt /opt/local ; do + for _AX_BOOST_BASE_boost_path_tmp in /usr /usr/local /opt /opt/local /opt/homebrew ; do if test -d "$_AX_BOOST_BASE_boost_path_tmp/include/boost" && test -r "$_AX_BOOST_BASE_boost_path_tmp/include/boost" ; then for libsubdir in $search_libsubdirs ; do if ls "$_AX_BOOST_BASE_boost_path_tmp/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi @@ -227,7 +227,7 @@ AC_DEFUN([_AX_BOOST_BASE_RUNDETECT],[ fi else if test "x$cross_compiling" != "xyes" ; then - for _AX_BOOST_BASE_boost_path in /usr /usr/local /opt /opt/local ; do + for _AX_BOOST_BASE_boost_path in /usr /usr/local /opt /opt/local /opt/homebrew ; do if test -d "$_AX_BOOST_BASE_boost_path" && test -r "$_AX_BOOST_BASE_boost_path" ; then for i in `ls -d $_AX_BOOST_BASE_boost_path/include/boost-* 2>/dev/null`; do _version_tmp=`echo $i | sed "s#$_AX_BOOST_BASE_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` @@ -289,6 +289,8 @@ AC_DEFUN([_AX_BOOST_BASE_RUNDETECT],[ else AC_MSG_NOTICE([Your boost libraries seems to old (version $_version).]) fi + BOOST_LDFLAGS="" + BOOST_CPPFLAGS="" # execute ACTION-IF-NOT-FOUND (if present): ifelse([$3], , :, [$3]) else diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp index c92a520..085ed09 100644 --- a/src/ConfigParser.cpp +++ b/src/ConfigParser.cpp @@ -102,7 +102,7 @@ static void parse_configfile( mod_settings.startupCheck = pt.Get("general.startupcheck", ""); // remote controller interfaces: - if (pt.GetInteger("remotecontrol.telnet", 0) == 1) { + if (pt.GetBoolean("remotecontrol.telnet", false)) { try { int telnetport = pt.GetInteger("remotecontrol.telnetport", 0); auto telnetrc = make_shared<RemoteControllerTelnet>(telnetport); @@ -115,7 +115,7 @@ static void parse_configfile( } } #if defined(HAVE_ZEROMQ) - if (pt.GetInteger("remotecontrol.zmqctrl", 0) == 1) { + if (pt.GetBoolean("remotecontrol.zmqctrl", false)) { try { std::string zmqCtrlEndpoint = pt.Get("remotecontrol.zmqctrlendpoint", ""); auto zmqrc = make_shared<RemoteControllerZmq>(zmqCtrlEndpoint); @@ -130,12 +130,33 @@ static void parse_configfile( #endif // input params: - if (pt.GetInteger("input.loop", 0) == 1) { + if (pt.GetBoolean("input.loop", false)) { mod_settings.loop = true; } mod_settings.inputTransport = pt.Get("input.transport", "file"); + bool defaultBackpressureInput = false; + if (mod_settings.inputTransport == "edi" or + mod_settings.inputTransport == "tcp") { + defaultBackpressureInput = false; + } + else if (mod_settings.inputTransport == "file") { + defaultBackpressureInput = true; + } + else { + throw std::runtime_error("invalid input transport " + + mod_settings.inputTransport + " selected!"); + } + + // With unsynchronised sources (e.g. file input), the mod should + // throttle the input. For network inputs however, it's better to + // allow queue overflows, otherwise during startup, a slow output + // device will also block the entire mod and input. + mod_settings.sdr_device_config.blockingQueue = + pt.GetBoolean("input.backpressure_input", defaultBackpressureInput); + + mod_settings.edi_max_delay_ms = pt.GetReal("input.edi_max_delay", 0.0); mod_settings.inputName = pt.Get("input.source", "/dev/stdin"); @@ -150,11 +171,11 @@ static void parse_configfile( #endif } - if (pt.GetInteger("log.syslog", 0) == 1) { + if (pt.GetBoolean("log.syslog", false)) { etiLog.register_backend(make_shared<LogToSyslog>()); } - if (pt.GetInteger("log.filelog", 0) == 1) { + if (pt.GetBoolean("log.filelog", false)) { std::string logfilename; try { logfilename = pt.Get("log.filename", ""); @@ -173,7 +194,7 @@ static void parse_configfile( etiLog.register_backend(make_shared<LogTracer>(trace_filename)); } - mod_settings.showProcessTime = pt.GetInteger("log.show_process_time", + mod_settings.showProcessTime = pt.GetBoolean("log.show_process_time", mod_settings.showProcessTime); // modulator parameters: @@ -195,13 +216,13 @@ static void parse_configfile( mod_settings.ofdmWindowOverlap); // FIR Filter parameters: - if (pt.GetInteger("firfilter.enabled", 0) == 1) { + if (pt.GetBoolean("firfilter.enabled", false)) { mod_settings.filterTapsFilename = pt.Get("firfilter.filtertapsfile", "default"); } // Poly coefficients: - if (pt.GetInteger("poly.enabled", 0) == 1) { + if (pt.GetBoolean("poly.enabled", false)) { mod_settings.polyCoefFilename = pt.Get("poly.polycoeffile", "dpd/poly.coef"); @@ -210,7 +231,7 @@ static void parse_configfile( } // Crest factor reduction - if (pt.GetInteger("cfr.enabled", 0) == 1) { + if (pt.GetBoolean("cfr.enabled", false)) { mod_settings.enableCfr = true; mod_settings.cfrClip = pt.GetReal("cfr.clip", 0.0); mod_settings.cfrErrorClip = pt.GetReal("cfr.error_clip", 0.0); @@ -231,8 +252,9 @@ static void parse_configfile( std::cerr << " Configuration does not specify file name for file output\n"; throw std::runtime_error("Configuration error"); } - mod_settings.fileOutputShowMetadata = - (pt.GetInteger("fileoutput.show_metadata", 0) > 0); + mod_settings.fileOutputShowMetadata = pt.GetBoolean( + "fileoutput.show_metadata", false); + mod_settings.useFileOutput = true; mod_settings.fileOutputFormat = pt.Get("fileoutput.format", @@ -240,7 +262,7 @@ static void parse_configfile( } #if defined(HAVE_OUTPUT_UHD) else if (output_selected == "uhd") { - Output::SDRDeviceConfig sdr_device_config; + auto& sdr_device_config = mod_settings.sdr_device_config; string device = pt.Get("uhdoutput.device", ""); const auto usrpType = pt.Get("uhdoutput.type", ""); @@ -309,7 +331,6 @@ static void parse_configfile( sdr_device_config.dpdFeedbackServerPort = pt.GetInteger("uhdoutput.dpd_port", 0); - mod_settings.sdr_device_config = sdr_device_config; mod_settings.useUHDOutput = true; } #endif // defined(HAVE_OUTPUT_UHD) @@ -446,8 +467,8 @@ static void parse_configfile( #if defined(HAVE_OUTPUT_UHD) || defined(HAVE_DEXTER) - mod_settings.sdr_device_config.enableSync = (pt.GetInteger("delaymanagement.synchronous", 0) == 1); - mod_settings.sdr_device_config.muteNoTimestamps = (pt.GetInteger("delaymanagement.mutenotimestamps", 0) == 1); + mod_settings.sdr_device_config.enableSync = pt.GetBoolean("delaymanagement.synchronous", false); + mod_settings.sdr_device_config.muteNoTimestamps = pt.GetBoolean("delaymanagement.mutenotimestamps", false); if (mod_settings.sdr_device_config.enableSync) { std::string delay_mgmt = pt.Get("delaymanagement.management", ""); std::string fixedoffset = pt.Get("delaymanagement.fixedoffset", ""); @@ -468,9 +489,8 @@ static void parse_configfile( } #endif - /* Read TII parameters from config file */ - mod_settings.tiiConfig.enable = pt.GetInteger("tii.enable", 0); + mod_settings.tiiConfig.enable = pt.GetBoolean("tii.enable", false); mod_settings.tiiConfig.comb = pt.GetInteger("tii.comb", 0); mod_settings.tiiConfig.pattern = pt.GetInteger("tii.pattern", 0); mod_settings.tiiConfig.old_variant = pt.GetInteger("tii.old_variant", 0); diff --git a/src/output/SDR.cpp b/src/output/SDR.cpp index 22398c7..7d5a609 100644 --- a/src/output/SDR.cpp +++ b/src/output/SDR.cpp @@ -188,10 +188,15 @@ meta_vec_t SDR::process_metadata(const meta_vec_t& metadataIn) const auto max_size = m_config.enableSync ? FRAMES_MAX_SIZE_SYNC : FRAMES_MAX_SIZE_UNSYNC; - auto r = m_queue.push_overflow(std::move(frame), max_size); - etiLog.log(trace, "SDR,push %d %zu", r.overflowed, r.new_size); - - num_queue_overflows += r.overflowed ? 1 : 0; + if (m_config.blockingQueue) { + const auto new_size = m_queue.push_wait_if_full(std::move(frame), max_size); + etiLog.log(trace, "SDR,push 0 %zu", new_size); + } + else { + const auto r = m_queue.push_overflow(std::move(frame), max_size); + etiLog.log(trace, "SDR,push %d %zu", r.overflowed, r.new_size); + num_queue_overflows += r.overflowed ? 1 : 0; + } } } else { diff --git a/src/output/SDRDevice.h b/src/output/SDRDevice.h index ec9373d..c466285 100644 --- a/src/output/SDRDevice.h +++ b/src/output/SDRDevice.h @@ -58,7 +58,7 @@ struct SDRDeviceConfig { std::string rx_antenna; bool fixedPoint = false; - + bool blockingQueue = false; long masterClockRate = 32768000; unsigned sampleRate = 2048000; double frequency = 0.0; |
