# Liquidsoap

## audio stream generation

Since after version 0.9.3, liquidsoap has decoding formats. These are special values describing how to encode raw data. Practically, this means that instead of writing:

    output.icecast.vorbis(quality=0.3,samplerate=44100,...)

you shall now write:

    output.icecast(%vorbis(quality=0.3,samplerate=44100),etc)

The same goes for `output.file` and for other formats.

### List of formats and their syntax

All parameters are optional, and the parenthesis are not needed when no parameter is passed. In the following default values are shown. As a special case, the keywords `mono` and `stereo` can be used to indicate the number of channels (whether is is passed as an integer or a boolean).

#### MP3

Mp3 encoder comes in 3 flavors:

- `%mp3` or `%mp3.cbr`: Constant bitrate encoding
- `%mp3.vbr`: Variable bitrate, quality-based encoding.
- `%mp3.abr`: Average bitrate based encoding.

Parameters common to each flavor are:

- `stereo=true/false`, `mono=true/false`: Encode stereo or mono data (default: `stereo`).
- `samplerate=44100`: Encoded data samplerate (default: `44100`)
- `id3v2=true`: Add an `id3v2` tag to encoded data (default: `false`). This option is only valid if liquidsoap has been compiled with taglib support.

Parameters for `%mp3` are:

- `bitrate`: Encoded data fixed bitrate

Parameters for `%mp3.vbr` are:

- `quality`: Quality of encoded data; ranges from `0` (highest quality) to `9` (worst quality).

Parameters for `%mp3.abr` are:

- `bitrate`: Average bitrate
- `min_bitrate`: Minimun bitrate
- `max_bitrate`: Maximun bitrate
- `hard_min`: Enforce minimal bitrate

Examples:

- Contstant `128` kbps bitrate encoding: `%mp3(bitrate=128)`
- Variable bitrate with quality `6` and samplerate of `22050` Hz: `%mp3.vbr(quality=7,samplerate=22050)`
- Average bitrate with mean of `128` kbps, maximun bitrate `192` kbps and `id3v2` tags: `%mp3.abr(bitrate=128,max_bitrate=192,id3v2=true)`

Additionaly, liquidsoap inserts a message within mp3 data. Currently, this message is: `"Liquidsoap/1.0.0-beta3 (Unix; OCaml 3.12.0)"`. We plan on using this data for flows and other services involving liquidsoap. You can set its value using the `msg` parameter. Setting it to `""` disables this feature.

#### WAV

    %wav(stereo=true, channels=2, samplesize=16, header=true, duration=10.)

If `header` is `false`, the encoder outputs raw PCM. `duration` is optional and is used to set the WAV length header.

Because Liquidsoap encodes a possibly infinite stream, there is no way to know in advance the duration of encoded data. Since WAV header has to be written first, by default its length is set to the maximun possible value. If you know the expected duration of the encoded data and you actually care about the WAV length header then you should use this parameter.

#### Ogg

The following formats can be put together in an Ogg container. The syntax for doing so is `%ogg(x,y,z)` but it is also possible to just write `%vorbis(...)`, for example, instead of `%ogg(%vorbis(...))`.

##### Vorbis

    # Variable bitrate
    %vorbis(samplerate=44100, channels=2, quality=0.3)
    % Average bitrate
    %vorbis.abr(samplerate=44100, channels=2, bitrate=128, max_bitrate=192, min_bitrate=64)
    # Constant bitrate
    %vorbis.cbr(samplerate=44100, channels=2, bitrate=128)

Quality ranges from -0.2 to 1, but quality -0.2 is only available with the aotuv implementation of libvorbis.

##### Theora

    %theora(quality=40,width=w,height=h,
            picture_width=w,picture_height=h,
            picture_x=0, picture_y=0,
            aspect_numerator=1, aspect_denominator=1,
            keyframe_frequency=64, vp3_compatible=false,
            soft_target=false, buffer_delay=0.1,
            speed=0)

You can also pass `bitrate=x` explicitly instead of a quality. The default dimensions are liquidsoap's default, from the settings `frame.video.height/width`.

##### Dirac

    %dirac(quality=35,width=w,height=h,
           picture_x=0, picture_y=0,
           aspect_numerator=1, aspect_denominator=1)

##### Speex

    %speex(stereo=false, samplerate=44100, quality=7,
           mode=[wideband|narrowband|ultra-wideband],
           frames_per_packet=1,
           complexity=none)

You can also control quality using `abr=x` or `vbr=y`.

##### Flac

The flac encoding format comes in two flavors:

- `%flac` is the native flac format, useful for file output but not for streaming purpose
- `%ogg(%flac,...)` is the ogg/flac format, which can be used to broadcast data with icecast

The parameters are:

    %flac(samplerate=44100,
          channels=2,
          compression=5,
          bits_per_sample=16)

`compression` ranges from 0 to 8 and `bits_per_sample` should be one of: `8`, `16` or `32`.

#### AAC

The syntax for the internal AAC encoder is:

    %aac(channels=2, samplerate=44100, bitrate=64, adts=true)

#### AAC+

The syntax for the internal AAC+ encoder is:

    %aacplus(channels=2, samplerate=44100, bitrate=64)

#### External encoders

For a detailed presentation of external encoders, see this page.

    %external(channels=2,samplerate=44100,header=true,
              restart_on_crash=false,
              restart_on_new_track,
              restart_after_delay=<int>,
              process="")

Only one of `restart_on_new_track` and `restart_after_delay` should be passed. The delay is specified in seconds. The encoding process is mandatory, and can also be passed directly as a string, without `process=`.

### Formats determine the stream content

In most liquidsoap scripts, the encoding format determines what kind of data is streamed.

The type of an encoding format depends on its parameter. For example, `%mp3` has type `format(audio=2,video=0,midi=0)` but `%mp3(mono)` has type `format(audio=1,video=0,midi=0)`.

The type of an output like `output.icecast` or `output.file` is something like `(...,format('a),...,source('a))->source('a)`. This means that your source will have to have the same type as your format.

For example if you write `output.file(%mp3,"/tmp/foo.mp3",playlist("~/audio"))` then the playlist source will have to stream stereo audio. Thus it will reject mono and video files.

### Technical details

You can store an atomic format in a variable, it is a value like another: `fmt = %mp3`. However, an atomic format is an atomic constant despite its appearance. You cannot use a variable for one of its parameters: for example

    x = 44100
    %vorbis(samplerate=x)

is not allowed, you must write `%vorbis(samplerate=44100)`.

In programming languages like ML, the typing of `printf` is a bit special. Alone, `printf` has an esoteric type. Together with its parameter, it takes a meaningful type, for example `printf "An integer: %d\n"` has type `int -> unit`. So, the format string `"An integer: %d\n"` is not a string at all, it has a more complex type, and cannot be manipulated as a string. Our encoding formats have a similar role, hence the symbol `%`.