Skip to content
63 changes: 63 additions & 0 deletions docs/configuration/audio-addict.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,66 @@ audio_addict_pass = PASSWORD
## Location

The **Audio Addict Radio Network** folder is located within your media library. From there, you can browse and access all available stations directly.

## Shows and episodes

Besides the live stations, DI.fm network offers an **Events** folder. It lists the upcoming shows, and
for a show that has already been broadcast it also offers the recording, so you can listen to it
afterwards.

Shows with a back catalogue get a folder of their own holding the older episodes. Some shows have
hundreds of them, so the folder is split into smaller groups, each labelled with the episode numbers
and dates it contains.

```
# How many episodes one group holds before it is split. Default 20, minimum 1.
audio_addict_episodes_per_container = 20
```

Building this list means asking the service for the events and for each show's episodes, which takes
a moment. UMS remembers the answer so that browsing and starting playback do not each pay for it
again:

```
# How long the show and episode lists are reused, in minutes.
# Default 60. Set to 0 to ask the service every time.
audio_addict_tree_cache_ttl_minutes = 60
```

A longer time makes browsing snappier, a shorter one picks up newly published episodes sooner. The
addresses UMS receives stay valid far longer than the default hour, so there is no need to keep this
value small.

## Live titles

Audio Addict stations do not announce the current track inside the audio stream. UMS asks the
service instead and delivers the result to your player, so you still see what is playing. This is
described in [Internet radio and live titles](/configuration/internet-radio).

```
# Send live titles for Audio Addict stations. On by default.
audio_addict_icy_metadata = TRUE
```

## Curated playlists

Curated playlists play one track after another from your account. When the playlist reaches its end,
UMS can start over instead of stopping:

```
# Start a curated playlist again when it ends. Off by default.
audio_addict_playlist_loop = FALSE
```


## All settings at a glance

| Setting | Default | Purpose |
|---|---|---|
| `audio_addict_user` | — | Your account name |
| `audio_addict_pass` | — | Your password |
| `audio_addict_europe` | `TRUE` | Prefer the European streaming server |
| `audio_addict_icy_metadata` | `TRUE` | Send live titles to the player |
| `audio_addict_episodes_per_container` | `20` | Episodes per group before splitting |
| `audio_addict_tree_cache_ttl_minutes` | `60` | How long show and episode lists are reused |
| `audio_addict_playlist_loop` | `FALSE` | Repeat a curated playlist when it ends |
51 changes: 51 additions & 0 deletions docs/configuration/change-notifications.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Change Notifications

When something in your library changes, connected apps should notice without you pressing refresh —
and without asking UMS every few seconds whether anything happened. UPnP solves this with
subscriptions: an app registers its interest once, and UMS tells it when there is news.

This works in both directions, and the two are controlled separately.

## What UMS announces about your library

UMS publishes two pieces of information whenever the library changes:

- a **counter** that goes up on any change, which tells a subscriber that something happened
- a **list of the containers that changed**, which tells it what

The second one is what keeps things quick. An app that learns only "something changed" has to
reload; one that learns "this folder changed" reloads that folder and leaves the rest alone.

Both are announced at most a few times per second. A scan that imports a thousand files therefore
does not produce a thousand notifications — the changes are collected and reported as a handful of
messages.

Typical moments when this happens:

- a file appears in, or disappears from, a shared folder
- you [edit a playlist](/configuration/playlist-editing) from a control point
- you rate something, because that changes what the ratings folders contain
- artwork is added for a station or a folder

Whether your app acts on the news is up to the app. Most refresh the view you are looking at; some
only use the information when you open a folder again. If a change does not appear, it is worth
opening the folder anew before assuming it was not delivered.

## What UMS listens to on your players

The other direction is UMS subscribing to your **players**, so it can show what they are doing —
what is playing, whether they are paused, how loud they are — and offer controls for them.

```
# Follow the players on the network. On by default.
upnp_subscribe_services = TRUE
```

Leave this on when UMS is the place you control playback from.

Turn it off when playback is driven by a separate control point. In that arrangement UMS has no
business following and claiming control of the players: the control point is doing that, and two
parties steering the same device is a good way to get confusing results. Switching this off makes
UMS keep its hands off and simply serve the media.

See [Two-box and three-box setups](/configuration/control-point-setups) for what that arrangement looks like.
51 changes: 51 additions & 0 deletions docs/configuration/control-point-setups.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Two-Box and Three-Box Setups

UPnP knows two ways of arranging the parts of a media system, and UMS behaves differently in each.

In a **two-box** setup, the device that browses your library is also the device that plays: a TV, a
streaming box, a phone app that shows the folders and then plays the track itself. The device asking
for the list and the device asking for the audio are one and the same.

In a **three-box** setup they are separate. A *control point* — an app on your phone or a web
interface — shows the library and tells a *renderer* to play. The app never touches the audio; it
only points the renderer at it. This is the arrangement typical of hi-fi streamers, where a
dedicated device does the playing and you steer it from somewhere else.

## Why UMS has to know the difference

UMS decides how to deliver a track based on what the receiving device can handle: a player that
cannot decode FLAC gets a converted stream, one that can gets the file untouched.

In a two-box setup that decision is easy, because whoever asked for the list is whoever will play.
In a three-box setup it is not: the request for the list comes from your phone, the request for the
audio from the streamer. Deciding on the basis of the phone would be exactly wrong — it would send
the streamer whatever suits a phone.

## How UMS tells them apart

```
# Require accounts and sign-in. On by default.
authentication_enabled = TRUE
```

With authentication **on**, UMS ties playback to the identity that browsed, so that what a user is
allowed to see is also what that user gets to play. This is the right behaviour for a household with
several accounts and per-user access, and it assumes a two-box arrangement.

With authentication **off**, UMS stops assuming the two are the same. It determines the playing
device at the moment the audio is requested, from that request itself — its address and what it says
about itself — and makes the conversion decision for *that* device. The identity in the browse
request is then understood as the control point it actually is.

Two devices sharing one address, which happens when the control point and the renderer run on the
same machine, are still told apart, because they are distinguished by what they report about
themselves rather than by the address alone.

## Choosing

Neither setting is more correct than the other; for maximum compatibility turn authentication **off**. The price is that UMS then has no accounts: there is no per-user access control, and everything it shares is visible to everything on the network that can
reach it. If that is a concern, restrict which devices may reach UMS at all — see
[Security and privacy](/configuration/security-and-privacy).

Leave it **on** if your players browse and play for themselves, or if you need the per-user
separation. This is the default.
87 changes: 87 additions & 0 deletions docs/configuration/internet-radio.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Internet Radio and Live Titles

An internet radio station does not only send audio, it also announces the track it is playing right
now. UMS picks that announcement up and passes it on, so your control point can show what is
currently on air instead of just the station name.

This works for radio streams you have added to a playlist and for the stations of the
[Audio Addict Network](/configuration/audio-addict).

## How the title reaches your player

There are two ways a title can travel, and UMS uses whichever fits:

- Players that ask for in-band metadata get the title woven into the audio stream, the way internet
radio has always done it.
- Players that do not ask : Because UMS reads the announcement itself and pushes it to the control point separately, the live title
appears even with players that know nothing about radio metadata.

There is one case without live titles: if UMS has to **transcode** the stream for your player, the
title cannot be woven in, because the transcoder produces the audio and knows nothing about the
station's announcements. Streams that play directly — which is the normal case for MP3 and AAC
stations — are unaffected.

## Interpreting the announcement

Stations announce a single line of text, and there is no rule that says which part is the artist.
The common convention is:

```text
Miles Davis - So What
```

but some stations put the station name at the end instead:

```text
So What - Jazz Radio on example.com
```

Taken as "artist first", the second line would list *So What* as the artist. UMS therefore looks at
the part after the last dash and treats it as a station name, not an artist, when any of these
applies:

- it contains something that looks like a web address, such as `example.com`
- it resembles the station name UMS already knows from your playlist
- it resembles the host name of the stream address, ignoring generic parts like `stream`, `listen`
or `radio`

If none of them applies, the first part is taken as the artist, which is the usual convention.

## Correcting a station by hand

The rules above get it right for most stations, but a station can always break them — a show name
at the end, an unusual separator, or an artist whose name happens to contain a domain. For those,
tell UMS explicitly with an `#EXTICYORDER:` line in the playlist, directly above the stream:

```text
#EXTM3U
#EXTINF:-1,Jazz Radio
#EXTICYORDER:title-first
http://stream.example.com/jazz.mp3
```

| Value | Meaning |
|---|---|
| `auto` | Decide automatically, as described above. This is the default. |
| `artist-first` | Always read the announcement as *Artist - Title*. |
| `title-first` | Always read it as *Title - Station*. |

An unknown value is treated as `auto`. The setting applies to that one station; see
[Playlist directives](/configuration/playlist-directives) for how such lines work in general.

If your control point offers a way to switch the order while listening, it can set the same value
through UMS, and UMS writes it into the playlist file so the choice survives a restart.

## Audio Addict stations

Stations of the Audio Addict Network do not announce their titles in the stream. UMS asks the
service for the current track instead and delivers it the same way, so the behaviour is identical
from the outside.

```
# Send live titles for Audio Addict stations. On by default.
audio_addict_icy_metadata = TRUE
```

Turn this off if a player of yours reacts badly to in-band metadata; the titles pushed to the
control point are unaffected by it.
78 changes: 78 additions & 0 deletions docs/configuration/performance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Performance

The defaults are chosen to be safe on modest hardware. On a machine with a large library and cores
to spare, a few settings are worth revisiting — and one of them matters more than the rest.

Change one thing at a time and watch the result. Every setting here trades one resource for another,
so a value that helps one installation can hurt the next.

## Reading the library in parallel

Before UMS can present a file, it has to work out what it is: read the metadata, find the artwork,
determine what the requesting device needs. This is the single biggest factor in how long a scan
takes and how quickly a large folder opens, and it is done by a pool of worker threads.

```
# How many files UMS works on at once. Default 4, allowed 1 to 64.
media_resolve_threads = 4
```

The work is dominated by waiting — for the disk, for the database, occasionally for the network — so
more threads help well beyond the number of cores you have. On a server with a large library, a
value in the region of the core count or above is reasonable. On a small machine, or one where UMS
shares the disk with something else, leave it alone.

This setting also sizes the pool of database connections, which is kept at twice the number of
threads and never below ten. That is deliberate: worker threads need connections, and raising the
threads without the connections to go with them would leave them queueing for one another. Because
the two move together, there is nothing separate to adjust.

## Database memory

The database keeps recently used pages in memory. How much it may use is decided automatically, and
that is normally the right answer:

```
# Database cache in KB. Default -1, which lets UMS decide.
database_media_cache_size = -1
```

Two further switches trade memory for speed. Both are off by default and both are worth a
measurement rather than a guess:

```
# Hold database indexes in memory.
database_media_use_memory_indexes = FALSE

# Let the cache give memory back under pressure instead of holding it.
database_media_use_cache_soft = FALSE
```

Memory indexes make lookups faster at the cost of memory that is then unavailable for anything else.
The soft cache is the opposite trade: it releases memory when the system needs it, which keeps UMS
out of trouble on a machine that is short of memory, at the price of having to read those pages
again afterwards.

## Logging

By default UMS writes each log line out as it happens. Buffering makes logging cheaper:

```
# Collect log lines before writing them out. Off by default.
logging_buffered = FALSE
```

The catch shows up exactly when you need the log most. If UMS is killed or crashes, whatever is
still in the buffer is lost, so the log can stop short of the event you are investigating — and an
abruptly ending log then looks like a freeze that never happened. Leave buffering off while chasing
a problem.

## What to measure

Two numbers tell you whether a change helped:

- How long a full scan of your library takes. It is in the log, as a line reporting the media scan
completed and the number of seconds it needed.
- How long it takes to open your largest folder in a control point, once after a restart and once
again straight afterwards. The first time includes the work of building the folder, the second
does not, and the difference is what these settings act on.
Loading