summaryrefslogtreecommitdiffstats
path: root/README.md
blob: 4b078c917c4d6ce34968d6ef8abca55e74d65d81 (plain)
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
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
ODR-AudioEnc Package
========================

This package contains a DAB and DAB+ encoder that integrates into the
ODR-mmbTools.

The DAB encoder is based on toolame. The DAB+ encoder uses a modified library
of the Fraunhofer FDK AAC code from Android, patched for 960-transform to do
DAB+ broadcast encoding. FDK-AAC has to be supplied separately, and is available
in the [repository](https://github.com/Opendigitalradio/fdk-aac.git).

The main tool is the *odr-audioenc* encoder, which can read audio from
a file (raw or wav), from an ALSA source, from JACK or using libVLC,
and encode to a file, a pipe, to a ZeroMQ or EDI output compatible with ODR-DabMux.

The libVLC input allows the encoder to use all inputs supported by VLC, and
therefore also webstreams and other network sources.

The ALSA and libVLC inputs support sound card clock drift
compensation, that can compensate for imprecise sound card clocks.

The JACK input does not automatically connect to anything. The encoder runs
at the rate defined by the system clock, and therefore sound
card clock drift compensation is also used.

*odr-audioenc* can insert Programme-Associated Data, that can be generated with
ODR-PadEnc.

For detailed usage, see the usage screen of the tool with the *-h* option.

More information is available on the
[Opendigitalradio wiki](http://opendigitalradio.org)


Requirements
============

* A C++11 compiler
* [FDK-AAC](https://github.com/Opendigitalradio/fdk-aac.git) (already contains the DAB+ patches)
* ZeroMQ 4.0.4 or more recent
* JACK audio connection kit (optional)
* The alsa libraries (libasound2, optional)
* libvlc and vlc for the plugins (optional)
* (optional) cURL to download the TAI-UTC bulletin, needed for timestamps in EDI output.

For Debian (and Ubuntu) use

    $ sudo apt-get install libzmq3-dev libzmq5
    $ sudo apt-get install libvlc-dev vlc-data vlc-nox
    $ sudo apt-get install libjack-jackd2-dev jackd2
    $ sudo apt-get install libasound2-dev libasound2

Attention: on debian buster, you'll need `libzmq5-dev` and `vlc-plugins-base`

Installation
============

    $ git clone https://github.com/Opendigitalradio/ODR-AudioEnc.git

If you want to clone the next branch (under development) use

    $ git clone https://github.com/Opendigitalradio/ODR-AudioEnc.git -b next

Configure the project

    $ cd ODR-AudioEnc/
    $ ./bootstrap
    $ ./configure

If you want to use ALSA, JACK and libVLC inputs, please use

    $ ./configure --enable-alsa --enable-jack --enable-vlc

    $ make
    $ sudo make install

* See the possible scenarios below on how to use the tools


How to use
==========

We assume that you have a ODR-DabMux configured for an ZeroMQ
input on port 9000.

    ALSASRC="default"
    DST="tcp://yourserver:9000"
    BITRATE=64

General remarks
---------------

Avoid using sources that are already encoded with a low bitrate, because
encoder cascading will noticeably reduce audio quality. Best are sources
encoded with a lossless codec (FLAC). Otherwise, try to get MP3 at 320kbps, AAC
at 256kbps or higher bitrates.

Ideally use a source at the correct sampling rate (32kHz or 48kHz, according to
your encoder configuration). VLC can do resampling, but on some systems selects
the ugly resampler which creates artifacts. Try adding
`-L --audio-resampler=samplerate -L --src-converter-type=0`
to your command line, but enable verbose mode and read the VLC debug output to
check that it enables the libsamplerate resampler, and not the ugly resampler.

The codecs do not behave well when your source material has peaks that go close
to saturation, especially when you have to resample. When you see little
exclamation marks with the -l option, it's too loud! Reduce the gain at the
source, or use the gain option if that's not possible.


DAB+ AAC encoder configuration
------------------------------
By default, when not overridden by the --aaclc, --sbr or --ps options,
the encoder is configured according to bitrate and number of channels.

If only one channel is used, SBR (Spectral-Band Replication, also called
HE-AAC) is enabled up to 64kbps. AAC-LC is used for higher bitrates.

If two channels are used, PS (Parametric Stereo, also called HE-AAC v2)
is enabled up to 48kbps. Between 56kbps and 80kbps, SBR is enabled. 88kbps
and higher are using AAC-LC.

ZeroMQ output
-------------

The ZeroMQ output included in ODR-AudioEnc is able to connect to
one or several instances of ODR-DabMux. The -o option can be used
more than once to achieve this.

Scenario *wav file for offline processing*
------------------------------------------
Wave file encoding, for non-realtime processing

    odr-audioenc -b $BITRATE -i wave_file.wav -o station1.dabp

Scenario *file that VLC supports*
---------------------------------
If you want to input a file through libvlc, you need to give an absolute path:

    odr-audioenc -b $BITRATE -v file:///home/odr/audio/source.mp3 -o station1.dabp

Scenario *ALSA*
---------------
Live Stream from ALSA sound card at 32kHz, with ZMQ output for ODR-DabMux:

    odr-audioenc -d $ALSASRC -c 2 -r 32000 -b $BITRATE -o $DST -l

To enable sound card drift compensation, add the option **-D**:

    odr-audioenc -d $ALSASRC -c 2 -r 32000 -b $BITRATE -o $DST -D -l

You might see **U** and **O** appearing on the terminal. They correspond
to audio underruns and overruns that happen due to the different speeds at which
the audio is captured from the soundcard, and encoded into HE-AACv2.

High occurrence of these will lead to audible artifacts.

Scenario *libVLC input for a webstream*
---------------------------------------
Read a webstream and send it to ODR-DabMux over ZMQ:

    odr-audioenc -v $URL -r 32000 -c 2 -o $DST -l -b $BITRATE

If you need to extract the ICY-Text information, e.g. for DLS, you can use the
**-w <filename>** option to write the ICY-Text into a file that can be read by
*ODR-PadEnc*.

If the webstream bitrate is slightly wrong (bad clock at the source), you can
enable drift compensation with **-D**.

Scenario *JACK input*
---------------------
JACK input: Instead of -i (file input) or -d (ALSA input), use -j *name*, where *name* specifies the JACK
name for the encoder:

    odr-audioenc -j myenc -l -b $BITRATE -o $DST

The JACK server must run at the samplerate of the encoder (32kHz or 48kHz). If that is not possible,
one workaround is to access JACK through VLC, which will resample accordingly:

    odr-audioenc -l -v jack://dab -b $BITRATE -o $DST

Scenario *LiveWire* or *AES67*
------------------------------

When audio data is available on the network as a multicast stream, it can be encoded using the following pipeline:

    rtpdump -F payload 239.192.1.1/5004 | \
    sox -t raw -e signed-integer -r 48000 -c 2 -b 24 -B /dev/stdin -t raw --no-dither -r 48000 -c 2 -b 16 -L /dev/stdout gain 4 | \
    odr-audioenc -f raw -b $BITRATE -i /dev/stdin -o $DST

It is also possible to use the libvlc input, where you need to create an SDP file with the following contents:

    v=0
    o=Node 1 1 IN IP4 172.16.235.155
    s=TestSine
    t=0 0
    a=type:multicast
    c=IN IP4 239.192.0.1
    m=audio 5004 RTP/AVP 97
    a=rtpmap:97 L24/48000/2

Replace the IP address in the `o=` field by the one corresponding to your
source node IP address, and the IP in `c=` by the multicast IP of your stream.
Then use this SDP file as input for the VLC input.


Scenario *local file through snd-aloop*
---------------------------------------
Play some local audio source from a file, with ZMQ output for ODR-DabMux. The problem with
playing a file is that *odr-audioenc* cannot directly be used, because ODR-DabMux
does not back-pressure the encoder, which will therefore encode much faster than realtime.

While this issue is sorted out, the following trick is a very flexible solution: use the
alsa virtual loop soundcard *snd-aloop* in the following way:

    modprobe snd-aloop

This creates a new audio card (usually 'hw:1' but have a look at /proc/asound/card to be sure) that
can then be used for the alsa encoder.

    ./odr-audioenc -d hw:1 -c 2 -r 32000 -b 64 -o $DST -l

Then, you can use any media player that has an alsa output to play whatever source it supports:

    cd your/preferred/music
    mplayer -ao alsa:device=hw=1.1 -srate 32000 -format=s16le -shuffle *

Important: you must specify the correct sample rate and sample format on both
"sides" of the virtual sound card.


Scenario *mplayer and fifo*
---------------------------
*Warning*: Connection through pipes to ODR-DabMux are deprecated in favour of ZeroMQ.

Live Stream resampling (to 32KHz) and encoding from FIFO and preparing for DAB muxer, with FIFO to odr-dabmux
using mplayer. If there are no data in FIFO, encoder generates silence.

    mplayer -quiet -loop 0 -af resample=32000:nowaveheader,format=s16le,channels=2 -ao pcm:file=/tmp/aac.fifo:fast <FILE/URL> &
    odr-audioenc -l -f raw --fifo-silence -i /tmp/aac.fifo -r 32000 -c 2 -b 72 -o /dev/stdout \
    mbuffer -q -m 10k -P 100 -s 1080 > station1.fifo

*Note*: Do not use /dev/stdout for pcm output in mplayer. Mplayer log messages on stdout.

Return values
-------------
odr-audioenc returns:

 * 0 if it encoded the whole input file
 * 1 if some options were not understood, or encoder initialisation failed
 * 2 if the silence timeout was reached
 * 3 if the AAC encoder failed
 * 4 it the ZeroMQ send failed
 * 5 if the input had a fault

The *-R* option to get ODR-AudioEnc to restart the input
automatically has been deprecated. As this feature does not guarantee that
the odr-audioenc process will never die, running it under a process supervisor
is recommended regardless of this feature being enabled or not. It will be removed
in a future version.


Known Limitations
-----------------
The gain option for libVLC enables the VLC audio compressor with default
settings. This has more impact than just changing the volume of the audio.

Some receivers did not decode audio anymore between v0.3.0 and v0.5.0, because of
a change implemented to get PAD to work. The change was subsequently reverted in
v0.5.1 because it was deemed essential that audio decoding works on all receivers.
v0.7.0 fixes most issues, and PAD now works much more reliably.

Version 0.4.0 of the encoder changed the ZeroMQ framing. It will only work with
ODR-DabMux v0.7.0 and later.

LICENCE
=======

The ODR-AudioEnc project contains

 - The code for odr-audioenc in src/ licensed under the Apache Licence v2.0. See
   http://www.apache.org/licenses/LICENSE-2.0
 - libtoolame-dab, derived from TooLAME, licensed under LGPL v2.1 or later. See
   libtoolame-dab/LGPL.txt. This is built into a shared library.
 - EDI output (files in src/edi) are GPLv3+

The odr-audioenc binary is linked against the libtoolame-dab and fdk-aac
shared libraries.

Whether it is legal or not to distribute compiled binaries from these sources
is unclear to me. Please seek legal advice to answer this question.