Skip to content

v1.6.4: cover-art identification + messy-name recovery - #16

Merged
DynamycSound merged 1 commit into
masterfrom
claude/song-matching-improvements-7tp3qn
Jul 20, 2026
Merged

v1.6.4: cover-art identification + messy-name recovery#16
DynamycSound merged 1 commit into
masterfrom
claude/song-matching-improvements-7tp3qn

Conversation

@DynamycSound

Copy link
Copy Markdown
Owner

Cover-art identification (new)

A file with no usable artist anywhere ("Bounce", artist Unknown) is textually indistinguishable from every other same-titled song — that's how it saved Russian lyrics from an unrelated "BOUNCE". Its embedded cover art, however, is distinguishable, and the user confirmed the file's thumbnail matches the real song's cover.

CoverIdentity.discover() searches iTunes/Deezer widely (up to 25 rows per service via the new LastResortAPI.identityCandidates(), vs. top-3 in the canonicalizer — "Bounce" by Voyage sits at ~#18) with the bare title, hashes each result's album art (existing aHash from CoverArtCompare), and treats a perceptual match + compatible runtime (±15s) as the file's identity. The discovered identity is injected as:

  • the leading query candidate (new MatchStrategy.COVER_IDENTITY) — the search runs "Voyage Bounce" instead of a blind "Bounce" (LRCLib has it, synced, verified live), and
  • an artist guess the wrong-singer veto can finally use.

Wired into both batch (LyricsUtils) and single-song (LyricsFetchViewModel). Bounded: ≤2 queries, ≤12 cover downloads per song, only runs when there are no artist guesses (or on demand, below).

Cover second opinion for runtime coincidences

"CHECK" by WAV3POP got Portuguese lyrics from a same-duration "Check" by The Boy — it survived v1.6.3's veto through the exact-runtime escape. In batch, a hit whose artist agrees with none of the artist guesses now triggers cover identification before being trusted: if the file's art identifies a different artist, the hit is skipped. No art / no identification keeps existing behaviour (the escape is load-bearing for junk-artist rips). Verified live: Deezer has "CHECK" by WAV3POP (140s, with art); LRCLib has no WAV3POP entry → honest no-lyrics instead of an impostor.

Messy-name recovery (each verified against the live catalogues)

Version

1.6.3 (163)1.6.4 (164), release notes rewritten.

Testing

  • 5 new tests in MessyNameRecoveryTest (all four reported name shapes + the no-guess/no-veto invariant) — pass.
  • WrongSingerVetoTest (8) and BadMetadataMatchTest (7) — pass, no precision/recall regressions.
  • Full matching suite green except the pre-existing live-network SuicideboysMatchTest.loot (LRCLib data drift, fails on unmodified master).
  • :app:compileDebugKotlin clean.
  • Live API probes for every claim above (LRCLib/Deezer/iTunes) run during development.

🤖 Generated with Claude Code

https://claude.ai/code/session_01QADiJzVyNycc1w28sirc1a


Generated by Claude Code

- CoverIdentity: for files with no usable artist anywhere, search iTunes/
  Deezer widely with the bare title and match each result's album art
  against the file's embedded cover (aHash); a visual match plus a
  compatible runtime becomes the file's identity, injected as the leading
  query candidate and as an artist guess for the wrong-singer veto.
  Fixes 'Bounce' (Unknown) saving lyrics of an unrelated Bounce.
- Hits that agree with no artist guess (survived only on the exact-runtime
  escape) now get a cover second opinion before batch trusts them; a
  different identified artist skips the impostor ('CHECK' by WAV3POP
  getting a same-length 'Check' by The Boy).
- FilenameParser: strip ?-runs/U+FFFD from queries (DEVITO - FLEX ????);
  bare-title fallback for unknown bracket junk incl. unterminated trailing
  clauses (CC #2 (JUŽNI VETAR 2022)); every collab part as candidate+guess
  (GRCA X FOX); channel-suffix-stripped tag artist (WAV3POP - Topic).
- LastResortAPI: identityCandidates() wide search with durations + art.
- Version 1.6.4 (164), release notes; 5 new regression tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QADiJzVyNycc1w28sirc1a
@DynamycSound
DynamycSound merged commit c9130ca into master Jul 20, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant