No description
  • C 48.3%
  • C++ 46.1%
  • Python 1.8%
  • Makefile 1.4%
  • HTML 0.9%
  • Other 1.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-09-30 12:36:13 +00:00
apis Rename package from rivolution to lindon; revert internal paths 2026-09-09 13:47:35 +00:00
cae Fix QSignalMapper::mapped(int) breaking ripcd's client-connection routing 2026-06-24 12:13:36 -07:00
conf Rename package from rivolution to lindon; revert internal paths 2026-09-09 13:47:35 +00:00
debian Bump to 6.0.0~rc1-7 2026-09-30 09:15:29 +00:00
docs Rename package from rivolution to lindon; revert internal paths 2026-09-09 13:47:35 +00:00
helpers 2023-01-18 Fred Gleason <fredg@paravelsystems.com> 2023-01-18 11:39:38 -05:00
icons Rename package from rivolution to lindon; revert internal paths 2026-09-09 13:47:35 +00:00
importers Fix stale QMYSQL3 driver name; add fork copyright line; document install gaps 2026-06-23 23:27:27 -07:00
ios 2016-05-24 Fred Gleason <fredg@paravelsystems.com> 2016-05-24 13:13:26 -04:00
lib Add number-key (1-8) play/stop toggle for CartSlots 2026-09-30 08:00:34 +00:00
LICENSES 2021-12-15 Fred Gleason <fredg@paravelsystems.com> 2021-12-15 12:17:10 -05:00
rdadmin Add number-key (1-8) play/stop toggle for CartSlots 2026-09-30 08:00:34 +00:00
rdairplay Rename package from rivolution to lindon; revert internal paths 2026-09-09 13:47:35 +00:00
rdalsa Qt6 migration: C++17 bump, build-flag shell-escaping fix, CHANGELOG 2026-06-22 10:57:44 -07:00
rdcartslots Add number-key (1-8) play/stop toggle for CartSlots 2026-09-30 08:00:34 +00:00
rdcastmanager Rename package from rivolution to lindon; revert internal paths 2026-09-09 13:47:35 +00:00
rdcatch Add per-station LUFS loudness normalization option for audio import 2026-09-29 08:29:15 +00:00
rdcatchd Fix QSignalMapper::mapped(int) breaking ripcd's client-connection routing 2026-06-24 12:13:36 -07:00
rdhpi Rename package from rivolution to lindon; revert internal paths 2026-09-09 13:47:35 +00:00
rdlibrary Add per-station LUFS loudness normalization option for audio import 2026-09-29 08:29:15 +00:00
rdlogedit Rename package from rivolution to lindon; revert internal paths 2026-09-09 13:47:35 +00:00
rdlogin Rename package from rivolution to lindon; revert internal paths 2026-09-09 13:47:35 +00:00
rdlogmanager Rename package from rivolution to lindon; revert internal paths 2026-09-09 13:47:35 +00:00
rdmonitor Rename package from rivolution to lindon; revert internal paths 2026-09-09 13:47:35 +00:00
rdpadd Fix QSignalMapper::mapped(int) breaking ripcd's client-connection routing 2026-06-24 12:13:36 -07:00
rdpadengined Qt6 migration: C++17 bump, build-flag shell-escaping fix, CHANGELOG 2026-06-22 10:57:44 -07:00
rdpanel Rename package from rivolution to lindon; revert internal paths 2026-09-09 13:47:35 +00:00
rdrepld Qt6 migration: C++17 bump, build-flag shell-escaping fix, CHANGELOG 2026-06-22 10:57:44 -07:00
rdrssd Qt6 migration: C++17 bump, build-flag shell-escaping fix, CHANGELOG 2026-06-22 10:57:44 -07:00
rdselect Rename package from rivolution to lindon; revert internal paths 2026-09-09 13:47:35 +00:00
rdservice pipewire phase 1: system-scope PipeWire, rdservice root check removed 2026-07-01 11:33:00 -07:00
rdvairplayd Fix QSignalMapper::mapped(int) breaking ripcd's client-connection routing 2026-06-24 12:13:36 -07:00
ripcd Fix three more Qt6 signal renames that silently fail to connect, plus add errno diagnostic for the createWave() failure 2026-06-26 07:16:43 -07:00
scripts Add scripts/forgejo-release.sh, replacing gh release create as we move off GitHub 2026-09-30 12:36:13 +00:00
systemd 2025-01-24 Fred Gleason <fredg@paravelsystems.com> 2025-01-24 18:13:53 -05:00
tests Qt6 migration: C++17 bump, build-flag shell-escaping fix, CHANGELOG 2026-06-22 10:57:44 -07:00
tools Add tools/ folder for station Python tooling 2026-09-23 08:58:12 +00:00
utils Add number-key (1-8) play/stop toggle for CartSlots 2026-09-30 08:00:34 +00:00
versions Bump version to 6.0.0~rc1-1 2026-07-10 14:59:59 -07:00
web Rename package from rivolution to lindon; revert internal paths 2026-09-09 13:47:35 +00:00
xdg Rename package from rivolution to lindon; revert internal paths 2026-09-09 13:47:35 +00:00
.gitignore Rename package from rivolution to lindon; revert internal paths 2026-09-09 13:47:35 +00:00
acinclude.m4 2022-01-04 Fred Gleason <fredg@paravelsystems.com> 2022-01-04 18:18:57 -05:00
AUTHORS 2023-07-07 Fred Gleason <fredg@paravelsystems.com> 2023-07-07 13:28:52 -04:00
autogen.sh 2024-01-12 Fred Gleason <fredg@paravelsystems.com> 2024-01-12 15:53:06 -05:00
BACKLOG.md BACKLOG: root-cause the degenerate-segue-transition coercion bypass 2026-07-26 16:30:25 -07:00
build_debs.sh.in 2021-07-31 Fred Gleason <fredg@paravelsystems.com> 2021-07-31 13:26:54 -04:00
ChangeLog Work around intermittent FOP/JIT crash; fix autoreconf ChangeLog check 2026-06-27 21:42:06 -07:00
CHANGELOG.md build-deb.yml: build only the noble x64 leg, acid-mart covers 26.04 2026-07-26 22:13:29 -07:00
ChangeLog.upstream-v4 Add selectable MP3 import format and passthrough mode 2026-06-17 13:45:53 -07:00
CODINGSTYLE 2025-04-24 Fred Gleason <fredg@paravelsystems.com> 2025-04-24 16:29:39 -04:00
configure.ac rdadmin: show full package version (incl. Debian revision) in System Info 2026-07-21 16:44:54 -07:00
configure_build.sh Auto-detect the DocBook stylesheet path from the filesystem, not a distro-name guess 2026-06-26 16:48:42 -07:00
get_distro.pl 2021-05-19 Fred Gleason <fredg@paravelsystems.com> 2021-05-20 08:02:24 -04:00
get_target.sh 2016-05-24 Fred Gleason <fredg@paravelsystems.com> 2016-05-24 13:13:26 -04:00
INSTALL-WINDOWS 2018-09-06 Fred Gleason <fredg@paravelsystems.com> 2018-09-06 16:17:58 -04:00
INSTALL.md Fix VLC's documented purpose across INSTALL.md, ROADMAP.md, spec 0010 2026-07-22 21:47:01 -07:00
KNOWN_ISSUES.md Remove three stale KNOWN_ISSUES entries no real install path still hits 2026-07-22 11:34:25 -07:00
lindon-install.sh Add fixed-48kHz option to ConfigureSampleRate 2026-09-23 08:58:12 +00:00
Makefile.am 2025-09-17 Fred Gleason <fredg@paravelsystems.com> 2025-09-17 17:17:09 -04:00
NEWS 2026-02-13 Fred Gleason <fredg@paravelsystems.com> 2026-02-13 14:56:26 -05:00
README 2023-06-07 Fred Gleason <fredg@paravelsystems.com> 2023-06-07 11:45:44 -04:00
README.md Document number-key CartSlot playback and file-import LUFS fix in README 2026-09-30 08:12:45 +00:00
rivendell.ism 2018-05-08 Fred Gleason <fredg@paravelsystems.com> 2018-05-08 18:16:22 +00:00
rivendell.pro 2021-07-28 Fred Gleason <fredg@paravelsystems.com> 2021-07-28 19:54:17 -04:00
rivendell.spec.in 2025-10-13 Fred Gleason <fredg@paravelsystems.com> 2025-10-13 11:05:12 -04:00
ROADMAP.md Fix VLC's documented purpose across INSTALL.md, ROADMAP.md, spec 0010 2026-07-22 21:47:01 -07:00
UPGRADING 2023-06-07 Fred Gleason <fredg@paravelsystems.com> 2023-06-07 11:45:44 -04:00

lindon

A private, trimmed fork of Rivolution (itself a Qt6 fork of Rivendell), maintained for use at some local radio stations, both fm and dab+ transmitted.

Not a public project — kept private intentionally. This README exists for our own future reference as much as anything else.

What this is

Rivolution's Qt6 migration is the part worth having: vanilla Rivendell v4 still depends on Qt5 components (notably QtWebKit) that have aged out of current distributions, making it awkward to package on a current Ubuntu. Rivolution solves that.

What we didn't want was everything Rivolution built on top of that migration — a web dashboard, a self-healing PipeWire patchbay, Icecast/Stereo Tool/Tailscale baked into the packaged stack, and (the one that actually broke things) a segue back-timing feature that doesn't compose correctly with voice tracking. lindon is Rivolution with those parts removed or reverted, plus a couple of packaging bugs fixed that we ran into ourselves.

How this differs from upstream Rivolution

  • rivapi (the Go dashboard) removed entirely — never built by the autotools chain to begin with; its systemd/sudoers hooks are stripped from postinst/rules.src too. No web UI, no dashboard auth, no associated sudo grant for the service account.

  • PipeWire is user-scope, not system-scope — this deployment always runs with desktop autologin (rdairplay in the desktop autostart), so a separate system-scope PipeWire instance (and its linger/tmpfiles workarounds) is unnecessary complexity. rivendell.service binds to user@<uid>.service instead.

  • icecast2 and stereo-tool.service dropped from the packaged stack — neither is installed or managed by lindon. Stereo Tool runs locally and gets patched into PipeWire by hand.

  • tailscaled removed from rivolution-stack.target.

  • Segue back-timing (upstream spec docs/specs/0002-segue- backtiming.md) fully reverted, including its follow-on "second bug" fix. Upstream's own spec explicitly reasoned that voice tracking wouldn't interact with this feature — that reasoning turned out to be wrong on two separate counts:

    • Voice-tracked transitions save SEGUE_GAIN=0 as their normal, incidental value (full volume, no duck) — the exact same field this feature gates on — so every voice-tracked segue triggered it regardless of operator intent, playing out to the element's natural end with no audible transition instead of blending.
    • The follow-on fix for a related regression (Finished()/ FinishEvent() skipping the next element's start whenever anything else was still running, assuming it would be re-triggered later) silently stalled the log whenever the next line was a marker or an empty voice-track slot with no audio of its own to generate that re-trigger — the log would just sit there indefinitely, indistinguishable from a Stop.

    Both reverted; confirmed via diff that the affected functions are now byte-identical to vanilla Rivendell 4.5.0. Reported upstream weeks ago, no response as of this writing.

  • libmad0 / libtwolame0 added to Depends: — both are loaded via dlopen() at runtime rather than linked, so their absence doesn't show up via ldd and wasn't caught by upstream's own packaging; without them, MP3/MPEG import silently fails.

  • Renamed from rivolution to lindon at the package level (Conflicts:/Replaces: against every old rivolution-* package for a clean apt upgrade). Internal paths went the other way — /usr/share/rivolution/, our own systemd units (rivolution-stack.target, rivolution.conf) — reverted back to plain rivendell naming, since there's no benefit to a third naming scheme once the package itself already says lindon, and it keeps the diff surface smaller if anything here is ever worth pulling back upstream. Two things this surfaced, worth knowing if you're doing the same kind of rename elsewhere:

    • postinst's fresh-install-vs-upgrade branch keyed only on $OLD_VERSION (set by dpkg for a same-name package upgrade). dpkg leaves that empty for a Replaces:-triggered rename, even with a fully working install already in place — the very first rivolution→lindon install would otherwise have hit the fresh-install branch and dropped the production database (drop database if exists ...). Now also checks for a pre-existing /etc/rivendell.d/rd-default.conf before deciding.
    • A PYPAD_INSTANCES.SCRIPT_PATH value written before the rename doesn't update itself — it's just a string frozen in the database at creation time, unaffected by anything the newly installed package changes. Existing PyPAD instances need their script path corrected by hand after an upgrade; new ones created afterward pick up the right path automatically (RDAdmin's file picker defaults into RD_PYPAD_SCRIPT_DIR, compiled from the current package).
    • rivolution.conf under rivendell.service.d/ isn't a dpkg-tracked conffile (just cp'd in by postinst, same as rivendell.conf that replaces it) — dpkg has no reason to remove it on upgrade, so it's left sitting alongside the new rivendell.conf unless removed by hand.
  • New: "Make Next & Wait max" grace-time mode, a fourth option alongside vanilla's Start Immediately / Make Next / Wait up to (rdairplay, rdlogedit, and rdlogmanager's clock/event editor). Reserves the "next" slot immediately like Make Next (so the log doesn't fall through to whatever else happens to be next in a busy/segue-chained clock — e.g. a news slot skipping straight to the wrong interstitial instead of joining the current segue chain), but still enforces a bounded timeout like Wait up to, so an overrunning predecessor can't push a hard-timed element (news, legally-timed IDs) past its deadline. Encoded as GRACE_TIME <= -2 (timeout_ms = -GRACE_TIME - 2); no database schema change. Three bugs found so far, all worth remembering:

    • RDLogPlay::transTimerData(): makeNext() calls SetTransTimer() internally, which can silently reassign the member play_trans_line to whatever the next upcoming hard-time line is. Reading that member again afterward (instead of the function's own pre-captured local trans_line, which exists for exactly this reason and is already used elsewhere in the function) armed the grace timer for the wrong log line — the symptom was a hard-timed element several lines away getting force-started instead of the one actually configured, skipping everything in between.
    • Two separate, unrelated display bugs made a correctly-saved value look wrong without actually being wrong: EventWidget::load() (rdlogmanager) lost the grace= event_event->graceTime() assignment when its switch was restructured to add the new branch, so re-opening any Hard-Time event always showed "Start Immediately" regardless of what was saved. RDEventLine::propertiesText() didn't know about the new GRACE_TIME <= -2 range and ran it through the old Wait up to formatting path, where QTime::addMSecs() wraps a sufficiently negative value around a 24-hour clock — a 2:00 timeout rendered as a nonsensical "57:59" in the RDLogManager event list.
    • A race between RDLogPlay::Stopped() and graceTimerData(): when the grace line was started by a normal segue from its predecessor, the predecessor's Stopped() could arrive before the grace line's own Playing() had stopped the grace timer (short segue, cued load latency). The timer then woke and called StartEvent() for the already-running line a second time, stopping both decks and stalling the log until the next hard time (observed: 4:18 dead air in production). Stopped() now cancels the timer if the grace line is no longer Scheduled/Paused, and graceTimerData() ignores such a line.
  • New: per-station LUFS-based loudness normalization, alongside the existing peak-based normalization (RDAdmin Host dialog switch). Ports the approach already used in the external M3U-import tooling (StereoTool) into core Rivendell itself, so stations not using that M3U-import workflow also benefit. Touches rdaudioconvert and every import path: dropbox/feed/replicator, RDCatch (download/recording/ upload), CD ripper, and the rdimport CLI. New STATIONS.LOUDNESS_NORMALIZATION column (schema 379 -> 380).

    • Fixed RDCartDialog::loadFileData() (the "Load from File" quick-import in RDCartSlots) using a hardcoded dBFS-appropriate value (-11) that became far too loud once reinterpreted as a LUFS target on stations with LUFS normalization enabled; now picks -23 (LUFS) or -11 (dBFS) based on the station's setting.
  • New: number-key playback toggle for RDCartSlots (RDAdmin Edit CartSlots dialog switch, per station). Digit keys 1-8 toggle play/stop on the corresponding slot, independent of which widget has focus, as long as the RDCartSlots window itself is the active window. Slots in Breakaway mode ignore the key. A green border is drawn around the window while it's focused and the feature is enabled, so it's visible when the shortcut is live. New STATIONS.CARTSLOT_KEY_PLAYBACK column (schema 380 -> 381).

  • lindon-install.sh — a setup wrapper (not part of upstream) that creates the rd operator account, configures desktop autologin (preferring X11 over Wayland), installs the built .debs, walks through NFS export/mount plus database pointer setup for standalone/server/client roles, and lets you pick the audio sample rate (44.1kHz fixed, 48kHz fixed, or auto-detect) via ConfigureSampleRate.

Installation

Grab the .deb files and lindon-install.sh from this repo's Releases page, put them in the same directory, then:

sudo ./lindon-install.sh

The operator account is always named rd — see the comments in lindon-install.sh for why, and what to do if you need something else.

Upgrading an existing rivolution install

Don't run lindon-install.sh for this — it's a first-run wrapper (account creation, autologin setup, NFS export/mount, database pointer setup) that a working install has already been through. Install the packages directly instead:

sudo apt install lindon_*.deb lindon-*.deb

Conflicts:/Replaces: handles removing the old rivolution-* packages as part of the same transaction — review apt's summary before confirming, it should show the matching set of rivolution-* packages being removed. Back up the database first regardless (mysqldump --all-databases > backup.sql) — see the PYPAD_INSTANCES and rivolution.conf notes above for what still needs manual cleanup after an upgrade.

Remotes / staying current

This repo tracks anjeleno/rivolution as its upstream remote:

git remote add upstream https://github.com/anjeleno/rivolution.git
git fetch upstream
git log --oneline main..upstream/main

Pulling upstream changes in isn't automatic or guaranteed to be conflict-free — Rivolution's own Qt6 migration touched a large fraction of the codebase, so a given upstream fix may or may not apply cleanly depending on whether it lands in code that migration also touched.

Not our own bug reports

Where a problem traces back to vanilla Rivendell itself rather than anything Rivolution- or lindon-specific, that's tracked separately — this repo's commit history is specifically about the delta from Rivolution, not a general Rivendell bug tracker.