From 1834e7886112944cbb8b92751c13f50799142079 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sun, 10 Dec 2017 04:49:18 +0100 Subject: Rename misleading variable name --- src/OutputUHD.cpp | 10 +++++----- src/OutputUHD.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/OutputUHD.cpp b/src/OutputUHD.cpp index e1fe9dd..e2616a6 100644 --- a/src/OutputUHD.cpp +++ b/src/OutputUHD.cpp @@ -267,7 +267,7 @@ OutputUHD::OutputUHD( myConf.muteNoTimestamps ? "enabled" : "disabled"); // preparing output thread worker data - sourceContainsTimestamp = false; + sync_and_ts_valid = false; SetDelayBuffer(myConf.dabMode); @@ -407,7 +407,7 @@ int OutputUHD::process(Buffer* dataIn) throw std::runtime_error("Non-constant input length!"); } - sourceContainsTimestamp = myConf.enableSync and + sync_and_ts_valid = myConf.enableSync and myEtiSource->sourceContainsTimestamp(); if (gpsfix_needs_check()) { @@ -733,7 +733,7 @@ void OutputUHD::handle_frame(const struct UHDWorkerFrameData *frame) double usrp_time = myUsrp->get_time_now().get_real_secs(); bool timestamp_discontinuity = false; - if (sourceContainsTimestamp) { + if (sync_and_ts_valid) { // Tx time from MNSC and TIST uint32_t tx_second = frame->ts.timestamp_sec; uint32_t tx_pps = frame->ts.timestamp_pps; @@ -812,7 +812,7 @@ void OutputUHD::handle_frame(const struct UHDWorkerFrameData *frame) throw std::runtime_error("Timestamp error. Aborted."); } } - else { // !sourceContainsTimestamp + else { // !sync_and_ts_valid if (myConf.muting or myConf.muteNoTimestamps) { /* There was some error decoding the timestamp */ if (myConf.muting) { @@ -849,7 +849,7 @@ void OutputUHD::tx_frame(const struct UHDWorkerFrameData *frame, bool ts_update) //ensure the the last packet has EOB set if the timestamps has been //refreshed and need to be reconsidered. md_tx.end_of_burst = ( - sourceContainsTimestamp and + sync_and_ts_valid and (frame->ts.timestamp_refresh or ts_update) and samps_to_send <= usrp_max_num_samps ); diff --git a/src/OutputUHD.h b/src/OutputUHD.h index dfa471d..0630480 100644 --- a/src/OutputUHD.h +++ b/src/OutputUHD.h @@ -209,7 +209,7 @@ class OutputUHD: public ModOutput, public RemoteControllable { // Used to print statistics once a second std::chrono::steady_clock::time_point last_print_time; - bool sourceContainsTimestamp = false; + bool sync_and_ts_valid = false; ThreadsafeQueue frames; -- cgit v1.2.3 From 1ed50fe16d749ac3a841650c4054d137b9cf7a10 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sun, 10 Dec 2017 04:59:04 +0100 Subject: Make boost check more portable --- Makefile.am | 6 +- configure.ac | 4 +- m4/ax_boost_base.m4 | 241 +++++++++++++++++++++++++++++--------------------- m4/ax_boost_system.m4 | 121 +++++++++++++++++++++++++ m4/ax_boost_thread.m4 | 163 ++++++++++++++++++++++++++++++++++ 5 files changed, 431 insertions(+), 104 deletions(-) create mode 100644 m4/ax_boost_system.m4 create mode 100644 m4/ax_boost_thread.m4 diff --git a/Makefile.am b/Makefile.am index 2d84ab6..54ae62e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -37,11 +37,11 @@ bin_PROGRAMS = odr-dabmod FFT_LDADD= -odr_dabmod_CXXFLAGS = -Wall -Isrc -Ilib -std=c++11 \ - $(GITVERSION_FLAGS) odr_dabmod_CFLAGS = -Wall -Isrc -Ilib \ $(GITVERSION_FLAGS) -odr_dabmod_LDADD = $(FFT_LDADD) +odr_dabmod_CXXFLAGS = -Wall -Isrc -Ilib -std=c++11 \ + $(BOOST_CPPFLAGS) $(GITVERSION_FLAGS) +odr_dabmod_LDADD = $(FFT_LDADD) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_SYSTEM_LIB) odr_dabmod_SOURCES = src/DabMod.cpp \ src/PcDebug.h \ src/Socket.h \ diff --git a/configure.ac b/configure.ac index 6b58d3f..23369c9 100644 --- a/configure.ac +++ b/configure.ac @@ -138,8 +138,8 @@ AS_IF([test "x$enable_soapysdr" = "xyes"], [AC_DEFINE(HAVE_SOAPYSDR, [1], [Define if SoapySDR output is enabled])]) AX_BOOST_BASE([1.54.0], [], AC_MSG_ERROR([BOOST 1.54 or later is required])) -AC_CHECK_LIB([boost_system], [main], [], [AC_MSG_ERROR([library boost_system is missing])]) -AC_CHECK_LIB([boost_thread], [main], [], [AC_MSG_ERROR([library boost_thread is missing])]) +AX_BOOST_SYSTEM +AX_BOOST_THREAD AC_CHECK_LIB([rt], [clock_gettime], [], [AC_MSG_ERROR([library rt is missing])]) diff --git a/m4/ax_boost_base.m4 b/m4/ax_boost_base.m4 index 54a2a1b..2bce519 100644 --- a/m4/ax_boost_base.m4 +++ b/m4/ax_boost_base.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_boost_base.html +# https://www.gnu.org/software/autoconf-archive/ax_boost_base.html # =========================================================================== # # SYNOPSIS @@ -33,7 +33,15 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 20 +#serial 43 + +# example boost program (need to pass version) +m4_define([_AX_BOOST_BASE_PROGRAM], + [AC_LANG_PROGRAM([[ +#include +]],[[ +(void) ((void)sizeof(char[1 - 2*!!((BOOST_VERSION) < ($1))])); +]])]) AC_DEFUN([AX_BOOST_BASE], [ @@ -44,87 +52,121 @@ AC_ARG_WITH([boost], or disable it (ARG=no) @<:@ARG=yes@:>@ ])], [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then - want_boost="yes" - ac_boost_path="" - else - want_boost="yes" - ac_boost_path="$withval" - fi + AS_CASE([$withval], + [no],[want_boost="no";_AX_BOOST_BASE_boost_path=""], + [yes],[want_boost="yes";_AX_BOOST_BASE_boost_path=""], + [want_boost="yes";_AX_BOOST_BASE_boost_path="$withval"]) ], [want_boost="yes"]) AC_ARG_WITH([boost-libdir], - AS_HELP_STRING([--with-boost-libdir=LIB_DIR], - [Force given directory for boost libraries. Note that this will override library path detection, so use this parameter only if default library detection fails and you know exactly where your boost libraries are located.]), - [ - if test -d "$withval" - then - ac_boost_lib_path="$withval" - else - AC_MSG_ERROR(--with-boost-libdir expected directory name) - fi - ], - [ac_boost_lib_path=""] -) + [AS_HELP_STRING([--with-boost-libdir=LIB_DIR], + [Force given directory for boost libraries. + Note that this will override library path detection, + so use this parameter only if default library detection fails + and you know exactly where your boost libraries are located.])], + [ + AS_IF([test -d "$withval"], + [_AX_BOOST_BASE_boost_lib_path="$withval"], + [AC_MSG_ERROR([--with-boost-libdir expected directory name])]) + ], + [_AX_BOOST_BASE_boost_lib_path=""]) -if test "x$want_boost" = "xyes"; then - boost_lib_version_req=ifelse([$1], ,1.20.0,$1) - boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([[0-9]]*\.[[0-9]]*\)'` - boost_lib_version_req_major=`expr $boost_lib_version_req : '\([[0-9]]*\)'` - boost_lib_version_req_minor=`expr $boost_lib_version_req : '[[0-9]]*\.\([[0-9]]*\)'` - boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'` - if test "x$boost_lib_version_req_sub_minor" = "x" ; then - boost_lib_version_req_sub_minor="0" - fi - WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+ $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor` - AC_MSG_CHECKING(for boostlib >= $boost_lib_version_req) +BOOST_LDFLAGS="" +BOOST_CPPFLAGS="" +AS_IF([test "x$want_boost" = "xyes"], + [_AX_BOOST_BASE_RUNDETECT([$1],[$2],[$3])]) +AC_SUBST(BOOST_CPPFLAGS) +AC_SUBST(BOOST_LDFLAGS) +]) + + +# convert a version string in $2 to numeric and affect to polymorphic var $1 +AC_DEFUN([_AX_BOOST_BASE_TONUMERICVERSION],[ + AS_IF([test "x$2" = "x"],[_AX_BOOST_BASE_TONUMERICVERSION_req="1.20.0"],[_AX_BOOST_BASE_TONUMERICVERSION_req="$2"]) + _AX_BOOST_BASE_TONUMERICVERSION_req_shorten=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req : '\([[0-9]]*\.[[0-9]]*\)'` + _AX_BOOST_BASE_TONUMERICVERSION_req_major=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req : '\([[0-9]]*\)'` + AS_IF([test "x$_AX_BOOST_BASE_TONUMERICVERSION_req_major" = "x"], + [AC_MSG_ERROR([You should at least specify libboost major version])]) + _AX_BOOST_BASE_TONUMERICVERSION_req_minor=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req : '[[0-9]]*\.\([[0-9]]*\)'` + AS_IF([test "x$_AX_BOOST_BASE_TONUMERICVERSION_req_minor" = "x"], + [_AX_BOOST_BASE_TONUMERICVERSION_req_minor="0"]) + _AX_BOOST_BASE_TONUMERICVERSION_req_sub_minor=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'` + AS_IF([test "X$_AX_BOOST_BASE_TONUMERICVERSION_req_sub_minor" = "X"], + [_AX_BOOST_BASE_TONUMERICVERSION_req_sub_minor="0"]) + _AX_BOOST_BASE_TONUMERICVERSION_RET=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req_major \* 100000 \+ $_AX_BOOST_BASE_TONUMERICVERSION_req_minor \* 100 \+ $_AX_BOOST_BASE_TONUMERICVERSION_req_sub_minor` + AS_VAR_SET($1,$_AX_BOOST_BASE_TONUMERICVERSION_RET) +]) + +dnl Run the detection of boost should be run only if $want_boost +AC_DEFUN([_AX_BOOST_BASE_RUNDETECT],[ + _AX_BOOST_BASE_TONUMERICVERSION(WANT_BOOST_VERSION,[$1]) succeeded=no + + AC_REQUIRE([AC_CANONICAL_HOST]) dnl On 64-bit systems check for system libraries in both lib64 and lib. dnl The former is specified by FHS, but e.g. Debian does not adhere to dnl this (as it rises problems for generic multi-arch support). dnl The last entry in the list is chosen by default when no libraries dnl are found, e.g. when only header-only libraries are installed! - libsubdirs="lib" - ax_arch=`uname -m` - if test $ax_arch = x86_64 -o $ax_arch = ppc64 -o $ax_arch = s390x -o $ax_arch = sparc64; then - libsubdirs="lib64 lib lib64" - fi + AS_CASE([${host_cpu}], + [x86_64],[libsubdirs="lib64 libx32 lib lib64"], + [ppc64|s390x|sparc64|aarch64|ppc64le],[libsubdirs="lib64 lib lib64"], + [libsubdirs="lib"] + ) + + dnl allow for real multi-arch paths e.g. /usr/lib/x86_64-linux-gnu. Give + dnl them priority over the other paths since, if libs are found there, they + dnl are almost assuredly the ones desired. + AS_CASE([${host_cpu}], + [i?86],[multiarch_libsubdir="lib/i386-${host_os}"], + [multiarch_libsubdir="lib/${host_cpu}-${host_os}"] + ) 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 or if you install boost with RPM - if test "$ac_boost_path" != ""; then - BOOST_CPPFLAGS="-I$ac_boost_path/include" - for ac_boost_path_tmp in $libsubdirs; do - if test -d "$ac_boost_path"/"$ac_boost_path_tmp" ; then - BOOST_LDFLAGS="-L$ac_boost_path/$ac_boost_path_tmp" - break - fi - done - elif test "$cross_compiling" != yes; then - for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do - if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then - for libsubdir in $libsubdirs ; do - if ls "$ac_boost_path_tmp/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi + 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"]) + AS_IF([test -d "$_AX_BOOST_BASE_boost_path/include" && test -r "$_AX_BOOST_BASE_boost_path/include"],[ + AC_MSG_RESULT([yes]) + BOOST_CPPFLAGS="-I$_AX_BOOST_BASE_boost_path/include" + for _AX_BOOST_BASE_boost_path_tmp in $multiarch_libsubdir $libsubdirs; do + AC_MSG_CHECKING([for boostlib >= $1 ($WANT_BOOST_VERSION) lib path in "$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp"]) + AS_IF([test -d "$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp" && test -r "$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp" ],[ + AC_MSG_RESULT([yes]) + BOOST_LDFLAGS="-L$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp"; + break; + ], + [AC_MSG_RESULT([no])]) + done],[ + AC_MSG_RESULT([no])]) + ],[ + if test X"$cross_compiling" = Xyes; then + search_libsubdirs=$multiarch_libsubdir + else + search_libsubdirs="$multiarch_libsubdir $libsubdirs" + fi + for _AX_BOOST_BASE_boost_path_tmp in /usr /usr/local /opt /opt/local ; 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 done - BOOST_LDFLAGS="-L$ac_boost_path_tmp/$libsubdir" - BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include" + BOOST_LDFLAGS="-L$_AX_BOOST_BASE_boost_path_tmp/$libsubdir" + BOOST_CPPFLAGS="-I$_AX_BOOST_BASE_boost_path_tmp/include" break; fi done - fi + ]) dnl overwrite ld flags if we have required special directory with dnl --with-boost-libdir parameter - if test "$ac_boost_lib_path" != ""; then - BOOST_LDFLAGS="-L$ac_boost_lib_path" - fi + AS_IF([test "x$_AX_BOOST_BASE_boost_lib_path" != "x"], + [BOOST_LDFLAGS="-L$_AX_BOOST_BASE_boost_lib_path"]) + AC_MSG_CHECKING([for boostlib >= $1 ($WANT_BOOST_VERSION)]) CPPFLAGS_SAVED="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" export CPPFLAGS @@ -135,15 +177,7 @@ if test "x$want_boost" = "xyes"; then AC_REQUIRE([AC_PROG_CXX]) AC_LANG_PUSH(C++) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - @%:@include - ]], [[ - #if BOOST_VERSION >= $WANT_BOOST_VERSION - // Everything is okay - #else - # error Boost version is too old - #endif - ]])],[ + AC_COMPILE_IFELSE([_AX_BOOST_BASE_PROGRAM($WANT_BOOST_VERSION)],[ AC_MSG_RESULT(yes) succeeded=yes found_system=yes @@ -155,30 +189,50 @@ if test "x$want_boost" = "xyes"; then dnl if we found no boost with system layout we search for boost libraries dnl built and installed without the --layout=system option or for a staged(not installed) version - if test "x$succeeded" != "xyes"; then + if test "x$succeeded" != "xyes" ; then + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + BOOST_CPPFLAGS= + if test -z "$_AX_BOOST_BASE_boost_lib_path" ; then + BOOST_LDFLAGS= + fi _version=0 - if test "$ac_boost_path" != ""; then - if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then - for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do - _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` + if test -n "$_AX_BOOST_BASE_boost_path" ; then + 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/_/./'` V_CHECK=`expr $_version_tmp \> $_version` - if test "$V_CHECK" = "1" ; then + if test "x$V_CHECK" = "x1" ; then _version=$_version_tmp fi VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` - BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE" + BOOST_CPPFLAGS="-I$_AX_BOOST_BASE_boost_path/include/boost-$VERSION_UNDERSCORE" done + dnl if nothing found search for layout used in Windows distributions + if test -z "$BOOST_CPPFLAGS"; then + if test -d "$_AX_BOOST_BASE_boost_path/boost" && test -r "$_AX_BOOST_BASE_boost_path/boost"; then + BOOST_CPPFLAGS="-I$_AX_BOOST_BASE_boost_path" + fi + fi + dnl if we found something and BOOST_LDFLAGS was unset before + dnl (because "$_AX_BOOST_BASE_boost_lib_path" = ""), set it here. + if test -n "$BOOST_CPPFLAGS" && test -z "$BOOST_LDFLAGS"; then + for libsubdir in $libsubdirs ; do + if ls "$_AX_BOOST_BASE_boost_path/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi + done + BOOST_LDFLAGS="-L$_AX_BOOST_BASE_boost_path/$libsubdir" + fi fi else - if test "$cross_compiling" != yes; then - for ac_boost_path in /usr /usr/local /opt /opt/local ; do - if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then - for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do - _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` + if test "x$cross_compiling" != "xyes" ; then + for _AX_BOOST_BASE_boost_path in /usr /usr/local /opt /opt/local ; 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/_/./'` V_CHECK=`expr $_version_tmp \> $_version` - if test "$V_CHECK" = "1" ; then + if test "x$V_CHECK" = "x1" ; then _version=$_version_tmp - best_path=$ac_boost_path + best_path=$_AX_BOOST_BASE_boost_path fi done fi @@ -186,7 +240,7 @@ if test "x$want_boost" = "xyes"; then VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE" - if test "$ac_boost_lib_path" = ""; then + if test -z "$_AX_BOOST_BASE_boost_lib_path" ; then for libsubdir in $libsubdirs ; do if ls "$best_path/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi done @@ -194,7 +248,7 @@ if test "x$want_boost" = "xyes"; then fi fi - if test "x$BOOST_ROOT" != "x"; then + if test -n "$BOOST_ROOT" ; then for libsubdir in $libsubdirs ; do if ls "$BOOST_ROOT/stage/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi done @@ -203,7 +257,7 @@ if test "x$want_boost" = "xyes"; then stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'` stage_version_shorten=`expr $stage_version : '\([[0-9]]*\.[[0-9]]*\)'` V_CHECK=`expr $stage_version_shorten \>\= $_version` - if test "$V_CHECK" = "1" -a "$ac_boost_lib_path" = "" ; then + if test "x$V_CHECK" = "x1" && test -z "$_AX_BOOST_BASE_boost_lib_path" ; then AC_MSG_NOTICE(We will use a staged boost library from $BOOST_ROOT) BOOST_CPPFLAGS="-I$BOOST_ROOT" BOOST_LDFLAGS="-L$BOOST_ROOT/stage/$libsubdir" @@ -218,15 +272,7 @@ if test "x$want_boost" = "xyes"; then export LDFLAGS AC_LANG_PUSH(C++) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - @%:@include - ]], [[ - #if BOOST_VERSION >= $WANT_BOOST_VERSION - // Everything is okay - #else - # error Boost version is too old - #endif - ]])],[ + AC_COMPILE_IFELSE([_AX_BOOST_BASE_PROGRAM($WANT_BOOST_VERSION)],[ AC_MSG_RESULT(yes) succeeded=yes found_system=yes @@ -235,17 +281,15 @@ if test "x$want_boost" = "xyes"; then AC_LANG_POP([C++]) fi - if test "$succeeded" != "yes" ; then - if test "$_version" = "0" ; then - AC_MSG_NOTICE([[We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in . See http://randspringer.de/boost for more documentation.]]) + if test "x$succeeded" != "xyes" ; then + if test "x$_version" = "x0" ; then + AC_MSG_NOTICE([[We could not detect the boost libraries (version $1 or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in . See http://randspringer.de/boost for more documentation.]]) else AC_MSG_NOTICE([Your boost libraries seems to old (version $_version).]) fi # execute ACTION-IF-NOT-FOUND (if present): ifelse([$3], , :, [$3]) else - AC_SUBST(BOOST_CPPFLAGS) - AC_SUBST(BOOST_LDFLAGS) AC_DEFINE(HAVE_BOOST,,[define if the Boost library is available]) # execute ACTION-IF-FOUND (if present): ifelse([$2], , :, [$2]) @@ -253,6 +297,5 @@ if test "x$want_boost" = "xyes"; then CPPFLAGS="$CPPFLAGS_SAVED" LDFLAGS="$LDFLAGS_SAVED" -fi ]) diff --git a/m4/ax_boost_system.m4 b/m4/ax_boost_system.m4 new file mode 100644 index 0000000..207d7be --- /dev/null +++ b/m4/ax_boost_system.m4 @@ -0,0 +1,121 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_boost_system.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_BOOST_SYSTEM +# +# DESCRIPTION +# +# Test for System library from the Boost C++ libraries. The macro requires +# a preceding call to AX_BOOST_BASE. Further documentation is available at +# . +# +# This macro calls: +# +# AC_SUBST(BOOST_SYSTEM_LIB) +# +# And sets: +# +# HAVE_BOOST_SYSTEM +# +# LICENSE +# +# Copyright (c) 2008 Thomas Porschberg +# Copyright (c) 2008 Michael Tindal +# Copyright (c) 2008 Daniel Casimiro +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 19 + +AC_DEFUN([AX_BOOST_SYSTEM], +[ + AC_ARG_WITH([boost-system], + AS_HELP_STRING([--with-boost-system@<:@=special-lib@:>@], + [use the System library from boost - it is possible to specify a certain library for the linker + e.g. --with-boost-system=boost_system-gcc-mt ]), + [ + if test "$withval" = "no"; then + want_boost="no" + elif test "$withval" = "yes"; then + want_boost="yes" + ax_boost_user_system_lib="" + else + want_boost="yes" + ax_boost_user_system_lib="$withval" + fi + ], + [want_boost="yes"] + ) + + if test "x$want_boost" = "xyes"; then + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_BUILD]) + CPPFLAGS_SAVED="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + + LDFLAGS_SAVED="$LDFLAGS" + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + + AC_CACHE_CHECK(whether the Boost::System library is available, + ax_cv_boost_system, + [AC_LANG_PUSH([C++]) + CXXFLAGS_SAVE=$CXXFLAGS + CXXFLAGS= + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], + [[boost::system::error_category *a = 0;]])], + ax_cv_boost_system=yes, ax_cv_boost_system=no) + CXXFLAGS=$CXXFLAGS_SAVE + AC_LANG_POP([C++]) + ]) + if test "x$ax_cv_boost_system" = "xyes"; then + AC_SUBST(BOOST_CPPFLAGS) + + AC_DEFINE(HAVE_BOOST_SYSTEM,,[define if the Boost::System library is available]) + BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` + + LDFLAGS_SAVE=$LDFLAGS + if test "x$ax_boost_user_system_lib" = "x"; then + for libextension in `ls -r $BOOSTLIBDIR/libboost_system* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'` ; do + ax_lib=${libextension} + AC_CHECK_LIB($ax_lib, exit, + [BOOST_SYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_SYSTEM_LIB) link_system="yes"; break], + [link_system="no"]) + done + if test "x$link_system" != "xyes"; then + for libextension in `ls -r $BOOSTLIBDIR/boost_system* 2>/dev/null | sed 's,.*/,,' | sed -e 's,\..*,,'` ; do + ax_lib=${libextension} + AC_CHECK_LIB($ax_lib, exit, + [BOOST_SYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_SYSTEM_LIB) link_system="yes"; break], + [link_system="no"]) + done + fi + + else + for ax_lib in $ax_boost_user_system_lib boost_system-$ax_boost_user_system_lib; do + AC_CHECK_LIB($ax_lib, exit, + [BOOST_SYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_SYSTEM_LIB) link_system="yes"; break], + [link_system="no"]) + done + + fi + if test "x$ax_lib" = "x"; then + AC_MSG_ERROR(Could not find a version of the library!) + fi + if test "x$link_system" = "xno"; then + AC_MSG_ERROR(Could not link against $ax_lib !) + fi + fi + + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + fi +]) diff --git a/m4/ax_boost_thread.m4 b/m4/ax_boost_thread.m4 new file mode 100644 index 0000000..87f03e3 --- /dev/null +++ b/m4/ax_boost_thread.m4 @@ -0,0 +1,163 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_boost_thread.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_BOOST_THREAD +# +# DESCRIPTION +# +# Test for Thread library from the Boost C++ libraries. The macro requires +# a preceding call to AX_BOOST_BASE. Further documentation is available at +# . +# +# This macro calls: +# +# AC_SUBST(BOOST_THREAD_LIB) +# +# And sets: +# +# HAVE_BOOST_THREAD +# +# LICENSE +# +# Copyright (c) 2009 Thomas Porschberg +# Copyright (c) 2009 Michael Tindal +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 30 + +AC_DEFUN([AX_BOOST_THREAD], +[ + AC_ARG_WITH([boost-thread], + AS_HELP_STRING([--with-boost-thread@<:@=special-lib@:>@], + [use the Thread library from boost - + it is possible to specify a certain library for the linker + e.g. --with-boost-thread=boost_thread-gcc-mt ]), + [ + if test "$withval" = "yes"; then + want_boost="yes" + ax_boost_user_thread_lib="" + else + want_boost="yes" + ax_boost_user_thread_lib="$withval" + fi + ], + [want_boost="yes"] + ) + + if test "x$want_boost" = "xyes"; then + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_BUILD]) + CPPFLAGS_SAVED="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + + LDFLAGS_SAVED="$LDFLAGS" + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + + AC_CACHE_CHECK(whether the Boost::Thread library is available, + ax_cv_boost_thread, + [AC_LANG_PUSH([C++]) + CXXFLAGS_SAVE=$CXXFLAGS + + if test "x$host_os" = "xsolaris" ; then + CXXFLAGS="-pthreads $CXXFLAGS" + elif test "x$host_os" = "xmingw32" ; then + CXXFLAGS="-mthreads $CXXFLAGS" + else + CXXFLAGS="-pthread $CXXFLAGS" + fi + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM( + [[@%:@include ]], + [[boost::thread_group thrds; + return 0;]])], + ax_cv_boost_thread=yes, ax_cv_boost_thread=no) + CXXFLAGS=$CXXFLAGS_SAVE + AC_LANG_POP([C++]) + ]) + if test "x$ax_cv_boost_thread" = "xyes"; then + if test "x$host_os" = "xsolaris" ; then + BOOST_CPPFLAGS="-pthreads $BOOST_CPPFLAGS" + elif test "x$host_os" = "xmingw32" ; then + BOOST_CPPFLAGS="-mthreads $BOOST_CPPFLAGS" + else + BOOST_CPPFLAGS="-pthread $BOOST_CPPFLAGS" + fi + + AC_SUBST(BOOST_CPPFLAGS) + + AC_DEFINE(HAVE_BOOST_THREAD,, + [define if the Boost::Thread library is available]) + BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` + + LDFLAGS_SAVE=$LDFLAGS + case "x$host_os" in + *bsd* ) + LDFLAGS="-pthread $LDFLAGS" + break; + ;; + esac + if test "x$ax_boost_user_thread_lib" = "x"; then + for libextension in `ls -r $BOOSTLIBDIR/libboost_thread* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'`; do + ax_lib=${libextension} + AC_CHECK_LIB($ax_lib, exit, + [link_thread="yes"; break], + [link_thread="no"]) + done + if test "x$link_thread" != "xyes"; then + for libextension in `ls -r $BOOSTLIBDIR/boost_thread* 2>/dev/null | sed 's,.*/,,' | sed 's,\..*,,'`; do + ax_lib=${libextension} + AC_CHECK_LIB($ax_lib, exit, + [link_thread="yes"; break], + [link_thread="no"]) + done + fi + + else + for ax_lib in $ax_boost_user_thread_lib boost_thread-$ax_boost_user_thread_lib; do + AC_CHECK_LIB($ax_lib, exit, + [link_thread="yes"; break], + [link_thread="no"]) + done + + fi + if test "x$ax_lib" = "x"; then + AC_MSG_ERROR(Could not find a version of the library!) + fi + if test "x$link_thread" = "xno"; then + AC_MSG_ERROR(Could not link against $ax_lib !) + else + BOOST_THREAD_LIB="-l$ax_lib" + case "x$host_os" in + *bsd* ) + BOOST_LDFLAGS="-pthread $BOOST_LDFLAGS" + break; + ;; + solaris ) + BOOST_THREAD_LIB="$BOOST_THREAD_LIB -lpthread" + break; + ;; + mingw32 ) + break; + ;; + * ) + BOOST_THREAD_LIB="$BOOST_THREAD_LIB -lpthread" + break; + ;; + esac + AC_SUBST(BOOST_THREAD_LIB) + fi + fi + + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + fi +]) -- cgit v1.2.3 From 1087a7f4ad8bb1bc9bf4472bf2734b0e4929e7d1 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 11 Dec 2017 15:07:18 +0100 Subject: Remove references to malloc.h and use posix_memalign --- configure.ac | 3 +-- src/Buffer.cpp | 12 ++++-------- src/DabMod.cpp | 7 ------- src/Flowgraph.cpp | 6 ------ src/FormatConverter.cpp | 1 - src/FrequencyInterleaver.cpp | 8 ++++++-- src/Resampler.cpp | 7 +++++-- 7 files changed, 16 insertions(+), 28 deletions(-) diff --git a/configure.ac b/configure.ac index 23369c9..d260f9e 100644 --- a/configure.ac +++ b/configure.ac @@ -154,8 +154,7 @@ AS_IF([test "x$enable_debug" != "xno"], )]) # Checks for header files. -AC_CHECK_HEADERS([fcntl.h limits.h malloc.h memory.h netinet/in.h stdint.h stdlib.h string.h sys/time.h sys/timeb.h unistd.h]) -AC_CHECK_DECLS([_mm_malloc], [], [], [#include ]) +AC_CHECK_HEADERS([fcntl.h limits.h memory.h netinet/in.h stdint.h stdlib.h string.h sys/time.h sys/timeb.h unistd.h]) AC_HEADER_STDC # Checks for typedefs, structures, and compiler characteristics. diff --git a/src/Buffer.cpp b/src/Buffer.cpp index 8631c42..6b14561 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -30,13 +30,6 @@ #include #include -#include -#if HAVE_DECL__MM_MALLOC -# include -#else -# define memalign(a, b) malloc(b) -#endif - Buffer::Buffer(size_t len, const void *data) @@ -92,7 +85,10 @@ void Buffer::setLength(size_t len) void *tmp = data; /* Align to 32-byte boundary for AVX. */ - data = memalign(32, len); + const int ret = posix_memalign(&data, 32, len); + if (ret != 0) { + throw std::runtime_error("memory allocation failed: " + std::to_string(ret)); + } if (tmp != NULL) { memcpy(data, tmp, this->len); diff --git a/src/DabMod.cpp b/src/DabMod.cpp index af3adde..1625a82 100644 --- a/src/DabMod.cpp +++ b/src/DabMod.cpp @@ -64,13 +64,6 @@ # include #endif -#if HAVE_DECL__MM_MALLOC -# include -#else -# define memalign(a, b) malloc(b) -#endif - - /* UHD requires the input I and Q samples to be in the interval * [-1.0,1.0], otherwise they get truncated, which creates very * wide-spectrum spikes. Depending on the Transmission Mode, the diff --git a/src/Flowgraph.cpp b/src/Flowgraph.cpp index 6ee7b81..4870534 100644 --- a/src/Flowgraph.cpp +++ b/src/Flowgraph.cpp @@ -29,12 +29,6 @@ #include #include #include - -#if HAVE_DECL__MM_MALLOC -# include -#else -# define memalign(a, b) malloc(b) -#endif #include #include #include diff --git a/src/FormatConverter.cpp b/src/FormatConverter.cpp index 6826972..60c0545 100644 --- a/src/FormatConverter.cpp +++ b/src/FormatConverter.cpp @@ -29,7 +29,6 @@ #include "FormatConverter.h" #include "PcDebug.h" -#include #include #include #include diff --git a/src/FrequencyInterleaver.cpp b/src/FrequencyInterleaver.cpp index 29d54bb..bd5042c 100644 --- a/src/FrequencyInterleaver.cpp +++ b/src/FrequencyInterleaver.cpp @@ -24,7 +24,7 @@ #include #include -#include +#include #include typedef std::complex complexf; @@ -68,7 +68,11 @@ FrequencyInterleaver::FrequencyInterleaver(size_t mode) : break; } - d_indexes = (size_t*)memalign(16, d_carriers * sizeof(size_t)); + const int ret = posix_memalign((void**)(&d_indexes), 16, d_carriers * sizeof(size_t)); + if (ret != 0) { + throw std::runtime_error("memory allocation failed: " + std::to_string(ret)); + } + size_t* index = d_indexes; size_t perm = 0; PDEBUG("i: %4u, R: %4u\n", 0, 0); diff --git a/src/Resampler.cpp b/src/Resampler.cpp index 8069a61..2be753e 100644 --- a/src/Resampler.cpp +++ b/src/Resampler.cpp @@ -27,7 +27,7 @@ #include "Resampler.h" #include "PcDebug.h" -#include +#include #include #include #include @@ -81,7 +81,10 @@ Resampler::Resampler(size_t inputRate, size_t outputRate, size_t resolution) : myFactor = 1.0f / myFftSizeOut * outputRate / inputRate; } - myWindow = (float*)memalign(16, myFftSizeIn * sizeof(float)); + const int ret = posix_memalign((void**)(&myWindow), 16, myFftSizeIn * sizeof(float)); + if (ret != 0) { + throw std::runtime_error("memory allocation failed: " + std::to_string(ret)); + } for (size_t i = 0; i < myFftSizeIn; ++i) { myWindow[i] = (float)(0.5 * (1.0 - cos(2.0 * M_PI * i / (myFftSizeIn - 1)))); PDEBUG("Window[%zu] = %f\n", i, myWindow[i]); -- cgit v1.2.3 From 2376bde57d44194e59b85b20411e52307b43ec2e Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 11 Dec 2017 15:12:56 +0100 Subject: Only check librt if UHD enabled --- configure.ac | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index d260f9e..47e1c81 100644 --- a/configure.ac +++ b/configure.ac @@ -128,8 +128,9 @@ AC_SUBST([LIBS], ["$FFTW_LIBS $SOAPYSDR_LIBS $PTHREAD_LIBS $ZMQ_LIBS"]) # Checks for UHD. AS_IF([test "x$enable_output_uhd" = "xyes"], - [AC_CHECK_LIB([uhd], [main], [], - [AC_MSG_ERROR([library uhd is missing])] )]) + [ AC_CHECK_LIB([uhd], [main], [], [AC_MSG_ERROR([library uhd is missing])]) + AC_CHECK_LIB([rt], [clock_gettime], [], [AC_MSG_ERROR([library rt is missing])]) + ]) AS_IF([test "x$enable_output_uhd" = "xyes"], [AC_DEFINE(HAVE_OUTPUT_UHD, [1], [Define if UHD output is enabled])]) @@ -141,8 +142,6 @@ AX_BOOST_BASE([1.54.0], [], AC_MSG_ERROR([BOOST 1.54 or later is required])) AX_BOOST_SYSTEM AX_BOOST_THREAD -AC_CHECK_LIB([rt], [clock_gettime], [], [AC_MSG_ERROR([library rt is missing])]) - # Tests for different memory allocation debuggers. # Valgrind doesn't need any. AS_IF([test "x$enable_debug" != "xno"], -- cgit v1.2.3 From fa003e1facb2ec5d45a28f27a0e293701c673ec6 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 11 Dec 2017 15:23:21 +0100 Subject: Replace legacy bzero() by memset() --- src/NullSymbol.cpp | 2 +- src/OfdmGenerator.cpp | 2 +- src/TII.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/NullSymbol.cpp b/src/NullSymbol.cpp index 015e564..4684dfe 100644 --- a/src/NullSymbol.cpp +++ b/src/NullSymbol.cpp @@ -53,7 +53,7 @@ int NullSymbol::process(Buffer* dataOut) PDEBUG("NullSymbol::process(dataOut: %p)\n", dataOut); dataOut->setLength(myNbCarriers * 2 * sizeof(float)); - bzero(dataOut->getData(), dataOut->getLength()); + memset(dataOut->getData(), 0, dataOut->getLength()); return dataOut->getLength(); } diff --git a/src/OfdmGenerator.cpp b/src/OfdmGenerator.cpp index bac3db0..a6609a3 100644 --- a/src/OfdmGenerator.cpp +++ b/src/OfdmGenerator.cpp @@ -190,7 +190,7 @@ int OfdmGenerator::process(Buffer* const dataIn, Buffer* dataOut) myFftIn[0][0] = 0; myFftIn[0][1] = 0; - bzero(&myFftIn[myZeroDst], myZeroSize * sizeof(FFT_TYPE)); + memset(&myFftIn[myZeroDst], 0, myZeroSize * sizeof(FFT_TYPE)); memcpy(&myFftIn[myPosDst], &in[myPosSrc], myPosSize * sizeof(FFT_TYPE)); memcpy(&myFftIn[myNegDst], &in[myNegSrc], diff --git a/src/TII.cpp b/src/TII.cpp index 4710ed4..a30d7f6 100644 --- a/src/TII.cpp +++ b/src/TII.cpp @@ -190,7 +190,7 @@ int TII::process(Buffer* dataIn, Buffer* dataOut) } dataOut->setLength(m_carriers * sizeof(complexf)); - bzero(dataOut->getData(), dataOut->getLength()); + memset(dataOut->getData(), 0, dataOut->getLength()); if (m_conf.enable and m_insert) { boost::mutex::scoped_lock lock(m_enabled_carriers_mutex); -- cgit v1.2.3 From b2c5c74b7954279e8cc15790e168a1d4283b4e63 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 11 Dec 2017 15:25:05 +0100 Subject: Simplify porting.{h,c} --- configure.ac | 2 +- src/porting.c | 13 ------------- src/porting.h | 20 +------------------- 3 files changed, 2 insertions(+), 33 deletions(-) diff --git a/configure.ac b/configure.ac index 47e1c81..3a55d7b 100644 --- a/configure.ac +++ b/configure.ac @@ -192,7 +192,7 @@ AS_IF([test "x$enable_native" = "xyes"], ]) AC_TYPE_SIGNAL -AC_CHECK_FUNCS([bzero floor ftime gettimeofday memset sqrt strchr strerror strtol]) +AC_CHECK_FUNCS([floor memset sqrt strchr strerror strtol]) AC_CONFIG_FILES([Makefile]) AC_OUTPUT diff --git a/src/porting.c b/src/porting.c index 79523e5..f7421b0 100644 --- a/src/porting.c +++ b/src/porting.c @@ -21,19 +21,6 @@ #include "porting.h" - -#ifndef HAVE_GETTIMEOFDAY -#include -int gettimeofday(struct timeval* t, void* timezone) -{ - struct timeb timebuffer; - ftime(&timebuffer); - t->tv_sec=timebuffer.time; - t->tv_usec=1000*timebuffer.millitm; - return 0; -} -#endif - #ifdef _WIN32 unsigned int _CRT_fmode = _O_BINARY; #endif diff --git a/src/porting.h b/src/porting.h index 2ac9b90..1799ba7 100644 --- a/src/porting.h +++ b/src/porting.h @@ -19,25 +19,12 @@ along with ODR-DabMod. If not, see . */ -#ifndef PORTING_H -#define PORTING_H +#pragma once #ifdef HAVE_CONFIG_H # include #endif -#ifndef HAVE_BZERO -# define bzero(s, n) memset(s, 0, n) -#endif - -#ifndef HAVE_GETTIMEOFDAY -#include -#ifdef __cplusplus -extern "C" -#endif -int gettimeofday(struct timeval* t, void* timezone); -#endif - #ifdef _WIN32 #include // For setting default opening mode with fopen as binary, for all files @@ -45,8 +32,3 @@ int gettimeofday(struct timeval* t, void* timezone); extern unsigned int _CRT_fmode; #endif -#ifndef HAVE_KILL -# define kill(a, b) raise(b) -#endif - -#endif // PORTING_H -- cgit v1.2.3 From f0cd709e645a3d2210fce5daf80138696aac84e3 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 11 Dec 2017 15:28:33 +0100 Subject: Set the additional warning options to CXXFLAGS --- configure.ac | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 3a55d7b..4538da6 100644 --- a/configure.ac +++ b/configure.ac @@ -80,13 +80,13 @@ AC_ARG_ENABLE([output_uhd], [], [enable_output_uhd=yes]) AC_LANG_PUSH([C++]) -AX_CHECK_COMPILE_FLAG([-Wduplicated-cond], [CFLAGS="$CFLAGS -Wduplicated-cond"]) -AX_CHECK_COMPILE_FLAG([-Wduplicated-branches], [CFLAGS="$CFLAGS -Wduplicated-branches"]) -AX_CHECK_COMPILE_FLAG([-Wlogical-op], [CFLAGS="$CFLAGS -Wlogical-op"]) -AX_CHECK_COMPILE_FLAG([-Wrestrict], [CFLAGS="$CFLAGS -Wrestrict"]) -AX_CHECK_COMPILE_FLAG([-Wshadow], [CFLAGS="$CFLAGS -Wshadow"]) +AX_CHECK_COMPILE_FLAG([-Wduplicated-cond], [CXXFLAGS="$CXXFLAGS -Wduplicated-cond"]) +AX_CHECK_COMPILE_FLAG([-Wduplicated-branches], [CXXFLAGS="$CXXFLAGS -Wduplicated-branches"]) +AX_CHECK_COMPILE_FLAG([-Wlogical-op], [CXXFLAGS="$CXXFLAGS -Wlogical-op"]) +AX_CHECK_COMPILE_FLAG([-Wrestrict], [CXXFLAGS="$CXXFLAGS -Wrestrict"]) +AX_CHECK_COMPILE_FLAG([-Wshadow], [CXXFLAGS="$CXXFLAGS -Wshadow"]) AX_CHECK_COMPILE_FLAG([-Wdouble-promotion], [CXXFLAGS="$CXXFLAGS -Wdouble-promotion"]) -AX_CHECK_COMPILE_FLAG(["-Wformat=2"], [CFLAGS="$CFLAGS -Wformat=2"]) +AX_CHECK_COMPILE_FLAG(["-Wformat=2"], [CXXFLAGS="$CXXFLAGS -Wformat=2"]) AC_LANG_POP([C++]) -- cgit v1.2.3 From fdbea05b16e3c716b5226a1f0d45cc98561500e4 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 11 Dec 2017 15:56:55 +0100 Subject: Fix all the warnings shown since previous commit --- src/Buffer.cpp | 43 ++++++++++++++++++++++--------------------- src/Buffer.h | 10 +++++----- src/ConvEncoder.cpp | 1 + src/DabMod.cpp | 5 +++-- src/FIRFilter.cpp | 3 --- src/FicSource.cpp | 1 + src/Flowgraph.cpp | 1 + src/FrameMultiplexer.cpp | 1 + src/FrequencyInterleaver.cpp | 1 + src/GainControl.cpp | 12 ++++++------ src/GainControl.h | 2 +- src/MemlessPoly.cpp | 5 +---- src/OfdmGenerator.cpp | 12 ++++++------ src/OutputUHD.cpp | 10 +++++----- src/OutputUHD.h | 2 +- src/PrbsGenerator.cpp | 7 ++++--- src/PuncturingEncoder.cpp | 1 + src/RemoteControl.cpp | 18 +++++++++--------- src/Resampler.cpp | 3 ++- src/Socket.h | 1 + src/SubchannelSource.cpp | 1 + src/TII.cpp | 6 +++--- src/TimeInterleaver.cpp | 1 + src/TimestampDecoder.cpp | 6 +++--- 24 files changed, 80 insertions(+), 73 deletions(-) diff --git a/src/Buffer.cpp b/src/Buffer.cpp index 6b14561..9df834a 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -28,17 +28,17 @@ #include "Buffer.h" #include "PcDebug.h" +#include #include #include - Buffer::Buffer(size_t len, const void *data) { PDEBUG("Buffer::Buffer(%zu, %p)\n", len, data); - this->len = 0; - this->size = 0; - this->data = NULL; + m_len = 0; + m_size = 0; + m_data = NULL; setData(data, len); } @@ -46,23 +46,23 @@ Buffer::Buffer(const std::vector &vec) { PDEBUG("Buffer::Buffer(vector [%zu])\n", vec.size()); - this->len = 0; - this->size = 0; - this->data = NULL; + m_len = 0; + m_size = 0; + m_data = NULL; setData(vec.data(), vec.size()); } Buffer::~Buffer() { - PDEBUG("Buffer::~Buffer() len=%zu, data=%p\n", len, data); - free(data); + PDEBUG("Buffer::~Buffer() len=%zu, data=%p\n", m_len, m_data); + free(m_data); } Buffer &Buffer::operator=(const Buffer ©) { - setData(copy.data, copy.len); + setData(copy.m_data, copy.m_len); return *this; } @@ -74,29 +74,30 @@ Buffer &Buffer::operator=(const std::vector ©) Buffer &Buffer::operator+=(const Buffer ©) { - appendData(copy.data, copy.len); + appendData(copy.m_data, copy.m_len); return *this; } void Buffer::setLength(size_t len) { - if (len > size) { - void *tmp = data; + if (len > m_size) { + void *tmp = m_data; /* Align to 32-byte boundary for AVX. */ - const int ret = posix_memalign(&data, 32, len); + const int ret = posix_memalign(&m_data, 32, len); if (ret != 0) { - throw std::runtime_error("memory allocation failed: " + std::to_string(ret)); + throw std::runtime_error("memory allocation failed: " + + std::to_string(ret)); } if (tmp != NULL) { - memcpy(data, tmp, this->len); + memcpy(m_data, tmp, m_len); free(tmp); } - size = len; + m_size = len; } - this->len = len; + m_len = len; } @@ -109,10 +110,10 @@ void Buffer::setData(const void *data, size_t len) void Buffer::appendData(const void *data, size_t len) { - size_t offset = this->len; - setLength(this->len + len); + size_t offset = m_len; + setLength(m_len + len); if (data != NULL) { - memcpy((char*)this->data + offset, data, len); + memcpy((char*)m_data + offset, data, len); } } diff --git a/src/Buffer.h b/src/Buffer.h index 8c5c768..60a7d50 100644 --- a/src/Buffer.h +++ b/src/Buffer.h @@ -43,15 +43,15 @@ class Buffer { protected: /* Current length of the data in the Buffer */ - size_t len; + size_t m_len; /* Allocated size of the Buffer */ - size_t size; + size_t m_size; /* Pointer to the data. Memory allocation is entirely * handled by setLength. */ - void *data; + void *m_data; public: using sptr = std::shared_ptr; @@ -77,7 +77,7 @@ class Buffer { void appendData(const void *data, size_t len); Buffer &operator+=(const Buffer ©); - size_t getLength() const { return len; } - void *getData() const { return data; } + size_t getLength() const { return m_len; } + void *getData() const { return m_data; } }; diff --git a/src/ConvEncoder.cpp b/src/ConvEncoder.cpp index 06b2e85..074898f 100644 --- a/src/ConvEncoder.cpp +++ b/src/ConvEncoder.cpp @@ -25,6 +25,7 @@ #include #include #include +#include const static uint8_t PARITY[] = { diff --git a/src/DabMod.cpp b/src/DabMod.cpp index 1625a82..0ac7d4f 100644 --- a/src/DabMod.cpp +++ b/src/DabMod.cpp @@ -445,7 +445,7 @@ int launch_modulator(int argc, char* argv[]) } } #if defined(HAVE_ZEROMQ) - else if (auto in = dynamic_pointer_cast(inputReader)) { + else if (dynamic_pointer_cast(inputReader)) { run_again = true; // Create a new input reader auto inputZeroMQReader = make_shared(); @@ -453,7 +453,8 @@ int launch_modulator(int argc, char* argv[]) inputReader = inputZeroMQReader; } #endif - else if (auto in = dynamic_pointer_cast(inputReader)) { + else if (dynamic_pointer_cast(inputReader)) { + // Create a new input reader auto inputTcpReader = make_shared(); inputTcpReader->Open(mod_settings.inputName); inputReader = inputTcpReader; diff --git a/src/FIRFilter.cpp b/src/FIRFilter.cpp index 4296822..1450b1e 100644 --- a/src/FIRFilter.cpp +++ b/src/FIRFilter.cpp @@ -306,9 +306,6 @@ int FIRFilter::internal_process(Buffer* const dataIn, Buffer* dataOut) void FIRFilter::set_parameter(const string& parameter, const string& value) { - stringstream ss(value); - ss.exceptions ( stringstream::failbit | stringstream::badbit ); - if (parameter == "ntaps") { throw ParameterError("Parameter 'ntaps' is read-only"); } diff --git a/src/FicSource.cpp b/src/FicSource.cpp index 92932ec..04197db 100644 --- a/src/FicSource.cpp +++ b/src/FicSource.cpp @@ -28,6 +28,7 @@ #include "PcDebug.h" #include +#include #include #include #include diff --git a/src/Flowgraph.cpp b/src/Flowgraph.cpp index 4870534..465ef41 100644 --- a/src/Flowgraph.cpp +++ b/src/Flowgraph.cpp @@ -26,6 +26,7 @@ #include "Flowgraph.h" #include "PcDebug.h" +#include #include #include #include diff --git a/src/FrameMultiplexer.cpp b/src/FrameMultiplexer.cpp index 1cfaadd..4cee0b2 100644 --- a/src/FrameMultiplexer.cpp +++ b/src/FrameMultiplexer.cpp @@ -28,6 +28,7 @@ #include "PcDebug.h" #include +#include #include #include #include diff --git a/src/FrequencyInterleaver.cpp b/src/FrequencyInterleaver.cpp index bd5042c..e76d525 100644 --- a/src/FrequencyInterleaver.cpp +++ b/src/FrequencyInterleaver.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include diff --git a/src/GainControl.cpp b/src/GainControl.cpp index 2a91b12..f44aa68 100644 --- a/src/GainControl.cpp +++ b/src/GainControl.cpp @@ -46,7 +46,7 @@ using namespace std; static float var_variance; GainControl::GainControl(size_t framesize, - GainMode mode, + GainMode gainMode, float digGain, float normalise, float varVariance) : @@ -60,10 +60,10 @@ GainControl::GainControl(size_t framesize, m_digGain(digGain), m_normalise(normalise), m_var_variance_rc(varVariance), - m_gainmode(mode), + m_gainmode(gainMode), m_mutex() { - PDEBUG("GainControl::GainControl(%zu, %zu) @ %p\n", framesize, (size_t)mode, this); + PDEBUG("GainControl::GainControl(%zu, %zu) @ %p\n", framesize, (size_t)m_gainMode, this); /* register the parameters that can be remote controlled */ RC_ADD_PARAMETER(digital, "Digital Gain"); @@ -532,10 +532,10 @@ void GainControl::set_parameter(const string& parameter, const string& value) } } else { - stringstream ss; - ss << "Parameter '" << parameter + stringstream ss_err; + ss_err << "Parameter '" << parameter << "' is not exported by controllable " << get_rc_name(); - throw ParameterError(ss.str()); + throw ParameterError(ss_err.str()); } } diff --git a/src/GainControl.h b/src/GainControl.h index 44c9fa9..e9eaa8c 100644 --- a/src/GainControl.h +++ b/src/GainControl.h @@ -51,7 +51,7 @@ class GainControl : public PipelinedModCodec, public RemoteControllable { public: GainControl(size_t framesize, - GainMode mode, + GainMode gainMode, float digGain, float normalise, float varVariance); diff --git a/src/MemlessPoly.cpp b/src/MemlessPoly.cpp index f223d34..ae097c9 100644 --- a/src/MemlessPoly.cpp +++ b/src/MemlessPoly.cpp @@ -38,7 +38,7 @@ #include #include - +#include #include #include #include @@ -370,9 +370,6 @@ int MemlessPoly::internal_process(Buffer* const dataIn, Buffer* dataOut) void MemlessPoly::set_parameter(const string& parameter, const string& value) { - stringstream ss(value); - ss.exceptions ( stringstream::failbit | stringstream::badbit ); - if (parameter == "ncoefs") { throw ParameterError("Parameter 'ncoefs' is read-only"); } diff --git a/src/OfdmGenerator.cpp b/src/OfdmGenerator.cpp index a6609a3..915d568 100644 --- a/src/OfdmGenerator.cpp +++ b/src/OfdmGenerator.cpp @@ -230,9 +230,9 @@ int OfdmGenerator::process(Buffer* const dataIn, Buffer* dataOut) */ double sum_iq = 0; double sum_delta = 0; - for (size_t i = 0; i < mySpacing; i++) { - sum_iq += (double)std::norm(before_cfr[i]); - sum_delta += (double)std::norm(symbol[i] - before_cfr[i]); + for (size_t j = 0; j < mySpacing; j++) { + sum_iq += (double)std::norm(before_cfr[j]); + sum_delta += (double)std::norm(symbol[j] - before_cfr[j]); } // Clamp to 90dB, otherwise the MER average is going to be inf @@ -362,10 +362,10 @@ void OfdmGenerator::set_parameter(const std::string& parameter, throw ParameterError("Parameter 'clip_stats' is read-only"); } else { - stringstream ss; - ss << "Parameter '" << parameter + stringstream ss_err; + ss_err << "Parameter '" << parameter << "' is not exported by controllable " << get_rc_name(); - throw ParameterError(ss.str()); + throw ParameterError(ss_err.str()); } } diff --git a/src/OutputUHD.cpp b/src/OutputUHD.cpp index e2616a6..b533075 100644 --- a/src/OutputUHD.cpp +++ b/src/OutputUHD.cpp @@ -472,7 +472,7 @@ int OutputUHD::process(Buffer* dataIn) myUsrp, myConf.dpdFeedbackServerPort, myConf.sampleRate); } - size_t num_frames = frames.push_wait_if_full(frame, + size_t num_frames = m_frames.push_wait_if_full(frame, FRAMES_MAX_SIZE); etiLog.log(trace, "UHD,push %zu", num_frames); } @@ -686,7 +686,7 @@ void OutputUHD::workerthread() struct UHDWorkerFrameData frame; etiLog.log(trace, "UHD,wait"); - frames.wait_and_pop(frame, pop_prebuffering); + m_frames.wait_and_pop(frame, pop_prebuffering); etiLog.log(trace, "UHD,pop"); handle_frame(&frame); @@ -989,10 +989,10 @@ void OutputUHD::set_parameter(const string& parameter, const string& value) throw ParameterError("Parameter " + parameter + " is read-only."); } else { - stringstream ss; - ss << "Parameter '" << parameter + stringstream ss_err; + ss_err << "Parameter '" << parameter << "' is not exported by controllable " << get_rc_name(); - throw ParameterError(ss.str()); + throw ParameterError(ss_err.str()); } } diff --git a/src/OutputUHD.h b/src/OutputUHD.h index 0630480..9213183 100644 --- a/src/OutputUHD.h +++ b/src/OutputUHD.h @@ -211,7 +211,7 @@ class OutputUHD: public ModOutput, public RemoteControllable { bool sync_and_ts_valid = false; - ThreadsafeQueue frames; + ThreadsafeQueue m_frames; // Returns true if we want to verify loss of refclk bool refclk_loss_needs_check(void) const; diff --git a/src/PrbsGenerator.cpp b/src/PrbsGenerator.cpp index 69d6af4..b159bd3 100644 --- a/src/PrbsGenerator.cpp +++ b/src/PrbsGenerator.cpp @@ -22,9 +22,10 @@ #include "PrbsGenerator.h" #include "PcDebug.h" +#include +#include #include #include -#include PrbsGenerator::PrbsGenerator(size_t framesize, uint32_t polynomial, @@ -178,8 +179,8 @@ int PrbsGenerator::process( throw std::runtime_error("PrbsGenerator::process " "input size is not equal to output size!\n"); } - for (size_t i = 0; i < dataOut[0]->getLength(); ++i) { - out[i] ^= in[i]; + for (size_t j = 0; j < dataOut[0]->getLength(); ++j) { + out[j] ^= in[j]; } } diff --git a/src/PuncturingEncoder.cpp b/src/PuncturingEncoder.cpp index 9bd9004..de4319b 100644 --- a/src/PuncturingEncoder.cpp +++ b/src/PuncturingEncoder.cpp @@ -27,6 +27,7 @@ #include "PuncturingEncoder.h" #include "PcDebug.h" +#include #include #include #include diff --git a/src/RemoteControl.cpp b/src/RemoteControl.cpp index ceae942..a050278 100644 --- a/src/RemoteControl.cpp +++ b/src/RemoteControl.cpp @@ -422,11 +422,11 @@ void RemoteControllerZmq::process() std::string msg_s = ss.str(); - zmq::message_t msg(ss.str().size()); - memcpy ((void*) msg.data(), msg_s.data(), msg_s.size()); + zmq::message_t zmsg(ss.str().size()); + memcpy ((void*) zmsg.data(), msg_s.data(), msg_s.size()); int flag = (--cohort_size > 0) ? ZMQ_SNDMORE : 0; - repSocket.send(msg, flag); + repSocket.send(zmsg, flag); } } else if (msg.size() == 2 && command == "show") { @@ -437,11 +437,11 @@ void RemoteControllerZmq::process() for (auto ¶m_val : r) { std::stringstream ss; ss << param_val[0] << ": " << param_val[1] << endl; - zmq::message_t msg(ss.str().size()); - memcpy(msg.data(), ss.str().data(), ss.str().size()); + zmq::message_t zmsg(ss.str().size()); + memcpy(zmsg.data(), ss.str().data(), ss.str().size()); int flag = (--r_size > 0) ? ZMQ_SNDMORE : 0; - repSocket.send(msg, flag); + repSocket.send(zmsg, flag); } } catch (ParameterError &e) { @@ -454,9 +454,9 @@ void RemoteControllerZmq::process() try { std::string value = rcs.get_param(module, parameter); - zmq::message_t msg(value.size()); - memcpy ((void*) msg.data(), value.data(), value.size()); - repSocket.send(msg, 0); + zmq::message_t zmsg(value.size()); + memcpy ((void*) zmsg.data(), value.data(), value.size()); + repSocket.send(zmsg, 0); } catch (ParameterError &err) { send_fail_reply(repSocket, err.what()); diff --git a/src/Resampler.cpp b/src/Resampler.cpp index 2be753e..42951c5 100644 --- a/src/Resampler.cpp +++ b/src/Resampler.cpp @@ -27,10 +27,11 @@ #include "Resampler.h" #include "PcDebug.h" +#include +#include #include #include #include -#include #include #define FFT_REAL(x) x[0] diff --git a/src/Socket.h b/src/Socket.h index f6a023d..39554ca 100644 --- a/src/Socket.h +++ b/src/Socket.h @@ -37,6 +37,7 @@ DESCRIPTION: #include #include #include +#include #include #include #include diff --git a/src/SubchannelSource.cpp b/src/SubchannelSource.cpp index 2a8dc37..b4d6750 100644 --- a/src/SubchannelSource.cpp +++ b/src/SubchannelSource.cpp @@ -28,6 +28,7 @@ #include "PcDebug.h" #include "Log.h" +#include #include #include #include diff --git a/src/TII.cpp b/src/TII.cpp index a30d7f6..af64c9f 100644 --- a/src/TII.cpp +++ b/src/TII.cpp @@ -350,10 +350,10 @@ void TII::set_parameter(const std::string& parameter, const std::string& value) ss >> m_conf.old_variant; } else { - stringstream ss; - ss << "Parameter '" << parameter << + stringstream ss_err; + ss_err << "Parameter '" << parameter << "' is not exported by controllable " << get_rc_name(); - throw ParameterError(ss.str()); + throw ParameterError(ss_err.str()); } } diff --git a/src/TimeInterleaver.cpp b/src/TimeInterleaver.cpp index 3bf6339..7e19af8 100644 --- a/src/TimeInterleaver.cpp +++ b/src/TimeInterleaver.cpp @@ -23,6 +23,7 @@ #include "PcDebug.h" #include +#include #include diff --git a/src/TimestampDecoder.cpp b/src/TimestampDecoder.cpp index ddd3fb7..26deb60 100644 --- a/src/TimestampDecoder.cpp +++ b/src/TimestampDecoder.cpp @@ -228,10 +228,10 @@ void TimestampDecoder::set_parameter( throw ParameterError("timestamp is read-only"); } else { - stringstream ss; - ss << "Parameter '" << parameter + stringstream ss_err; + ss_err << "Parameter '" << parameter << "' is not exported by controllable " << get_rc_name(); - throw ParameterError(ss.str()); + throw ParameterError(ss_err.str()); } } -- cgit v1.2.3 From 477782190324caf69445f59e2a9ce02152c06106 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 15 Dec 2017 10:06:48 +0100 Subject: Make warning check work for clang --- configure.ac | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index 4538da6..9bb0ebc 100644 --- a/configure.ac +++ b/configure.ac @@ -80,13 +80,13 @@ AC_ARG_ENABLE([output_uhd], [], [enable_output_uhd=yes]) AC_LANG_PUSH([C++]) -AX_CHECK_COMPILE_FLAG([-Wduplicated-cond], [CXXFLAGS="$CXXFLAGS -Wduplicated-cond"]) -AX_CHECK_COMPILE_FLAG([-Wduplicated-branches], [CXXFLAGS="$CXXFLAGS -Wduplicated-branches"]) -AX_CHECK_COMPILE_FLAG([-Wlogical-op], [CXXFLAGS="$CXXFLAGS -Wlogical-op"]) -AX_CHECK_COMPILE_FLAG([-Wrestrict], [CXXFLAGS="$CXXFLAGS -Wrestrict"]) -AX_CHECK_COMPILE_FLAG([-Wshadow], [CXXFLAGS="$CXXFLAGS -Wshadow"]) -AX_CHECK_COMPILE_FLAG([-Wdouble-promotion], [CXXFLAGS="$CXXFLAGS -Wdouble-promotion"]) -AX_CHECK_COMPILE_FLAG(["-Wformat=2"], [CXXFLAGS="$CXXFLAGS -Wformat=2"]) +AX_CHECK_COMPILE_FLAG([-Wduplicated-cond], [CXXFLAGS="$CXXFLAGS -Wduplicated-cond"], [], ["-Werror"]) +AX_CHECK_COMPILE_FLAG([-Wduplicated-branches], [CXXFLAGS="$CXXFLAGS -Wduplicated-branches"], [], ["-Werror"]) +AX_CHECK_COMPILE_FLAG([-Wlogical-op], [CXXFLAGS="$CXXFLAGS -Wlogical-op"], [], ["-Werror"]) +AX_CHECK_COMPILE_FLAG([-Wrestrict], [CXXFLAGS="$CXXFLAGS -Wrestrict"], [], ["-Werror"]) +AX_CHECK_COMPILE_FLAG([-Wshadow], [CXXFLAGS="$CXXFLAGS -Wshadow"], [], ["-Werror"]) +AX_CHECK_COMPILE_FLAG([-Wdouble-promotion], [CXXFLAGS="$CXXFLAGS -Wdouble-promotion"], [], ["-Werror"]) +AX_CHECK_COMPILE_FLAG(["-Wformat=2"], [CXXFLAGS="$CXXFLAGS -Wformat=2"], [], ["-Werror"]) AC_LANG_POP([C++]) -- cgit v1.2.3 From f041360ac17bc032c7e5a4553372893e42ba68c6 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 15 Dec 2017 10:07:03 +0100 Subject: Check for prctl portability --- configure.ac | 11 +++++++++++ src/Utils.cpp | 6 +++++- src/Utils.h | 1 + 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 9bb0ebc..261d444 100644 --- a/configure.ac +++ b/configure.ac @@ -173,6 +173,17 @@ AC_COMPILE_IFELSE( [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no]) AC_DEFINE([M_PIl], [M_PI], [Replacing define])]) AC_LANG_POP([C++]) +# Linux has prctl to set thread names +AC_MSG_CHECKING(for prctl and PR_SET_NAME) +AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([[ + #include + void set_thread_name() { + prctl(PR_SET_NAME,"test",0,0,0); + } + ]])], + [ AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_PRCTL, 1, [Define this symbol if you have prctl and PR_SET_NAME]) ], + [ AC_MSG_RESULT(no) ]) # Check for march AS_IF([test "x$enable_native" = "xyes"], diff --git a/src/Utils.cpp b/src/Utils.cpp index cd116c7..f423dc1 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -27,7 +27,9 @@ #include "Utils.h" #include "GainControl.h" -#include +#if defined(HAVE_PRCTL) +# include +#endif #include static void printHeader() @@ -160,7 +162,9 @@ int set_realtime_prio(int prio) void set_thread_name(const char *name) { +#if defined(HAVE_PRCTL) prctl(PR_SET_NAME,name,0,0,0); +#endif } double parseChannel(const std::string& chan) diff --git a/src/Utils.h b/src/Utils.h index 8da3a1b..6a36baf 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -62,6 +62,7 @@ inline long timespecdiff_us(struct timespec& oldTime, struct timespec& time) // Set SCHED_RR with priority prio (0=lowest) int set_realtime_prio(int prio); +// Set the name of the thread void set_thread_name(const char *name); // Convert a channel like 10A to a frequency -- cgit v1.2.3 From 81fefc486ceb864a8eaf05e5f78587f3fb351bfe Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 15 Dec 2017 10:13:40 +0100 Subject: Add Travis-CI build matrix and build on OSX --- .travis.yml | 89 +++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 60 insertions(+), 29 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2bd4ad6..35a8365 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,36 +1,67 @@ language: c++ -sudo: required -dist: trusty - -addons: &addons - apt: - sources: &sources - - ubuntu-toolchain-r-test - packages: &packages - - libzmq3-dev - - libzmq3 - - automake - - libtool - - libboost1.55-all-dev - - libcurl4-openssl-dev - - libfftw3-dev - # libuhd-dev is not allowed - - g++-6 - -compiler: - - gcc + +matrix: + include: + # Clang on OSX + - env: CC=clang CXX=clang++ CONF= + os: osx + osx_image: xcode9.1 + compiler: clang + + # GCC and clang builds on Linux + - env: CC=gcc-6 CXX=g++-6 CONF=--disable-zeromq --disable-output-uhd + os: linux + dist: trusty + sudo: required + compiler: gcc + addons: &linuxaddons + apt: + sources: &sources + - ubuntu-toolchain-r-test + packages: &packages + - libzmq3-dev + - libzmq3 + - automake + - libtool + - libboost1.55-all-dev + - libcurl4-openssl-dev + - libfftw3-dev + # libuhd-dev is not allowed + - g++-6 + + - env: CC=gcc-6 CXX=g++-6 CONF=--disable-output-uhd --enable-output-raw + compiler: gcc + addons: *linuxaddons + + - env: CC=gcc-6 CXX=g++-6 CONF=--disable-output-uhd --disable-native + compiler: gcc + addons: *linuxaddons + + - env: CC=clang-4.0 CXX=clang++-4.0 CONF=--disable-output-uhd + compiler: clang + addons: &linuxclang40 + apt: + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-trusty-4.0 + packages: + - libzmq3-dev + - libzmq3 + - automake + - libtool + - libboost1.55-all-dev + - libcurl4-openssl-dev + - libfftw3-dev + # libuhd-dev is not allowed + - clang-4.0 + +before_install: + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install fftw boost zeromq automake curl uhd ; fi script: - | ./bootstrap.sh - CC=gcc-6 CXX=g++-6 ./configure --disable-zeromq --disable-output-uhd - make - - | - ./bootstrap.sh - CC=gcc-6 CXX=g++-6 ./configure --disable-output-uhd - make - - | - ./bootstrap.sh - CC=gcc-6 CXX=g++-6 ./configure --disable-output-uhd --disable-native + ./configure $CONF make -- cgit v1.2.3 From 91c9ed812f77f5691d96f76c67eadd28557aeb6c Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 15 Dec 2017 10:30:41 +0100 Subject: Set CC and CXX in Travis CI matrix properly --- .travis.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 35a8365..11cb48b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,13 +3,13 @@ language: c++ matrix: include: # Clang on OSX - - env: CC=clang CXX=clang++ CONF= + - env: MATRIX_EVAL="CC=clang CXX=clang++" CONF= os: osx osx_image: xcode9.1 compiler: clang # GCC and clang builds on Linux - - env: CC=gcc-6 CXX=g++-6 CONF=--disable-zeromq --disable-output-uhd + - env: MATRIX_EVAL="CC=gcc-6 CXX=g++-6" CONF=--disable-zeromq --disable-output-uhd os: linux dist: trusty sudo: required @@ -29,21 +29,20 @@ matrix: # libuhd-dev is not allowed - g++-6 - - env: CC=gcc-6 CXX=g++-6 CONF=--disable-output-uhd --enable-output-raw + - env: MATRIX_EVAL="CC=gcc-6 CXX=g++-6" CONF=--disable-output-uhd --enable-output-raw compiler: gcc addons: *linuxaddons - - env: CC=gcc-6 CXX=g++-6 CONF=--disable-output-uhd --disable-native + - env: MATRIX_EVAL="CC=gcc-6 CXX=g++-6" CONF=--disable-output-uhd --disable-native compiler: gcc addons: *linuxaddons - - env: CC=clang-4.0 CXX=clang++-4.0 CONF=--disable-output-uhd + - env: MATRIX_EVAL="CC=clang-5.0 CXX=clang++-5.0" CONF=--disable-output-uhd compiler: clang - addons: &linuxclang40 + addons: &linuxclang50 apt: sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-trusty-4.0 + - llvm-toolchain-trusty-5.0 packages: - libzmq3-dev - libzmq3 @@ -53,9 +52,10 @@ matrix: - libcurl4-openssl-dev - libfftw3-dev # libuhd-dev is not allowed - - clang-4.0 + - clang-5.0 before_install: + - eval "${MATRIX_EVAL}" - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install fftw boost zeromq automake curl uhd ; fi -- cgit v1.2.3 From 3b8aa8e2296b722b1f35121268d12a253902e160 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 15 Dec 2017 10:40:47 +0100 Subject: Properly set Travis flags --- .travis.yml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 11cb48b..7e36ee8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,13 +3,15 @@ language: c++ matrix: include: # Clang on OSX - - env: MATRIX_EVAL="CC=clang CXX=clang++" CONF= + # Sadly, OutputUHD still needs clock_gettime() even if UHD is available + # in homebrew + - env: MATRIX_EVAL="" CONF="--disable-output-uhd" os: osx osx_image: xcode9.1 compiler: clang # GCC and clang builds on Linux - - env: MATRIX_EVAL="CC=gcc-6 CXX=g++-6" CONF=--disable-zeromq --disable-output-uhd + - env: MATRIX_EVAL="CC=gcc-6 CXX=g++-6" CONF="--disable-zeromq --disable-output-uhd" os: linux dist: trusty sudo: required @@ -29,15 +31,16 @@ matrix: # libuhd-dev is not allowed - g++-6 - - env: MATRIX_EVAL="CC=gcc-6 CXX=g++-6" CONF=--disable-output-uhd --enable-output-raw + - env: MATRIX_EVAL="CC=gcc-6 CXX=g++-6" CONF="--disable-output-uhd --enable-output-raw" compiler: gcc addons: *linuxaddons - - env: MATRIX_EVAL="CC=gcc-6 CXX=g++-6" CONF=--disable-output-uhd --disable-native + - env: MATRIX_EVAL="CC=gcc-6 CXX=g++-6" CONF="--disable-output-uhd --disable-native" compiler: gcc addons: *linuxaddons - - env: MATRIX_EVAL="CC=clang-5.0 CXX=clang++-5.0" CONF=--disable-output-uhd + # Travis sets CC and CXX accordingly + - env: MATRIX_EVAL="" CONF="--disable-output-uhd" compiler: clang addons: &linuxclang50 apt: @@ -57,7 +60,7 @@ matrix: before_install: - eval "${MATRIX_EVAL}" - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install fftw boost zeromq automake curl uhd ; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install fftw boost zeromq automake curl; fi script: - | -- cgit v1.2.3 From 8468aed6e76237b0d10db48a6b53343b8794644b Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 15 Dec 2017 10:55:08 +0100 Subject: Switch travis back to clang 4 --- .travis.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7e36ee8..31be35e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,10 +42,11 @@ matrix: # Travis sets CC and CXX accordingly - env: MATRIX_EVAL="" CONF="--disable-output-uhd" compiler: clang - addons: &linuxclang50 + addons: &linuxclang40 apt: sources: - - llvm-toolchain-trusty-5.0 + - ubuntu-toolchain-r-test + - llvm-toolchain-trusty-4.0 packages: - libzmq3-dev - libzmq3 @@ -55,7 +56,7 @@ matrix: - libcurl4-openssl-dev - libfftw3-dev # libuhd-dev is not allowed - - clang-5.0 + - clang-4.0 before_install: - eval "${MATRIX_EVAL}" -- cgit v1.2.3 From ff5d43af8f76bb59a057fb277ee3703948796ccb Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 18 Dec 2017 08:44:13 +0100 Subject: Travis: don't build with clang on linux Apparently there's something wrong with the libc++ combined with boost. I'm afraid I don't care enough to fix this. --- .travis.yml | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/.travis.yml b/.travis.yml index 31be35e..8e55706 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,25 +39,6 @@ matrix: compiler: gcc addons: *linuxaddons - # Travis sets CC and CXX accordingly - - env: MATRIX_EVAL="" CONF="--disable-output-uhd" - compiler: clang - addons: &linuxclang40 - apt: - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-trusty-4.0 - packages: - - libzmq3-dev - - libzmq3 - - automake - - libtool - - libboost1.55-all-dev - - libcurl4-openssl-dev - - libfftw3-dev - # libuhd-dev is not allowed - - clang-4.0 - before_install: - eval "${MATRIX_EVAL}" - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi -- cgit v1.2.3 From 0e15b3df559a17c352c5135a786caac2d7c2111f Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 18 Dec 2017 08:45:53 +0100 Subject: Remove unused variable myCurrentFrame --- src/EtiReader.cpp | 1 - src/EtiReader.h | 1 - 2 files changed, 2 deletions(-) diff --git a/src/EtiReader.cpp b/src/EtiReader.cpp index 0b27126..5f2be50 100644 --- a/src/EtiReader.cpp +++ b/src/EtiReader.cpp @@ -58,7 +58,6 @@ EtiReader::EtiReader( unsigned tist_delay_stages) : state(EtiReaderStateSync), myTimestampDecoder(tist_offset_s, tist_delay_stages), - myCurrentFrame(0), eti_fc_valid(false) { rcs.enrol(&myTimestampDecoder); diff --git a/src/EtiReader.h b/src/EtiReader.h index 892afb4..f3a9764 100644 --- a/src/EtiReader.h +++ b/src/EtiReader.h @@ -107,7 +107,6 @@ private: eti_TIST eti_tist; TimestampDecoder myTimestampDecoder; - size_t myCurrentFrame; bool eti_fc_valid; std::vector > mySources; -- cgit v1.2.3 From 5ef2067ee1750cf32f12c05ee397106602f49390 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 18 Dec 2017 08:50:31 +0100 Subject: Remove unused variable d_polarity_mask --- src/PrbsGenerator.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/PrbsGenerator.h b/src/PrbsGenerator.h index b86bc70..9390179 100644 --- a/src/PrbsGenerator.h +++ b/src/PrbsGenerator.h @@ -53,8 +53,6 @@ private: unsigned char d_weight[256]; // PRBS polynomial generator uint32_t d_polynomial; - // PRBS generator polarity mask - unsigned char d_polarity_mask; // PRBS accumulator uint32_t d_accum; uint32_t d_accum_init; -- cgit v1.2.3 From f944de133002211ed4e2654ce0521f96a0ce057a Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 18 Dec 2017 08:54:45 +0100 Subject: Use ::bind in UdpSocket That should help for the OSX Travis build --- lib/UdpSocket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/UdpSocket.cpp b/lib/UdpSocket.cpp index 570da5f..e711577 100644 --- a/lib/UdpSocket.cpp +++ b/lib/UdpSocket.cpp @@ -88,7 +88,7 @@ int UdpSocket::reinit(int port, const std::string& name) address.setAddress(name); address.setPort(port); - if (bind(listenSocket, address.getAddress(), sizeof(sockaddr_in)) == SOCKET_ERROR) { + if (::bind(listenSocket, address.getAddress(), sizeof(sockaddr_in)) == SOCKET_ERROR) { setInetError("Can't bind socket"); ::close(listenSocket); listenSocket = INVALID_SOCKET; -- cgit v1.2.3 From e6ea4d1a11f0ecda6f007a39930302688511632e Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 18 Dec 2017 09:15:02 +0100 Subject: Travis OSX: sometimes brew works, sometimes brew fails... --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8e55706..6722ebe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,7 +42,7 @@ matrix: before_install: - eval "${MATRIX_EVAL}" - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install fftw boost zeromq automake curl; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then (brew install fftw boost zeromq automake || true); fi script: - | -- cgit v1.2.3 From 0cceefe1774263690dce352cf41c3fff3bf85135 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Thu, 21 Dec 2017 04:24:24 +0100 Subject: Simplify GuardIntervalInserter slightly --- src/GuardIntervalInserter.cpp | 26 +++++--------------------- src/GuardIntervalInserter.h | 18 ++++++++---------- 2 files changed, 13 insertions(+), 31 deletions(-) diff --git a/src/GuardIntervalInserter.cpp b/src/GuardIntervalInserter.cpp index 80ba900..a2542f7 100644 --- a/src/GuardIntervalInserter.cpp +++ b/src/GuardIntervalInserter.cpp @@ -21,16 +21,12 @@ #include "GuardIntervalInserter.h" #include "PcDebug.h" - - -#include #include #include #include typedef std::complex complexf; - GuardIntervalInserter::GuardIntervalInserter(size_t nbSymbols, size_t spacing, size_t nullSize, @@ -43,19 +39,6 @@ GuardIntervalInserter::GuardIntervalInserter(size_t nbSymbols, { PDEBUG("GuardIntervalInserter::GuardIntervalInserter(%zu, %zu, %zu, %zu)" " @ %p\n", nbSymbols, spacing, nullSize, symSize, this); - - if (d_nullSize) { - myHasNull = true; - } else { - myHasNull = false; - } -} - - -GuardIntervalInserter::~GuardIntervalInserter() -{ - PDEBUG("GuardIntervalInserter::~GuardIntervalInserter() @ %p\n", this); - } @@ -71,7 +54,7 @@ int GuardIntervalInserter::process(Buffer* const dataIn, Buffer* dataOut) complexf* out = reinterpret_cast(dataOut->getData()); size_t sizeIn = dataIn->getLength() / sizeof(complexf); - if (sizeIn != (d_nbSymbols + (myHasNull ? 1 : 0)) * d_spacing) { + if (sizeIn != (d_nbSymbols + (d_nullSize ? 1 : 0)) * d_spacing) { PDEBUG("Nb symbols: %zu\n", d_nbSymbols); PDEBUG("Spacing: %zu\n", d_spacing); PDEBUG("Null size: %zu\n", d_nullSize); @@ -81,8 +64,8 @@ int GuardIntervalInserter::process(Buffer* const dataIn, Buffer* dataOut) "GuardIntervalInserter::process input size not valid!"); } - // Null symbol - if (myHasNull) { + // Handle Null symbol separately because it is longer + if (d_nullSize) { // end - (nullSize - spacing) = 2 * spacing - nullSize memcpy(out, &in[2 * d_spacing - d_nullSize], (d_nullSize - d_spacing) * sizeof(complexf)); @@ -90,9 +73,10 @@ int GuardIntervalInserter::process(Buffer* const dataIn, Buffer* dataOut) in += d_spacing; out += d_nullSize; } + // Data symbols for (size_t i = 0; i < d_nbSymbols; ++i) { - // end - (nullSize - spacing) = 2 * spacing - nullSize + // end - (symSize - spacing) = 2 * spacing - symSize memcpy(out, &in[2 * d_spacing - d_symSize], (d_symSize - d_spacing) * sizeof(complexf)); memcpy(&out[d_symSize - d_spacing], in, d_spacing * sizeof(complexf)); diff --git a/src/GuardIntervalInserter.h b/src/GuardIntervalInserter.h index 70a8fcd..e6b3b64 100644 --- a/src/GuardIntervalInserter.h +++ b/src/GuardIntervalInserter.h @@ -25,20 +25,19 @@ # include #endif - #include "ModPlugin.h" +#include -#include - - +/* The GuardIntervalInserter prepends the cyclic prefix to all + * symbols in the transmission frame. */ class GuardIntervalInserter : public ModCodec { public: - GuardIntervalInserter(size_t nbSymbols, size_t spacing, size_t nullSize, size_t symSize); - virtual ~GuardIntervalInserter(); - GuardIntervalInserter(const GuardIntervalInserter&); - GuardIntervalInserter& operator=(const GuardIntervalInserter&); - + GuardIntervalInserter( + size_t nbSymbols, + size_t spacing, + size_t nullSize, + size_t symSize); int process(Buffer* const dataIn, Buffer* dataOut); const char* name() { return "GuardIntervalInserter"; } @@ -48,6 +47,5 @@ protected: size_t d_spacing; size_t d_nullSize; size_t d_symSize; - bool myHasNull; }; -- cgit v1.2.3 From 7da0cf21faf31888f8412a61ae4a12abe01a827f Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Thu, 21 Dec 2017 07:59:30 +0100 Subject: Make Buffer movable --- src/Buffer.cpp | 51 +++++++++++++++++++++++++++++++++++++++++---------- src/Buffer.h | 42 ++++++++++++++++++++++-------------------- 2 files changed, 63 insertions(+), 30 deletions(-) diff --git a/src/Buffer.cpp b/src/Buffer.cpp index 9df834a..3f6f296 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -3,7 +3,7 @@ Her Majesty the Queen in Right of Canada (Communications Research Center Canada) - Copyright (C) 2016 + Copyright (C) 2017 Matthias P. Braendli, matthias.braendli@mpb.li http://opendigitalradio.org @@ -37,18 +37,34 @@ Buffer::Buffer(size_t len, const void *data) PDEBUG("Buffer::Buffer(%zu, %p)\n", len, data); m_len = 0; - m_size = 0; - m_data = NULL; + m_capacity = 0; + m_data = nullptr; setData(data, len); } +Buffer::Buffer(const Buffer& other) +{ + setData(other.m_data, other.m_len); +} + +Buffer::Buffer(Buffer&& other) +{ + m_len = other.m_len; + m_capacity = other.m_capacity; + m_data = other.m_data; + + other.m_len = 0; + other.m_capacity = 0; + other.m_data = nullptr; +} + Buffer::Buffer(const std::vector &vec) { PDEBUG("Buffer::Buffer(vector [%zu])\n", vec.size()); m_len = 0; - m_size = 0; - m_data = NULL; + m_capacity = 0; + m_data = nullptr; setData(vec.data(), vec.size()); } @@ -56,7 +72,9 @@ Buffer::Buffer(const std::vector &vec) Buffer::~Buffer() { PDEBUG("Buffer::~Buffer() len=%zu, data=%p\n", m_len, m_data); - free(m_data); + if (m_data) { + free(m_data); + } } @@ -66,6 +84,19 @@ Buffer &Buffer::operator=(const Buffer ©) return *this; } +Buffer& Buffer::operator=(Buffer&& other) +{ + m_len = other.m_len; + m_capacity = other.m_capacity; + m_data = other.m_data; + + other.m_len = 0; + other.m_capacity = 0; + other.m_data = nullptr; + + return *this; +} + Buffer &Buffer::operator=(const std::vector ©) { setData(copy.data(), copy.size()); @@ -81,7 +112,7 @@ Buffer &Buffer::operator+=(const Buffer ©) void Buffer::setLength(size_t len) { - if (len > m_size) { + if (len > m_capacity) { void *tmp = m_data; /* Align to 32-byte boundary for AVX. */ @@ -91,11 +122,11 @@ void Buffer::setLength(size_t len) std::to_string(ret)); } - if (tmp != NULL) { + if (tmp != nullptr) { memcpy(m_data, tmp, m_len); free(tmp); } - m_size = len; + m_capacity = len; } m_len = len; } @@ -112,7 +143,7 @@ void Buffer::appendData(const void *data, size_t len) { size_t offset = m_len; setLength(m_len + len); - if (data != NULL) { + if (data != nullptr) { memcpy((char*)m_data + offset, data, len); } } diff --git a/src/Buffer.h b/src/Buffer.h index 60a7d50..88bd442 100644 --- a/src/Buffer.h +++ b/src/Buffer.h @@ -3,7 +3,7 @@ Her Majesty the Queen in Right of Canada (Communications Research Center Canada) - Copyright (C) 2016 + Copyright (C) 2017 Matthias P. Braendli, matthias.braendli@mpb.li http://opendigitalradio.org @@ -41,24 +41,13 @@ * The allocation/freeing of the data is handled internally. */ class Buffer { - protected: - /* Current length of the data in the Buffer */ - size_t m_len; - - /* Allocated size of the Buffer */ - size_t m_size; - - /* Pointer to the data. Memory allocation is entirely - * handled by setLength. - */ - void *m_data; - public: using sptr = std::shared_ptr; - Buffer(const Buffer& copy) = default; - Buffer(const std::vector &vec); - Buffer(size_t len = 0, const void *data = NULL); + Buffer(size_t len = 0, const void *data = nullptr); + Buffer(const Buffer& copy); + Buffer(Buffer&& other); + Buffer(const std::vector& vec); ~Buffer(); /* Resize the buffer, reallocate memory if needed */ @@ -68,16 +57,29 @@ class Buffer { * Reallocates memory if needed. */ void setData(const void *data, size_t len); - Buffer &operator=(const Buffer ©); - Buffer &operator=(const std::vector ©); + Buffer& operator=(const Buffer& copy); + Buffer& operator=(Buffer&& other); + Buffer& operator=(const std::vector& copy); /* Concatenate the current data with the new data given. * Reallocates memory if needed. */ void appendData(const void *data, size_t len); - Buffer &operator+=(const Buffer ©); + Buffer& operator+=(const Buffer& copy); size_t getLength() const { return m_len; } - void *getData() const { return m_data; } + void* getData() const { return m_data; } + + private: + /* Current length of the data in the Buffer */ + size_t m_len; + + /* Allocated size of the Buffer */ + size_t m_capacity; + + /* Pointer to the data. Memory allocation is entirely + * handled by setLength. */ + void *m_data; + }; -- cgit v1.2.3 From 5e45beb6a385a6830aa1e3efa1093d7d0eb88ab8 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Thu, 21 Dec 2017 08:00:10 +0100 Subject: Improve Buffer initialisation in EtiReader --- src/EtiReader.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/EtiReader.cpp b/src/EtiReader.cpp index 5f2be50..d84ed1f 100644 --- a/src/EtiReader.cpp +++ b/src/EtiReader.cpp @@ -207,8 +207,8 @@ int EtiReader::loadEtiData(const Buffer& dataIn) if (input_size < 128) { return dataIn.getLength() - input_size; } - PDEBUG("Writting 128 bytes of FIC channel data\n"); - Buffer fic = Buffer(128, in); + PDEBUG("Writing 128 bytes of FIC channel data\n"); + Buffer fic(128, in); myFicSource->loadFicData(fic); input_size -= 128; framesize -= 128; @@ -217,8 +217,8 @@ int EtiReader::loadEtiData(const Buffer& dataIn) if (input_size < 96) { return dataIn.getLength() - input_size; } - PDEBUG("Writting 96 bytes of FIC channel data\n"); - Buffer fic = Buffer(96, in); + PDEBUG("Writing 96 bytes of FIC channel data\n"); + Buffer fic(96, in); myFicSource->loadFicData(fic); input_size -= 96; framesize -= 96; @@ -230,7 +230,7 @@ int EtiReader::loadEtiData(const Buffer& dataIn) for (size_t i = 0; i < eti_stc.size(); ++i) { unsigned size = mySources[i]->framesize(); PDEBUG("Writting %i bytes of subchannel data\n", size); - Buffer subch = Buffer(size, in); + Buffer subch(size, in); mySources[i]->loadSubchannelData(subch); input_size -= size; framesize -= size; -- cgit v1.2.3 From e9ce4438abefdc164b0c5040756196a2d6bf1bfd Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Thu, 21 Dec 2017 08:13:17 +0100 Subject: Better example.ini defaults --- doc/example.ini | 87 ++++++++++++++++++++++++++------------------------------- 1 file changed, 39 insertions(+), 48 deletions(-) diff --git a/doc/example.ini b/doc/example.ini index e0a1fc8..cf56720 100644 --- a/doc/example.ini +++ b/doc/example.ini @@ -10,15 +10,15 @@ telnetport=2121 ; Enable zmq remote control. ; The zmq remote control is intended for machine-to-machine -; integration and requires that ODR-DabMod is built with zmq support. -; The zmq remote control may run in parallel with Telnet. +; integration. It may run in parallel with Telnet. ; ; Protocol: ; ODR-DabMod binds a zmq rep socket so clients must connect ; using either req or dealer socket. ; [] denotes message part as zmq multi-part message are used for delimitation. ; All message parts are utf-8 encoded strings and match the Telnet command set. -; Explicit codes are denoted with "". +; Messages to be sent as literal strings are denoted with "" below. +; ; The following commands are supported: ; REQ: ["ping"] ; REP: ["ok"] @@ -34,7 +34,7 @@ telnetport=2121 ; ; REQ: ["set"][module name][parameter][value] ; REP: ["ok"] _OR_ ["fail"][error description] -zmqctrl=0 +zmqctrl=1 zmqctrlendpoint=tcp://127.0.0.1:9400 [log] @@ -53,6 +53,17 @@ source=/dev/stdin ; When the end of file is reached, it is possible to rewind it loop=0 +; ETI-over-TCP example: +;transport=tcp +;source=localhost:9200 + +; When recieving data using ZeroMQ, the source is the URI to be used +;transport=zeromq +;source=tcp://localhost:8080 +; The option max_frames_queued defines the maximum number of ETI frames +; that can be in the input queue +;max_frames_queued=100 + ; EDI input. ; Listen for EDI data on a given UDP port ;transport=edi @@ -63,16 +74,6 @@ loop=0 ; No support yet for multicast, should work with and without PFT ; This EDI implementation does not support EDI Packet Resend -; When recieving data using ZeroMQ, the source is the URI to be used -;transport=zeromq -;source=tcp://localhost:8080 -; The option max_frames_queued defines the maximum number of ETI frames -; that can be in the input queue -;max_frames_queued=100 - -; ETI-over-TCP example: -;transport=tcp -;source=localhost:9200 [modulator] ; Mode 'fix' uses a fixed factor and is really not recommended. It is more @@ -99,7 +100,7 @@ gainmode=var ; Transmission mode ; If not defined, take the mode from ETI -;mode=2 +;mode=1 ; The digital gain is a value that is multiplied to each sample. It is used ; to tune the chain to make sure that no non-linearities appear up to the @@ -116,11 +117,11 @@ digital_gain=0.8 ; is enabled or not ! rate=2048000 -; CIC equaliser for USRP1 and USRP2 +; (DEPRECATED) CIC equaliser for USRP1 and USRP2 ; Set to 0 to disable CicEqualiser ; when set to 400000000, an additional USRP2 check is enabled. ; See DabModulator.cpp line 186 -dac_clk_rate=0 +;dac_clk_rate=0 ; The USRP1 does not have flexible clocking, you will need ;rate=3200000 @@ -149,19 +150,9 @@ enabled=1 ;filtertapsfile=simple_taps.txt [poly] -;Predistortion using memoryless polynom -enabled=1 +;Predistortion using memoryless polynom, see dpd/ folder for more info +enabled=0 polycoeffile=polyCoefs -;eg: -;echo "8 -;0.1 -;0 -;0 -;0 -;0 -;0 -;0 -;0" > polyCoefs [output] ; choose output: possible values: uhd, file, zmq, soapysdr @@ -191,7 +182,7 @@ output=uhd ;format=s8 ; The output file: -filename=/dev/stdout +filename=ofdm.iq [uhdoutput] ; The UHD output can be directly used with the Ettus USRP devices @@ -201,30 +192,30 @@ filename=/dev/stdout ; master_clock_rate = 4 * sample_rate ; or even a higher factor. ; -; Settings for a USRP B100: +; Settings for the B200: device= -; you can put additional UHD device settings here master_clock_rate=32768000 -type=b100 -txgain=2.0 -; Try first with small gain values -; Also set rate to 2048000 - -; For the B200 -; More information and measurements available on: -; http://wiki.opendigitalradio.org/index.php/USRP_B200_Measurements -; -; Settings: -;device= -;master_clock_rate=32768000 -;type=b200 -;txgain=40 +type=b200 +txgain=40 ; The B200 needs larger gains (up to 89dB) but, ; "Gain settings are application specific, but it is recommended that users ; consider using at least half of the available gain to get reasonable dynamic ; range." ; From the B200 User Manual ; http://files.ettus.com/uhd_docs/manual/html/usrp_b200.html +; +; More information and measurements available on: +; http://wiki.opendigitalradio.org/index.php/USRP_B200_Measurements + + +; Settings for a USRP B100: +;device= +; you can put additional UHD device settings here +;master_clock_rate=32768000 +;type=b100 +;txgain=2.0 +; Try first with small gain values +; Also set rate to 2048000 ; For the USRP1 @@ -233,7 +224,7 @@ txgain=2.0 ; the usrp1 can have two daughterboards, the subdevice parameter allows you ; to choose which one to use ;subdevice=A:0 -; The USRP1 doesn't support master_clock_rate, you need to enable resamping +; The USRP1 doesn't support master_clock_rate, you need to enable resampling ; You must specify either frequency or channel, but not both. @@ -275,7 +266,7 @@ max_gps_holdover_time=600 ; Enable the TCP server to communicate TX and RX feedback for ; digital predistortion. ; Set to 0 to disable -dpd_port=50055 +;dpd_port=50055 ; section defining ZeroMQ output properties [zmqoutput] -- cgit v1.2.3 From 3255ff66dab0870c54c8f5c62b1c461b38abfe20 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 22 Dec 2017 09:07:13 +0100 Subject: Check for invalid file output format --- src/DabMod.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/DabMod.cpp b/src/DabMod.cpp index 0ac7d4f..dfefb53 100644 --- a/src/DabMod.cpp +++ b/src/DabMod.cpp @@ -199,6 +199,10 @@ static shared_ptr prepare_output( output = make_shared(s.outputName); } + else { + throw runtime_error("File output format " + s.fileOutputFormat + + " not known"); + } } #if defined(HAVE_OUTPUT_UHD) else if (s.useUHDOutput) { -- cgit v1.2.3 From 286fc43b7b837bcd3786d46df3f4de7c965a392b Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 22 Dec 2017 09:08:03 +0100 Subject: Add Travis build for --enable-trace configuration --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 6722ebe..e664812 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,6 +39,10 @@ matrix: compiler: gcc addons: *linuxaddons + - env: MATRIX_EVAL="CC=gcc-6 CXX=g++-6" CONF="--disable-output-uhd --enable-trace" + compiler: gcc + addons: *linuxaddons + before_install: - eval "${MATRIX_EVAL}" - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi -- cgit v1.2.3 From 45b180cd1a0ccbd12b5fb1baf82a9430e4567d2b Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 22 Dec 2017 09:08:42 +0100 Subject: Fix some PDEBUG calls --- src/DabModulator.cpp | 3 +-- src/FIRFilter.cpp | 2 +- src/GainControl.cpp | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/DabModulator.cpp b/src/DabModulator.cpp index 0914469..be140d3 100644 --- a/src/DabModulator.cpp +++ b/src/DabModulator.cpp @@ -62,8 +62,7 @@ DabModulator::DabModulator(EtiSource& etiSource, myEtiSource(etiSource), myFlowgraph() { - PDEBUG("DabModulator::DabModulator(%u, %u, %u, %zu) @ %p\n", - outputRate, clockRate, dabMode, (size_t)gainMode, this); + PDEBUG("DabModulator::DabModulator() @ %p\n", this); if (m_settings.dabMode == 0) { setMode(2); diff --git a/src/FIRFilter.cpp b/src/FIRFilter.cpp index 1450b1e..bc2314a 100644 --- a/src/FIRFilter.cpp +++ b/src/FIRFilter.cpp @@ -119,7 +119,7 @@ void FIRFilter::load_filter_taps(const std::string &tapsFile) int n; for (n = 0; n < n_taps; n++) { taps_fstream >> filter_taps[n]; - PDEBUG("FIRFilter: tap: %f\n", filter_taps[n] ); + PDEBUG("FIRFilter: tap: %f\n", (double)filter_taps[n] ); if (taps_fstream.eof()) { fprintf(stderr, "FIRFilter: file %s should contains %d taps, but EOF reached "\ "after %d taps !\n", tapsFile.c_str(), n_taps, n); diff --git a/src/GainControl.cpp b/src/GainControl.cpp index f44aa68..0411482 100644 --- a/src/GainControl.cpp +++ b/src/GainControl.cpp @@ -63,7 +63,7 @@ GainControl::GainControl(size_t framesize, m_gainmode(gainMode), m_mutex() { - PDEBUG("GainControl::GainControl(%zu, %zu) @ %p\n", framesize, (size_t)m_gainMode, this); + PDEBUG("GainControl::GainControl(%zu, %zu) @ %p\n", framesize, (size_t)m_gainmode, this); /* register the parameters that can be remote controlled */ RC_ADD_PARAMETER(digital, "Digital Gain"); -- cgit v1.2.3 From ce490c8c25bdbb1fc40fc43d8631a807f6effa6a Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 22 Dec 2017 09:10:17 +0100 Subject: Add OFDM windowing support to GuardIntervalInserter --- src/DabModulator.cpp | 1 + src/GuardIntervalInserter.cpp | 232 ++++++++++++++++++++++++++++++++++++++---- src/GuardIntervalInserter.h | 60 +++++++---- 3 files changed, 257 insertions(+), 36 deletions(-) diff --git a/src/DabModulator.cpp b/src/DabModulator.cpp index be140d3..cded280 100644 --- a/src/DabModulator.cpp +++ b/src/DabModulator.cpp @@ -202,6 +202,7 @@ int DabModulator::process(Buffer* dataOut) auto cifGuard = make_shared( myNbSymbols, mySpacing, myNullSize, mySymSize); + rcs.enrol(cifGuard.get()); shared_ptr cifFilter; if (not m_settings.filterTapsFilename.empty()) { diff --git a/src/GuardIntervalInserter.cpp b/src/GuardIntervalInserter.cpp index a2542f7..1381a3c 100644 --- a/src/GuardIntervalInserter.cpp +++ b/src/GuardIntervalInserter.cpp @@ -1,6 +1,11 @@ /* Copyright (C) 2005, 2206, 2007, 2008, 2009, 2010, 2011 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) + + Copyright (C) 2017 + Matthias P. Braendli, matthias.braendli@mpb.li + + http://opendigitalradio.org */ /* This file is part of ODR-DabMod. @@ -24,37 +29,98 @@ #include #include #include +#include typedef std::complex complexf; -GuardIntervalInserter::GuardIntervalInserter(size_t nbSymbols, +GuardIntervalInserter::GuardIntervalInserter( + size_t nbSymbols, size_t spacing, size_t nullSize, - size_t symSize) : + size_t symSize, + size_t windowOverlap) : ModCodec(), + RemoteControllable("guardinterval"), d_nbSymbols(nbSymbols), d_spacing(spacing), d_nullSize(nullSize), - d_symSize(symSize) + d_symSize(symSize), + d_windowOverlap(0) { - PDEBUG("GuardIntervalInserter::GuardIntervalInserter(%zu, %zu, %zu, %zu)" - " @ %p\n", nbSymbols, spacing, nullSize, symSize, this); + if (d_nullSize == 0) { + throw std::logic_error("NULL symbol must be present"); + } + + RC_ADD_PARAMETER(windowlen, "Window length for OFDM windowng [0 to disable]"); + + /* We use a raised-cosine window for the OFDM windowing. + * Each symbol is extended on both sides by d_windowOverlap samples. + * + * + * Sym n |####################| + * Sym n+1 |####################| + * + * We now extend the symbols by d_windowOverlap (one dash) + * + * Sym n extended -|####################|- + * Sym n+1 extended -|####################|- + * + * The windows are raised-cosine: + * ____________________ + * Sym n window / \ + * ... ____/ \___________ ... + * + * Sym n+1 window ____________________ + * / \ + * ... ________________/ \__ ... + * + * The window length is 2*d_windowOverlap. + */ + + update_window(windowOverlap); + + PDEBUG("GuardIntervalInserter::GuardIntervalInserter" + "(%zu, %zu, %zu, %zu, %zu) @ %p\n", + nbSymbols, spacing, nullSize, symSize, windowOverlap, this); } +void GuardIntervalInserter::update_window(size_t new_window_overlap) +{ + std::lock_guard lock(d_windowMutex); + + d_windowOverlap = new_window_overlap; + + // d_window only contains the rising window edge. + d_window.resize(2*d_windowOverlap); + for (size_t i = 0; i < 2*d_windowOverlap; i++) { + d_window[i] = (float)(0.5 * (1.0 - cos(M_PI * i / (2*d_windowOverlap - 1)))); + } +} + +#pragma GCC optimize ("O0") int GuardIntervalInserter::process(Buffer* const dataIn, Buffer* dataOut) { PDEBUG("GuardIntervalInserter::process(dataIn: %p, dataOut: %p)\n", dataIn, dataOut); - dataOut->setLength((d_nullSize + (d_nbSymbols * d_symSize)) - * sizeof(complexf)); + std::lock_guard lock(d_windowMutex); + + // Every symbol overlaps over a length of d_windowOverlap with + // the previous symbol, and with the next symbol. First symbol + // receives no prefix window, because we don't remember the + // last symbol from the previous TF (yet). Last symbol also + // receives no suffix window, for the same reason. + // Overall output buffer length must stay independent of the windowing. + dataOut->setLength((d_nullSize + (d_nbSymbols * d_symSize)) * sizeof(complexf)); const complexf* in = reinterpret_cast(dataIn->getData()); complexf* out = reinterpret_cast(dataOut->getData()); size_t sizeIn = dataIn->getLength() / sizeof(complexf); - if (sizeIn != (d_nbSymbols + (d_nullSize ? 1 : 0)) * d_spacing) { + const size_t num_symbols = d_nbSymbols + 1; + if (sizeIn != num_symbols * d_spacing) + { PDEBUG("Nb symbols: %zu\n", d_nbSymbols); PDEBUG("Spacing: %zu\n", d_spacing); PDEBUG("Null size: %zu\n", d_nullSize); @@ -64,25 +130,153 @@ int GuardIntervalInserter::process(Buffer* const dataIn, Buffer* dataOut) "GuardIntervalInserter::process input size not valid!"); } - // Handle Null symbol separately because it is longer - if (d_nullSize) { + // TODO remember the end of the last TF so that we can do some + // windowing too. + + if (d_windowOverlap) { + { + // Handle Null symbol separately because it is longer + const size_t prefixlength = d_nullSize - d_spacing; + + // end = spacing + memcpy(out, &in[d_spacing - prefixlength], + prefixlength * sizeof(complexf)); + + memcpy(&out[prefixlength], in, (d_spacing - d_windowOverlap) * sizeof(complexf)); + + // The remaining part of the symbol must have half of the window applied, + // sloping down from 1 to 0.5 + for (size_t i = 0; i < d_windowOverlap; i++) { + const size_t out_ix = prefixlength + d_spacing - d_windowOverlap + i; + const size_t in_ix = d_spacing - d_windowOverlap + i; + out[out_ix] = in[in_ix] * d_window[2*d_windowOverlap - (i+1)]; + } + + // Suffix is taken from the beginning of the symbol, and sees the other + // half of the window applied. + for (size_t i = 0; i < d_windowOverlap; i++) { + const size_t out_ix = prefixlength + d_spacing + i; + out[out_ix] = in[i] * d_window[d_windowOverlap - (i+1)]; + } + + in += d_spacing; + out += d_nullSize; + // out is now pointing to the proper end of symbol. There are + // d_windowOverlap samples ahead that were already written. + } + + // Data symbols + for (size_t sym_ix = 0; sym_ix < d_nbSymbols; sym_ix++) { + // end = spacing + const size_t prefix_start_ix = 2*d_spacing - d_symSize - d_windowOverlap; + + // From out[-d_windowOverlap] to out[d_windowOverlap], we need to + // apply the window from 0 to 0.5, with our additional + // prefix, and add it to existing data. + for (size_t i = 0; i < 2*d_windowOverlap; i++) { + out[-i] += in[prefix_start_ix + i] * d_window[i]; + } + + const size_t remaining_prefix_length = d_symSize - d_spacing - d_windowOverlap; + + // After out[d_windowOverlap], no need to accumulate, we can copy. + memcpy( &out[d_windowOverlap], + &in[prefix_start_ix + 2*d_windowOverlap], + remaining_prefix_length * sizeof(complexf)); + + const size_t prefixlength = d_symSize - d_spacing + d_windowOverlap; + + const bool last_symbol = (sym_ix + 1 < d_nbSymbols); + if (last_symbol) { + // No windowing at all at end + memcpy(&out[prefixlength], in, d_spacing * sizeof(complexf)); + } + else { + // Copy the middle part of the symbol, d_windowOverlap samples + // short of the end. + memcpy( &out[prefixlength], + in, + (d_spacing - d_windowOverlap) * sizeof(complexf)); + + const size_t out_start = prefixlength + d_spacing - d_windowOverlap; + const size_t in_start = d_spacing - d_windowOverlap; + + // Apply window from 1 to 0.5 for the end of the symbol + for (size_t i = 0; i < d_windowOverlap; i++) { + out[out_start + i] = + in[in_start + i] * d_window[2*d_windowOverlap - (i+1)]; + } + + const size_t out_start_suffix = prefixlength + d_spacing; + + // Cyclic suffix, with window from 0.5 to 0 + for (size_t i = 0; i < d_windowOverlap; i++) { + out[out_start_suffix + i] = + in[i] * d_window[d_windowOverlap - (i+1)]; + } + } + + in += d_spacing; + out += d_symSize; + // out is now pointing to the proper end of symbol. There are + // d_windowOverlap samples ahead that were already written. + } + } + else { + // Handle Null symbol separately because it is longer // end - (nullSize - spacing) = 2 * spacing - nullSize memcpy(out, &in[2 * d_spacing - d_nullSize], (d_nullSize - d_spacing) * sizeof(complexf)); memcpy(&out[d_nullSize - d_spacing], in, d_spacing * sizeof(complexf)); in += d_spacing; out += d_nullSize; - } - // Data symbols - for (size_t i = 0; i < d_nbSymbols; ++i) { - // end - (symSize - spacing) = 2 * spacing - symSize - memcpy(out, &in[2 * d_spacing - d_symSize], - (d_symSize - d_spacing) * sizeof(complexf)); - memcpy(&out[d_symSize - d_spacing], in, d_spacing * sizeof(complexf)); - in += d_spacing; - out += d_symSize; + // Data symbols + for (size_t i = 0; i < d_nbSymbols; ++i) { + // end - (symSize - spacing) = 2 * spacing - symSize + memcpy(out, &in[2 * d_spacing - d_symSize], + (d_symSize - d_spacing) * sizeof(complexf)); + memcpy(&out[d_symSize - d_spacing], in, d_spacing * sizeof(complexf)); + in += d_spacing; + out += d_symSize; + } } return sizeIn; } + +void GuardIntervalInserter::set_parameter( + const std::string& parameter, + const std::string& value) +{ + using namespace std; + stringstream ss(value); + ss.exceptions ( stringstream::failbit | stringstream::badbit ); + + if (parameter == "windowlen") { + size_t new_window_overlap = 0; + ss >> new_window_overlap; + update_window(new_window_overlap); + } + else { + stringstream ss_err; + ss_err << "Parameter '" << parameter << + "' is not exported by controllable " << get_rc_name(); + throw ParameterError(ss_err.str()); + } +} + +const std::string GuardIntervalInserter::get_parameter(const std::string& parameter) const +{ + using namespace std; + stringstream ss; + if (parameter == "windowlen") { + ss << d_windowOverlap; + } + else { + ss << "Parameter '" << parameter << + "' is not exported by controllable " << get_rc_name(); + throw ParameterError(ss.str()); + } + return ss.str(); +} diff --git a/src/GuardIntervalInserter.h b/src/GuardIntervalInserter.h index e6b3b64..b2ac782 100644 --- a/src/GuardIntervalInserter.h +++ b/src/GuardIntervalInserter.h @@ -1,6 +1,11 @@ /* Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) + + Copyright (C) 2017 + Matthias P. Braendli, matthias.braendli@mpb.li + + http://opendigitalradio.org */ /* This file is part of ODR-DabMod. @@ -26,26 +31,47 @@ #endif #include "ModPlugin.h" +#include "RemoteControl.h" #include +#include /* The GuardIntervalInserter prepends the cyclic prefix to all - * symbols in the transmission frame. */ -class GuardIntervalInserter : public ModCodec + * symbols in the transmission frame. + * + * If windowOverlap is non-zero, it will also add a cyclic suffix of + * that length, enlarge the cyclic prefix too, and make symbols + * overlap using a raised cosine window. + * */ +class GuardIntervalInserter : public ModCodec , public RemoteControllable { -public: - GuardIntervalInserter( - size_t nbSymbols, - size_t spacing, - size_t nullSize, - size_t symSize); - - int process(Buffer* const dataIn, Buffer* dataOut); - const char* name() { return "GuardIntervalInserter"; } - -protected: - size_t d_nbSymbols; - size_t d_spacing; - size_t d_nullSize; - size_t d_symSize; + public: + GuardIntervalInserter( + size_t nbSymbols, + size_t spacing, + size_t nullSize, + size_t symSize, + size_t windowOverlap = 0); + + int process(Buffer* const dataIn, Buffer* dataOut); + const char* name() { return "GuardIntervalInserter"; } + + /******* REMOTE CONTROL ********/ + virtual void set_parameter(const std::string& parameter, + const std::string& value); + + virtual const std::string get_parameter( + const std::string& parameter) const; + + protected: + void update_window(size_t new_window_overlap); + + size_t d_nbSymbols; + size_t d_spacing; + size_t d_nullSize; + size_t d_symSize; + + mutable std::mutex d_windowMutex; + size_t d_windowOverlap; + std::vector d_window; }; -- cgit v1.2.3 From bbda6c46e5c322a32c2267da32b0150669174c12 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sat, 23 Dec 2017 07:50:54 +0100 Subject: Rework OFDM windowing for data symbols --- src/GuardIntervalInserter.cpp | 85 +++++++++++++++++++++++++++---------------- src/GuardIntervalInserter.h | 2 +- 2 files changed, 55 insertions(+), 32 deletions(-) diff --git a/src/GuardIntervalInserter.cpp b/src/GuardIntervalInserter.cpp index 1381a3c..14027d3 100644 --- a/src/GuardIntervalInserter.cpp +++ b/src/GuardIntervalInserter.cpp @@ -167,57 +167,80 @@ int GuardIntervalInserter::process(Buffer* const dataIn, Buffer* dataOut) // Data symbols for (size_t sym_ix = 0; sym_ix < d_nbSymbols; sym_ix++) { - // end = spacing - const size_t prefix_start_ix = 2*d_spacing - d_symSize - d_windowOverlap; - - // From out[-d_windowOverlap] to out[d_windowOverlap], we need to - // apply the window from 0 to 0.5, with our additional - // prefix, and add it to existing data. - for (size_t i = 0; i < 2*d_windowOverlap; i++) { - out[-i] += in[prefix_start_ix + i] * d_window[i]; + /* _ix variables are indices into in[], _ox variables are + * indices for out[] */ + const ssize_t start_rise_ox = -d_windowOverlap; + const size_t start_rise_ix = 2 * d_spacing - d_symSize - d_windowOverlap; + /* + const size_t start_real_symbol_ox = 0; + const size_t start_real_symbol_ix = 2 * d_spacing - d_symSize; + */ + const ssize_t end_rise_ox = d_windowOverlap; + const size_t end_rise_ix = 2 * d_spacing - d_symSize + d_windowOverlap; + const ssize_t end_cyclic_prefix_ox = d_symSize - d_spacing; + /* end_cyclic_prefix_ix = end of symbol + const size_t begin_fall_ox = d_symSize - d_windowOverlap; + const size_t begin_fall_ix = d_spacing - d_windowOverlap; + const size_t end_real_symbol_ox = d_symSize; + end_real_symbol_ix = end of symbol + const size_t end_fall_ox = d_symSize + d_windowOverlap; + const size_t end_fall_ix = d_spacing + d_windowOverlap; + */ + + ssize_t ox = start_rise_ox; + size_t ix = start_rise_ix; + + for (size_t i = 0; ix < end_rise_ix; i++) { + out[ox] += in[ix] * d_window.at(i); + ix++; + ox++; } + assert(ox == end_rise_ox); - const size_t remaining_prefix_length = d_symSize - d_spacing - d_windowOverlap; - - // After out[d_windowOverlap], no need to accumulate, we can copy. - memcpy( &out[d_windowOverlap], - &in[prefix_start_ix + 2*d_windowOverlap], + const size_t remaining_prefix_length = end_cyclic_prefix_ox - end_rise_ox; + memcpy( &out[ox], &in[ix], remaining_prefix_length * sizeof(complexf)); + ox += remaining_prefix_length; + assert(ox = end_cyclic_prefix_ox); + ix = 0; - const size_t prefixlength = d_symSize - d_spacing + d_windowOverlap; - - const bool last_symbol = (sym_ix + 1 < d_nbSymbols); + const bool last_symbol = (sym_ix + 1 >= d_nbSymbols); if (last_symbol) { // No windowing at all at end - memcpy(&out[prefixlength], in, d_spacing * sizeof(complexf)); + memcpy(&out[ox], &in[ix], d_spacing * sizeof(complexf)); + ox += d_spacing; } else { // Copy the middle part of the symbol, d_windowOverlap samples // short of the end. - memcpy( &out[prefixlength], - in, + memcpy( &out[ox], + &in[ix], (d_spacing - d_windowOverlap) * sizeof(complexf)); - - const size_t out_start = prefixlength + d_spacing - d_windowOverlap; - const size_t in_start = d_spacing - d_windowOverlap; + ox += d_spacing - d_windowOverlap; + ix += d_spacing - d_windowOverlap; + assert(ox == (ssize_t)(d_symSize - d_windowOverlap)); // Apply window from 1 to 0.5 for the end of the symbol - for (size_t i = 0; i < d_windowOverlap; i++) { - out[out_start + i] = - in[in_start + i] * d_window[2*d_windowOverlap - (i+1)]; + for (size_t i = 0; ox < (ssize_t)d_symSize; i++) { + out[ox] = in[ix] * d_window[2*d_windowOverlap - (i+1)]; + ox++; + ix++; } + assert(ix == d_spacing); - const size_t out_start_suffix = prefixlength + d_spacing; - + ix = 0; // Cyclic suffix, with window from 0.5 to 0 - for (size_t i = 0; i < d_windowOverlap; i++) { - out[out_start_suffix + i] = - in[i] * d_window[d_windowOverlap - (i+1)]; + for (size_t i = 0; ox < (ssize_t)(d_symSize + d_windowOverlap); i++) { + out[ox] = in[ix] * d_window[d_windowOverlap - (i+1)]; + ox++; + ix++; } + + assert(ix == d_windowOverlap); } - in += d_spacing; out += d_symSize; + in += d_spacing; // out is now pointing to the proper end of symbol. There are // d_windowOverlap samples ahead that were already written. } diff --git a/src/GuardIntervalInserter.h b/src/GuardIntervalInserter.h index b2ac782..7714c1a 100644 --- a/src/GuardIntervalInserter.h +++ b/src/GuardIntervalInserter.h @@ -42,7 +42,7 @@ * that length, enlarge the cyclic prefix too, and make symbols * overlap using a raised cosine window. * */ -class GuardIntervalInserter : public ModCodec , public RemoteControllable +class GuardIntervalInserter : public ModCodec, public RemoteControllable { public: GuardIntervalInserter( -- cgit v1.2.3 From 215e8143e3feefd69a76d0b6eaf36ed42a7a904f Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sat, 23 Dec 2017 07:59:14 +0100 Subject: Add OFDM windowing to config file --- doc/example.ini | 7 +++++++ src/ConfigParser.cpp | 6 +++++- src/ConfigParser.h | 2 ++ src/DabModulator.cpp | 3 ++- 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/doc/example.ini b/doc/example.ini index cf56720..d356ee1 100644 --- a/doc/example.ini +++ b/doc/example.ini @@ -128,6 +128,13 @@ rate=2048000 ; and ;dac_clk_rate=128000000 +; When nonzero, overlap ofdmwindowing samples from each OFDM symbol +; onto the previous and next symbol, using a raised cosine window function. +; This has the effect of smoothing the transition from one symbol to the next, +; which improves spectrum shape. +; In Transmission Mode I, every data symbol is composed of 2552 samples. +;ofdmwindowing=10 + ; Settings for crest factor reduction. Statistics for ratio of ; samples that were clipped are available through the RC. [cfr] diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp index 1cc94c0..2c93a57 100644 --- a/src/ConfigParser.cpp +++ b/src/ConfigParser.cpp @@ -159,8 +159,12 @@ static void parse_configfile( mod_settings.dabMode = pt.get("modulator.mode", mod_settings.dabMode); mod_settings.clockRate = pt.get("modulator.dac_clk_rate", (size_t)0); - mod_settings.digitalgain = pt.get("modulator.digital_gain", mod_settings.digitalgain); + mod_settings.digitalgain = pt.get("modulator.digital_gain", + mod_settings.digitalgain); + mod_settings.outputRate = pt.get("modulator.rate", mod_settings.outputRate); + mod_settings.ofdmWindowOverlap = pt.get("modulator.ofdmwindowing", + mod_settings.ofdmWindowOverlap); // FIR Filter parameters: if (pt.get("firfilter.enabled", 0) == 1) { diff --git a/src/ConfigParser.h b/src/ConfigParser.h index a8d7837..0be3558 100644 --- a/src/ConfigParser.h +++ b/src/ConfigParser.h @@ -82,6 +82,8 @@ struct mod_settings_t { float cfrClip = 1.0f; float cfrErrorClip = 1.0f; + // Settings for the OFDM windowing + unsigned ofdmWindowOverlap = 0; #if defined(HAVE_OUTPUT_UHD) OutputUHDConfig outputuhd_conf; diff --git a/src/DabModulator.cpp b/src/DabModulator.cpp index cded280..0818f4f 100644 --- a/src/DabModulator.cpp +++ b/src/DabModulator.cpp @@ -201,7 +201,8 @@ int DabModulator::process(Buffer* dataOut) rcs.enrol(cifGain.get()); auto cifGuard = make_shared( - myNbSymbols, mySpacing, myNullSize, mySymSize); + myNbSymbols, mySpacing, myNullSize, mySymSize, + m_settings.ofdmWindowOverlap); rcs.enrol(cifGuard.get()); shared_ptr cifFilter; -- cgit v1.2.3 From 626cfba78e2885200450ff8b4f4cf09ff6d0b830 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sun, 24 Dec 2017 04:06:10 +0100 Subject: Fix TII insertion for positive frequency carriers --- doc/example.ini | 8 ++++++-- src/TII.cpp | 15 ++------------- src/TII.h | 3 +++ 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/doc/example.ini b/doc/example.ini index d356ee1..ec0525c 100644 --- a/doc/example.ini +++ b/doc/example.ini @@ -318,8 +318,12 @@ offset=0.002 ; DAB modes I and II are supported, and must be set explicitly in ; this file. Reading DAB mode from ETI is not supported. enable=0 -comb=16 -pattern=3 +; comb is also known as sub-identifier. +comb=1 +; pattern is also known as main-identifier. If you run several transmitters +; in SFN, it is better to use the same pattern for all, and vary the comb. +; Otherwise identification of the transmitters may be more difficult. +pattern=11 ; There are two variants of TII being used. The old variant that uses the wrong ; phase on the second carrier in each carrier pairs and is therefore not ; conforming to the specification. Modern analysers can decode both variants, diff --git a/src/TII.cpp b/src/TII.cpp index af64c9f..446d9c6 100644 --- a/src/TII.cpp +++ b/src/TII.cpp @@ -197,10 +197,6 @@ int TII::process(Buffer* dataIn, Buffer* dataOut) complexf* in = reinterpret_cast(dataIn->getData()); complexf* out = reinterpret_cast(dataOut->getData()); - if ((m_enabled_carriers.size() % 2) != 0) { - throw std::logic_error("odd number of enabled carriers"); - } - /* Normalise the TII carrier power according to ETSI TR 101 496-3 * Clause 5.4.2.2 Paragraph 7: * @@ -213,13 +209,10 @@ int TII::process(Buffer* dataIn, Buffer* dataOut) */ const float normalise_factor = 0.14433756729740644112f; // = 1/sqrt(48) - for (size_t i = 0; i < m_enabled_carriers.size(); i+=2) { + for (size_t i = 0; i < m_enabled_carriers.size(); i++) { // See header file for an explanation of the old variant if (m_enabled_carriers[i]) { out[i] = normalise_factor * (m_conf.old_variant ? in[i+1] : in[i]); - } - - if (m_enabled_carriers[i+1]) { out[i+1] = normalise_factor * in[i+1]; } } @@ -239,10 +232,6 @@ void TII::enable_carrier(int k) { } m_enabled_carriers[ix] = true; - // NULL frequency is never enabled. - if (ix > 1 and (ix-1 != 768)) { - m_enabled_carriers[ix-1] = true; - } } void TII::prepare_pattern() { @@ -287,7 +276,7 @@ void TII::prepare_pattern() { } } - for (int k = 384; k <= 768; k++) { + for (int k = 385; k <= 768; k++) { for (int b = 0; b < 8; b++) { if ( k == 385 + 2 * comb + 48 * b and pattern_tm1_2_4[m_conf.pattern][b]) { diff --git a/src/TII.h b/src/TII.h index fe67978..4c5c605 100644 --- a/src/TII.h +++ b/src/TII.h @@ -122,6 +122,9 @@ class TII : public ModCodec, public RemoteControllable // m_enabled_carriers is read by modulator thread, and written // to by RC thread. mutable boost::mutex m_enabled_carriers_mutex; + + // m_enabled_carriers is true only for the first carrier in the + // active pair std::vector m_enabled_carriers; }; -- cgit v1.2.3 From 2a199ca830cb1338b5c52ca5f147ebef26330d22 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 25 Dec 2017 05:08:14 +0100 Subject: Do not use out_of_range for multiplex reconfiguration error --- src/DabMod.cpp | 15 +++++++++------ src/FrameMultiplexer.cpp | 4 ++-- src/FrameMultiplexer.h | 10 ++++++++-- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/DabMod.cpp b/src/DabMod.cpp index dfefb53..b6f2dee 100644 --- a/src/DabMod.cpp +++ b/src/DabMod.cpp @@ -36,6 +36,7 @@ #include "InputMemory.h" #include "OutputFile.h" #include "FormatConverter.h" +#include "FrameMultiplexer.h" #if defined(HAVE_OUTPUT_UHD) # include "OutputUHD.h" #endif @@ -534,17 +535,19 @@ run_modulator_state_t run_modulator(modulator_data& m) running = 0; ret = run_modulator_state_t::normal_end; } - } catch (zmq_input_overflow& e) { + } + catch (const zmq_input_overflow& e) { // The ZeroMQ input has overflowed its buffer etiLog.level(warn) << e.what(); ret = run_modulator_state_t::again; - } catch (std::out_of_range& e) { - // One of the DSP blocks has detected an invalid change - // or value in some settings. This can be due to a multiplex - // reconfiguration. + } + catch (const FrameMultiplexerError& e) { + // The FrameMultiplexer saw an error or a change in the size of a + // subchannel. This can be due to a multiplex reconfiguration. etiLog.level(warn) << e.what(); ret = run_modulator_state_t::reconfigure; - } catch (std::exception& e) { + } + catch (const std::exception& e) { etiLog.level(error) << "Exception caught: " << e.what(); ret = run_modulator_state_t::failure; } diff --git a/src/FrameMultiplexer.cpp b/src/FrameMultiplexer.cpp index 4cee0b2..5dc6dca 100644 --- a/src/FrameMultiplexer.cpp +++ b/src/FrameMultiplexer.cpp @@ -74,7 +74,7 @@ int FrameMultiplexer::process(std::vector dataIn, Buffer* dataOut) // Write subchannel const auto subchannels = m_etiSource.getSubchannels(); if (subchannels.size() != dataIn.size() - 1) { - throw std::out_of_range( + throw FrameMultiplexerError( "FrameMultiplexer detected subchannel size change from " + std::to_string(dataIn.size() - 1) + " to " + std::to_string(subchannels.size())); @@ -82,7 +82,7 @@ int FrameMultiplexer::process(std::vector dataIn, Buffer* dataOut) auto subchannel = subchannels.begin(); while (in != dataIn.end()) { if ((*subchannel)->framesizeCu() * 8 != (*in)->getLength()) { - throw std::out_of_range( + throw FrameMultiplexerError( "FrameMultiplexer detected invalid subchannel size! " + std::to_string((*subchannel)->framesizeCu() * 8) + " != " + std::to_string((*in)->getLength())); diff --git a/src/FrameMultiplexer.h b/src/FrameMultiplexer.h index 680cdc7..4d68d88 100644 --- a/src/FrameMultiplexer.h +++ b/src/FrameMultiplexer.h @@ -38,12 +38,18 @@ #include +class FrameMultiplexerError : public std::runtime_error { + public: + FrameMultiplexerError(const char* msg) : + std::runtime_error(msg) {} + FrameMultiplexerError(const std::string& msg) : + std::runtime_error(msg) {} +}; class FrameMultiplexer : public ModMux { public: - FrameMultiplexer( - const EtiSource& etiSource); + FrameMultiplexer(const EtiSource& etiSource); int process(std::vector dataIn, Buffer* dataOut); const char* name() { return "FrameMultiplexer"; } -- cgit v1.2.3 From 515959935cd7c741db5aca5b20bfb7611749fbfb Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 25 Dec 2017 05:08:23 +0100 Subject: Fix Soapy warning --- src/OutputSoapy.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/OutputSoapy.cpp b/src/OutputSoapy.cpp index 3f8db88..699501c 100644 --- a/src/OutputSoapy.cpp +++ b/src/OutputSoapy.cpp @@ -253,10 +253,10 @@ void OutputSoapy::set_parameter(const string& parameter, const string& value) throw ParameterError("Parameter 'overflows' is read-only"); } else { - stringstream ss; - ss << "Parameter '" << parameter + stringstream ss_err; + ss_err << "Parameter '" << parameter << "' is not exported by controllable " << get_rc_name(); - throw ParameterError(ss.str()); + throw ParameterError(ss_err.str()); } } -- cgit v1.2.3