Merge pull request #608 from lokal-music/release/v12.2.0
Changelog
Windows builds: free code signing provided by SignPath.io, certificate by SignPath Foundation (code signing policy).
FYI:
Lokal is 100% local; the library, history, anything in database, or any info that is used for API's such as yt-dlp, LRCLIB, is NOT seen by us.
What's Changed
-
feat(desktop): add Monochrome native FLAC search and playback (#606)
Details
Summary
- Register Monochrome (
mono) as a built-in provider alongside YouTube Music / SoundCloud, not an HTTP add-on, in both Electron IPC and local web API source lists. - Add native Monochrome
electron/online/monochrome.js: usehttps://tracks.monochrome.st/search/tracks, normalize metadata, validate IDs, and resolve a direct FLAC stream at/track/{id}. No add-on credentials, proxy endpoints, or YouTube session cookies are reused. - Wire search and streaming through Lokal's existing provider dispatcher and progressive
lokal-stream://path, including Range playback. - Preserve unique ghost-track identities for queued, liked and playlisted songs. Add source-aware download URLs, origin tracking, backfill, library downloads, source attribution, playback priority, and source-selection icon.
- Do not claim a specific bit depth or sample rate until the delivered media is measured.
Tests
scripts/monochrome-source.test.mjs: API shape, normalization, HTTPS/track-ID boundaries, ghost mapping, stream resolution, error behavior.- Updated
scripts/find-on-sources.test.mjsexpectations for the third built-in provider.
Reference / caveats
- Upstream API: Monochrome Tracks (Apache-2.0).
- Reviewed LunarTune's implementation (GPL-3.0; not copied).
- The remote service may have availability/rate-limit constraints. Actual content licensing must be handled separately.
- Node tests, full build and end-to-end streaming have not yet been executed; review CI before merging.
Summary by CodeRabbit
- New Features
- Added Monochrome as a built-in source for finding and playing tracks, alongside existing music providers.
- Monochrome tracks are labeled and recognizable in source icons, playback, and library downloads.
- Search results include track details and artwork when available, and supported tracks play in FLAC format.
- Invalid track links and IDs are rejected; searches handle cancellation and timeouts.
- Register Monochrome (
-
fix(desktop): keep hi-res downloads stereo and add explicit verified Atmos downloads (#607)
Details
Fix the reported quality mix-up
The desktop download manager previously used the add-on's saved
downloadQualitydirectly. If it wasDOLBY_ATMOS, an ordinary hi-res/lossless download incorrectly requested Atmos. The screenshot's repeated/dl/tidHTTP 502 errors came from that wrong requested tier.- Normal downloads now choose stereo/hi-res audio (prefer HI_RES_LOSSLESS, otherwise a supported lossless tier) even when an older setting was Atmos.
- The Settings > Addons quality selector shows Download quality (stereo); Atmos is not offered as a global default.
- No silent downgrade of an explicit Atmos request.
Explicit Atmos downloads
- Adds Download Dolby Atmos on eligible Mornye tracks in track right-click menus, online-result context menus, player menu and right-click download-icon menus.
- The action is displayed only when the catalogue advertises Atmos and the source is a Mornye-style add-on, and requests
DOLBY_ATMOSexplicitly. - Queues directly against the pinned add-on ID without first requesting a stereo stream. Regular/Atmos jobs do not deduplicate into each other. Explicit Atmos downloads are permitted even when a stereo library copy exists.
- Both the renderer request and backend service require explicit Atmos intent, and the add-on must publish that tier.
- After download, FFprobe must confirm E-AC-3 JOC from the actual audio. A stream-copy remux produces an
.atmos.m4afile with source title/artist/album metadata; an invalid/missing JOC profile fails rather than saving a mislabeled file. - The generic download postprocessor must not transcode E-AC-3 JOC to AAC or rewrite its MP4 atoms. Normal stereo streams and normal postprocessing remain unchanged.
Tests
Extended
scripts/atmos-stereo-handoff.test.mjsfor normal quality selection, explicit Atmos intent and no fallback. Addedscripts/atmos-downloads.test.mjsfor menu-action eligibility, correct provider identity and explicit download intent.Verification and known limitation
Code and tests are committed; test execution, CI and a real Tidal Atmos download were not available in this environment. HTTP 502 responses from the remote Tidal add-on endpoint cannot be repaired locally; true Atmos downloads still report service failure when the upstream is unavailable. This PR fixes incorrect requests and prevents invalid output, but does not claim to restore the remote endpoint.
Summary by CodeRabbit
-
New Features
- Added Dolby Atmos downloads for supported tracks from online results, track lists, the player, and context menus.
- Atmos downloads are saved separately from standard stereo and hi-res downloads, with track information preserved.
- Add-on quality settings keep Atmos separate from the stereo/hi-res selector and direct users to track menus for Atmos downloads.
-
Bug Fixes
- Improved handling of Atmos requests so unsupported or mismatched sources are rejected and existing Atmos copies don’t incorrectly satisfy standard download requests.
- Atmos downloads are checked for a supported format before being saved.
-
Improve AutoMix transition safety and Flow musical continuity (#605)
Details
Implementation complete on branch (experimental model tier)
Desktop playback: Cached PCM analysis, automatic local-MP3 CUE-DETR preparation through an explicitly configured external engine folder, safe model cue sidecars, source-stamped invalidation, 32-beat planning, Flow continuity selection, and opt-in live prepared Demucs stem-window playback through a third Web Audio deck. Correct local-source resume, source/clip SHA verification, volume/EQ compatibility, early preparation, pause/seek/skip cancellation and two-deck fallback are implemented.
User workflow: In Settings → Playback, enable AutoMix. Optional Automatic Cue Preparation analyzes upcoming eligible MP3 pairs using a separately installed external engine; no model runs during playback. For stem-rendered audio, prepare the upstream Demucs cache separately and export it with
--clip-output auto, then enable Prepared Stem Mixes (Experimental). This remains off by default; model weights are not bundled and runtime automatic Demucs inference is deliberately excluded.Validation status: Code committed; previous focused JS tests passed, but latest playback integration still needs listening/latency/device testing. Leaving this PR draft. No CI/review work is being pursued in this implementation pass.
AutoMix: safer, cue-aware playback planning
- Prevent transition plans from running past the outgoing track's audible end.
- Reject incomplete beat grids rather than applying unintended time stretch to a shortened phrase.
- Cache heuristic, bar-aligned entrance and exit cue candidates from existing lightweight PCM analysis (analysis schema v2).
- Prefer 32-beat handoffs only when both tracks have credible cues and the entire overlap fits; otherwise preserve the established 16-beat/short smart fade.
- Prefer tempo (including half/double-time) and energy continuity when Flow selects among otherwise eligible tracks; never hard-reject discoveries for missing analysis.
- Add regression tests for cue boundaries, short fades, 32-beat plans, malformed/unconfident cues and Flow affinity.
Reference
Informed by https://github.com/VertexSelection/automix-engine — especially structural cue timing and conservative beat-aligned transitions. No code, models or stems from the reference are copied or bundled. The heuristic cues here are not CUE-DETR predictions or vocal detection. See upstream LGPL-2.1 and separate model/dependency licenses before directly integrating upstream components.
Validation / limitations
Tests committed but not independently executed in this session; GitHub check status has not been verified as green. Desktop source remains Web Audio + per-song PCM analysis. A full port of CUE-DETR, Demucs, vocal phrase protection and stem-aware transitions is not included; that requires optional off-playback-thread preprocessing, caching, licensing review and listening QA. Keep this PR draft until tests and streaming/Atmos regression checks pass.
Persistent desktop analysis cache reliability (latest)
Desktop already stores its PCM-derived AutoMix analyses in SQLite. The local cache key now includes the source file's actual length and last-modified timestamp (plus CUE offsets), instead of only the logical track ID. Editing or replacing a local file therefore invalidates stale beats/cues and triggers one re-analysis. A regression suite verifies cache-key reuse and invalidation (
scripts/automix-file-cache.test.mjs). Stream provider analysis continues using its existing stable key; no CUE-DETR/Demucs models are bundled.Optional CUE-DETR / Demucs preprocessing (new)
scripts/automix-import-cues.mjsexplicitly runs a separately installed referencecue_analysis.pyor imports its existing cue report; it validates the source MP3 SHA-256 and file stamp before publishing a portable, size-bounded per-file.lokal-automix.jsonsidecar.electron/automix/advanced-report.jsvalidates the offline detector identity, cue bounds, duration and source revision. Desktop's IPC merges model cues with its cached FFmpeg/SQLite analysis without decoding again just because an optional sidecar changes.- The desktop transition planner now uses both role-specific CUE-DETR overlap starts for a safe 32-beat handoff, with existing beatmatch/smart/crossfade as fallback. The in-app planning cache refreshes when model cues change.
- Explicit
--prepare-stemsinvokes upstreamstem_transition.py --prepare-onlyafter verifying the upstream engine's fixedsong1.mp3/song2.mp3have identical SHA-256 bytes to the selected songs. Stem windows stay in the external engine cache; they are NOT rendered by Lokal yet. - Added model import, fingerprint, role-merge, 32-beat timing, and mismatched-stem-input tests. Usage and limitations in
docs/AUTOMIX_MODEL_PREPARATION.md.
This is offline, opt-in preparation; no Python runtime, CUE-DETR weights, or Demucs models are bundled or invoked during ordinary playback. Actual stem-aware audio rendering remains outstanding.
CI validation note
The Windows Atmos workflow initially failed because its tests loaded
electron/mornye/network.jsbefore installing the existingtough-cookiedependency. This PR now movesnpm ci --ignore-scriptsahead of those tests in.github/workflows/atmos-headphones.yml. The rerun must finish green before merge; no AutoMix or Android device playback validation is claimed.Latest validation and offline stem export
- Dedicated
AutoMix and Flow analysis regressionsGitHub Actions suite: passed on the latest checked head. - Windows Atmos bridge workflow: passed on the latest checked head, after correcting Node dependency installation order and an outdated Monochrome-default test expectation.
scripts/automix-export-stems.mjscan now ask an externally prepared Demucs engine to render its actual stem-aware mix offline and export a validated stereo WAV. Includes content-hash verification, WAV validation, atomic output copy, overwrite protection and regression tests. This output can be auditioned as a standard Lokal local audio file; there is no live player insertion or in-app stem mixing yet.- Adds a dedicated PR-scoped AutoMix/Flow CI workflow for subsequent commits.
Summary by CodeRabbit
- New Features
- AutoMix can use prepared transition cues to plan longer, phrase-aligned handoffs, with shorter transitions as a fallback.
- Optional offline tools support importing track cues, preparing stems, and exporting WAV mixes.
- Flow recommendations now account for tempo and energy continuity between tracks.
- Improvements
- AutoMix better handles short tracks and limits transitions to usable audio.
- Cached transition plans update when prepared cue data changes.
Experimental live stem transition (latest)
- Implements a real third-deck local playback path for pre-rendered Demucs transitions, behind Settings → Playback → Prepared Stem Mixes (Experimental) (default Off).
- The offline stem exporter supports
--clip-output autoto extract just the mixed transition window plus a manifest mapping the exact outgoing start to the incoming source resume timestamp. - A bounded
automix:stemClipIPC endpoint verifies the original song SHA-256 hashes, clip SHA-256, WAV header, clip duration and pair identity. The player prefetches eligible pair clips about a minute before the planned handoff. - The optional third media element routes through the existing Web Audio analyser, crossfades in/out, follows pause/play, aborts on seek/skip or source failure and restores the real next song at its manifest resume timestamp. A pause-aware progress watchdog prevents indefinite mixing locks.
- Streaming, native Atmos, encoded Atmos, other output routes, unsupported playback speeds, absent clips and mismatched model plans retain the existing two-deck AutoMix path.
- The library scanner and watcher ignore internally generated stem WAVs, so preparing pairs does not add fake songs to the user's library.
- New regression tests cover fingerprint matching and playback eligibility, fake third-deck lifecycle, pause/resume, seek cancellation and cache file exclusions.
Validation: Node regression/Windows build checks on the latest prior commits passed, but full playback listening/latency/device QA is required for this new opt-in live path. Leave PR draft. Do not imply this is runtime Demucs inference: all stem separation is done offline by a separately installed engine.
Contributors: @CHEYCKIT
Full Changelog: v12.1.0...v12.2.0
Setup
See README.md for full setup instructions.
macOS: this build is ad-hoc signed, not notarized (no Developer ID certificate is configured). The first time, right-click Lokal in Applications and choose Open, or run xattr -dr com.apple.quarantine /Applications/Lokal.app.
Binary Checksums (SHA-256)
Lokal-12.2.0-arm64-mac.zip:
[5116EC90A1028BBE09E2B36E8C2CF027E35D517BD14BADDF5669541BDD896E0B]
Lokal-12.2.0-arm64-mac.zip.blockmap:[D2783C8A09810D5004B99FCF9DE8F669492E7FCE3B56E81DDBEF1E18B4194259]
Lokal-12.2.0-arm64.AppImage:[FB15CF6896FC9CA92412A3A1046FE5D6A9BA9DB2D0E1C04970DFCD40BE6C8D8F]
Lokal-12.2.0-arm64.dmg:[F60F4F445089506FD59C029D61C98DB4A97C80D4692CE1E432CD72FE74D5B888]
Lokal-12.2.0-arm64.dmg.blockmap:[DBA0FE5CC5F957D906042A9075D48BB257B0C142064C936C1C9330F60B5FCC53]
Lokal-12.2.0-mac.zip:[7F51DC0803D94FC5FD91C3838BA2F9935CDC20BD8A2507DB319673A4F04E6A0F]
Lokal-12.2.0-mac.zip.blockmap:[7AD5EDD5363AD95CBAA9387693F0683EAEED75EB26180DA9F0EDBF5A3D60126C]
Lokal-12.2.0.AppImage:[91DECA861C5569E7D51AB7476C26583E085573E3E9BB7CEF42EC8F3A365AD8A0]
Lokal-12.2.0.dmg:[3E3A5C77983872676133C056B396E0A587BB7CEE80B0A6360BDD7932592585D4]
Lokal-12.2.0.dmg.blockmap:[A8E0F4726E2E74CC81AEBCE182793DC85E8908ACEC9111D102A8BE46DEDB7B0B]
Lokal-12.2.0.exe:[902D814B5D7185B4616465B49DF7B59464710784E73DE192A6F89CDF840DE15F]
Lokal-Setup-12.2.0.exe:[5FCD75351A6CFC9BFAFE705F43F2E532339AFDCD9DF79FE19AD2830CA486C758]
Lokal-Setup-12.2.0.exe.blockmap:[1D8059DFD482FB68BA575EE33BA1B7B05273D079E62797C147268FD6B34AD7F1]
builder-debug.yml:[7249B1EEB711B237CB322A70DF13B313A1CA8982C89B91268D366A1F258CF7B4]
latest-linux-arm64.yml:[D3B956765DB827E7F4B5346125273798044E3DCDDF5000CFB752192B4EB0ED5F]
latest-linux.yml:[B06D98C7F88D70A9E93B5BE1A322044098ECD28308D2E4B3EBD1E5B7CBB40AEE]
latest-mac.yml:[41BBB79DEBCED4B2CDD6F42A9DB0E19FF67A8A9F3A137FA3AC4BD43CDECF8466]
latest.yml:[D8612B6751557F473E0B9389A7196050FB14EC64490C84EE85BEF89907ABD7CE]
lokal-music_12.2.0_amd64.deb:[DB52F17846FAE86B3CDFD558EF71AE8F651C3182B1D39B9595D5725EB36CF236]
lokal-music_12.2.0_arm64.deb:[54B2846184DE2911F9197E00D57AF962E84DACC0826B7302798CC248EDF99EF6]
