Skip to main content

Scheduler Parameters (smart-scheduler-parameters.js)

smart-scheduler-parameters.js centralizes every tunable knob of the scheduler so the engine logic stays free of magic numbers. Tuning the station is a matter of editing this one file and restarting the scheduler.

What lives here

GroupExamples
Playlist sizingNumber of tracks per generated playlist, rotation frequency
RotationROTATION.BUFFER_MAX (120), ROTATION.REFRESH_FRACTION (0.85), ROTATION.MUSIC_FRESH_MS (3 h)
CooldownsPer-track repeat suppression windows (COOLDOWN_PERIOD 90 m, ELEMENT_COOLDOWN 10 m)
Energy bandsMapping of track energy (1–5) to allowed transition deltas
Category weightsBase weight per category for Dirichlet sampling
RL settingsLearning rate, exploration vs. exploitation (ε / Thompson priors)
Fetch guardrailsMinimum tracks per category (e.g. the 15-track safety floor), fetch windows
LoudnessEBU R128 targets (see Smart Scheduler)

Rotation knobs (SCHEDULER_CONFIG.ROTATION)

These control the on-air rotation — the stable M3U buffer Liquidsoap watches (see Anti-repeat & M3U rotation):

KnobDefaultMeaning
BUFFER_MAX120Target length of the on-air rotation (capped at 160 on regen).
REFRESH_FRACTION0.85Rotation is rewritten once rotationConsumed / length >= 0.85. Lower = more frequent regens; higher = fewer (and thus more stable) writes.
MUSIC_FRESH_MS3 * 60 * 60 * 1000Freshness window for music tracks: a song stays out of a rebuilt rotation for 3 h after playing. Imaging uses ELEMENT_COOLDOWN (10 min) instead.
SIG_JINGLE_NAME'loklok1_mixdown.mp3'Station signature jingle (excluded from the random jingles pool; reserved slots only).
SIG_JINGLE_MIN_SLOTS / SIG_JINGLE_MAX_SLOTS2 / 5Random range (slots of imaging) for the next signature-jingle airing after each firing (mean ~3.5 ≈ every 30–45 min). SIG_JINGLE_EVERY_SLOTS (if set) forces a fixed cadence instead.
CROSS_OVERRIDE{sfx:0.2, shorts:0.2, jingles:0.5, sweepers:0.5, ads:0.5, news:0.5, talkshow:0.5, programs:0.5}Per-category liq_cross_duration seconds emitted as an M3U annotate tag so Liquidsoap pre-buffers less than 2s around short items. Music/mashups get no override.

Cadence slots

Beyond rotation sizing, updateM3U reserves guaranteed slots so branding elements recur predictably:

CadenceMeaning
AD_EVERY (~8th slot)Guaranteed ad airing
NEWS_EVERY (~20–24th slot ≈ hourly)Guaranteed top-of-hour news bulletin airing (all dayparts)
MASHUP_EVERY (~8th slot)Guaranteed mashup airing (skipped in deep night)
Signature jingleRandomized 2–5 imaging-slot gap (SIG_JINGLE_MIN/MAX_SLOTS)

Tuning notes

  • Raising a category's base weight makes it appear more often; the Dirichlet sampler will still wobble around it rather than lock it in.
  • Reducing the cooldown increases variety but risks repeats on short rotations; the 90-minute default is a good balance for a 24/7 station. The rotation's 3 h MUSIC_FRESH_MS is deliberately longer than the queue cooldown because a rotation is a big file that listeners hear over a long stretch.
  • Energy delta limits are the main defense against jarring mixes. If you want smoother segues, tighten the maximum allowed step between consecutive tracks.
  • Raising REFRESH_FRACTION makes the rotation more stable (fewer reloads = fewer chances to rewind the stream), at the cost of fresher content appearing less often. Lowering it does the opposite.

Relationship to other modules

The parameters file is imported by smart-scheduler.js and overridden in parts by the reinforcement-learning arms (which adapt category weights at runtime). It is also referenced by the experimental scheduler variants under Legacy & experimental variants.