Skip to content

Smart Blocks

code edited this page Mar 2, 2026 · 1 revision

Smart Blocks

Smart blocks are rule-based content selectors that automatically pick tracks from your media library. Instead of manually building playlists, you define rules and the system builds the playlist for you — fresh every time.

Concepts

A smart block has four types of rules:

Rule Type Purpose
Include Filters Tracks must match ALL of these to be eligible
Exclude Filters Tracks matching ANY of these are rejected
Weights Preferred tracks get a score boost (more likely to be picked)
Quotas Enforce min/max counts for specific categories

Plus three behavioral settings:

Setting Purpose
Separation Prevent repeating the same artist/title/album/label within a time window
Duration Target length of the generated playlist
Fallbacks Other smart blocks to try if this one can't fill the slot

Include Filters

All include filters use AND logic — a track must match every filter to be eligible.

Field Match Type Example Value Notes
genre Exact (case-insensitive) "Rock"
mood Exact (case-insensitive) "Upbeat"
artist Normalized "The Beatles" Strips punctuation/spaces before comparing
album Exact "Abbey Road"
title Exact "Yesterday"
label Exact "Atlantic Records"
language Exact "en"
tags Tag match (selected in UI) Track must have at least one of the specified tags
text_search Fuzzy "love" Searches across title, artist, and album
bpm Range min: 120, max: 140
year Range min: 1990, max: 1999
explicit Boolean true/false
source_playlists Playlist membership (selected in UI) Track must belong to one of these playlists
include_public_archive Boolean true Also consider tracks from other stations marked as public

Exclude Filters

Same fields as include filters, but inverted — any track matching an exclude rule is dropped from the candidate pool.

Common use: exclude explicit = true to keep a clean broadcast.

Weights (Scoring Boosts)

Weights nudge the selection toward preferred content without being absolute filters. A track with a higher score is more likely to be chosen, but lower-scored tracks can still appear.

Field Value Weight Effect
genre "Jazz" +2.0 Jazz tracks are twice as likely to be picked
mood "Chill" +1.5 Chill tracks get a moderate boost
tag (tag UUID) +3.0 Tagged tracks get a strong boost
new_release 7 (days) +2.0 Tracks uploaded in the last 7 days get a boost

The new_release weight is particularly useful for shows that want to feature recently added content.

How Scoring Works

  1. Every eligible track starts with a base score of 1.0
  2. Each matching weight rule adds its weight value
  3. Energy curve alignment adds a bonus (if configured)
  4. A small random jitter (0-0.1) is added to break ties
  5. Tracks are selected highest-score-first

Quotas

Quotas enforce minimum and maximum counts for categories within the generated playlist.

Field Values Min Max Effect
genre ["Pop"] 2 5 At least 2 Pop tracks, at most 5
artist ["Radiohead"] 0 2 No more than 2 Radiohead tracks
explicit ["true"] 0 1 At most 1 explicit track
  • Max = 0 means no upper limit
  • Min unmet generates a warning but doesn't prevent generation
  • Max exceeded hard-stops selection of that category

Separation Rules

Separation prevents the same content from repeating too soon. The engine checks both the play_history table (what already aired) and the in-progress playlist being built.

Rule Typical Value Effect
Artist Separation 60 minutes Same artist won't appear within 60 minutes
Title Separation 240 minutes Same track won't repeat within 4 hours
Album Separation 30 minutes Different album each half hour
Label Separation 0 (disabled) No label separation

Important: Setting separation too high for a small library will cause the engine to relax constraints (see Progressive Relaxation below).

Duration Target

Set how long the smart block should fill:

  • Target Minutes: e.g., 55 minutes for a 1-hour slot
  • Tolerance: Acceptable overshoot in seconds (e.g., 2 seconds)

If the target is not set, it defaults to the clock slot's duration. If that's also unset, it defaults to 15 minutes.

Fallback Chain

If the primary rules can't find enough tracks (library too small, rules too strict), the engine tries fallback smart blocks in order:

  1. Fallback Block 1 — e.g., a broader "All Music" block
  2. Fallback Block 2 — e.g., an even broader "Emergency Mix"
  3. Maximum chain depth: 3 levels

Each fallback can have a Limit (max tracks to take from it), so you can say "take at most 3 tracks from the fallback, then stop."

Progressive Constraint Relaxation

When the engine can't find enough candidates, it automatically relaxes constraints in stages:

Level What's Dropped Warning
0 Nothing (strict mode)
1 Separation rules dropped constraint_relaxed:1
2 Separation + quotas dropped constraint_relaxed:2
3 Separation + quotas + exclude rules dropped constraint_relaxed:3

If all 4 levels fail, the fallback chain is tried. If that also fails, the scheduler picks a random track as an emergency fallback.

Energy Curve (Sequence Policy)

The energy curve controls the "flow" of the generated playlist. Define a sequence of energy targets (0-100) and the engine tries to match each position:

Curve: [60, 70, 80, 90, 80, 70]  →  Build → Peak → Ease down

Track energy is derived from BPM (preferred) or ReplayGain (fallback). The engine scores each candidate based on how close its energy is to the target for that position.

Creating a Smart Block (Dashboard)

  1. Go to Dashboard → Smart Blocks → New
  2. Fill in the name and description
  3. Configure your include/exclude filters using the dropdowns (genres, moods, and tags are populated from your library)
  4. Set separation rules
  5. Optionally configure weights, quotas, energy curve
  6. Set the target duration
  7. Click Create

Previewing

After creating a block, use the Preview button to see what tracks the engine would pick. You can generate multiple variants to see the diversity of output.

Testing via API

POST /api/v1/smart-blocks/{blockID}/materialize
{
  "station_id": "your-station-id",
  "mount_id": "your-mount-id",
  "duration_ms": 3600000
}

Returns a GenerateResult with the track list, total duration, and any warnings.

Examples

All-Day Variety Mix

Include: (none — picks from everything)
Exclude: explicit = true
Separation: artist 90 min, title 360 min
Target: 55 minutes

90s Rock Hour

Include: genre = "Rock", year range 1990-1999
Separation: artist 60 min, title 240 min
Weight: mood "Energetic" +2.0
Target: 55 minutes

Jazz Evenings (Chill, No Vocals)

Include: genre = "Jazz", mood = "Chill"
Exclude: tags = "vocal-jazz"
Separation: artist 45 min
Weight: new_release 30 days +1.5
Target: 115 minutes (for a 2-hour slot)

Weekly Show (Newest Uploads Only)

Include: tags = "sunday-show"
Weight: new_release 7 days +10.0
Separation: (none — show files are unique)
Target: 120 minutes

Interstitials and Bumpers

Smart blocks support automatic insertion of short clips between tracks:

Interstitials

  • Every N tracks: Insert a clip (e.g., every 4 songs)
  • Source: A playlist of jingles/station IDs
  • Per Break: How many clips per insertion point (1-3)

Bumpers

  • Source: A playlist of bumper clips
  • Max Per Gap: Maximum bumpers inserted between tracks

Configure these in the smart block's advanced settings. The engine inserts them during sequence generation, fitting them into the target duration.

See Also

Clone this wiki locally