diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ConfigParser.cpp | 14 | ||||
| -rw-r--r-- | src/DabMux.cpp | 10 | ||||
| -rw-r--r-- | src/Makefile.am | 5 | ||||
| -rw-r--r-- | src/ParserCmdline.cpp | 771 | ||||
| -rw-r--r-- | src/ParserCmdline.h | 54 | ||||
| -rw-r--r-- | src/dabInputFifo.cpp | 5 | ||||
| -rw-r--r-- | src/dabInputFifo.h | 13 | ||||
| -rw-r--r-- | src/dabInputPrbs.cpp | 122 | ||||
| -rw-r--r-- | src/dabInputPrbs.h | 48 | ||||
| -rw-r--r-- | src/prbs.cpp (renamed from src/prbs.c) | 100 | ||||
| -rw-r--r-- | src/prbs.h | 74 | ||||
| -rw-r--r-- | src/utils.cpp | 160 | 
12 files changed, 173 insertions, 1203 deletions
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);      }  } @@ -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)  {  | 
