beets icon indicating copy to clipboard operation
beets copied to clipboard

Tracks detected in wrong order

Open lapo-luchini opened this issue 2 months ago • 5 comments

Problem

Running this command in verbose (-vv) mode:

Success. Distance: 0.73
Evaluating 5 candidates.

/home/lapo/Music/Library/Low Roar/Once In a Long, Long While (12 items)
Sending event: import_task_before_choice
Sending event: before_choose_candidate

Finding tags for album" - ".
  Candidates:
  1. (30.5%) Various Artists - Strange Games and Things
             ≠ tracks, album, source
             MusicBrainz, CD, 1997, GB, BBE, BBE CD 005, None
  2. (29.0%) Various Artists - Dance Fever: Hits of the 70’s
             ≠ tracks, album, source
             MusicBrainz, CD, None, US, Rebound Records, 314-520-265-2, None
  3. (27.0%) Various Artists - Goin’ Home: A Tribute to Duke Ellington
             ≠ tracks, album, source
             MusicBrainz, CD, 2001, US, None, None, None
  4. (24.0%) Various Artists - Alternator
             ≠ tracks, missing tracks, album, ...
             MusicBrainz, 2xCD, 1996, GB, Synchro Digital Recordings, SYNCHRO 007 CD, None
  5. (23.8%) Various Artists - Almighty: The Definitive Collection 6
             ≠ tracks, missing tracks, album, ...
             MusicBrainz, 2xCD, 2009, GB, Almighty Records, ALMYCD66, None
➜ # selection (default 1), Skip, Use as-is, as Tracks, Group albums,
Enter search, enter Id, aBort? i
Enter release ID: bc506aa8-12cf-47b3-9553-f35c65e6dcac
Tagging  -
Searching for album ID: bc506aa8-12cf-47b3-9553-f35c65e6dcac
musicbrainz: Requesting MusicBrainz release bc506aa8-12cf-47b3-9553-f35c65e6dcac
Sending event: mb_track_extract
Sending event: mb_track_extract
Sending event: mb_track_extract
Sending event: mb_track_extract
Sending event: mb_track_extract
Sending event: mb_track_extract
Sending event: mb_track_extract
Sending event: mb_track_extract
Sending event: mb_track_extract
Sending event: mb_track_extract
Sending event: mb_track_extract
Sending event: mb_track_extract
Sending event: mb_album_extract
Sending event: albuminfo_received
Candidate: Low Roar - Once in a Long, Long While… (bc506aa8-12cf-47b3-9553-f35c65e6dcac)
Computing track assignment...
...done.
Success. Distance: 0.65
Evaluating 1 candidates.
Sending event: before_choose_candidate

  Match (35.3%):
  Low Roar - Once in a Long, Long While…
  ≠ tracks, album, artist, source
  MusicBrainz, Digital Media, 2017, AF, Tonequake Records, None, iTunes, Deezer, Spotify
  https://musicbrainz.org/release/bc506aa8-12cf-47b3-9553-f35c65e6dcac
  ≠ Artist:  -> Low Roar
     ≠ (#0) 01 Don't Be So Serious.wav (6:13) -> (#1) Don’t Be so Serious (6:13)
     ≠ (#0) 02 Bones.wav (2:49) -> (#2) Bones (2:49)
     ≠ (#0) 04 Give Me An Answer.wav (3:43) -> (#3) St. Eriksplan (3:41)
     ≠ (#0) 03 St. Eriksplan.wav (3:41) -> (#4) Give Me an Answer (3:43)
     ≠ (#0) 07 Gosia.wav (4:13) -> (#5) Waiting (10 Years) (4:04)
     ≠ (#0) 11 Miserably.wav (3:55) -> (#6) Without You (3:54)
     ≠ (#0) 09 Crawl Back.wav (4:08) -> (#7) Gosia (4:13)
     ≠ (#0) 12 13.wav (5:24) -> (#8) Once in a Long, Long While (5:16)
     ≠ (#0) 05 Waiting (10 Years).wav (4:04) -> (#9) Crawl Back (4:08)
     ≠ (#0) 10 Poznań.wav (2:03) -> (#10) Poznań (2:03)
     ≠ (#0) 06 Without You.wav (3:54) -> (#11) Miserably (3:55)
     ≠ (#0) 08 Once In A Long, Long While.wav (5:16) -> (#12) 13 (5:24)
➜ Apply, More candidates, Skip, Use as-is, as Tracks, Group albums,
Enter search, enter Id, aBort?

Led to this problem: tracks are detected in the wrong order, even if track length (and also filenames) could allow them to be matched correctly. E.g. track 3 and 4 have been switched around, and they have different lengths. Same goes for 7→5→9→7.

Here's a link to the music files that trigger the bug (if relevant):

Digital download as bought from official website.

How can I import the album? Is there a way to force track order?

Setup

  • OS: FreeBSD
  • Python version: 3.11.13
  • beets version: 2.4.0

My configuration (output of beet config) is:

% beet config
directory: /data/local/music
# --------------- Main ---------------

library: /data/local/music/beets.db

import:
    move: yes

match:
    strong_rec_thresh: 0.1
paths:
    default: $albumartist/$year $album%aunique{}/$track $title
    singleton: Non-Album/$artist/$title
    comp: Compilations/$year $album%aunique{}/$track $title
convert:
    format: flac
    no_concert: format:AAC

# --------------- Plugins ---------------

plugins: musicbrainz fetchart lyrics lastgenre
disabled_plugins: []
musicbrainz:
    search_limit: 5
    source_weight: 0.5
    host: musicbrainz.org
    https: no
    ratelimit: 1
    ratelimit_interval: 1
    genres: no
    external_ids:
        discogs: no
        bandcamp: no
        spotify: no
        deezer: no
        tidal: no
    extra_tags: []
fetchart:
    auto: yes
    minwidth: 0
    maxwidth: 0
    quality: 0
    max_filesize: 0
    enforce_ratio: no
    cautious: no
    cover_names:
    - cover
    - front
    - art
    - album
    - folder
    sources:
    - filesystem
    - coverart
    - itunes
    - amazon
    - albumart
    - cover_art_url
    store_source: no
    high_resolution: no
    deinterlace: no
    cover_format:
    google_key: REDACTED
    google_engine: REDACTED
    fanarttv_key: REDACTED
    lastfm_key: REDACTED
lyrics:
    auto: yes
    translate:
        api_key: REDACTED
        from_languages: []
        to_language:
    dist_thresh: 0.11
    google_API_key: REDACTED
    google_engine_ID: REDACTED
    genius_api_key: REDACTED
    fallback:
    force: no
    local: no
    print: no
    synced: no
    sources:
    - lrclib
    - google
    - genius
    - tekstowo
lastgenre:
    whitelist: yes
    min_weight: 10
    count: 1
    fallback:
    canonical: no
    source: album
    force: no
    keep_existing: no
    auto: yes
    separator: ', '
    prefer_specific: no
    title_case: yes
    extended_debug: no

lapo-luchini avatar Oct 06 '25 08:10 lapo-luchini

Hm, looks like it's not picking up that there are tracks with a better length distance, and is falling back on the default track_length_grace value of 10.

I think, at least for the moment, you could try enabling the fromfilename plugin, as it doesn't look like the tracks have any existing metadata. This'll let it pick up from the .wav filename..

You can also try adding the following, but it could cause issues with CD rips:


match:
  track_length_grace: 2

henry-oberholtzer avatar Oct 07 '25 01:10 henry-oberholtzer

I tried lowering grace to 2 and even to 1, but there were still mismatches.

  ≠ Artist:  -> Low Roar
     ≠ (#0) 01 Don't Be So Serious.wav (6:13) -> (#1) Don’t Be so Serious (6:13)
     ≠ (#0) 02 Bones.wav (2:49) -> (#2) Bones (2:49)
     ≠ (#0) 03 St. Eriksplan.wav (3:41) -> (#3) St. Eriksplan (3:41)
     ≠ (#0) 04 Give Me An Answer.wav (3:43) -> (#4) Give Me an Answer (3:43)
     ≠ (#0) 05 Waiting (10 Years).wav (4:04) -> (#5) Waiting (10 Years) (4:04)
     ≠ (#0) 11 Miserably.wav (3:55) -> (#6) Without You (3:54)
     ≠ (#0) 07 Gosia.wav (4:13) -> (#7) Gosia (4:13)
     ≠ (#0) 08 Once In A Long, Long While.wav (5:16) -> (#8) Once in a Long, Long While (5:16)
     ≠ (#0) 09 Crawl Back.wav (4:08) -> (#9) Crawl Back (4:08)
     ≠ (#0) 10 Poznań.wav (2:03) -> (#10) Poznań (2:03)
     ≠ (#0) 06 Without You.wav (3:54) -> (#11) Miserably (3:55)
     ≠ (#0) 12 13.wav (5:24) -> (#12) 13 (5:24)

Adding plugin fromfilename solved it perfectly:

  Match (68.8%):
  Low Roar - Once in a Long, Long While…
  ≠ album, artist, tracks, source
  MusicBrainz, Digital Media, 2017, AF, Tonequake Records, None, iTunes, Deezer, Spotify
  https://musicbrainz.org/release/bc506aa8-12cf-47b3-9553-f35c65e6dcac
  ≠ Artist:  -> Low Roar
     ≠ (#1) Don't Be So Serious (6:13) -> (#1) Don’t Be so Serious (6:13)
     ≠ (#4) Give Me An Answer (3:43) -> (#4) Give Me an Answer (3:43)
     ≠ (#8) Once In A Long, Long While (5:16) -> (#8) Once in a Long, Long While (5:16)
     ≠ (#10) Poznań (2:03) -> (#10) Poznań (2:03)

My own problem is solved (thanks!), should I close this or is it useful to delve into the underlying bug for others / th future?

lapo-luchini avatar Oct 07 '25 14:10 lapo-luchini

I think there's definitely room to improve its ability to match tracks based on duration if there's no other metadata to go off of, but fromfilename is definitely a key to helping it identify anything better. Ultimately beets has to guess if it can't pick up any metadata, but those guesses could always be better!

henry-oberholtzer avatar Oct 07 '25 14:10 henry-oberholtzer

It seems to me this is a matter of adjusting match.distance_weights for this specific use case. Beets by default 'cares' about the track title slightly more than the track duration, see:

match:
    distance_weights:
        data_source: 2.0
        artist: 3.0
        album: 3.0
        media: 1.0
        mediums: 1.0
        year: 1.0
        country: 0.5
        label: 0.5
        catalognum: 0.5
        albumdisambig: 0.5
        album_id: 5.0
        tracks: 2.0
        missing_tracks: 0.9
        unmatched_tracks: 0.6
        track_title: 3.0
        track_artist: 2.0
        track_index: 1.0
        track_length: 2.0
        track_id: 5.0
        medium: 1.0

Try lowering track_title and increasing track_length weights?

snejus avatar Oct 07 '25 16:10 snejus

It seems to me this is a matter of adjusting match.distance_weights for this specific use case. ... Try lowering track_title and increasing track_length weights?

I don't think that tweaking weights would matter in the OP scenario: we don't have any metadata for track_title, all we know is the total number of tracks and each track's length.

Also tweaking track_length_grace doesn't fix the problem, even reducing it to 0 there could always be the case of a difference in track lengths between the file and the proposed candidate, and I guess we have no way to prevent beets from making a "wrong order" mistake, am I right?

I guess the only way to avoid this kind of error is by using the fromfilename plugin, since it always ensures to at least extract information about the track number (provided the filename starts with a digit character). When we have track number + track length, the current default values of distance_weights guarantee that no ordering mistakes can happen: I've been using this configuration for years to import files ripped from my CD collection (i.e. only relying on track number and length) and I never ran into any ordering problem.

So I think we should definitely recommend using the plugin in the docs (I guess we already do? maybe we should activate it by default in config_default.yaml, as we do for the musicbrainz plugin?).

The only remaining potentially problematic case is when beets is configured to use the plugin, but the plugin doesn't actually extract any info because the file(s) already have a title tag (this is by design: the plugin trusts the existing title tag and doesn't try to replace it and other tags). I.e. we have a file with bogus tags (including title) and good information (track number, title) in the file name, and we want to use the latter for the import procedure. In this case we should implement some way to force the execution of the plugin even if a title exists, but I'm not sure how frequent this corner case is.

Vrihub avatar Oct 16 '25 13:10 Vrihub