aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am4
-rw-r--r--README.md6
-rw-r--r--src/mot-encoder.cpp (renamed from src/mot-encoder.c)265
3 files changed, 138 insertions, 137 deletions
diff --git a/Makefile.am b/Makefile.am
index f698249..b807cd3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -60,9 +60,9 @@ dabplus_enc_SOURCES = src/dabplus-enc.cpp \
src/utils.h \
src/wavreader.c
-mot_encoder_CFLAGS = $(GITVERSION_FLAGS) @MAGICKWAND_CFLAGS@ -Icontrib
+mot_encoder_CXXFLAGS = $(GITVERSION_FLAGS) @MAGICKWAND_CFLAGS@ -Icontrib
mot_encoder_LDADD = @MAGICKWAND_LDADD@
-mot_encoder_SOURCES = src/mot-encoder.c \
+mot_encoder_SOURCES = src/mot-encoder.cpp \
contrib/lib_crc.h \
contrib/lib_crc.c
diff --git a/README.md b/README.md
index 533ef02..3af1fa2 100644
--- a/README.md
+++ b/README.md
@@ -169,14 +169,14 @@ the specified folder, and generates the PAD data for the encoder. This is
communicated through a fifo to the encoder. It also reads DLS from a file, and
includes this information in the PAD.
-*dabplus-enc-file-zmq* and *dabplus-enc-alsa-zmq* can insert the PAD data from
-mot-encoder into the bitstream.
+*dabplus-enc* can insert the PAD data from mot-encoder into the bitstream.
The mp2 encoder [toolame-dab](https://github.com/Opendigitalradio/toolame-dab)
can also read *mot-encoder* data.
This is an ongoing development. Make sure you use the same pad length option
for *mot-encoder* and the audio encoder. Only some pad lengths are supported,
-please see *mot-encoder*'s help.
+please see *mot-encoder*'s help. Only pad lengths 34, 42 and 58 seem to be
+working with some receivers, 23 and 26 appear to be broken.
Known Limitations
-----------------
diff --git a/src/mot-encoder.c b/src/mot-encoder.cpp
index 6f83eab..e227412 100644
--- a/src/mot-encoder.c
+++ b/src/mot-encoder.cpp
@@ -1,6 +1,8 @@
/*
Copyright (C) 2014 CSP Innovazione nelle ICT s.c.a r.l. (http://rd.csp.it/)
+ Copyright (C) 2014 Matthias P. Braendli (http://opendigitalradio.org)
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
@@ -14,17 +16,21 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
- MotEncoder.c
+ mot-encoder.c
Generete PAD data for MOT Slideshow and DLS
Authors:
- Sergio Sagliocco <sergio.sagliocco@csp.it>
+ Sergio Sagliocco <sergio.sagliocco@csp.it>
+ Matthias P. Braendli <matthias@mpb.li>
*/
-#include <stdio.h>
+#include <cstdio>
#include <stdlib.h>
+#include <stdint.h>
#include <unistd.h>
-#include <string.h>
+#include <cstring>
+#include <vector>
+#include <deque>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -32,7 +38,9 @@
#include <wand/magick_wand.h>
#include <getopt.h>
+extern "C" {
#include "lib_crc.h"
+}
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
@@ -40,9 +48,6 @@
#define MAXSEGLEN 8179
#define MAXDLS 129
-typedef unsigned char UCHAR;
-typedef unsigned short int USHORT;
-
typedef struct {
// MSC Data Group Header (extension field not supported)
unsigned char extflag; // 1 bit
@@ -92,12 +97,19 @@ void writeMotPAD(int output_fd,
unsigned short int mscdgsize,
unsigned short int padlen);
-void create_dls_datagroup (char* text, int padlen, unsigned char*** p_dlsdg, int* p_numdg);
+void create_dls_datagroup(char* text, int padlen);
void writeDLS(int output_fd, const char* dls_file, int padlen);
int get_xpadlengthmask(int padlen);
#define ALLOWED_PADLEN "23, 26, 34, 42, 58"
+// The toggle flag for the DLS
+static uint8_t dls_toggle = 0;
+
+// The DLS data groups
+std::deque<std::vector<uint8_t> > dlsdg;
+static int dlsfd = 0;
+
void usage(char* name)
{
@@ -106,8 +118,6 @@ void usage(char* name)
"Reads image data from the specified directory, and outputs PAD data\n"
"on standard output\n"
"Reads DLS from /tmp/dls.file\n\n"
- "WARNING: This program has memory leaks! Do not attempt\n"
- "to leave it running for long periods of time!\n\n"
" http://opendigitalradio.org\n\n",
#if defined(GITVERSION)
GITVERSION
@@ -137,7 +147,7 @@ int main(int argc, char *argv[])
struct dirent *pDirent;
DIR *pDir;
char imagepath[128];
- char dlstext[MAXDLS], dlstextprev[MAXDLS];
+ char dlstext[MAXDLS];
int padlen=58;
char* dir = NULL;
@@ -351,7 +361,7 @@ void createMotHeader(size_t blobsize, int fidx, unsigned char* mothdr, int* moth
MotHeaderCore[3] = (blobsize<<4 & 0x000000FF);
sprintf(cntemp, "img%04d.jpg", fidx);
- for (i = 0; i < sizeof(cntemp); i++) {
+ for (i = 0; i < strlen(cntemp); i++) {
MotHeaderExt[8+i] = cntemp[i];
}
*mothdrlen = 26;
@@ -425,102 +435,13 @@ void packMscDG(unsigned char* b, MSCDG* msc, unsigned short int* bsize)
}
-void writeMotPAD(int output_fd,
- unsigned char* mscdg,
- unsigned short int mscdgsize,
- unsigned short int padlen)
-{
-
- unsigned char pad[128];
- int xpadlengthmask, i, j,k, numseg, lastseglen;
- unsigned short int crc;
-
-
- xpadlengthmask = get_xpadlengthmask(padlen);
-
- // Write MSC Data Groups
- int curseglen, non_ci_seglen;
- for (i = 0; i < mscdgsize; i += curseglen) {
- UCHAR* curseg;
- UCHAR firstseg;
-
- curseg = &mscdg[i];
- //fprintf(stderr,"Segment offset %d\n",i);
-
- if (i == 0) { // First segment
- firstseg = 1;
- curseglen = padlen-10;
-
- non_ci_seglen = curseglen + 4 + 1 + 2; // size of first X-PAD = MSC-DG + DGLI-DG + End of CI list + 2x CI = size of subsequent non-CI X-PADs
- }
- else {
- firstseg = 0;
- curseglen = MIN(non_ci_seglen,mscdgsize-i);
- }
-
- if (firstseg == 1) {
- // FF-PAD Byte L (CI=1)
- pad[padlen-1] = 0x02;
-
- // FF-PAD Byte L-1 (Variable size X_PAD)
- pad[padlen-2] = 0x20;
-
- // Write Data Group Length Indicator
- crc = 0xffff;
- // CI for data group length indicator: data length=4, Application Type=1
- pad[padlen-3]=0x01;
- // CI for data group length indicator: Application Type=12 (Start of MOT)
- pad[padlen-4]=(xpadlengthmask<<5) | 12;
- // End of CI list
- pad[padlen-5]=0x00;
- // RFA+HI Data group length
- pad[padlen-6]=(mscdgsize & 0x3F00)>>8;
- pad[padlen-7]=(mscdgsize & 0x00FF);
- crc = update_crc_ccitt(crc, pad[padlen-6]);
- crc = update_crc_ccitt(crc, pad[padlen-7]);
- crc = ~crc;
- // HI CRC
- pad[padlen-8]=(crc & 0xFF00) >> 8;
- // LO CRC
- pad[padlen-9]=(crc & 0x00FF);
- k=10;
- }
- else {
- // FF-PAD Byte L (CI=0)
- pad[padlen-1] = 0x00;
-
- // FF-PAD Byte L-1 (Variable size X_PAD)
- pad[padlen-2] = 0x20;
- k=3;
- }
-
- for (j = 0; j < curseglen; j++) {
- pad[padlen-k-j] = curseg[j];
- }
- for (j = padlen-k-curseglen; j >= 0; j--) {
- pad[j] = 0x00;
- }
-
- write(output_fd, pad, padlen);
- //fprintf(stderr,"MSC Data Group - Segment %d: ",i);
- //for (j=0;j<padlen;j++) fprintf(stderr,"%02x ",pad[j]);
- // fprintf(stderr,"\n");
-
- }
-}
-
void writeDLS(int output_fd, const char* dls_file, int padlen) {
char dlstext[MAXDLS];
- static char dlstextprev[MAXDLS];
int dlslen;
int i;
- static unsigned char** dlsdg;
- static int numdg = 0;
-
- static int dlsfd = 0;
- if (dlsfd!=0) {
+ if (dlsfd != 0) {
close(dlsfd);
}
@@ -532,34 +453,26 @@ void writeDLS(int output_fd, const char* dls_file, int padlen) {
dlslen = read(dlsfd, dlstext, MAXDLS);
dlstext[dlslen] = 0x00;
- //if (strcmp(dlstext,dlstextprev)!=0) {
- create_dls_datagroup(dlstext, padlen, &dlsdg, &numdg);
- strcpy(dlstextprev, dlstext);
- //}
- for (i = 0; i < numdg; i++) {
- write(output_fd, dlsdg[i], padlen);
+ create_dls_datagroup(dlstext, padlen);
+ for (i = 0; i < dlsdg.size(); i++) {
+ write(output_fd, &dlsdg[i].front(), dlsdg[i].size());
}
}
-void create_dls_datagroup (char* text, int padlen, UCHAR*** p_dlsdg, int* p_numdg) {
-
- UCHAR dlsseg[8][16]; // max 8 segments, each max 16 chars
- UCHAR** dlsdg; // Array of datagroups composing dls text;
-
+void create_dls_datagroup(char* text, int padlen) {
+ int numdg = 0; // Number of data groups
int numseg; // Number of DSL segments
int lastseglen; // Length of the last segment
- int numdg; // Number of data group
int xpadlengthmask;
int i, j, k, z, idx_start_crc, idx_stop_crc;
- USHORT dlscrc;
- static UCHAR toggle = 0;
+ uint16_t dlscrc;
- if (toggle == 0)
- toggle = 1;
+ if (dls_toggle == 0)
+ dls_toggle = 1;
else
- toggle = 0;
+ dls_toggle = 0;
numseg = strlen(text) / 16;
lastseglen = strlen(text) % 16;
@@ -588,7 +501,6 @@ void create_dls_datagroup (char* text, int padlen, UCHAR*** p_dlsdg, int* p_numd
}
}
- *p_numdg = numdg;
fprintf(stderr, "PAD Length: %d\n", padlen);
fprintf(stderr, "DLS text: %s\n", text);
fprintf(stderr, "Number of DLS segments: %d\n", numseg);
@@ -596,14 +508,14 @@ void create_dls_datagroup (char* text, int padlen, UCHAR*** p_dlsdg, int* p_numd
xpadlengthmask = get_xpadlengthmask(padlen);
- *p_dlsdg = (UCHAR**) malloc(numdg * sizeof(UCHAR*));
- dlsdg = *p_dlsdg;
+ dlsdg.resize(0);
+ dlsdg.resize(numdg);
i = 0;
for (z=0; z < numseg; z++) {
char* curseg;
int curseglen;
- UCHAR firstseg, lastseg;
+ uint8_t firstseg, lastseg;
curseg = &text[z * 16];
fprintf(stderr, "Segment number %d\n", z+1);
@@ -630,7 +542,7 @@ void create_dls_datagroup (char* text, int padlen, UCHAR*** p_dlsdg, int* p_numd
}
if (curseglen <= padlen-9) { // Segment is composed of 1 data group
- dlsdg[i] = (UCHAR*) malloc(padlen * sizeof(UCHAR));
+ dlsdg[i].resize(padlen);
// FF-PAD Byte L (CI=1)
dlsdg[i][padlen-1]=0x02;
@@ -646,7 +558,8 @@ void create_dls_datagroup (char* text, int padlen, UCHAR*** p_dlsdg, int* p_numd
dlsdg[i][padlen-4]=0x00;
// DLS Prefix (T=1,Only one segment,segment length-1)
- dlsdg[i][padlen-5]=((toggle*8+firstseg*4+lastseg*2+0)<<4) | (curseglen-1);
+ dlsdg[i][padlen-5]=((dls_toggle*8+firstseg*4+lastseg*2+0)<<4) |
+ (curseglen-1);
if (firstseg==1) {
// DLS Prefix (Charset standard)
@@ -675,8 +588,8 @@ void create_dls_datagroup (char* text, int padlen, UCHAR*** p_dlsdg, int* p_numd
dlscrc = ~dlscrc;
fprintf(stderr, "crc=%x ~crc=%x\n", ~dlscrc, dlscrc);
- dlsdg[i][padlen-7-curseglen] = (dlscrc & 0xFF00) >> 8; // HI CRC
- dlsdg[i][padlen-7-curseglen-1] = dlscrc & 0x00FF; // LO CRC
+ dlsdg[i][padlen-7-curseglen] = (dlscrc & 0xFF00) >> 8; // HI CRC
+ dlsdg[i][padlen-7-curseglen-1] = dlscrc & 0x00FF; // LO CRC
// NULL PADDING
for (j = padlen-7-curseglen-2; j >= 0; j--) {
@@ -695,7 +608,7 @@ void create_dls_datagroup (char* text, int padlen, UCHAR*** p_dlsdg, int* p_numd
// FIRST DG (NO CRC)
dlscrc = 0xffff;
- dlsdg[i] = (UCHAR*) malloc(padlen * sizeof(UCHAR));
+ dlsdg[i].resize(padlen);
// FF-PAD Byte L (CI=1)
dlsdg[i][padlen-1]=0x02;
@@ -711,7 +624,8 @@ void create_dls_datagroup (char* text, int padlen, UCHAR*** p_dlsdg, int* p_numd
dlsdg[i][padlen-4]=0x00;
// DLS Prefix (T=1,Only one segment,segment length-1)
- dlsdg[i][padlen-5]=((toggle*8+firstseg*4+lastseg*2+0)<<4) | (curseglen-1);
+ dlsdg[i][padlen-5]=((dls_toggle*8+firstseg*4+lastseg*2+0)<<4) |
+ (curseglen-1);
if (firstseg == 1) {
@@ -746,14 +660,15 @@ void create_dls_datagroup (char* text, int padlen, UCHAR*** p_dlsdg, int* p_numd
dlsdg[i][0]=0x00;
fprintf(stderr, "First Data group: ");
- for (j = 0; j < padlen; j++)
+ for (j = 0; j < padlen; j++) {
fprintf(stderr, "%x ", dlsdg[i][j]);
+ }
fprintf(stderr,"\n");
// SECOND DG (NO CI, NO PREFIX)
i++;
- dlsdg[i] = (UCHAR*) malloc(padlen*sizeof(UCHAR));
+ dlsdg[i].resize(padlen);
// FF-PAD Byte L (CI=0)
dlsdg[i][padlen-1] = 0x00;
@@ -780,8 +695,9 @@ void create_dls_datagroup (char* text, int padlen, UCHAR*** p_dlsdg, int* p_numd
}
fprintf(stderr, "Second Data group: ");
- for (j = 0; j < padlen; j++)
+ for (j = 0; j < padlen; j++) {
fprintf(stderr, "%x ", dlsdg[i][j]);
+ }
fprintf(stderr, "\n");
fprintf(stderr, "**** crc=%x ~crc=%x\n", ~dlscrc, dlscrc);
@@ -790,6 +706,91 @@ void create_dls_datagroup (char* text, int padlen, UCHAR*** p_dlsdg, int* p_numd
}
}
+void writeMotPAD(int output_fd,
+ unsigned char* mscdg,
+ unsigned short int mscdgsize,
+ unsigned short int padlen)
+{
+
+ unsigned char pad[128];
+ int xpadlengthmask, i, j,k, numseg, lastseglen;
+ unsigned short int crc;
+
+ xpadlengthmask = get_xpadlengthmask(padlen);
+
+ // Write MSC Data Groups
+ int curseglen, non_ci_seglen;
+ for (i = 0; i < mscdgsize; i += curseglen) {
+ uint8_t* curseg;
+ uint8_t firstseg;
+
+ curseg = &mscdg[i];
+ //fprintf(stderr,"Segment offset %d\n",i);
+
+ if (i == 0) { // First segment
+ firstseg = 1;
+ curseglen = padlen-10;
+
+ // size of first X-PAD = MSC-DG + DGLI-DG + End of CI list + 2x CI = size of subsequent non-CI X-PADs
+ non_ci_seglen = curseglen + 4 + 1 + 2;
+ }
+ else {
+ firstseg = 0;
+ curseglen = MIN(non_ci_seglen,mscdgsize-i);
+ }
+
+ if (firstseg == 1) {
+ // FF-PAD Byte L (CI=1)
+ pad[padlen-1] = 0x02;
+
+ // FF-PAD Byte L-1 (Variable size X_PAD)
+ pad[padlen-2] = 0x20;
+
+ // Write Data Group Length Indicator
+ crc = 0xffff;
+ // CI for data group length indicator: data length=4, Application Type=1
+ pad[padlen-3]=0x01;
+ // CI for data group length indicator: Application Type=12 (Start of MOT)
+ pad[padlen-4]=(xpadlengthmask<<5) | 12;
+ // End of CI list
+ pad[padlen-5]=0x00;
+ // RFA+HI Data group length
+ pad[padlen-6]=(mscdgsize & 0x3F00)>>8;
+ pad[padlen-7]=(mscdgsize & 0x00FF);
+ crc = update_crc_ccitt(crc, pad[padlen-6]);
+ crc = update_crc_ccitt(crc, pad[padlen-7]);
+ crc = ~crc;
+ // HI CRC
+ pad[padlen-8]=(crc & 0xFF00) >> 8;
+ // LO CRC
+ pad[padlen-9]=(crc & 0x00FF);
+ k=10;
+ }
+ else {
+ // FF-PAD Byte L (CI=0)
+ pad[padlen-1] = 0x00;
+
+ // FF-PAD Byte L-1 (Variable size X_PAD)
+ pad[padlen-2] = 0x20;
+ k=3;
+ }
+
+ for (j = 0; j < curseglen; j++) {
+ pad[padlen-k-j] = curseg[j];
+ }
+ for (j = padlen-k-curseglen; j >= 0; j--) {
+ pad[j] = 0x00;
+ }
+
+ write(output_fd, pad, padlen);
+ //fprintf(stderr,"MSC Data Group - Segment %d: ",i);
+ //for (j=0;j<padlen;j++) fprintf(stderr,"%02x ",pad[j]);
+ // fprintf(stderr,"\n");
+
+ }
+}
+
+
int get_xpadlengthmask(int padlen)
{
int xpadlengthmask;