From e7ad2e1fab9c51189fdc8b4f2d81f625da9dd422 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sat, 29 Oct 2016 22:09:13 +0200 Subject: Modernise PRBS generator and remove code for cmd line parser --- configure.ac | 6 - src/ConfigParser.cpp | 14 +- src/DabMux.cpp | 10 - src/Makefile.am | 5 +- src/ParserCmdline.cpp | 771 -------------------------------------------------- src/ParserCmdline.h | 54 ---- src/dabInputFifo.cpp | 5 + src/dabInputFifo.h | 13 +- src/dabInputPrbs.cpp | 122 +++----- src/dabInputPrbs.h | 48 ++-- src/prbs.c | 140 --------- src/prbs.cpp | 144 ++++++++++ src/prbs.h | 74 ++--- src/utils.cpp | 160 ----------- 14 files changed, 265 insertions(+), 1301 deletions(-) delete mode 100644 src/ParserCmdline.cpp delete mode 100644 src/ParserCmdline.h delete mode 100644 src/prbs.c create mode 100644 src/prbs.cpp diff --git a/configure.ac b/configure.ac index 09ca8c1..6297365 100644 --- a/configure.ac +++ b/configure.ac @@ -115,12 +115,6 @@ AC_ARG_ENABLE([input_file], AS_IF([test "x$enable_input_file" = "xyes"], [AC_DEFINE(HAVE_INPUT_FILE, [1], [Define if FILE input is enabled])]) -# PRBS -AC_ARG_ENABLE([input_prbs], - [AS_HELP_STRING([--enable-input-prbs], [Enable PRBS input])], - [], [enable_input_prbs=no]) -AS_IF([test "x$enable_input_prbs" = "xyes"], - [AC_DEFINE(HAVE_INPUT_PRBS, [1], [Define if PRBS input is enabled])]) # TEST AC_ARG_ENABLE([input_test], [AS_HELP_STRING([--enable-input-test], [Enable TEST input])], diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp index 0ba1d78..8e5fed1 100644 --- a/src/ConfigParser.cpp +++ b/src/ConfigParser.cpp @@ -3,7 +3,7 @@ 2011, 2012 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) - Copyright (C) 2014, 2015 + Copyright (C) 2016 Matthias P. Braendli, matthias.braendli@mpb.li http://www.opendigitalradio.org @@ -742,6 +742,12 @@ static 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) { @@ -749,10 +755,6 @@ static 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; @@ -761,7 +763,7 @@ static 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/DabMux.cpp b/src/DabMux.cpp index 046b149..f72ea8d 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" @@ -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("general.managementport", pt.get("general.statsserverport", 0) ); diff --git a/src/Makefile.am b/src/Makefile.am index ef43a97..dfcdb12 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. @@ -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 \ @@ -114,7 +113,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 \ 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 . -*/ -#include "ParserCmdline.h" - -#if ENABLE_CMDLINE_OPTIONS - -#include -#include -#include -#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 -# include -# include -# include -# include // 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 -# include -# include -# include -# include -#endif - -using namespace std; - -bool parse_cmdline(char **argv, - int argc, - vector &outputs, - dabEnsemble* ensemble, - bool* enableTist, - unsigned* FICL, - bool* factumAnalyzer, - unsigned long* limit - ) -{ - vector::iterator output; - vector::iterator subchannel = ensemble->subchannels.end(); - vector::iterator component = ensemble->components.end(); - vector::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 . -*/ -#ifndef _PARSER_CMDLINE -#define _PARSER_CMDLINE - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include "MuxElements.h" - -#define ENABLE_CMDLINE_OPTIONS 0 - -#if ENABLE_CMDLINE_OPTIONS - -bool parse_cmdline(char **argv, - int argc, - std::vector &outputs, - dabEnsemble* ensemble, - bool* enableTist, - unsigned* FICL, - bool* factumAnalyzer, - unsigned long* limit - ); - -#endif - -#endif diff --git a/src/dabInputFifo.cpp b/src/dabInputFifo.cpp index 7e07731..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. 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 . */ -#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 - # 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/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 +#include #include #include #include +#include +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(buffer); + unsigned char* cbuffer = reinterpret_cast(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 . */ -#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 +#include -#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/prbs.c b/src/prbs.c deleted file mode 100644 index c29a830..0000000 --- a/src/prbs.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - Copyright (C) 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in Right - of Canada (Communications Research Center Canada) - */ -/* - 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 . - */ - -#include "prbs.h" - -#include -#include -#include - - -/* - * Generate a parity check for a 32-bit word. - */ -unsigned long parity_check(unsigned long prbs_accum) -{ - unsigned long mask=1UL, parity=0UL; - int i; - for (i = 0; i < 32; ++i) { - parity ^= ((prbs_accum & mask) != 0UL); - mask <<= 1; - } - return parity; -} - -/* - * Generate a table of matrix products to update a 32-bit PRBS generator. - */ -void gen_prbs_table(void* args) -{ - prbs_data* data = (prbs_data*)args; - int i; - for (i = 0; i < 4; ++i) { - int j; - for (j = 0; j < 256; ++j) { - unsigned long prbs_accum = ((unsigned long)j << (i * 8)); - int k; - for (k = 0; k < 8; ++k) { - prbs_accum = (prbs_accum << 1) - ^ parity_check(prbs_accum & data->polynomial); - } - data->prbs_table[i][j] = (prbs_accum & 0xff); - } - } -} - -/* - * Update a 32-bit PRBS generator eight bits at a time. - */ -unsigned long update_prbs(void* args) -{ - 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 ]; - } - return (data->accum << 8) ^ ((unsigned long)acc_lsb); -} - -/* - * Generate the weight table. - */ -void gen_weight_table(void* args) -{ - 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) { - ones_count += ((i & mask) != 0U); - mask = mask << 1; - } - data->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, - 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); - } - - /* check the received data */ - for (i = 0; i < rx_data_length; ++i) { - unsigned char error_pattern = (unsigned char) - ((prbs_accum >> 24) - ^ (rx_data[i] ^ data->polarity_mask)); - if (error_pattern != 0U) { - error_count += data->weight[error_pattern]; - } - prbs_accum = update_prbs(data); - } - return error_count; -} - -void gen_sequence(void* args, 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) { - prbs_accum <<= 1; - prbs_accum |= 1; - } - - while (tx_data_length-- > 0) { - prbs_accum = update_prbs(data); - *(tx_data++) = (unsigned char)(prbs_accum & 0xff); - } -} diff --git a/src/prbs.cpp b/src/prbs.cpp new file mode 100644 index 0000000..0ac3187 --- /dev/null +++ b/src/prbs.cpp @@ -0,0 +1,144 @@ +/* + Copyright (C) 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in Right + of Canada (Communications Research Center Canada) + */ +/* + 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 . + */ + +#include "prbs.h" + +#include +#include + + +/* + * Generate a parity check for a 32-bit word. + */ +static unsigned long parity_check(unsigned long prbs_accum) +{ + unsigned long mask=1UL, parity=0UL; + int i; + for (i = 0; i < 32; ++i) { + parity ^= ((prbs_accum & mask) != 0UL); + mask <<= 1; + } + return parity; +} + +void PrbsGenerator::setup(long polynomial) +{ + 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)); + for (int k = 0; k < 8; ++k) { + prbs_accum = (prbs_accum << 1) + ^ parity_check(prbs_accum & polynomial); + } + + prbs_table[i][j] = (prbs_accum & 0xff); + } + } +} + +unsigned long PrbsGenerator::update_prbs() +{ + unsigned char acc_lsb = 0; + int i; + for (i = 0; i < 4; ++i ) { + acc_lsb ^= prbs_table [i] [ (accum >> (i * 8) ) & 0xff ]; + } + return (accum << 8) ^ ((unsigned long)acc_lsb); +} + +void PrbsGenerator::gen_weight_table() +{ + 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; + } + weight[i] = ones_count; + } +} + +size_t PrbsGenerator::error_count( + unsigned char *rx_data, + int rx_data_length) +{ + unsigned long error_count = 0U; + unsigned long prbs_accum = 0U; + + /* seed the PRBS accumulator */ + for (int i = 0; i < 4; ++i) { + prbs_accum = (prbs_accum << 8) ^ (rx_data[i] ^ polarity_mask); + } + + /* check the received data */ + for (int i = 0; i < rx_data_length; ++i) { + unsigned char error_pattern = (unsigned char) + ((prbs_accum >> 24) + ^ (rx_data[i] ^ polarity_mask)); + if (error_pattern != 0U) { + error_count += weight[error_pattern]; + } + prbs_accum = update_prbs(); + } + return error_count; +} + +void PrbsGenerator::gen_sequence( + unsigned char *tx_data, + int tx_data_length, + unsigned long polynomial) +{ + unsigned long prbs_accum = 0U; + + while (prbs_accum < polynomial) { + prbs_accum <<= 1; + prbs_accum |= 1; + } + + while (tx_data_length-- > 0) { + prbs_accum = update_prbs(); + *(tx_data++) = (unsigned char)(prbs_accum & 0xff); + } +} diff --git a/src/prbs.h b/src/prbs.h index c039a6e..5b6b7c2 100644 --- a/src/prbs.h +++ b/src/prbs.h @@ -19,43 +19,53 @@ along with ODR-DabMux. If not, see . */ -#ifndef _PRBS -#define _PRBS +#pragma once + +#include +#include #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 c776b0b..9976e88 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -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 : 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 : 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 : service|subchannel|" - "serviceComponent id (default: )\n"); - fprintf(out, " -k : set non-blocking file input " - "(audio and packet only)\n"); - fprintf(out, " -L label : label of service " - " (default: CRC-Audio)\n"); - fprintf(out, " -l sLabel : short label flag of service " - " (default: 0xf040)\n"); - fprintf(out, " -p protection : 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 >& outputs) { -- cgit v1.2.3