diff options
Diffstat (limited to 'src')
30 files changed, 347 insertions, 1377 deletions
diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp index 1876697..fa12521 100644 --- a/src/ConfigParser.cpp +++ b/src/ConfigParser.cpp @@ -107,15 +107,20 @@ typedef DWORD32 uint32_t; using namespace std; +static void setup_subchannel_from_ptree(DabSubchannel* subchan, + const boost::property_tree::ptree &pt, + std::shared_ptr<dabEnsemble> ensemble, + const string& subchanuid); + /* a helper class to parse hexadecimal ids */ -int hexparse(std::string input) +static int hexparse(std::string input) { int value; if (input.find("0x") == 0) { - value = strtoll(input.c_str() + 2, NULL, 16); + value = strtoll(input.c_str() + 2, nullptr, 16); } else { - value = strtoll(input.c_str(), NULL, 10); + value = strtoll(input.c_str(), nullptr, 10); } if (errno == ERANGE) { @@ -125,7 +130,7 @@ int hexparse(std::string input) return value; } -uint16_t get_announcement_flag_from_ptree( +static uint16_t get_announcement_flag_from_ptree( boost::property_tree::ptree& pt ) { @@ -474,7 +479,7 @@ void parse_ptree( ptree pt_subchans = pt.get_child("subchannels"); for (ptree::iterator it = pt_subchans.begin(); it != pt_subchans.end(); ++it) { string subchanuid = it->first; - DabSubchannel* subchan = new DabSubchannel(subchanuid); + auto subchan = new DabSubchannel(subchanuid); ensemble->subchannels.push_back(subchan); @@ -547,7 +552,7 @@ void parse_ptree( int packet_datagroup = pt_comp.get("datagroup", false); uint8_t component_type = hexparse(pt_comp.get("type", "0")); - DabComponent* component = new DabComponent(componentuid); + auto component = new DabComponent(componentuid); component->serviceId = service->id; component->subchId = subchannel->id; @@ -644,10 +649,44 @@ void parse_ptree( parse_linkage(pt, ensemble); } -void setup_subchannel_from_ptree(DabSubchannel* subchan, - boost::property_tree::ptree &pt, +static dab_input_zmq_config_t setup_zmq_input( + const boost::property_tree::ptree &pt, + const std::string& subchanuid) +{ + using boost::property_tree::ptree_error; + + dab_input_zmq_config_t zmqconfig; + + try { + zmqconfig.buffer_size = pt.get<int>("zmq-buffer"); + } + catch (ptree_error &e) { + stringstream ss; + ss << "Subchannel " << subchanuid << ": " << "no zmq-buffer defined!"; + throw runtime_error(ss.str()); + } + try { + zmqconfig.prebuffering = pt.get<int>("zmq-prebuffering"); + } + catch (ptree_error &e) { + stringstream ss; + ss << "Subchannel " << subchanuid << ": " << "no zmq-prebuffer defined!"; + throw runtime_error(ss.str()); + } + + zmqconfig.curve_encoder_keyfile = pt.get<string>("encoder-key",""); + zmqconfig.curve_secret_keyfile = pt.get<string>("secret-key",""); + zmqconfig.curve_public_keyfile = pt.get<string>("public-key",""); + + zmqconfig.enable_encryption = pt.get<int>("encryption", 0); + + return zmqconfig; +} + +static void setup_subchannel_from_ptree(DabSubchannel* subchan, + const boost::property_tree::ptree &pt, std::shared_ptr<dabEnsemble> ensemble, - string subchanuid) + const string& subchanuid) { using boost::property_tree::ptree; using boost::property_tree::ptree_error; @@ -714,43 +753,24 @@ void setup_subchannel_from_ptree(DabSubchannel* subchan, #if defined(HAVE_INPUT_ZEROMQ) } else if (proto == "tcp" || - proto == "epmg" || + proto == "epgm" || proto == "ipc") { input_is_old_style = false; - dab_input_zmq_config_t zmqconfig; - - try { - zmqconfig.buffer_size = pt.get<int>("zmq-buffer"); - } - catch (ptree_error &e) { - stringstream ss; - ss << "ZMQ Subchannel with uid " << subchanuid << - " has no zmq-buffer defined!"; - throw runtime_error(ss.str()); - } - try { - zmqconfig.prebuffering = pt.get<int>("zmq-prebuffering"); - } - catch (ptree_error &e) { - stringstream ss; - ss << "ZMQ Subchannel with uid " << subchanuid << - " has no zmq-buffer defined!"; - throw runtime_error(ss.str()); - } - zmqconfig.enable_encryption = false; + auto zmqconfig = setup_zmq_input(pt, subchanuid); DabInputZmqMPEG* inzmq = new DabInputZmqMPEG(subchanuid, zmqconfig); rcs.enrol(inzmq); subchan->input = inzmq; - if (proto == "epmg") { - etiLog.level(warn) << "Using untested epmg:// zeromq input"; + if (proto == "epgm") { + etiLog.level(warn) << "Using untested epgm:// zeromq input"; } else if (proto == "ipc") { etiLog.level(warn) << "Using untested ipc:// zeromq input"; } + #endif // defined(HAVE_INPUT_ZEROMQ) } else { stringstream ss; @@ -773,37 +793,11 @@ void setup_subchannel_from_ptree(DabSubchannel* subchan, #if defined(HAVE_INPUT_ZEROMQ) } else if (proto == "tcp" || - proto == "epmg" || + proto == "epgm" || proto == "ipc") { input_is_old_style = false; - dab_input_zmq_config_t zmqconfig; - - try { - zmqconfig.buffer_size = pt.get<int>("zmq-buffer"); - } - catch (ptree_error &e) { - stringstream ss; - ss << "ZMQ Subchannel with uid " << subchanuid << - " has no zmq-buffer defined!"; - throw runtime_error(ss.str()); - } - - try { - zmqconfig.prebuffering = pt.get<int>("zmq-prebuffering"); - } - catch (ptree_error &e) { - stringstream ss; - ss << "ZMQ Subchannel with uid " << subchanuid << - " has no zmq-buffer defined!"; - throw runtime_error(ss.str()); - } - - zmqconfig.curve_encoder_keyfile = pt.get<string>("encoder-key",""); - zmqconfig.curve_secret_keyfile = pt.get<string>("secret-key",""); - zmqconfig.curve_public_keyfile = pt.get<string>("public-key",""); - - zmqconfig.enable_encryption = pt.get<int>("encryption", 0); + auto zmqconfig = setup_zmq_input(pt, subchanuid); DabInputZmqAAC* inzmq = new DabInputZmqAAC(subchanuid, zmqconfig); @@ -811,8 +805,8 @@ void setup_subchannel_from_ptree(DabSubchannel* subchan, rcs.enrol(inzmq); subchan->input = inzmq; - if (proto == "epmg") { - etiLog.level(warn) << "Using untested epmg:// zeromq input"; + if (proto == "epgm") { + etiLog.level(warn) << "Using untested epgm:// zeromq input"; } else if (proto == "ipc") { etiLog.level(warn) << "Using untested ipc:// zeromq input"; @@ -836,6 +830,12 @@ void setup_subchannel_from_ptree(DabSubchannel* subchan, #endif // defined(HAVE_INPUT_UDP) #endif // defined(HAVE_FORMAT_BRIDGE) } + } else if (type == "data" and proto == "prbs") { + input_is_old_style = false; + + subchan->input = new DabInputPrbs(); + subchan->type = subchannel_type_t::DataDmb; + subchan->bitrate = DEFAULT_DATA_BITRATE; } else if (type == "data") { // TODO default proto should be udp:// if (0) { @@ -843,10 +843,6 @@ void setup_subchannel_from_ptree(DabSubchannel* subchan, } else if (proto == "udp") { operations = dabInputUdpOperations; #endif -#if defined(HAVE_INPUT_PRBS) && defined(HAVE_FORMAT_RAW) - } else if (proto == "prbs") { - operations = dabInputPrbsOperations; -#endif #if defined(HAVE_INPUT_FILE) && defined(HAVE_FORMAT_RAW) } else if (proto == "file") { operations = dabInputRawFileOperations; @@ -855,7 +851,7 @@ void setup_subchannel_from_ptree(DabSubchannel* subchan, operations = dabInputRawFifoOperations; } else { stringstream ss; - ss << "Subchannel with uid " << subchanuid << + ss << "Subchannel with uid " << subchanuid << ": Invalid protocol for data input (" << proto << ")" << endl; throw runtime_error(ss.str()); diff --git a/src/ConfigParser.h b/src/ConfigParser.h index 1297b90..6399cdd 100644 --- a/src/ConfigParser.h +++ b/src/ConfigParser.h @@ -41,10 +41,5 @@ void parse_ptree(boost::property_tree::ptree& pt, std::shared_ptr<dabEnsemble> ensemble); -void setup_subchannel_from_ptree(DabSubchannel* subchan, - boost::property_tree::ptree &pt, - std::shared_ptr<dabEnsemble> ensemble, - std::string subchanuid); - #endif diff --git a/src/DabMultiplexer.cpp b/src/DabMultiplexer.cpp index 90d3d02..4a3234e 100644 --- a/src/DabMultiplexer.cpp +++ b/src/DabMultiplexer.cpp @@ -162,7 +162,7 @@ void DabMultiplexer::prepare() * Ideally, we must be able to restart transmission s.t. the receiver * synchronisation is preserved. */ - gettimeofday(&mnsc_time, NULL); + gettimeofday(&mnsc_time, nullptr); #if HAVE_OUTPUT_EDI edi_time = chrono::system_clock::now(); @@ -212,7 +212,7 @@ void DabMultiplexer::prepare_subchannels() void DabMultiplexer::prepare_services_components() { set<uint32_t> ids; - dabProtection* protection = NULL; + dabProtection* protection = nullptr; vector<DabComponent*>::iterator component; vector<DabSubchannel*>::iterator subchannel; @@ -301,7 +301,7 @@ void DabMultiplexer::prepare_services_components() void DabMultiplexer::prepare_data_inputs() { - dabProtection* protection = NULL; + dabProtection* protection = nullptr; vector<DabSubchannel*>::iterator subchannel; // Prepare and check the data inputs @@ -773,7 +773,7 @@ void DabMultiplexer::mux_frame(std::vector<std::shared_ptr<DabOutput> >& outputs currentFrame++; } -void DabMultiplexer::print_info(void) +void DabMultiplexer::print_info() { // Print settings before starting etiLog.log(info, "--- Multiplex configuration ---"); diff --git a/src/DabMux.cpp b/src/DabMux.cpp index 6dd30bf..2af58c5 100644 --- a/src/DabMux.cpp +++ b/src/DabMux.cpp @@ -125,7 +125,6 @@ typedef DWORD32 uint32_t; #include "DabMux.h" #include "MuxElements.h" #include "utils.h" -#include "ParserCmdline.h" #include "ConfigParser.h" #include "ManagementServer.h" #include "Log.h" @@ -188,8 +187,8 @@ int main(int argc, char *argv[]) sa.sa_handler = &signalHandler; const int sigs[] = {SIGHUP, SIGQUIT, SIGINT, SIGTERM}; - for (int i = 0; i < 4; i++) { - if (sigaction(sigs[i], &sa, NULL) == -1) { + for (int sig : sigs) { + if (sigaction(sig, &sa, nullptr) == -1) { perror("sigaction"); return EXIT_FAILURE; } @@ -252,18 +251,9 @@ int main(int argc, char *argv[]) throw MuxInitException(e.what()); } } -#if ENABLE_CMDLINE_OPTIONS - else { - if (!parse_cmdline(argv, argc, outputs, ensemble, &enableTist, &FICL, - &factumAnalyzer, &limit)) { - throw MuxInitException(); - } - } -#else else { throw MuxInitException("No configuration file specified"); } -#endif int mgmtserverport = pt.get<int>("general.managementport", pt.get<int>("general.statsserverport", 0) ); @@ -399,7 +389,7 @@ int main(int argc, char *argv[]) throw MuxInitException(); } - if (output == NULL) { + if (output == nullptr) { etiLog.level(error) << "Unable to init output " << uri; diff --git a/src/Dmb.cpp b/src/Dmb.cpp index e168b63..92688ea 100644 --- a/src/Dmb.cpp +++ b/src/Dmb.cpp @@ -45,7 +45,7 @@ Dmb::Dmb(bool reverse) : interleaver(12, 17), encoder(204, 188) { - buffer = NULL; + buffer = nullptr; bufferSize = 0; setReverse(reverse); } @@ -53,7 +53,7 @@ encoder(204, 188) Dmb::~Dmb() { - if (buffer != NULL) { + if (buffer != nullptr) { delete[] buffer; } } @@ -93,7 +93,7 @@ int Dmb::encode( char* output = reinterpret_cast<char*>(dataOut); if (bufferSize < sizeIn + 204) { - if (buffer != NULL) { + if (buffer != nullptr) { delete[] buffer; } unsigned char* oldBuffer = buffer; @@ -263,9 +263,9 @@ int Dmb::sync(void* dataIn, unsigned long sizeIn) char* sync = input; unsigned long size = sizeIn; - while (sync != NULL) { + while (sync != nullptr) { sync = (char*)memchr(sync, 0x47, size); - if (sync != NULL) { + if (sync != nullptr) { int offset = sync - input; if (offset % 12 != 0) { offset = ((offset / 12) * 12) + 12; diff --git a/src/InetAddress.cpp b/src/InetAddress.cpp index 90cdd06..d92e1b9 100644 --- a/src/InetAddress.cpp +++ b/src/InetAddress.cpp @@ -44,8 +44,8 @@ int inetErrNo = 0; -const char *inetErrMsg = NULL; -const char *inetErrDesc = NULL; +const char *inetErrMsg = nullptr; +const char *inetErrDesc = nullptr; /** diff --git a/src/Makefile.am b/src/Makefile.am index 5edd0a4..1d33231 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ # (Communications Research Center Canada) # Pascal Charest # -# Copyright (C) 2014, Matthias P. Braendli, http://mpb.li +# Copyright (C) 2016, Matthias P. Braendli, http://opendigitalradio.org # # This file is part of ODR-DabMux. @@ -41,7 +41,7 @@ CURL_LIBS = endif odr_dabmux_CFLAGS =-Wall -I$(FARSYNC_DIR) $(GITVERSION_FLAGS) -odr_dabmux_CXXFLAGS =-Wall -I$(FARSYNC_DIR) $(GITVERSION_FLAGS) +odr_dabmux_CXXFLAGS =-Wall -std=c++11 -I$(FARSYNC_DIR) $(GITVERSION_FLAGS) odr_dabmux_LDADD =$(ZMQ_LIBS) $(CURL_LIBS) \ -lpthread -lboost_thread -lboost_system -lboost_regex @@ -87,7 +87,6 @@ odr_dabmux_SOURCES =DabMux.cpp DabMux.h \ Log.h Log.cpp \ ManagementServer.h ManagementServer.cpp \ MuxElements.cpp MuxElements.h \ - ParserCmdline.cpp ParserCmdline.h \ PcDebug.h \ ReedSolomon.h ReedSolomon.cpp \ RemoteControl.cpp RemoteControl.h \ @@ -115,7 +114,7 @@ odr_dabmux_SOURCES =DabMux.cpp DabMux.h \ fig/FIGCarousel.cpp fig/FIGCarousel.h \ fig/TransitionHandler.h \ mpeg.h mpeg.c \ - prbs.h prbs.c \ + prbs.h prbs.cpp \ utils.cpp utils.h \ zmq.hpp \ fec/char.h fec/rs-common.h \ @@ -135,4 +134,4 @@ odr_zmq2farsync_SOURCES = zmq2farsync/zmq2farsync.cpp \ zmq.hpp odr_zmq2farsync_LDADD = $(ZMQ_LIBS) odr_zmq2farsync_CFLAGS = -Wall $(GITVERSION_FLAGS) -I$(FARSYNC_DIR) -odr_zmq2farsync_CXXFLAGS = -Wall $(GITVERSION_FLAGS) -I$(FARSYNC_DIR) +odr_zmq2farsync_CXXFLAGS = -Wall -std=c++11 $(GITVERSION_FLAGS) -I$(FARSYNC_DIR) diff --git a/src/ManagementServer.cpp b/src/ManagementServer.cpp index dd4da89..c44738a 100644 --- a/src/ManagementServer.cpp +++ b/src/ManagementServer.cpp @@ -339,11 +339,11 @@ std::string InputStat::encodeStateJSON() return ss.str(); } -input_state_t InputStat::determineState(void) +input_state_t InputStat::determineState() { boost::mutex::scoped_lock lock(m_mutex); - time_t now = time(NULL); + time_t now = time(nullptr); input_state_t state; /* if the last event was more that INPUT_COUNTER_RESET_TIME diff --git a/src/MuxElements.cpp b/src/MuxElements.cpp index 510775e..2215bda 100644 --- a/src/MuxElements.cpp +++ b/src/MuxElements.cpp @@ -71,7 +71,7 @@ std::string AnnouncementCluster::tostring() const return ss.str(); } -bool AnnouncementCluster::is_active(void) +bool AnnouncementCluster::is_active() { if (m_deferred_start_time) { @@ -415,7 +415,7 @@ const string DabComponent::get_parameter(const string& parameter) const subchannel_type_t DabService::getType(std::shared_ptr<dabEnsemble> ensemble) const { vector<DabSubchannel*>::iterator subchannel; - vector<DabComponent*>::iterator component = + auto component = getComponent(ensemble->components, id); if (component == ensemble->components.end()) { throw std::runtime_error("No component found for service"); @@ -647,17 +647,17 @@ unsigned short DabSubchannel::getSizeCu() const return 0; } -unsigned short DabSubchannel::getSizeByte(void) const +unsigned short DabSubchannel::getSizeByte() const { return bitrate * 3; } -unsigned short DabSubchannel::getSizeWord(void) const +unsigned short DabSubchannel::getSizeWord() const { return (bitrate * 3) >> 2; } -unsigned short DabSubchannel::getSizeDWord(void) const +unsigned short DabSubchannel::getSizeDWord() const { return (bitrate * 3) >> 3; } diff --git a/src/ParserCmdline.cpp b/src/ParserCmdline.cpp deleted file mode 100644 index 8ce6f7a..0000000 --- a/src/ParserCmdline.cpp +++ /dev/null @@ -1,771 +0,0 @@ -/* - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, - 2011, 2012 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - - Includes modifications - 2012, Matthias P. Braendli, matthias.braendli@mpb.li - - The command-line parser reads the parameters given on the command - line, and builds an ensemble. - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see <http://www.gnu.org/licenses/>. -*/ -#include "ParserCmdline.h" - -#if ENABLE_CMDLINE_OPTIONS - -#include <vector> -#include <stdint.h> -#include <cstring> -#include "dabOutput/dabOutput.h" -#include "dabInput.h" -#include "utils.h" -#include "dabInputFile.h" -#include "dabInputFifo.h" -#include "dabInputMpegFile.h" -#include "dabInputMpegFifo.h" -#include "dabInputDabplusFile.h" -#include "dabInputDabplusFifo.h" -#include "dabInputPacketFile.h" -#include "dabInputEnhancedPacketFile.h" -#include "dabInputEnhancedFifo.h" -#include "dabInputUdp.h" -#include "dabInputBridgeUdp.h" -#include "dabInputSlip.h" -#include "dabInputTest.h" -#include "dabInputPrbs.h" -#include "dabInputRawFile.h" -#include "dabInputRawFifo.h" -#include "dabInputDmbFile.h" -#include "dabInputDmbUdp.h" -#include "DabMux.h" - - -#ifdef _WIN32 -# pragma warning ( disable : 4103 ) -# include "Eti.h" -# pragma warning ( default : 4103 ) -#else -# include "Eti.h" -#endif - - -#ifdef _WIN32 -# include <time.h> -# include <process.h> -# include <io.h> -# include <conio.h> -# include <winsock2.h> // For types... -typedef u_char uint8_t; -typedef WORD uint16_t; -typedef DWORD32 uint32_t; - -# ifndef __MINGW32__ -# include "xgetopt.h" -# endif -# define read _read -# define snprintf _snprintf -# define sleep(a) Sleep((a) * 1000) -#else -# include <unistd.h> -# include <sys/time.h> -# include <sys/wait.h> -# include <sys/ioctl.h> -# include <sys/times.h> -#endif - -using namespace std; - -bool parse_cmdline(char **argv, - int argc, - vector<dabOutput*> &outputs, - dabEnsemble* ensemble, - bool* enableTist, - unsigned* FICL, - bool* factumAnalyzer, - unsigned long* limit - ) -{ - vector<dabOutput*>::iterator output; - vector<DabSubchannel*>::iterator subchannel = ensemble->subchannels.end(); - vector<DabComponent*>::iterator component = ensemble->components.end(); - vector<DabService*>::iterator service = ensemble->services.end(); - dabProtection* protection = NULL; - - // Yes, this is ugly, but it suppresses warnings - dabInputOperations operations = { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL - }; - - // Default ensemble parameters: - ensemble->lto = 0; - ensemble->lto_auto = true; // Transmit local time by default - ensemble->mode = 1; // Default TM=1 - - // Parse command line - int scids_temp = 0; - - const char* error_at = ""; - int success; - - char* progName = strrchr(argv[0], '/'); - if (progName == NULL) { - progName = argv[0]; - } else { - ++progName; - } - - while (1) { - int c = getopt(argc, argv, - "A:B:CD:E:F:L:M:O:P:STVa:b:c:de:f:g:hi:kl:m:n:op:rst:y:z"); - if (c == -1) { - break; - } - switch (c) { - case 'O': - char* proto; - - proto = strstr(optarg, "://"); - if (proto == NULL) { - etiLog.log(error, - "No protocol defined for output\n"); - goto EXIT; - } else { - *proto = 0; // terminate optarg - outputs.push_back(new dabOutput(optarg, proto + 3)); - output = outputs.end() - 1; - } - - subchannel = ensemble->subchannels.end(); - protection = NULL; - component = ensemble->components.end(); - service = ensemble->services.end(); - break; - case 'S': - ensemble->services.push_back(new DabService("?")); - - subchannel = ensemble->subchannels.end(); - protection = NULL; - component = ensemble->components.end(); - service = ensemble->services.end() - 1; - output = outputs.end(); - - (*service)->label.setLabel("Service", "Serv"); - (*service)->id = DEFAULT_SERVICE_ID + ensemble->services.size(); - (*service)->pty = 0; - (*service)->language = 0; - scids_temp = 0; - - break; - case 'C': - if (service == ensemble->services.end()) { - etiLog.log(error, "You must define a service" - " before using option -%c\n", c); - printUsage(progName); - goto EXIT; - } - - ensemble->components.push_back(new DabComponent("?")); - - component = ensemble->components.end() - 1; - subchannel = ensemble->subchannels.end(); - protection = NULL; - output = outputs.end(); - - (*component)->label.setLabel("Component", "Comp"); - (*component)->serviceId = (*service)->id; - (*component)->subchId = (*(ensemble->subchannels.end() - 1))->id; - (*component)->SCIdS = scids_temp++; - break; - case 'A': - case 'B': - case 'D': - case 'E': - case 'F': - case 'M': - case 'P': - case 'T': - if (optarg == NULL && c != 'T') { - etiLog.log(error, - "Missing parameter for option -%c\n", c); - printUsage(progName); - goto EXIT; - } - - ensemble->subchannels.push_back(new DabSubchannel); - - subchannel = ensemble->subchannels.end() - 1; - protection = &(*subchannel)->protection; - component = ensemble->components.end(); - service = ensemble->services.end(); - output = outputs.end(); - - if (c != 'T') { - (*subchannel)->inputName = optarg; - } else { - (*subchannel)->inputName = NULL; - } - if (0) { -#if defined(HAVE_INPUT_FILE) && defined(HAVE_FORMAT_MPEG) - } else if (c == 'A') { - (*subchannel)->inputProto = "file"; - (*subchannel)->type = Audio; - (*subchannel)->bitrate = 0; - operations = dabInputMpegFileOperations; -#endif // defined(HAVE_INPUT_FILE) && defined(HAVE_FORMAT_MPEG) -#if defined(HAVE_FORMAT_DABPLUS) - } else if (c == 'F') { - (*subchannel)->type = Audio; - (*subchannel)->bitrate = 32; - - char* proto; - - proto = strstr(optarg, "://"); - if (proto == NULL) { - (*subchannel)->inputProto = "file"; - } else { - (*subchannel)->inputProto = optarg; - (*subchannel)->inputName = proto + 3; - *proto = 0; - } - - if (0) { -#if defined(HAVE_INPUT_FILE) - } else if (strcmp((*subchannel)->inputProto, "file") == 0) { - operations = dabInputDabplusFileOperations; -#endif // defined(HAVE_INPUT_FILE) - } else { - etiLog.log(error, - "Invalid protocol for DAB+ input (%s)\n", - (*subchannel)->inputProto); - printUsage(progName); - goto EXIT; - } -#endif // defined(HAVE_FORMAT_DABPLUS) - } else if (c == 'B') { - char* proto; - - proto = strstr(optarg, "://"); - if (proto == NULL) { - (*subchannel)->inputProto = "udp"; - } else { - (*subchannel)->inputProto = optarg; - (*subchannel)->inputName = proto + 3; - *proto = 0; - } - if (0) { -#if defined(HAVE_FORMAT_BRIDGE) -#if defined(HAVE_INPUT_UDP) - } else if (strcmp((*subchannel)->inputProto, "udp") == 0) { - operations = dabInputBridgeUdpOperations; -#endif // defined(HAVE_INPUT_UDP) -#endif // defined(HAVE_FORMAT_BRIDGE) - } - } else if (c == 'D') { - char* proto; - - proto = strstr(optarg, "://"); - if (proto == NULL) { - (*subchannel)->inputProto = "udp"; - } else { - (*subchannel)->inputProto = optarg; - (*subchannel)->inputName = proto + 3; - *proto = 0; - } - if (0) { -#if defined(HAVE_INPUT_UDP) - } else if (strcmp((*subchannel)->inputProto, "udp") == 0) { - operations = dabInputUdpOperations; -#endif -#if defined(HAVE_INPUT_PRBS) && defined(HAVE_FORMAT_RAW) - } else if (strcmp((*subchannel)->inputProto, "prbs") == 0) { - operations = dabInputPrbsOperations; -#endif -#if defined(HAVE_INPUT_FILE) && defined(HAVE_FORMAT_RAW) - } else if (strcmp((*subchannel)->inputProto, "file") == 0) { - operations = dabInputRawFileOperations; -#endif - } else if (strcmp((*subchannel)->inputProto, "fifo") == 0) { - operations = dabInputRawFifoOperations; - } else { - etiLog.log(error, - "Invalid protocol for data input (%s)\n", - (*subchannel)->inputProto); - printUsage(progName); - goto EXIT; - } - - (*subchannel)->type = DataDmb; - (*subchannel)->bitrate = DEFAULT_DATA_BITRATE; -#if defined(HAVE_INPUT_TEST) && defined(HAVE_FORMAT_RAW) - } else if (c == 'T') { - (*subchannel)->inputProto = "test"; - (*subchannel)->type = DataDmb; - (*subchannel)->bitrate = DEFAULT_DATA_BITRATE; - operations = dabInputTestOperations; -#endif // defined(HAVE_INPUT_TEST)) && defined(HAVE_FORMAT_RAW) -#ifdef HAVE_FORMAT_PACKET - } else if (c == 'P') { - (*subchannel)->inputProto = "file"; - (*subchannel)->type = Packet; - (*subchannel)->bitrate = DEFAULT_PACKET_BITRATE; -#ifdef HAVE_INPUT_FILE - operations = dabInputPacketFileOperations; -#elif defined(HAVE_INPUT_FIFO) - operations = dabInputFifoOperations; -#else -# pragma error("Must defined at least one packet input") -#endif // defined(HAVE_INPUT_FILE) -#ifdef HAVE_FORMAT_EPM - } else if (c == 'E') { - (*subchannel)->inputProto = "file"; - (*subchannel)->type = Packet; - (*subchannel)->bitrate = DEFAULT_PACKET_BITRATE; - operations = dabInputEnhancedPacketFileOperations; -#endif // defined(HAVE_FORMAT_EPM) -#endif // defined(HAVE_FORMAT_PACKET) -#ifdef HAVE_FORMAT_DMB - } else if (c == 'M') { - char* proto; - - proto = strstr(optarg, "://"); - if (proto == NULL) { - (*subchannel)->inputProto = "udp"; - } else { - (*subchannel)->inputProto = optarg; - (*subchannel)->inputName = proto + 3; - *proto = 0; - } - if (strcmp((*subchannel)->inputProto, "udp") == 0) { - operations = dabInputDmbUdpOperations; - } else if (strcmp((*subchannel)->inputProto, "file") == 0) { - operations = dabInputDmbFileOperations; - } else { - etiLog.log(error, - "Invalid protocol for DMB input (%s)\n", - (*subchannel)->inputProto); - printUsage(progName); - goto EXIT; - } - - (*subchannel)->type = DataDmb; - (*subchannel)->bitrate = DEFAULT_DATA_BITRATE; -#endif - } else { - etiLog.log(error, - "Service '%c' not yet coded!\n", c); - goto EXIT; - } - (*subchannel)->input = new DabInputCompatible(operations); - - for (int i = 0; i < 64; ++i) { // Find first free subchannel - subchannel = getSubchannel(ensemble->subchannels, i); - if (subchannel == ensemble->subchannels.end()) { - subchannel = ensemble->subchannels.end() - 1; - (*subchannel)->id = i; - break; - } - } - (*subchannel)->startAddress = 0; - - if (c == 'A') { - protection->form = UEP; - protection->level = 2; - protection->uep.tableIndex = 0; - } else { - protection->form = EEP; - protection->level = 2; - protection->eep.profile = EEP_A; - } - break; - case 'L': - if (optarg == NULL) { - etiLog.log(error, - "Missing parameter for option -L\n"); - printUsage(progName); - goto EXIT; - } - if (service == ensemble->services.end()) { - ensemble->label.setLabel(optarg); - } else if (component != ensemble->components.end()) { - (*component)->label.setLabel(optarg); - } else { // Service - (*service)->label.setLabel(optarg); - } - break; - case 'V': - goto EXIT; - case 'l': - if (optarg == NULL) { - etiLog.log(error, - "Missing parameter for option -l\n"); - printUsage(progName); - goto EXIT; - } - - if (service == ensemble->services.end()) { - success = ensemble->label.setLabel(ensemble->label.text(), optarg); - error_at = "Ensemble"; - } - else if (component != ensemble->components.end()) { - success = (*component)->label.setLabel(ensemble->label.text(), optarg); - error_at = "Component"; - } - else { - success = (*service)->label.setLabel(ensemble->label.text(), optarg); - error_at = "Service"; - } - - switch (success) - { - case 0: - break; - case -1: - etiLog.level(error) << error_at << " short label " << - optarg << " is not subset of label '" << - ensemble->label.text() << "'"; - goto EXIT; - case -2: - etiLog.level(error) << error_at << " short label " << - optarg << " is too long (max 8 characters)"; - goto EXIT; - case -3: - etiLog.level(error) << error_at << " label " << - ensemble->label.text() << " is too long (max 16 characters)"; - goto EXIT; - default: - etiLog.level(error) << error_at << " short label definition: program error !"; - abort(); - } - break; - case 'i': - if (optarg == NULL) { - etiLog.log(error, - "Missing parameter for option -i\n"); - printUsage(progName); - goto EXIT; - } - if (component != ensemble->components.end()) { - (*component)->subchId = strtoul(optarg, NULL, 0); - } else if (subchannel != ensemble->subchannels.end()) { - (*subchannel)->id = strtoul(optarg, NULL, 0); - } else if (service != ensemble->services.end()) { - (*service)->id = strtoul(optarg, NULL, 0); - if ((*service)->id == 0) { - etiLog.log(error, - "Service id 0 is invalid\n"); - goto EXIT; - } - } else { - ensemble->id = strtoul(optarg, NULL, 0); - } - break; - case 'b': - if (optarg == NULL) { - etiLog.log(error, - "Missing parameter for option -b\n"); - printUsage(progName); - goto EXIT; - } - if (subchannel == ensemble->subchannels.end()) { - etiLog.log(error, - "You must define a subchannel first!\n"); - printUsage(progName); - goto EXIT; - } - (*subchannel)->bitrate = strtoul(optarg, NULL, 0); - if (((*subchannel)->bitrate & 0x7) != 0) { - (*subchannel)->bitrate += 8; - (*subchannel)->bitrate &= ~0x7; - etiLog.log(warn, - "bitrate must be multiple of 8 -> ceiling to %i\n", - (*subchannel)->bitrate); - } - break; - case 'c': - if (optarg == NULL) { - etiLog.log(error, - "Missing parameter for option -c\n"); - printUsage(progName); - goto EXIT; - } - ensemble->ecc = strtoul(optarg, NULL, 0); - break; -#if defined(HAVE_INPUT_FIFO) && defined(HAVE_INPUT_FILE) - case 'k': - if (subchannel == ensemble->subchannels.end()) { - etiLog.log(error, - "You must define a subchannel first!\n"); - printUsage(progName); - goto EXIT; - } - switch ((*subchannel)->type) { -#ifdef HAVE_FORMAT_PACKET - case Packet: - if ( ((DabInputCompatible*)(*subchannel)->input)->getOpts() == dabInputPacketFileOperations) { - operations = dabInputFifoOperations; -#ifdef HAVE_FORMAT_EPM - } else if ( ((DabInputCompatible*)(*subchannel)->input)->getOpts() == dabInputEnhancedPacketFileOperations) { - operations = dabInputEnhancedFifoOperations; -#endif // defined(HAVE_FORMAT_EPM) - } else { - etiLog.log(error, - "Error, wrong packet subchannel operations!\n"); - goto EXIT; - } - delete (*subchannel)->input; - (*subchannel)->input = new DabInputCompatible(operations); - (*subchannel)->inputProto = "fifo"; - break; -#endif // defined(HAVE_FORMAT_PACKET) -#ifdef HAVE_FORMAT_MPEG - case Audio: - if ( ((DabInputCompatible*)(*subchannel)->input)->getOpts() == dabInputMpegFileOperations) { - operations = dabInputMpegFifoOperations; - } else if (((DabInputCompatible*)(*subchannel)->input)->getOpts() == - dabInputDabplusFileOperations) { - operations = dabInputDabplusFifoOperations; - } else { - etiLog.log(error, - "Error, wrong audio subchannel operations!\n"); - goto EXIT; - } - delete (*subchannel)->input; - (*subchannel)->input = new DabInputCompatible(operations); - (*subchannel)->inputProto = "fifo"; - break; -#endif // defined(HAVE_FORMAT_MPEG) - default: - etiLog.log(error, - "sorry, non-blocking input file is " - "only valid with audio or packet services\n"); - goto EXIT; - } - break; -#endif // defined(HAVE_INPUT_FIFO) && defined(HAVE_INPUT_FILE) - case 'p': - int level; - if (optarg == NULL) { - etiLog.log(error, - "Missing parameter for option -p\n"); - printUsage(progName); - goto EXIT; - } - if (subchannel == ensemble->subchannels.end()) { - etiLog.log(error, - "You must define a subchannel first!\n"); - printUsage(progName); - goto EXIT; - } - level = strtoul(optarg, NULL, 0) - 1; - if (protection->form == UEP) { - if ((level < 0) || (level > 4)) { - etiLog.log(error, - "UEP protection level must be between " - "1 to 5 inclusively (current = %i)\n", level); - goto EXIT; - } - } - else if (protection->form == EEP) { - if ((level < 0) || (level > 3)) { - etiLog.log(error, - "EEP protection level must be between " - "1 to 4 inclusively (current = %i)\n", level); - goto EXIT; - } - } - protection->level = level; - break; - case 'm': - if (optarg) { - ensemble->mode = strtoul(optarg, NULL, 0); - if ((ensemble->mode < 1) || (ensemble->mode > 4)) { - etiLog.log(error, - "Mode must be between 1-4\n"); - goto EXIT; - } - if (ensemble->mode == 4) - ensemble->mode = 0; - if (ensemble->mode == 3) { - *FICL = 32; - } else { - *FICL = 24; - } - } else { - etiLog.log(error, - "Missing parameter for option -m\n"); - printUsage(progName); - goto EXIT; - } - break; - case 'n': - if (optarg) { - *limit = strtoul(optarg, NULL, 0); - } else { - etiLog.log(error, - "Missing parameter for option -n\n"); - printUsage(progName); - goto EXIT; - } - break; - case 'o': - etiLog.register_backend(new LogToSyslog()); // TODO don't leak the LogToSyslog backend - break; - case 't': - if (optarg == NULL) { - etiLog.log(error, - "Missing parameter for option -t\n"); - printUsage(progName); - goto EXIT; - } - if (component == ensemble->components.end()) { - etiLog.log(error, - "You must define a component before setting " - "service type!\n"); - printUsage(progName); - goto EXIT; - } - (*component)->type = strtoul(optarg, NULL, 0); - break; - case 'a': - if (component == ensemble->components.end()) { - etiLog.log(error, - "You must define a component before setting " - "packet address!\n"); - printUsage(progName); - goto EXIT; - } - if (!(*component)->isPacketComponent(ensemble->subchannels)) { - etiLog.log(error, "address\n"); - printUsage(progName); - goto EXIT; - } - (*component)->packet.address = strtoul(optarg, NULL, 0); - break; - case 'd': - if (component == ensemble->components.end()) { - etiLog.log(error, - "You must define a component before setting " - "datagroup!\n"); - printUsage(progName); - goto EXIT; - } - if (!(*component)->isPacketComponent(ensemble->subchannels)) { - etiLog.log(error, "datagroup\n"); - printUsage(progName); - goto EXIT; - } - (*component)->packet.datagroup = true; - break; - case 'f': - if (component == ensemble->components.end()) { - etiLog.log(error, - "You must define a component first!\n"); - printUsage(progName); - goto EXIT; - } - if (!(*component)->isPacketComponent(ensemble->subchannels)) { - etiLog.log(error, "application type\n"); - printUsage(progName); - goto EXIT; - } - (*component)->packet.appType = strtoul(optarg, NULL, 0); - break; - case 'g': - if (service == ensemble->services.end()) { - etiLog.log(error, "You must define a service" - " before using option -%c\n", c); - printUsage(progName); - goto EXIT; - } - (*service)->language = strtoul(optarg, NULL, 0); - break; - case 's': - { - /* - struct timeval tv; - gettimeofday(&tv, NULL); - unsigned _8ms = (tv.tv_usec / 1000) / 8; - unsigned _1ms = (tv.tv_usec - (_8ms * 8000)) / 1000; - unsigned _4us = 20; - unsigned _488ns = 0; - unsigned _61ns = 0; - timestamp = (((((((_8ms << 3) | _1ms) << 8) | _4us) << 3) | _488ns) << 8) | _61ns; - */ - *enableTist = true; - } - break; - case 'y': - if (service == ensemble->services.end()) { - etiLog.log(error, "You must define a service" - " before using option -%c\n", c); - printUsage(progName); - goto EXIT; - } - (*service)->pty = strtoul(optarg, NULL, 0); - break; - case 'z': - *factumAnalyzer = true; - break; - case 'r': - etiLog.log(info, - "Enabling throttled output using simul, one frame every 24ms\n"); - outputs.push_back(new dabOutput("simul", "simul")); - output = outputs.end() - 1; - - subchannel = ensemble->subchannels.end(); - protection = NULL; - component = ensemble->components.end(); - service = ensemble->services.end(); - break; - case '?': - case 'h': - printUsage(progName, stdout); - goto EXIT; - default: - etiLog.log(error, "Option '%c' not coded yet\n", c); - goto EXIT; - } - } - if (optind < argc) { - etiLog.log(error, "Too much parameters:"); - while (optind < argc) { - etiLog.log(error, " %s", argv[optind++]); - } - etiLog.log(error, "\n"); - printUsage(progName); - goto EXIT; - } - - return true; -EXIT: - return false; -} - -#endif // ENABLE_CMDLINE_OPTIONS - diff --git a/src/ParserCmdline.h b/src/ParserCmdline.h deleted file mode 100644 index 1c4545b..0000000 --- a/src/ParserCmdline.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, - 2011, 2012 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - - Includes modifications - 2012, Matthias P. Braendli, matthias.braendli@mpb.li - - The command-line parser reads the parameters given on the command - line, and builds an ensemble. - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see <http://www.gnu.org/licenses/>. -*/ -#ifndef _PARSER_CMDLINE -#define _PARSER_CMDLINE - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include <vector> -#include "MuxElements.h" - -#define ENABLE_CMDLINE_OPTIONS 0 - -#if ENABLE_CMDLINE_OPTIONS - -bool parse_cmdline(char **argv, - int argc, - std::vector<dabOutput*> &outputs, - dabEnsemble* ensemble, - bool* enableTist, - unsigned* FICL, - bool* factumAnalyzer, - unsigned long* limit - ); - -#endif - -#endif diff --git a/src/ReedSolomon.cpp b/src/ReedSolomon.cpp index 69e1191..38d8ea8 100644 --- a/src/ReedSolomon.cpp +++ b/src/ReedSolomon.cpp @@ -1,6 +1,11 @@ /* Copyright (C) 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) + + Copyright (C) 2016 + Matthias P. Braendli, matthias.braendli@mpb.li + + http://www.opendigitalradio.org */ /* This file is part of ODR-DabMux. @@ -20,6 +25,8 @@ */ #include "ReedSolomon.h" +#include <vector> +#include <algorithm> #include <stdexcept> #include <sstream> #include <stdio.h> // For galois.h ... @@ -29,7 +36,6 @@ extern "C" { #include "fec/fec.h" } #include <assert.h> -#include <stdlib.h> #define SYMSIZE 8 @@ -38,8 +44,8 @@ ReedSolomon::ReedSolomon(int N, int K, bool reverse, int gfpoly, int firstRoot, { setReverse(reverse); - myN = N; - myK = K; + m_N = N; + m_K = K; const int symsize = SYMSIZE; const int nroots = N - K; // For EDI PFT, this must be 48 @@ -47,7 +53,7 @@ ReedSolomon::ReedSolomon(int N, int K, bool reverse, int gfpoly, int firstRoot, rsData = init_rs_char(symsize, gfpoly, firstRoot, primElem, nroots, pad); - if (rsData == NULL) { + if (rsData == nullptr) { std::stringstream ss; ss << "Invalid Reed-Solomon parameters! " << "N=" << N << " ; K=" << K << " ; pad=" << pad; @@ -68,25 +74,25 @@ void ReedSolomon::setReverse(bool state) } -int ReedSolomon::encode(void* data, void* fec, unsigned long size) +int ReedSolomon::encode(void* data, void* fec, size_t size) { - unsigned char* input = reinterpret_cast<unsigned char*>(data); - unsigned char* output = reinterpret_cast<unsigned char*>(fec); + uint8_t* input = reinterpret_cast<uint8_t*>(data); + uint8_t* output = reinterpret_cast<uint8_t*>(fec); int ret = 0; if (reverse) { - unsigned char* buffer = new unsigned char[myN]; - memcpy(buffer, input, myK); - memcpy(&buffer[myK], output, myN - myK); + std::vector<uint8_t> buffer(m_N); + + memcpy(&buffer[0], input, m_K); + memcpy(&buffer[m_K], output, m_N - m_K); - ret = decode_rs_char(rsData, buffer, NULL, 0); + ret = decode_rs_char(rsData, &buffer[0], nullptr, 0); if ((ret != 0) && (ret != -1)) { - memcpy(input, buffer, myK); - memcpy(output, &buffer[myK], myN - myK); + memcpy(input, &buffer[0], m_K); + memcpy(output, &buffer[m_K], m_N - m_K); } - - delete[] buffer; - } else { + } + else { encode_rs_char(rsData, input, output); } @@ -94,15 +100,16 @@ int ReedSolomon::encode(void* data, void* fec, unsigned long size) } -int ReedSolomon::encode(void* data, unsigned long size) +int ReedSolomon::encode(void* data, size_t size) { - unsigned char* input = reinterpret_cast<unsigned char*>(data); + uint8_t* input = reinterpret_cast<uint8_t*>(data); int ret = 0; if (reverse) { - ret = decode_rs_char(rsData, input, NULL, 0); - } else { - encode_rs_char(rsData, input, &input[myK]); + ret = decode_rs_char(rsData, input, nullptr, 0); + } + else { + encode_rs_char(rsData, input, &input[m_K]); } return ret; diff --git a/src/ReedSolomon.h b/src/ReedSolomon.h index d96a522..abcef62 100644 --- a/src/ReedSolomon.h +++ b/src/ReedSolomon.h @@ -1,6 +1,11 @@ /* Copyright (C) 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) + + Copyright (C) 2016 + Matthias P. Braendli, matthias.braendli@mpb.li + + http://www.opendigitalradio.org */ /* This file is part of ODR-DabMux. @@ -19,34 +24,33 @@ along with ODR-DabMux. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef _REEDSOLOMON -#define _REEDSOLOMON +#pragma once #ifdef HAVE_CONFIG_H # include <config.h> #endif +#include <stdlib.h> class ReedSolomon { public: - ReedSolomon(int N, int K, bool reverse = false, + ReedSolomon(int N, int K, + bool reverse = false, int gfpoly = 0x11d, int firstRoot = 0, int primElem = 1); - ReedSolomon(const ReedSolomon& clone); - virtual ~ReedSolomon(); + ReedSolomon(const ReedSolomon& other) = delete; + ReedSolomon operator=(const ReedSolomon& other) = delete; + ~ReedSolomon(); void setReverse(bool state); - int encode(void* data, void* fec, unsigned long size); - int encode(void* data, unsigned long size); - -protected: - int myN; - int myK; + int encode(void* data, void* fec, size_t size); + int encode(void* data, size_t size); private: + int m_N; + int m_K; + void* rsData; bool reverse; }; - -#endif // _REEDSOLOMON diff --git a/src/dabInputDabplusFifo.cpp b/src/dabInputDabplusFifo.cpp index 81f373b..94aec13 100644 --- a/src/dabInputDabplusFifo.cpp +++ b/src/dabInputDabplusFifo.cpp @@ -68,7 +68,7 @@ int dabInputDabplusFifoInit(void** args) dabInputDabplusFifoData* data = new dabInputDabplusFifoData; dabInputFifoInit(&data->fifoData); - data->buffer = NULL; + data->buffer = nullptr; data->bufferSize = 0; data->bufferIndex = 0; data->bufferOffset = 0; @@ -100,7 +100,7 @@ int dabInputDabplusFifoRead(void* args, void* buffer, int size) dabInputDabplusFifoData* data = (dabInputDabplusFifoData*)args; if (data->bufferSize != (size_t)size * 5) { - if (data->buffer != NULL) { + if (data->buffer != nullptr) { delete[] data->buffer; } data->buffer = new uint8_t[size * 5]; diff --git a/src/dabInputDabplusFile.cpp b/src/dabInputDabplusFile.cpp index 396a376..64b7f07 100644 --- a/src/dabInputDabplusFile.cpp +++ b/src/dabInputDabplusFile.cpp @@ -40,8 +40,8 @@ struct dabInputOperations dabInputDabplusFileOperations = { dabInputDabplusFileOpen, dabInputSetbuf, dabInputDabplusFileRead, - NULL, - NULL, + nullptr, + nullptr, dabInputDabplusFileReadFrame, dabInputSetbitrate, dabInputDabplusFileClose, @@ -54,7 +54,7 @@ int dabInputDabplusFileInit(void** args) { dabInputDabplusFileData* data = new dabInputDabplusFileData; data->file = -1; - data->buffer = NULL; + data->buffer = nullptr; data->bufferSize = 0; data->bufferIndex = 0; @@ -80,7 +80,7 @@ int dabInputDabplusFileRead(void* args, void* buffer, int size) { dabInputDabplusFileData* data = (dabInputDabplusFileData*)args; if (data->bufferSize != (size_t)size * 5) { - if (data->buffer == NULL) { + if (data->buffer == nullptr) { delete[] data->buffer; } data->buffer = new uint8_t[size * 5]; @@ -158,7 +158,7 @@ int dabInputDabplusFileClose(void* args) int dabInputDabplusFileClean(void** args) { dabInputDabplusFileData* data = (dabInputDabplusFileData*)*args; - if (data->buffer != NULL) { + if (data->buffer != nullptr) { delete[] data->buffer; } delete data; diff --git a/src/dabInputDmbFile.cpp b/src/dabInputDmbFile.cpp index 423d644..17bd72d 100644 --- a/src/dabInputDmbFile.cpp +++ b/src/dabInputDmbFile.cpp @@ -42,14 +42,14 @@ struct dabInputOperations dabInputDmbFileOperations = { dabInputDmbFileInit, dabInputDmbFileOpen, dabInputSetbuf, - NULL, - NULL, - NULL, + nullptr, + nullptr, + nullptr, dabInputDmbFileRead, dabInputSetbitrate, dabInputDmbFileClose, dabInputDmbFileClean, - NULL + nullptr }; @@ -58,7 +58,7 @@ int dabInputDmbFileInit(void** args) dabInputDmbFileData* input = new dabInputDmbFileData; memset(&input->stats, 0, sizeof(input->stats)); input->stats.id = dabInputFifoData::nb++; - input->file = NULL; + input->file = nullptr; input->bufferLength = 0; input->dmb = new Dmb(); *args = input; @@ -73,7 +73,7 @@ int dabInputDmbFileOpen(void* args, const char* inputName) dabInputDmbFileData* input = (dabInputDmbFileData*)args; input->file = fopen(inputName, "r"); - if (input->file == NULL) { + if (input->file == nullptr) { perror(inputName); returnCode = -1; } @@ -138,7 +138,7 @@ int dabInputDmbFileClose(void* args) { dabInputDmbFileData* input = (dabInputDmbFileData*)args; - if (input->file != NULL) { + if (input->file != nullptr) { if (fclose(input->file)) { perror(""); return -1; diff --git a/src/dabInputEnhancedPacketFile.cpp b/src/dabInputEnhancedPacketFile.cpp index 1b5c8bc..3b12e0b 100644 --- a/src/dabInputEnhancedPacketFile.cpp +++ b/src/dabInputEnhancedPacketFile.cpp @@ -29,8 +29,8 @@ struct dabInputOperations dabInputEnhancedPacketFileOperations = { dabInputFileOpen, dabInputSetbuf, dabInputFileRead, - NULL, - NULL, + nullptr, + nullptr, dabInputPacketFileRead, dabInputSetbitrate, dabInputFileClose, diff --git a/src/dabInputFifo.cpp b/src/dabInputFifo.cpp index 3e35c20..6fa3aad 100644 --- a/src/dabInputFifo.cpp +++ b/src/dabInputFifo.cpp @@ -1,6 +1,11 @@ /* Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) + + Copyright (C) 2016 + Matthias P. Braendli, matthias.braendli@mpb.li + + http://www.opendigitalradio.org */ /* This file is part of ODR-DabMux. @@ -61,9 +66,9 @@ int dabInputFifoInit(void** args) data->curSize = 0; data->head = 0; data->tail = 0; - data->buffer = NULL; - data->packetData = NULL; - data->enhancedPacketData = NULL; + data->buffer = nullptr; + data->packetData = nullptr; + data->enhancedPacketData = nullptr; data->packetLength = 0; data->enhancedPacketLength = 0; data->enhancedPacketWaiting = 0; @@ -145,7 +150,7 @@ int dabInputFifoOpen(void* args, const char* filename) return -1; } #else - if (pthread_create(&data->thread, NULL, dabInputFifoThread, data)) { + if (pthread_create(&data->thread, nullptr, dabInputFifoThread, data)) { perror("Can't create FIFO child"); return -1; } @@ -166,7 +171,7 @@ int dabInputFifoSetbuf(void* args, int size) sem_wait(&data->semBuffer); #endif } - if (data->buffer != NULL) { + if (data->buffer != nullptr) { delete data->buffer; } if (size == 0) { @@ -367,7 +372,7 @@ int dabInputFifoClean(void** args) } #else if (data->thread != (pthread_t)NULL) { - if (pthread_join(data->thread, NULL)) { + if (pthread_join(data->thread, nullptr)) { etiLog.log(debug, "ERROR: FIFO child thread had not exit normally\n"); } } @@ -382,12 +387,12 @@ int dabInputFifoClean(void** args) sem_destroy(&data->semFull); sem_destroy(&data->semBuffer); #endif - if (data->packetData != NULL) { + if (data->packetData != nullptr) { delete[] data->packetData; } - if (data->enhancedPacketData != NULL) { + if (data->enhancedPacketData != nullptr) { for (int i = 0; i < 12; ++i) { - if (data->enhancedPacketData[i] != NULL) { + if (data->enhancedPacketData[i] != nullptr) { delete[] data->enhancedPacketData[i]; } } @@ -505,7 +510,7 @@ void* dabInputFifoThread(void* args) sem_post(&data->semBuffer); #endif } - return NULL; + return nullptr; } diff --git a/src/dabInputFifo.h b/src/dabInputFifo.h index e5f5206..99edac6 100644 --- a/src/dabInputFifo.h +++ b/src/dabInputFifo.h @@ -1,6 +1,11 @@ /* Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) + + Copyright (C) 2016 + Matthias P. Braendli, matthias.braendli@mpb.li + + http://www.opendigitalradio.org */ /* This file is part of ODR-DabMux. @@ -19,19 +24,18 @@ along with ODR-DabMux. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef DAB_INPUT_FIFO_H -#define DAB_INPUT_FIFO_H +#pragma once #ifdef HAVE_CONFIG_H -# include "config.h" +# include "config.h" #endif + #include "dabInputFile.h" #include "Log.h" #ifdef _WIN32 # include <io.h> - # define sem_t HANDLE # define O_NONBLOCK 0 #else @@ -97,4 +101,3 @@ void* dabInputFifoThread(void* args); # endif #endif -#endif // DAB_INPUT_FIFO_H diff --git a/src/dabInputFile.cpp b/src/dabInputFile.cpp index 30ab37d..2847caa 100644 --- a/src/dabInputFile.cpp +++ b/src/dabInputFile.cpp @@ -38,7 +38,7 @@ int dabInputFileInit(void** args) data->parity = false; data->packetLength = 0; data->packetData = new unsigned char[96]; - data->enhancedPacketData = NULL; + data->enhancedPacketData = nullptr; data->enhancedPacketLength = 0; data->enhancedPacketWaiting = 0; @@ -79,12 +79,12 @@ int dabInputFileClose(void* args) int dabInputFileClean(void** args) { dabInputFileData* data = (dabInputFileData*)*args; - if (data->packetData != NULL) { + if (data->packetData != nullptr) { delete[] data->packetData; } - if (data->enhancedPacketData != NULL) { + if (data->enhancedPacketData != nullptr) { for (int i = 0; i < 12; ++i) { - if (data->enhancedPacketData[i] != NULL) { + if (data->enhancedPacketData[i] != nullptr) { delete[] data->enhancedPacketData[i]; } } diff --git a/src/dabInputMpegFile.cpp b/src/dabInputMpegFile.cpp index 724ad54..804ea29 100644 --- a/src/dabInputMpegFile.cpp +++ b/src/dabInputMpegFile.cpp @@ -37,8 +37,8 @@ struct dabInputOperations dabInputMpegFileOperations = { dabInputFileOpen, dabInputSetbuf, dabInputFileRead, - NULL, - NULL, + nullptr, + nullptr, dabInputMpegFileRead, dabInputMpegSetbitrate, dabInputFileClose, diff --git a/src/dabInputPacketFile.cpp b/src/dabInputPacketFile.cpp index 3ff4e56..867d9fc 100644 --- a/src/dabInputPacketFile.cpp +++ b/src/dabInputPacketFile.cpp @@ -59,8 +59,8 @@ struct dabInputOperations dabInputPacketFileOperations = { dabInputFileOpen, dabInputSetbuf, dabInputFileRead, - NULL, - NULL, + nullptr, + nullptr, dabInputPacketFileRead, dabInputSetbitrate, dabInputFileClose, @@ -114,7 +114,7 @@ int dabInputPacketFileRead(dabInputOperations* ops, void* args, void* buffer, dataBuffer[22] = 0x60; dataBuffer[23] = 0x4b; length = 24; - } else if (data->enhancedPacketData != NULL) { + } else if (data->enhancedPacketData != nullptr) { if (data->enhancedPacketLength + data->packetLength > (12 * 188)) { memset(dataBuffer, 0, 22); @@ -131,7 +131,7 @@ int dabInputPacketFileRead(dabInputOperations* ops, void* args, void* buffer, length = data->packetLength; data->packetLength = 0; } - if (data->enhancedPacketData != NULL) { + if (data->enhancedPacketData != nullptr) { indexCol = data->enhancedPacketLength / 12; indexRow = data->enhancedPacketLength % 12; // TODO Check if always 0 for (int j = 0; j < length; ++j) { @@ -179,7 +179,7 @@ int dabInputPacketFileRead(dabInputOperations* ops, void* args, void* buffer, data->packetLength = length; continue; } - if (data->enhancedPacketData != NULL) { + if (data->enhancedPacketData != nullptr) { if (data->enhancedPacketLength + length > (12 * 188)) { memcpy(data->packetData, header, 3); ops->read(args, &data->packetData[3], length - 3); @@ -203,7 +203,7 @@ int dabInputPacketFileRead(dabInputOperations* ops, void* args, void* buffer, "read %i out of %i bytes\n", nbBytes, length - 3); break; } - if (data->enhancedPacketData != NULL) { + if (data->enhancedPacketData != nullptr) { indexCol = data->enhancedPacketLength / 12; indexRow = data->enhancedPacketLength % 12; // TODO Check if always 0 for (int j = 0; j < length; ++j) { diff --git a/src/dabInputPrbs.cpp b/src/dabInputPrbs.cpp index 8d8c0d9..f34c427 100644 --- a/src/dabInputPrbs.cpp +++ b/src/dabInputPrbs.cpp @@ -1,6 +1,13 @@ /* Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) + + Copyright (C) 2016 + Matthias P. Braendli, matthias.braendli@mpb.li + + http://www.opendigitalradio.org + + Pseudo-Random Bit Sequence generator for test purposes. */ /* This file is part of ODR-DabMux. @@ -21,126 +28,65 @@ #include "dabInputPrbs.h" +#include <stdexcept> +#include <sstream> #include <string.h> #include <limits.h> #include <stdlib.h> +#include <errno.h> +using namespace std; -#ifdef HAVE_FORMAT_RAW -# ifdef HAVE_INPUT_PRBS - - -struct dabInputOperations dabInputPrbsOperations = { - dabInputPrbsInit, - dabInputPrbsOpen, - NULL, - dabInputPrbsRead, - NULL, - NULL, - dabInputPrbsReadFrame, - dabInputPrbsBitrate, - dabInputPrbsClose, - dabInputPrbsClean, - dabInputPrbsRewind, -}; - - -int dabInputPrbsInit(void** args) -{ - prbs_data* data = new prbs_data; - - memset(data, 0, sizeof(*data)); - - *args = data; - return 0; -} - - -int dabInputPrbsOpen(void* args, const char* name) +int DabInputPrbs::open(const string name) { - prbs_data* data = (prbs_data*)args; - - if (*name != ':') { - etiLog.log(error, - "Sorry, PRBS address format is prbs://:polynomial.\n"); - errno = EINVAL; - return -1; + if (name[0] != ':') { + throw invalid_argument( + "Invalid PRBS address format. Must be prbs://:polynomial."); } - long polynomial = strtol(++name, (char **)NULL, 10); + const string poly_str = name.substr(1); + + long polynomial = strtol(poly_str.c_str(), (char **)NULL, 10); if ((polynomial == LONG_MIN) || (polynomial == LONG_MAX)) { - etiLog.log(error, "can't convert polynomial number %s\n", name); - errno = EINVAL; - return -1; + stringstream ss; + ss << "Can't convert polynomial number " << poly_str; + throw invalid_argument(ss.str()); } + if (polynomial == 0) { - etiLog.log(error, "you must specify a polynomial number\n"); - errno = EINVAL; - return -1; + throw invalid_argument("No polynomial given for PRBS input"); } - - data->polynomial = polynomial; - data->accum = 0; - gen_prbs_table(data); - gen_weight_table(data); - dabInputPrbsRewind(args); + + m_prbs.setup(polynomial); + rewind(); return 0; } - -int dabInputPrbsRead(void* args, void* buffer, int size) +int DabInputPrbs::readFrame(void* buffer, int size) { - prbs_data* data = (prbs_data*)args; - unsigned char* cbuffer = reinterpret_cast<unsigned char*>(buffer); + unsigned char* cbuffer = reinterpret_cast<unsigned char*>(buffer); - for(int i = 0; i < size; ++i) { - data->accum = update_prbs(args); - *(cbuffer++) = (unsigned char)(data->accum & 0xff); + for (int i = 0; i < size; ++i) { + cbuffer[i] = m_prbs.step(); } return size; } - -int dabInputPrbsReadFrame(dabInputOperations* ops, void* args, - void* buffer, int size) -{ - return ops->read(args, buffer, size); -} - - -int dabInputPrbsBitrate(dabInputOperations* ops, void* args, int bitrate) +int DabInputPrbs::setBitrate(int bitrate) { return bitrate; } - -int dabInputPrbsClose(void* args) +int DabInputPrbs::close() { return 0; } - -int dabInputPrbsClean(void** args) +int DabInputPrbs::rewind() { - delete (prbs_data*)(*args); + m_prbs.rewind(); return 0; } - -int dabInputPrbsRewind(void* args) -{ - prbs_data* data = (prbs_data*)args; - - while (data->accum < data->polynomial) { - data->accum <<= 1; - data->accum |= 1; - } - - return 0; -} - - -# endif -#endif diff --git a/src/dabInputPrbs.h b/src/dabInputPrbs.h index 22c088c..9cde7e2 100644 --- a/src/dabInputPrbs.h +++ b/src/dabInputPrbs.h @@ -1,6 +1,13 @@ /* Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) + + Copyright (C) 2016 + Matthias P. Braendli, matthias.braendli@mpb.li + + http://www.opendigitalradio.org + + Pseudo-Random Bit Sequence generator for test purposes. */ /* This file is part of ODR-DabMux. @@ -19,38 +26,27 @@ along with ODR-DabMux. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef DAB_INPUT_PRBS_H -#define DAB_INPUT_PRBS_H - +#pragma once #ifdef HAVE_CONFIG_H -# include "config.h" +# include "config.h" #endif -#include "dabInput.h" -#include "prbs.h" - -#include <errno.h> +#include <string> -#ifdef HAVE_FORMAT_RAW -# ifdef HAVE_INPUT_PRBS - - -extern struct dabInputOperations dabInputPrbsOperations; - -int dabInputPrbsInit(void** args); -int dabInputPrbsOpen(void* args, const char* name); -int dabInputPrbsRead(void* args, void* buffer, int size); -int dabInputPrbsReadFrame(dabInputOperations* ops, void* args, - void* buffer, int size); -int dabInputPrbsBitrate(dabInputOperations* ops, void* args, int bitrate); -int dabInputPrbsClose(void* args); -int dabInputPrbsClean(void** args); -int dabInputPrbsRewind(void* args); +#include "dabInput.h" +#include "prbs.h" +class DabInputPrbs : public DabInputBase { + public: + virtual int open(const std::string name); + virtual int readFrame(void* buffer, int size); + virtual int setBitrate(int bitrate); + virtual int close(); -# endif -#endif + private: + virtual int rewind(); + PrbsGenerator m_prbs; +}; -#endif // DAB_INPUT_PRBS_H diff --git a/src/dabInputRawFifo.cpp b/src/dabInputRawFifo.cpp index 0da9727..cc6268b 100644 --- a/src/dabInputRawFifo.cpp +++ b/src/dabInputRawFifo.cpp @@ -40,8 +40,8 @@ struct dabInputOperations dabInputRawFifoOperations = { dabInputRawFifoOpen, dabInputRawFifoSetbuf, dabInputRawFifoRead, - NULL, - NULL, + nullptr, + nullptr, dabInputRawFifoReadFrame, dabInputSetbitrate, dabInputRawFifoClose, @@ -54,7 +54,7 @@ int dabInputRawFifoInit(void** args) { dabInputRawFifoData* data = new dabInputRawFifoData; data->file = -1; - data->buffer = NULL; + data->buffer = nullptr; data->bufferSize = 0; data->bufferOffset = 0; @@ -97,7 +97,7 @@ int dabInputRawFifoSetbuf(void* args, int size) } if (data->bufferSize != (size_t)size) { - if (data->buffer != NULL) { + if (data->buffer != nullptr) { delete[] data->buffer; } data->buffer = new uint8_t[size]; @@ -174,7 +174,7 @@ int dabInputRawFifoClose(void* args) int dabInputRawFifoClean(void** args) { dabInputRawFifoData* data = (dabInputRawFifoData*)*args; - if (data->buffer != NULL) { + if (data->buffer != nullptr) { delete[] data->buffer; } delete data; diff --git a/src/dabInputRawFile.cpp b/src/dabInputRawFile.cpp index 88ffa2a..be33a45 100644 --- a/src/dabInputRawFile.cpp +++ b/src/dabInputRawFile.cpp @@ -32,8 +32,8 @@ struct dabInputOperations dabInputRawFileOperations = { dabInputFileOpen, dabInputSetbuf, dabInputFileRead, - NULL, - NULL, + nullptr, + nullptr, dabInputRawFileRead, dabInputSetbitrate, dabInputFileClose, diff --git a/src/dabInputZmq.cpp b/src/dabInputZmq.cpp index 70fd0c8..790a961 100644 --- a/src/dabInputZmq.cpp +++ b/src/dabInputZmq.cpp @@ -213,7 +213,7 @@ void DabInputZmqBase::rebind() m_zmq_sock_bound_to = m_inputUri; try { - m_zmq_sock.setsockopt(ZMQ_SUBSCRIBE, NULL, 0); + m_zmq_sock.setsockopt(ZMQ_SUBSCRIBE, nullptr, 0); } catch (zmq::error_t& err) { std::ostringstream os; @@ -387,7 +387,7 @@ int DabInputZmqMPEG::readFromSocket(size_t framesize) } else if (m_enable_input) { // copy the input frame blockwise into the frame_buffer - uint8_t* framedata = new uint8_t[framesize]; + auto framedata = new uint8_t[framesize]; memcpy(framedata, data, framesize); m_frame_buffer.push_back(framedata); } @@ -467,7 +467,7 @@ int DabInputZmqAAC::readFromSocket(size_t framesize) for (uint8_t* framestart = data; framestart < &data[5*framesize]; framestart += framesize) { - uint8_t* audioframe = new uint8_t[framesize]; + auto audioframe = new uint8_t[framesize]; memcpy(audioframe, framestart, framesize); m_frame_buffer.push_back(audioframe); } diff --git a/src/prbs.c b/src/prbs.cpp index c29a830..0ac3187 100644 --- a/src/prbs.c +++ b/src/prbs.cpp @@ -22,14 +22,13 @@ #include "prbs.h" #include <string.h> -#include <stdlib.h> #include <limits.h> /* * Generate a parity check for a 32-bit word. */ -unsigned long parity_check(unsigned long prbs_accum) +static unsigned long parity_check(unsigned long prbs_accum) { unsigned long mask=1UL, parity=0UL; int i; @@ -40,92 +39,97 @@ unsigned long parity_check(unsigned long prbs_accum) return parity; } -/* - * Generate a table of matrix products to update a 32-bit PRBS generator. - */ -void gen_prbs_table(void* args) +void PrbsGenerator::setup(long polynomial) { - prbs_data* data = (prbs_data*)args; - int i; - for (i = 0; i < 4; ++i) { - int j; - for (j = 0; j < 256; ++j) { + this->polynomial = polynomial; + this->accum = 0; + gen_prbs_table(); + gen_weight_table(); +} + +uint8_t PrbsGenerator::step() +{ + accum = update_prbs(); + return accum & 0xff; +} + +void PrbsGenerator::rewind() +{ + while (accum < polynomial) { + accum <<= 1; + accum |= 1; + } +} + +void PrbsGenerator::gen_prbs_table() +{ + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 256; ++j) { unsigned long prbs_accum = ((unsigned long)j << (i * 8)); - int k; - for (k = 0; k < 8; ++k) { + for (int k = 0; k < 8; ++k) { prbs_accum = (prbs_accum << 1) - ^ parity_check(prbs_accum & data->polynomial); + ^ parity_check(prbs_accum & polynomial); } - data->prbs_table[i][j] = (prbs_accum & 0xff); + + prbs_table[i][j] = (prbs_accum & 0xff); } } } -/* - * Update a 32-bit PRBS generator eight bits at a time. - */ -unsigned long update_prbs(void* args) +unsigned long PrbsGenerator::update_prbs() { - prbs_data* data = (prbs_data*)args; unsigned char acc_lsb = 0; int i; for (i = 0; i < 4; ++i ) { - acc_lsb ^= data->prbs_table [i] [ (data->accum >> (i * 8) ) & 0xff ]; + acc_lsb ^= prbs_table [i] [ (accum >> (i * 8) ) & 0xff ]; } - return (data->accum << 8) ^ ((unsigned long)acc_lsb); + return (accum << 8) ^ ((unsigned long)acc_lsb); } -/* - * Generate the weight table. - */ -void gen_weight_table(void* args) +void PrbsGenerator::gen_weight_table() { - prbs_data* data = (prbs_data*)args; - int i; - for (i = 0; i < 256; ++i) { - unsigned char mask=1U, ones_count = 0U; - int j; - for (j = 0; j < 8; ++j) { + for (int i = 0; i < 256; ++i) { + unsigned char mask = 1U; + unsigned char ones_count = 0U; + + for (int j = 0; j < 8; ++j) { ones_count += ((i & mask) != 0U); mask = mask << 1; } - data->weight[i] = ones_count; + weight[i] = ones_count; } } -/* - * Count the number of errors in a block of received data. - */ -unsigned long error_count(void* args, unsigned char *rx_data, +size_t PrbsGenerator::error_count( + unsigned char *rx_data, int rx_data_length) { - prbs_data* data = (prbs_data*)args; unsigned long error_count = 0U; unsigned long prbs_accum = 0U; - int i; /* seed the PRBS accumulator */ - for (i = 0; i < 4; ++i) { - prbs_accum = (prbs_accum << 8) ^ (rx_data[i] ^ data->polarity_mask); + for (int i = 0; i < 4; ++i) { + prbs_accum = (prbs_accum << 8) ^ (rx_data[i] ^ polarity_mask); } /* check the received data */ - for (i = 0; i < rx_data_length; ++i) { + for (int i = 0; i < rx_data_length; ++i) { unsigned char error_pattern = (unsigned char) ((prbs_accum >> 24) - ^ (rx_data[i] ^ data->polarity_mask)); + ^ (rx_data[i] ^ polarity_mask)); if (error_pattern != 0U) { - error_count += data->weight[error_pattern]; + error_count += weight[error_pattern]; } - prbs_accum = update_prbs(data); + prbs_accum = update_prbs(); } return error_count; } -void gen_sequence(void* args, unsigned char *tx_data, int tx_data_length, +void PrbsGenerator::gen_sequence( + unsigned char *tx_data, + int tx_data_length, unsigned long polynomial) { - prbs_data* data = (prbs_data*)args; unsigned long prbs_accum = 0U; while (prbs_accum < polynomial) { @@ -134,7 +138,7 @@ void gen_sequence(void* args, unsigned char *tx_data, int tx_data_length, } while (tx_data_length-- > 0) { - prbs_accum = update_prbs(data); + prbs_accum = update_prbs(); *(tx_data++) = (unsigned char)(prbs_accum & 0xff); } } @@ -19,43 +19,53 @@ along with ODR-DabMux. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef _PRBS -#define _PRBS +#pragma once + +#include <stdint.h> +#include <stdlib.h> #ifdef HAVE_CONFIG_H # include "config.h" #endif +class PrbsGenerator { + public: + void setup(long polynomial); -#ifdef __cplusplus -extern "C" { // } -#endif + uint8_t step(void); -typedef struct { - // table of matrix products used to update a 32-bit PRBS generator - unsigned long prbs_table [4] [256]; - // table of weights for 8-bit bytes - unsigned char weight[256]; - // PRBS polynomial generator - unsigned long polynomial; - // PRBS generator polarity mask - unsigned char polarity_mask; - // PRBS accumulator - unsigned long accum; -} prbs_data; - - -unsigned long parity_check(unsigned long prbs_accum); -void gen_prbs_table(void* args); -unsigned long update_prbs(void* args); -void gen_weight_table(void* args); -unsigned long error_count(void* args, unsigned char *rx_data, - int rx_data_length); -void gen_sequence(void* args, unsigned char *tx_data, int tx_data_length, - unsigned long polynomial); - -#ifdef __cplusplus -} -#endif + void rewind(void); + + private: + /* Generate a table of matrix products to update a 32-bit PRBS + * generator. */ + void gen_prbs_table(void); + + /* Update a 32-bit PRBS generator eight bits at a time. */ + unsigned long update_prbs(void); + + /* Generate the weight table. */ + void gen_weight_table(void); + + /* Count the number of errors in a block of received data. */ + size_t error_count( + unsigned char *rx_data, + int rx_data_length); + + void gen_sequence( + unsigned char *tx_data, + int tx_data_length, + unsigned long polynomial); + + // table of matrix products used to update a 32-bit PRBS generator + unsigned long prbs_table [4] [256]; + // table of weights for 8-bit bytes + unsigned char weight[256]; + // PRBS polynomial generator + unsigned long polynomial; + // PRBS generator polarity mask + unsigned char polarity_mask; + // PRBS accumulator + unsigned long accum; +}; -#endif // _PRBS diff --git a/src/utils.cpp b/src/utils.cpp index 94268da..0399467 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -38,7 +38,7 @@ static int dab_time_millis = 0; void update_dab_time() { if (dab_time_seconds == 0) { - dab_time_seconds = time(NULL); + dab_time_seconds = time(nullptr); } else { dab_time_millis+= 24; if (dab_time_millis >= 1000) { @@ -102,9 +102,7 @@ void header_message() "http://opendigitalradio.org\n\n"); std::cerr << "Input URLs supported:" << std::endl << -#if defined(HAVE_INPUT_PRBS) " prbs" << -#endif #if defined(HAVE_INPUT_TEST) " test" << #endif @@ -166,163 +164,6 @@ void header_message() } -#if ENABLE_CMDLINE_OPTIONS -void printUsage(char *name, FILE* out) -{ - fprintf(out, "NAME\n"); - fprintf(out, " %s - A software DAB multiplexer\n", name); - fprintf(out, "\nSYNOPSYS\n"); - fprintf(out, " You can use either a configuration file, or the command line arguments\n"); - fprintf(out, " With external configuration file:\n"); - fprintf(out, " %s [-e] configuration.mux\n", name); - fprintf(out, " See doc/example.config for an example format for the configuration file\n"); - fprintf(out, " With command line arguments:\n"); - fprintf(out, " %s" - " [ensemble]" - " [subchannel1 subchannel2 ...]" - " [service1 component1 [component2 ...] service2 ...]" - " [output1 ...]" - " [-h]" - " [-m mode]" - " [-n nbFrames]" - " [-o]" - " [-s]" - " [-V]" - " [-z]" - "\n", - name); - fprintf(out, "\n Where ensemble =" - " [-i ensembleId]" - " [-L label]" - " [-l sLabel]" - "\n"); - fprintf(out, "\n Where subchannel =" - " -(A | B | D | E | F | M | P | T) inputName" - " [-b bitrate]" - " [-i subchannelId]" - " [-k]" - " [-p protection]" - "\n"); - fprintf(out, "\n Where service =" - " -S" - " [-g language]" - " [-i serviceId]" - " [-L label]" - " [-l sLabel]" - " [-y PTy]" - "\n"); - fprintf(out, "\n Where component =" - " -C" - " [-a address]" - " [-d]" - " [-f figType]" - " [-i subchannelId]" - " [-L label]" - " [-l sLabel]" - " [-t type]" - "\n"); - fprintf(out, "\nDESCRIPTION\n"); - fprintf(out, - " %s is a software multiplexer that generates an ETI stream from\n" - " audio and data streams. Because of its software based architecture,\n" - " many typical DAB services can be generated and multiplexed on a single\n" - " PC platform with live or pre-recorded sources.\n" - "\n" - " A DAB multiplex configuration is composed of one ensemble. An ensemble\n" - " is the entity that receivers tune to and process. An ensemble contains\n" - " several services. A service is the listener-selectable output. Each\n" - " service contains one mandatory service component which is called pri-\n" - " mary component. An audio primary component define a program service\n" - " while a data primary component define a data service. Service can con-\n" - " tain additional components which are called secondary components. Maxi-\n" - " mum total number of components is 12 for program services and 11 for\n" - " data services. A service component is a link to one subchannel (of Fast\n" - " Information Data Channel). A subchannel is the physical space used\n" - " within the common interleaved frame.\n" - "\n" - " __________________________________________________\n" - " | Ensemble | ENSEMBLE\n" - " |__________________________________________________|\n" - " | | |\n" - " | | |\n" - " _______V______ _______V______ _______V______\n" - " | Service 1 | | Service 2 | | Service 3 | SERVICES\n" - " |______________| |______________| |______________|\n" - " | | | | |______ |\n" - " | | | | | |\n" - " __V__ __V__ __V__ __V__ __V__ __V__\n" - " | SC1 | | SC2 | | SC3 | | SC4 | | SC5 | | SC6 | SERVICE\n" - " |_____| |_____| |_____| |_____| |_____| |_____| COMPONENTS\n" - " | | _____| | | ____|\n" - " | | | | | |\n" - " __V________V__V______________V________V___V_______ COMMON\n" - " | SubCh1 | SubCh9 | ... | SubCh3 | SubCh60 | ... | INTERLEAVED\n" - " |________|________|_______|________|_________|_____| FRAME\n" - " Figure 1: An example of a DAB multiplex configuration\n", - name); - - fprintf(out, "\nGENERAL OPTIONS\n"); - fprintf(out, " -h : get this help\n"); - fprintf(out, " -m : DAB mode (default: 2)\n"); - fprintf(out, " -n nbFrames : number of frames to produce\n"); - fprintf(out, " -o : enable logging to syslog\n"); - fprintf(out, " -r : throttle the output rate to one ETI frame every 24ms\n"); - fprintf(out, " -V : print version information and " - "exit\n"); - fprintf(out, " -z : write SCCA field for Factum ETI" - " analyzer\n"); - fprintf(out, "\nINPUT OPTIONS\n"); - fprintf(out, " -A : set audio service\n"); - fprintf(out, " -B : set CRC-Bridge data service\n"); - fprintf(out, " -D : set data service\n"); - fprintf(out, " -E : set enhanced packet service\n"); - fprintf(out, " -F : set DAB+ service\n"); - fprintf(out, " -M : set DMB service\n"); - fprintf(out, " -P : set packet service\n"); - fprintf(out, " -T : set test service\n"); - fprintf(out, " inputName<n> : name of file for audio and " - "packet service and Udp input address for data service " - "([address]:port)\n"); - fprintf(out, " -a : packet address (default: 0x%x " - "(%i))\n", DEFAULT_PACKET_ADDRESS, DEFAULT_PACKET_ADDRESS); - fprintf(out, " -b bitrate<n> : bitrate (in kbits/s) of the " - "subchannel (default: audio 1st frame, data %i, packet %i)\n", - DEFAULT_DATA_BITRATE, DEFAULT_PACKET_BITRATE); - fprintf(out, " -c : set the extendend country code ECC " - "(default: %u (0x%2x)\n", DEFAULT_ENSEMBLE_ECC, DEFAULT_ENSEMBLE_ECC); - fprintf(out, " -d : turn on datagroups in packet " - "mode\n"); - fprintf(out, " -f figType : user application type in FIG " - "0/13 for packet mode\n"); - fprintf(out, " -g language : Primary service component " - "language: english=9, french=15\n"); - fprintf(out, " -i id<n> : service|subchannel|" - "serviceComponent id <n> (default: <n>)\n"); - fprintf(out, " -k : set non-blocking file input " - "(audio and packet only)\n"); - fprintf(out, " -L label<n> : label of service <n>" - " (default: CRC-Audio<n>)\n"); - fprintf(out, " -l sLabel<n> : short label flag of service <n>" - " (default: 0xf040)\n"); - fprintf(out, " -p protection<n> : protection level (default: 3)\n"); - fprintf(out, " -s : enable TIST, synchronized on 1PPS at level 2.\n"); - fprintf(out, " This also transmits time using the MNSC.\n"); - fprintf(out, " -t type : audio/data service component type" - " (default: 0)\n"); - fprintf(out, " audio: foreground=0, " - "background=1, multi-channel=2\n"); - fprintf(out, " data: unspecified=0, TMC=1, " - "EWS=2, ITTS=3, paging=4, TDC=5, DMB=24, IP=59, MOT=60, " - "proprietary=61\n"); - fprintf(out, " -y PTy : Primary service component program" - " type international code\n"); - fprintf(out, "\nOUTPUT OPTIONS\n"); - fprintf(out, " -O output : name of the output in format " - "scheme://[address][:port][/name]\n" - " where scheme is (raw|udp|tcp|file|fifo|simul)\n" - ); -} -#else // no command line options void printUsage(char *name, FILE* out) { fprintf(out, "NAME\n"); @@ -371,7 +212,6 @@ void printUsage(char *name, FILE* out) " Figure 1: An example of a DAB multiplex configuration\n", name); } -#endif void printOutputs(const vector<shared_ptr<DabOutput> >& outputs) { @@ -603,7 +443,7 @@ void printEnsemble(const shared_ptr<dabEnsemble> ensemble) etiLog.log(info, " mode: %u", ensemble->mode); if (ensemble->lto_auto) { - time_t now = time(NULL); + time_t now = time(nullptr); struct tm* ltime = localtime(&now); time_t now2 = timegm(ltime); etiLog.log(info, " lto: %2.1f hours", 0.5 * (now2 - now) / 1800); |