1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
|
\section{Interfacing the Tools}
\subsection{Files}
The first versions of these tools used files and pipes to exchange data. For
offline generation of a multiplex or a modulated I/Q, it is possible to
generate all files separately, one after the other.
Here is an example to generate a two-minute ETI file for a multiplex containing two programmes:
\begin{itemize}
\item one DAB programme at 128kbps, encoded with toolame-dab
\item one \dabplus{} programme at 88kbps, encoded with fdk-aac-dabplus
\end{itemize}
We assume that the audio data for the two programmes is located in uncompressed
48kHz WAV in the files \filename{prog1.wav} and \filename{prog2.wav}. The first step
is to encode the audio. The DAB programme is encoded to \filename{prog1.mp2} using:
\begin{lstlisting}
toolame -b 128 prog1.wav prog1.mp2
\end{lstlisting}
The DAB+ programme is encoded to \filename{prog2.dabp}. The extension
\filename{.dabp} is arbitrary, but since the framing is not the same as for
other AAC encoded audio, it makes sense to use a special extension. The command
is:
\begin{lstlisting}
dabplus-enc -i prog2.wav -b 88 -a o prog2.dabp
\end{lstlisting}
These resulting files can then be used with ODR-DabMux to create an ETI file.
ODR-DabMux supports many options, which makes it much more practical to set
the configuration using a file than using very long command lines. Here is a short
file that can be used for the example, which will be saved as \filename{2programmes.mux}:
\begin{lstlisting}
general {
dabmode 1
nbframes 5000
}
remotecontrol { telnetport 0 }
ensemble {
id 0x4fff
ecc 0xec ; Extended Country Code
local-time-offset auto
international-table 1
label "mmbtools"
shortlabel "mmbtools"
}
services {
srv-p1 { label "Prog1" }
srv-p2 { label "Prog2" }
}
subchannels {
sub-p1 {
type audio ; MPEG
inputfile "prog1.mp2"
bitrate 128
id 10
protection 5
}
sub-p2 {
type dabplus
inputfile "prog2.dabp"
bitrate 88
id 1
protection 1
}
}
components {
comp-p1 {
label Prog1
service srv-p1
subchannel sub-p1
}
comp-p2 {
label Prog2
service srv-p2
subchannel sub-p2
}
}
outputs { output1 "file://myfirst.eti?type=raw" }
\end{lstlisting}
This file defines two components, that each link one service and one
subchannel. The IDs and different protection settings are also defined.
The bitrates defined in the subchannels must correspond to the bitrate set at the encoder.
The duration of the ETI file is limited by the \lstinline{nbframes 5000} setting. Each frame
corresponds to $24$\ms, and therefore $120 / 0.024 = 5000$ frames are needed
for $120$ seconds.
The output is written to the file \filename{myfirst.eti} in the ETI(NI) format. Please
see Appendix~\ref{etiformat} for more options.
To run the multiplexer, run:
\begin{lstlisting}
odr-dabmux -e 2programmes.mux
\end{lstlisting}
This will generate the file \filename{myfirst.eti}, which will be $5000 * 6144
\approx 30$\si{MB} in size.
Congratulations! You have just created your first DAB multiplex! With the configuration file,
adding more programmes is easy. More information is available in the \filename{doc/example.mux}
\subsection{Over the Network}
In a real-time scenario, where the audio sources produce data continuously and the tools have to
run at the native rate, it is not possible to use files anymore to interconnect the tools. For this
usage, a network interconnection is available between the tools.
This network connection is based on ZeroMQ, a library that permits the creation of a socket
connection with automatic connection management (connection, disconnection, error handling).
ZeroMQ uses a TCP/IP connection, and can therefore be used over any kind of IP networks.
\subsubsection{Between Encoder and Multiplexer}
Between fdk-aac-dabplus and ODR-DabMux, the ZeroMQ connection transmits AAC superframes, with
additional metadata that contains the audio level indication for monitoring purposes. The
multiplexer cannot easily derive the audio level from the AAC bitstream without decoding it, so it
makes more sense to calculate this in the encoder.
The toolame-dab encoder also can send MPEG frames over ZeroMQ, but is not yet able to calculate and
transmit audio level metadata yet.
\sidenote{Add configuration example for encoders}
On the multiplexer, the subchannel must be configured for ZeroMQ as follows:
\begin{lstlisting}
sub-fb {
type dabplus
bitrate 80
id 24
protection 3
inputfile "tcp://*:9001"
zmq-buffer 40
zmq-prebuffering 20
}
\end{lstlisting}
The ZeroMQ input supports several options in addition to the ones of a subchannel that uses a file
input. The options are:
\begin{itemize}
\item \texttt{inputfile}: This defines the interface and port on which to listen for incoming
data. It must be of the form \texttt{tcp://*:<port>}. Support for the \texttt{pgm://}
protocol is experimental, please see the \texttt{zmq\_bind} manpage for more information
about the protocols.
\item \texttt{zmq-buffer}: The ZeroMQ input handles an internal buffer for incoming data. The
maximum buffer size is given by this option, the units are AAC frames ($24$\ms). Therefore,
with a value of $40$, you will have a buffer of $40 * 24 = 960$\ms. The multiplexer will
never buffer more than this value, and will discard data one AAC superframe
($5$ frames $= 100$\ms) when the buffer is full.
\item \texttt{zmq-prebuffering}: When the buffer is empty, the multiplexer waits until this
amount of AAC frames are available in the buffer before it starts to consume data.
\end{itemize}
The goal of having a buffer in the input of the multiplexer is to be able to absorb network latency
jitter: Because IP does not guarantee anything about the latency, some packets will reach the
encoder faster than others. The buffer can then be used to avoid disruptions in these cases, and its
size should be adapted to the network connection. This has to be done in an empirical way, and is a
trade-off between absolute delay and robustness.
If the encoder is running remotely on a machine, encoding from a sound card, it will encode at the
rate defined by the sound card clock. This clock will, if no special precautions are taken, be
slightly off frequency. The multiplexer however runs on a machine where the system time is
synchronised over NTP, and will not show any drift or offset. Two situations can occur:
Either the sound card clock is a bit slow, in which case the ZeroMQ buffer in the multiplexer will
fill up to the amount given by \texttt{zmq-prebuffering}, and then start streaming data. Because the
multiplexer will be a bit faster than the encoder, the amount of buffered data will slowly decrease,
until the buffer is empty. Then the multiplexer will enter prebuffering, and wait again until the
buffer is full enough. This will create an audible interruption, whose length corresponds to the
prebuffering.
Or the sound card clock is a bit slow, and the buffer will be filled up faster than data is consumed
by the multiplexer. At some point, the buffer will hit the maximum size, and one superframe will be
discarded. This also creates an audible glitch.
Consumer grade sound cards have clocks of varying quality. While these glitches would only occur
sporadically for some, bad sound cards can provoke such behaviour in intervals that are not
acceptable, e.g. more than once per hour.
Both situations are suboptimal, because they lead to audio glitches, and also degrade the ability to
compensate for network latency changes. It is preferable to use the drift compensation feature
available in fdk-aac-dabplus, which insures that the encoder outputs the AAC bitstream at the
nominal rate, aligned to the NTP-synchronised system time, and not to the sound card clock. The
sound card clock error is compensated for inside the encoder.
\subsubsection{Authentication Support}
In order to be able to use the Internet as contribution network, some form of protection has to be
put in place to make sure the audio data cannot be altered by third parties. Usually, some form of
VPN is set up for this case.
Alternatively, the encryption mechanism ZeroMQ offers can also be used. To do this, it is necessary
to set up keys and to distribute them to the encoder and the multiplexer.
\begin{lstlisting}
encryption 1
secret-key "keys/mux.sec"
public-key "keys/mux.pub"
encoder-key "keys/encoder1.pub"
\end{lstlisting}
\sidenote{Add configuration example}
\subsubsection{Between Multiplexer and Modulator}
\subsection{Pipes}
|