Playback logic#

Radiotomate has an original logic to decide what sound it should play in real time. It is very adaptative and aims at simplifying the life of radio producers while ensuring listeners receive a coherent and continuous program. But this logic relies on assumptions that may not fit all radios. In this page we detail Radiotomate's logic and assumptions, with advice and examples.

The 4 streams#

Radiotomate will play the first stream available among:

  1. the live input (top priority)
  2. a relayed stream
  3. sound carts
  4. auto-DJ (lowest priority)

Radiotomate assumes that the first 3 sources have nothing to play most of the time. The auto-DJ is the only one that can always find something to play (the only exception being an empty radio that has just been installed). Sound carts and relayed streams will play something at the time they're set in Radiotomate. The live input takes over when an authorized user starts streaming to it.

When a higher-priority stream has something to play, it will instantly cross-fade to its program. When switching to a lower-priority stream it will start a new track. For example, when switching back to the Auto-DJ it will always start from the beginning of a song. When it's time to play a pre-recorded show it will interrupt the current song. However sound carts are queued one after the other.

This original approach to broadcasting ensures we avoid two things we don't like as listeners: silences, and cutting the last minute of a program.

In practice, usually everything is on time. But when something gets late, this logic will let programs flow slightly off-schedule, up to a configurable limit. This matches what would happen if everyone was producing their show live in the same studio: if one program is a bit longer, the next one will follow as they can. If it's a bit shorter, we'd like to insert a jingle and a music track before the next one starts on time. If the live stream doesn't work, we'd like to have some music instead. This is further illustrated in examples below.

We explain in the users management section that Radiotomate assumes your radio defines and enforces its own internal rules. This include respecting the schedule. Radiotomate can enforce maximum durations, but does not by default.

⚠️ this also means that Radiotomate will let you do what you might consider as mistakes: typically, scheduling shows at overlapping times. Although the system will do its best to let you see such cases and to play them nonetheless, in the worst case it may cause a show to be skipped entirely. Upcoming versions will include a calendar showing what's coming next, and a history browser to see what has been really aired.

This logic is unusual among broadcast automation systems, and explains why Radiotomate does not pre-computes its playlist in advance: it always balances between the schedule set by users and how sounds are really available. This logic turned out to be reliable and efficient over multiple years in our radios. Thanks to this approach, Radiotomate is much easier to configure (and develop).

Before illustrating with examples, we detail how each stream source works.

Auto-DJ#

The goal of the Auto-DJ is to pick music and jingles according to criteria configurable over a weekly schedule.

This schedule is displayed when you open the Auto-DJ tab in the Web interface. It is splitted in time slots over the 7 weekdays. A time slot only has a start time, it will last until the next one or the end of the day. You can assign a name and a color to each slot, but more importantly you want to assign it filters.

Each slot has one filter or more, that it will use to pick the music when it's its time to play. For example:

  • to play only Pop, set the filter to genre:Pop
  • to play 80s music, set the filter to year:1980..1989
  • to play music recently added to the library, set added:-9m.. (this select tracks uploaded to Radiotomate at most 9 months ago)
  • to play french songs, set language:fra

Filters follow the syntax of Beets queries, you can use any expression or tag that Beets supports. Don't forget to check that music in your library does have the tags you want to filter on. The interface has a Test button for each filter so you can see a sample of what a filter would pick before assigning it to a slot. If at some point a filter does not match any track, Radiotomate will treat it as an empty filter and pick in the whole collection.

A slot can use multiple filters, each having a different weight, to balance them during this time slot. For example if you set

  • added:-3m.. with weight 50
  • added:-1y..-3m with weight 30
  • an empty filter with weight 20 (this selects all music)

Then on the long term this time slot will contain 50% tracks inserted over the last 3 months, 30% tracks inserted over the last year (but more than 3 months) and 20% tracks among the whole collection (that may include recent tracks too). To set intuitive probabilities we advise you sum up weights to 100, but you do not have to.

The auto-DJ will regularly insert jingles between tracks. After playing a jingle, it will wait 13 minutes before attempting to insert a jingle again. This delay can be changed in the configuration file. Jingles are picked in jingle carts.

Sound carts#

Sound carts contain individual sound files, or one URL to stream from. They represent a program that will be broadcasted at a configurable time (regularly or not), with the exception of jingle carts that are inserted in the auto-DJ's stream (see above).

You can set how a cart will choose which sound to play:

  • random: every time the cart has to play, it will choose one sound randomly. This is often a adapted to jingles.
  • playlist: when using this mode sounds are ordered in the cart. Radiotomate will play each sound once, so be careful to add new sounds at the end of the list.
  • playlist loop: like playlist, but when all sounds have played Radiotomate starts again from the first.

When it's their time to play, Sound carts are queued in their own stream, that will interrupt the auto-DJ. So they don't interrupt each other! Radiotomate can enforce a maximal duration for a cart, but by default it does not. This means that we assume you check that carts' schedule do match their contents' duration. Also note that a sound will not stay queued forever, if it's been waiting for too long Radiotomate will remove it from the queue and attempt to re-insert it next time the cart is scheduled.

If you do not want to interrupt the auto-DJ, you can also configure a timed cart to be queued in the auto-DJ's playlist. If a cart is empty when it should be playing, it will be ignored and will not interrupt the auto-DJ. A cart can be empty if it contains no sound, or if it is a playlist but all its sound have already been broadcasted.

You can set a maximum duration per cart: if a sound from the cart is still playing after this delay, it will be interrupted. Note that this delay is computed according to the cart's schedule, who might not match the actual start time of the sound (see the example below, "When everybody's late").

Relayed streams#

This source pulls another radio's stream, relayed live from their HTTP or HTTPS source. In the interface you can configure when Radiotomate should start relaying a given URL, and how long it should last. If the source interrupts their stream too early, or if the URL is incorrect, Radiotomate will handover to the auto-DJ.

⚠️ If the connection between your source and Radiotomate is unstable, it might unexpectedly handover to the Auto-DJ for short periods. Indeed Radiotomate cannot make the difference between lost packets and a source ending its stream.

Live stream input#

This is source allows you to stream to Radiotomate, as if it was an Icecast server. When someone starts streaming they interrupt the current programs and are on air in a few seconds. The aired program is slightly delayed because of network buffers.

⚠️ Like relayed streams, this input assumes you have a stable connection from the live studio to Radiotomate. Otherwise you might experience programs "stuttering" to the auto-DJ (inserting a jingle). If such short interruptions happen too frequently, consider increasing input_min_buffer in your configuration file.

Note that this is only allowed to users having the "Live" role. Instructions to configure their applications are in another section.

Example: an evening's schedule#

We detail a typical schedule and describe how things may actually happen, especially when sounds or streams do not last as expected or if an user streams live while carts should be playing.

The usual schedule#

  • In the afternoon, no cart is scheduled so the auto-DJ is playing, picking music according to the 14:00 slot filters, inserting jingles regularly.

  • At 18:00 a relay cart is scheduled and has been set with a maximum duration of one hour.

  • At 19:00 an user should start a live stream, during one hour.

    • by default the live stream inserts a delay of at least 5 seconds, so the user should start a few seconds earlier. Radiotomate will crossfade to live as soon as the stream is loaded, so the live will probably overlap with the last seconds of the relayed stream (who's buffered, too).
  • At 20:00 a sound cart is scheduled to play a pre-recorded show, that lasts one hour.

  • At 21:00 the auto-DJ is the only remaining source so it restarts, it has not inserted a jingle for more than 13 minutes so it will firstly play a jingle.

When everybody's late#

What happens if streams start too late and sound carts contain a slightly too long sound?

  • In the afternoon, the auto-DJ plays as usual
  • If the relayed URL is not available at 18:00, the auto-DJ will continue playing but Radiotomate will keep trying to connect. As soon as it is available, it is relayed.
  • Let's say the relayed stream continues to 19:05...
  • ... but the live user starts streaming at 19:03
  • Our user want to air their 1-hour show, so they stream to 20:03
  • Radiotomate did queue the sound cart at 20:00, but it was waiting for the end of the stream. The cart starts playing right after the stream, at 20:03.
  • If the cart contained a too-long episode, it will play until its end because the auto-DJ waits for the carts' end.

Live take-over#

If one evening the live stream is exceptionally streaming from 18:00 to 22:00, it will override the whole schedule.

Radiotomate will dequeue the sound cart after detecting that it has not started (this will be configurable in upcoming versions). The episode that should have played will be re-scheduled next time.

Combining streams and schedules#

By exploiting streams' priorities, you can achieve some interesting combinations that will adapt precisely to contents' durations.

Add a prolog or epilog to an imported program#

What if we want to play a specific jingle before and after the relayed stream?

Let's say we have one 10-seconds sound to insert before the relay starts, and a 20-seconds sound to be played afterwards. We could set up this variant of the previous schedule:

  • Create a sound cart for the introduction sound, in playlist loop mode. Schedule it at 17:59:55.
  • The relay cart is still scheduled at 18:00. Because the introduction lasts 10 seconds, they will overlap. This is intentional: the 5-seconds overlap will let Radiotomate load the stream's buffer and crossfade to the stream.
  • Create a sound cart for the outro sound, in playlist loop mode. Schedule it at 18:59 - Radiotomate will always play it "late", because carts are played after relayed streams... which is exactly what we want to achieve here.

This also works fine if you want to add an intro/outro to a sound cart.

How to enforce auto-DJ filters are applied on time#

Switching to the next auto-DJ slot does not interrupt the current track. This means that its filters will only be applied when the next track is pushed, which might be a few minutes after. What if you want it on time?

Let's say you have no program scheduled during a complete afternoon, so the auto-DJ is playing. The afternoon contains 3 auto-DJ slots:

  • no filter from 14:00 to 15:00, so the auto-DJ picks in whole music collection,
  • from 15:00 to 16:00 the slot selects only songs singing in French (with the filter language:fra),
  • from 16:00 to 18:00 we get back to the whole collection.

If you want to be sure that at 15:00 the radio starts singing in french, the trick is to schedule an introduction cart that will contain a few short introduction jingle(s) of this specific auto-DJ slot. The cart should use random or looping playlist modes and be timed at 15:00. It will interrupt the previous auto-DJ track, play once, then the 15:00 slot start.

What if ...?#

If after those examples you're still wondering if Radiotomate can apply the schedule you'd like, reach out to us.