summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac6
-rw-r--r--src/ConfigParser.cpp14
-rw-r--r--src/DabMux.cpp10
-rw-r--r--src/Makefile.am5
-rw-r--r--src/ParserCmdline.cpp771
-rw-r--r--src/ParserCmdline.h54
-rw-r--r--src/dabInputFifo.cpp5
-rw-r--r--src/dabInputFifo.h13
-rw-r--r--src/dabInputPrbs.cpp122
-rw-r--r--src/dabInputPrbs.h48
-rw-r--r--src/prbs.cpp (renamed from src/prbs.c)100
-rw-r--r--src/prbs.h74
-rw-r--r--src/utils.cpp160
13 files changed, 173 insertions, 1209 deletions
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<int>("general.managementport",
pt.get<int>("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 <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/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 <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/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/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);
}
}
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 <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 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<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)
{