diff --git a/CMakeLists.txt b/CMakeLists.txt
index 05203f365..b39c72ef7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -214,6 +214,7 @@ endif()
add_subdirectory(sdrbase)
add_subdirectory(sdrgui)
add_subdirectory(sdrsrv)
+add_subdirectory(sdrbench)
add_subdirectory(httpserver)
add_subdirectory(logging)
add_subdirectory(qrtplib)
@@ -293,6 +294,29 @@ target_link_libraries(sdrangelsrv
qt5_use_modules(sdrangelsrv Multimedia)
+##############################################################################
+# main benchmark application
+
+set(sdrangelbench_SOURCES
+ appbench/main.cpp
+)
+
+add_executable(sdrangelbench
+ ${sdrangelbench_SOURCES}
+)
+
+target_include_directories(sdrangelbench
+ PUBLIC ${CMAKE_SOURCE_DIR}/sdrbench
+)
+
+target_link_libraries(sdrangelbench
+ sdrbench
+ logging
+ ${QT_LIBRARIES}
+)
+
+qt5_use_modules(sdrangelbench Multimedia)
+
##############################################################################
if (BUILD_DEBIAN)
@@ -325,6 +349,7 @@ endif(LIBUSB_FOUND AND UNIX)
#install targets
install(TARGETS sdrangel DESTINATION bin)
install(TARGETS sdrangelsrv DESTINATION bin)
+install(TARGETS sdrangelbench DESTINATION bin)
#install(TARGETS sdrbase DESTINATION lib)
#install files and directories
diff --git a/appbench/main.cpp b/appbench/main.cpp
new file mode 100644
index 000000000..74adea9bc
--- /dev/null
+++ b/appbench/main.cpp
@@ -0,0 +1,110 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2018 Edouard Griffiths, F4EXB. //
+// //
+// Swagger server adapter interface //
+// //
+// This program is free software; you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation as version 3 of the License, or //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include "loggerwithfile.h"
+#include "mainbench.h"
+#include "dsp/dsptypes.h"
+
+void handler(int sig) {
+ fprintf(stderr, "quit the application by signal(%d).\n", sig);
+ QCoreApplication::quit();
+}
+
+void catchUnixSignals(const std::vector& quitSignals) {
+ sigset_t blocking_mask;
+ sigemptyset(&blocking_mask);
+
+ for (std::vector::const_iterator it = quitSignals.begin(); it != quitSignals.end(); ++it) {
+ sigaddset(&blocking_mask, *it);
+ }
+
+ struct sigaction sa;
+ sa.sa_handler = handler;
+ sa.sa_mask = blocking_mask;
+ sa.sa_flags = 0;
+
+ for (std::vector::const_iterator it = quitSignals.begin(); it != quitSignals.end(); ++it) {
+ sigaction(*it, &sa, 0);
+ }
+}
+
+static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *logger)
+{
+ QCoreApplication a(argc, argv);
+
+ QCoreApplication::setOrganizationName("f4exb");
+ QCoreApplication::setApplicationName("SDRangelBench");
+ QCoreApplication::setApplicationVersion("3.14.5");
+
+ int catchSignals[] = {SIGQUIT, SIGINT, SIGTERM, SIGHUP};
+ std::vector vsig(catchSignals, catchSignals + sizeof(catchSignals) / sizeof(int));
+ catchUnixSignals(vsig);
+
+ ParserBench parser;
+ parser.parse(a);
+
+#if QT_VERSION >= 0x050400
+ qInfo("%s %s Qt %s %db %s %s DSP Rx:%db Tx:%db PID %lld",
+ qPrintable(QCoreApplication::applicationName()),
+ qPrintable(QCoreApplication::applicationVersion()),
+ qPrintable(QString(QT_VERSION_STR)),
+ QT_POINTER_SIZE*8,
+ qPrintable(QSysInfo::currentCpuArchitecture()),
+ qPrintable(QSysInfo::prettyProductName()),
+ SDR_RX_SAMP_SZ,
+ SDR_TX_SAMP_SZ,
+ QCoreApplication::applicationPid());
+#else
+ qInfo("%s %s Qt %s %db DSP Rx:%db Tx:%db PID %lld",
+ qPrintable(QCoreApplication::applicationName()),
+ qPrintable((QCoreApplication::>applicationVersion()),
+ qPrintable(QString(QT_VERSION_STR)),
+ QT_POINTER_SIZE*8,
+ SDR_RX_SAMP_SZ,
+ SDR_TX_SAMP_SZ,
+ QCoreApplication::applicationPid());
+#endif
+
+ MainBench m(logger, parser, &a);
+
+ // This will cause the application to exit when the main core is finished
+ QObject::connect(&m, SIGNAL(finished()), &a, SLOT(quit()));
+ // This will run the task from the application event loop
+ QTimer::singleShot(0, &m, SLOT(run()));
+
+ return a.exec();
+}
+
+int main(int argc, char* argv[])
+{
+ qtwebapp::LoggerWithFile *logger = new qtwebapp::LoggerWithFile(qApp);
+ logger->installMsgHandler();
+ int res = runQtApplication(argc, argv, logger);
+ qWarning("SDRangel quit.");
+ return res;
+}
+
+
diff --git a/sdrbench/CMakeLists.txt b/sdrbench/CMakeLists.txt
new file mode 100644
index 000000000..94975cdd3
--- /dev/null
+++ b/sdrbench/CMakeLists.txt
@@ -0,0 +1,42 @@
+project (sdrbench)
+
+set(sdrbench_SOURCES
+ mainbench.cpp
+ parserbench.cpp
+)
+
+set(sdrbench_HEADERS
+ mainbench.h
+ parserbench.h
+)
+
+set(sdrbench_SOURCES
+ ${sdrbench_SOURCES}
+ ${sdrbench_HEADERS}
+)
+
+add_definitions(${QT_DEFINITIONS})
+add_definitions(-DQT_SHARED)
+
+add_library(sdrbench SHARED
+ ${sdrbench_SOURCES}
+ ${sdrbench_HEADERS_MOC}
+)
+
+include_directories(
+ .
+ ${CMAKE_SOURCE_DIR}/logging
+ ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+target_link_libraries(sdrbench
+ ${QT_LIBRARIES}
+ logging
+)
+
+target_compile_features(sdrbench PRIVATE cxx_generalized_initializers) # cmake >= 3.1.0
+
+qt5_use_modules(sdrbench Core Gui)
+
+install(TARGETS sdrbench DESTINATION lib)
+
diff --git a/sdrbench/mainbench.cpp b/sdrbench/mainbench.cpp
new file mode 100644
index 000000000..4da6db668
--- /dev/null
+++ b/sdrbench/mainbench.cpp
@@ -0,0 +1,46 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2018 Edouard Griffiths, F4EXB. //
+// //
+// Swagger server adapter interface //
+// //
+// This program is free software; you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation as version 3 of the License, or //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#include
+#include "mainbench.h"
+
+MainBench *MainBench::m_instance = 0;
+
+MainBench::MainBench(qtwebapp::LoggerWithFile *logger, const ParserBench& parser, QObject *parent) :
+ QObject(parent),
+ m_logger(logger),
+ m_parser(parser)
+{
+ qDebug() << "MainBench::MainBench: start";
+ m_instance = this;
+ qDebug() << "MainBench::MainBench: end";
+}
+
+void MainBench::run()
+{
+ qDebug() << "MainBench::run: work in progress";
+ qDebug() << "MainBench::run: parameters:"
+ << " test: " << m_parser.getTest()
+ << " nsamples: " << m_parser.getNbSamples()
+ << " repet: " << m_parser.getRepetition()
+ << " log2f: " << m_parser.getLog2Factor();
+ emit finished();
+}
+
+MainBench::~MainBench()
+{}
\ No newline at end of file
diff --git a/sdrbench/mainbench.h b/sdrbench/mainbench.h
new file mode 100644
index 000000000..a94ec05b9
--- /dev/null
+++ b/sdrbench/mainbench.h
@@ -0,0 +1,49 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2018 Edouard Griffiths, F4EXB. //
+// //
+// Swagger server adapter interface //
+// //
+// This program is free software; you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation as version 3 of the License, or //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef SDRBENCH_MAINBENCH_H_
+#define SDRBENCH_MAINBENCH_H_
+
+#include
+
+#include "parserbench.h"
+
+namespace qtwebapp {
+ class LoggerWithFile;
+}
+
+class MainBench: public QObject {
+ Q_OBJECT
+
+public:
+ explicit MainBench(qtwebapp::LoggerWithFile *logger, const ParserBench& parser, QObject *parent = 0);
+ ~MainBench();
+
+public slots:
+ void run();
+
+signals:
+ void finished();
+
+private:
+ static MainBench *m_instance;
+ qtwebapp::LoggerWithFile *m_logger;
+ const ParserBench& m_parser;
+};
+
+#endif // SDRBENCH_MAINBENCH_H_
diff --git a/sdrbench/parserbench.cpp b/sdrbench/parserbench.cpp
new file mode 100644
index 000000000..8f914a72e
--- /dev/null
+++ b/sdrbench/parserbench.cpp
@@ -0,0 +1,113 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2018 F4EXB //
+// written by Edouard Griffiths //
+// //
+// This program is free software; you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation as version 3 of the License, or //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#include
+#include
+#include
+
+#include "parserbench.h"
+
+ParserBench::ParserBench() :
+ m_testOption(QStringList() << "t" << "test",
+ "Test type.",
+ "test",
+ "decimate"),
+ m_nbSamplesOption(QStringList() << "n" << "nb-samples",
+ "Number of sample to deal with.",
+ "samples",
+ "1048576"),
+ m_repetitionOption(QStringList() << "r" << "repeat",
+ "Number of repetitions.",
+ "repetition",
+ "1"),
+ m_log2FactorOption(QStringList() << "l" << "log2-factor",
+ "Log2 factor for rate conversion.",
+ "log2",
+ "2")
+{
+ m_test = "decimate";
+ m_nbSamples = 1048576;
+ m_repetition = 1;
+ m_log2Factor = 4;
+
+ m_parser.setApplicationDescription("Software Defined Radio application benchmarks");
+ m_parser.addHelpOption();
+ m_parser.addVersionOption();
+
+ m_parser.addOption(m_testOption);
+ m_parser.addOption(m_nbSamplesOption);
+ m_parser.addOption(m_repetitionOption);
+ m_parser.addOption(m_log2FactorOption);
+}
+
+ParserBench::~ParserBench()
+{ }
+
+void ParserBench::parse(const QCoreApplication& app)
+{
+ m_parser.process(app);
+
+ int pos;
+ bool ok;
+
+ // test switch
+
+ QString test = m_parser.value(m_testOption);
+
+ QString testStr = "(decimate)";
+ QRegExp ipRegex ("^" + testStr + "$");
+ QRegExpValidator ipValidator(ipRegex);
+
+ if (ipValidator.validate(test, pos) == QValidator::Acceptable) {
+ m_test = test;
+ } else {
+ qWarning() << "ParserBench::parse: test type invalid. Defaulting to " << m_test;
+ }
+
+ // number of samples
+
+ QString nbSamplesStr = m_parser.value(m_nbSamplesOption);
+ int nbSamples = nbSamplesStr.toInt(&ok);
+
+ if (ok && (nbSamples > 1024) && (nbSamples < 1073741824)) {
+ m_nbSamples = nbSamples;
+ } else {
+ qWarning() << "ParserBench::parse: number of samples invalid. Defaulting to " << m_nbSamples;
+ }
+
+ // repetition
+
+ QString repetitionStr = m_parser.value(m_repetitionOption);
+ int repetition = repetitionStr.toInt(&ok);
+
+ if (ok && (repetition >= 0)) {
+ m_repetition = repetition;
+ } else {
+ qWarning() << "ParserBench::parse: repetition invalid. Defaulting to " << m_repetition;
+ }
+
+ // log2 factor
+
+ QString log2FactorStr = m_parser.value(m_log2FactorOption);
+ int log2Factor = log2FactorStr.toInt(&ok);
+
+ if (ok && (log2Factor >= 0) && (log2Factor <= 6)) {
+ m_log2Factor = log2Factor;
+ } else {
+ qWarning() << "ParserBench::parse: repetilog2 factortion invalid. Defaulting to " << m_log2Factor;
+ }
+}
diff --git a/sdrbench/parserbench.h b/sdrbench/parserbench.h
new file mode 100644
index 000000000..a7b7a2660
--- /dev/null
+++ b/sdrbench/parserbench.h
@@ -0,0 +1,52 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2018 F4EXB //
+// written by Edouard Griffiths //
+// //
+// This program is free software; you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation as version 3 of the License, or //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef SDRBENCH_PARSERBENCH_H_
+#define SDRBENCH_PARSERBENCH_H_
+
+#include
+#include
+
+class ParserBench
+{
+public:
+ ParserBench();
+ ~ParserBench();
+
+ void parse(const QCoreApplication& app);
+
+ const QString& getTest() const { return m_test; }
+ uint32_t getNbSamples() const { return m_nbSamples; }
+ uint32_t getRepetition() const { return m_repetition; }
+ uint32_t getLog2Factor() const { return m_log2Factor; }
+
+private:
+ QString m_test;
+ uint32_t m_nbSamples;
+ uint32_t m_repetition;
+ uint32_t m_log2Factor;
+
+ QCommandLineParser m_parser;
+ QCommandLineOption m_testOption;
+ QCommandLineOption m_nbSamplesOption;
+ QCommandLineOption m_repetitionOption;
+ QCommandLineOption m_log2FactorOption;
+};
+
+
+
+#endif /* SDRBENCH_PARSERBENCH_H_ */