-
Notifications
You must be signed in to change notification settings - Fork 5
/
interfaces.tex
276 lines (238 loc) · 10.5 KB
/
interfaces.tex
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
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
% LICENSE: see LICENCE
\section{Interfacing the Tools}
\subsection{Using files}
\label{sec-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
\item one \dabplus{} programme at 88kbps
\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}
odr-audioenc --dab -b 128 -i prog1.wav -o 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}
odr-audioenc -i prog2.wav -b 88 -o prog2.dabp
\end{lstlisting}
These resulting audio 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
a configuration file rather 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
}
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
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 {
service srv-p1
subchannel sub-p1
}
comp-p2 {
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 bitrate defined in each subchannel 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 with this configuration, run:
\begin{lstlisting}
odr-dabmux 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{Using 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.
The standard protocol to carry both contribution (from audio encoder to
multiplexer) and distribution (from multiplexer to modulator) is
EDI, specified by ETSI~\cite{etsits102693}
EDI can be carried over UDP or other unreliable links, and offers a protection
layer to correct bit-errors. Over network connections where the occasional
congestion can occur, EDI can also be carried over TCP, which will ensure lost
packets get retransmitted. Unless you are able to guarantee reserved bandwidth
for the EDI traffic, using TCP is the safer option.
While the main reason to use EDI is to put the different tools on different
computers, it is not necessary to do so.
It is possible, and even encouraged to use this interconnection locally on the
same machine, for increased flexibility.
\subsubsection{Between Encoder and Multiplexer}
\label{sec:between_encoder_and_multiplexer}
Between ODR-AudioEnc and ODR-DabMux, the EDI protocol carries \dabplus{}
superframes or DAB frames, with additional metadata that contains the audio
level indication, a version field and a free-form identifier string for
monitoring purposes.\footnote{This metadata is carried in the custom EDI TAGs
\texttt{ODRv} and \texttt{ODRa}.}
The multiplexer cannot easily derive the audio level from the encoded bitstream
without decoding it, so it makes more sense to calculate this in the encoder and
carry it along the encoded data.
The first step is to encode the 2 audio programs with the output set for EDI.
Assuming that both encoders and multiplexer run on the same host:
\begin{lstlisting}
odr-audioenc --dab -i prog1.wav -b 128 -e tcp://localhost:9001
odr-audioenc -i prog2.wav -b 88 -e tcp://localhost:9002
\end{lstlisting}
On the multiplexer configuration file, the subchannel must be configured for
EDI as follows:
\begin{lstlisting}
subchannels {
sub-p1 {
type audio
bitrate 128
id 10
protection 5
inputproto edi
inputuri "tcp://*:9001"
buffer-management prebuffering
}
sub-p2 {
type dabplus
bitrate 88
id 1
protection 1
inputproto edi
inputuri "tcp://*:9002"
buffer-management prebuffering
}
}
\end{lstlisting}
The EDI input supports several options in addition to the ones of a
subchannel that uses a file input. The options are:
\begin{itemize}
\item \texttt{inputuri}: This defines the interface and port on which to
listen for incoming data. It must be of the form
\texttt{<proto>://*:<port>}, with \texttt{proto} may be either
\texttt{tcp} or \texttt{udp}.
\item \texttt{buffer-management}: Two buffer management approaches are
possible with EDI:
\begin{itemize}
\item \texttt{prebuffering} ignores timestamps and
pre-buffers some data before it starts streaming. This allows to
compensate for network jitter.
\item \texttt{timestamped} takes
into account the timestamps carried in EDI, inserting the audio into the
ETI frame associated to that same time stamp.
\end{itemize}
\item \texttt{buffer}: (Both buffer management settings)
The input contains an internal buffer for
incoming data. The maximum buffer size is given by this option, the
units are 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 when the buffer is
full.
\item \texttt{prebuffering}: (Only in buffer management \texttt{prebuffering})
When the buffer is empty, the multiplexer
waits until this amount of 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.
In both buffer management techniques, it is a trade-off between absolute delay
and robustness. When using pre-buffering, you directly control size of the
buffer, and you set it to a value depending on your network delays. When using
timestamped buffer management, the size of the input buffer is a consequence of
the effective delay you set in the timestamps.
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 input buffer in
the multiplexer will fill up to the amount given by \texttt{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 fast, 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 frame 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 ODR-AudioEnc, which
insures that the encoder outputs the encoded 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.
Complete examples of such a setup are given in the scenarios.
\subsubsection{Between Multiplexer and Modulator}
The EDI protocol can also carry data of a complete ensemble from ODR-DabMux to
one or more instanced of ODR-DabMod.
On the multiplexer configuration file, the output must be configured for EDI
as follows:
\begin{lstlisting}
outputs {
edi {
destinations {
edi_tcp {
protocol tcp
listenport 9201
}
}
}
; Throttle output to real-time (one ETI frame every 24ms)
throttle "simul://"
}\end{lstlisting}
In case you wish to interface ODR-DabMux with a modulator that does not support
EDI over TCP, but your network is not stable enough to use UDP, you can use
ODR-EDI2EDI. See \url{http://github.com/Opendigitalradio/ODR-EDI2EDI} for
information about that tool.
% vim: spl=en spell tw=80 et