Skip to content

[Feature request] (Beta) Support sequental album tracks within playlists in hybrid ReplayGain mode #1102

Open
@HeroBrine1st

Description

@HeroBrine1st

I'm on 0.9.14. Currently, if I place tracks with gapless playback in playlist with hybrid replaygain, there may be sudden jump of volume on next track, and due to tracks being "unite" it is easily seen.

Current behavior

Hybrid ReplayGain uses track gain even if both tracks are from the same album and list [previousTrack, nextTrack] is a sublist of all tracks in their album.

Expected behavior

Hybrid ReplayGain uses album gain in such cases, preventing volume jump on gapless albums.

Proposed solution

The most optimal solution is to find "sequental tracks" in queue and use album gain in those ranges, using this algorithm:

I wrote that for other project so that it is python, anyway I want to show the algorithm
    for playlist in playlists:
        sequental_ranges = []
        i = 0
        while i < len(playlist["tracks"]):
            start = i
            # Find the end of the current sequential range
            while (
                (i + 1) < len(playlist["tracks"])
                and playlist["tracks"][i + 1]["album_uri"] == playlist["tracks"][i]["album_uri"]  # same album
                and (  # same disk
                    (playlist["tracks"][i]["disc_number"] == playlist["tracks"][i + 1]["disc_number"] and
                     playlist["tracks"][i]["track_number"] + 1 == playlist["tracks"][i + 1]["track_number"])
                    or  # next disk
                    (playlist["tracks"][i]["disc_number"] + 1 == playlist["tracks"][i + 1]["disc_number"] and
                     playlist["tracks"][i + 1]["track_number"] == 1)
                )
            ):
                i += 1
            end = i
            # Add the range to the list if it contains at least two tracks
            if end > start:
                sequental_ranges.append(range(start, end + 1))
            i += 1
        playlist["sequental_ranges"] = sequental_ranges

"sequental_ranges" then contains every range where you need to use album gain

There's also other solution, I think it is the one Spotify uses. It involves adding fourth option to volume normalization - "always use album gain". Looking at source code, I see that you already considered that:

double? getEffectiveGainChange(
MediaItem currentTrack, jellyfin_models.BaseItemDto? item) {
final baseItem = item ??
jellyfin_models.BaseItemDto.fromJson(currentTrack.extras?["itemJson"]);
double? effectiveGainChange;
switch (FinampSettingsHelper.finampSettings.volumeNormalizationMode) {
case VolumeNormalizationMode.hybrid:
// case VolumeNormalizationMode.albumBased: // we use the context normalization gain for album-based because we don't have the album item here
// use context normalization gain if available, otherwise use track normalization gain
effectiveGainChange = currentTrack.extras?["contextNormalizationGain"] ??
baseItem.normalizationGain;
break;
case VolumeNormalizationMode.trackBased:
// only ever use track normalization gain
effectiveGainChange = baseItem.normalizationGain;
break;
case VolumeNormalizationMode.albumOnly:
// only ever use context normalization gain, don't normalize tracks out of special contexts
effectiveGainChange = currentTrack.extras?["contextNormalizationGain"];
break;
}
return effectiveGainChange;
}

If it really needs AlbumItem here for this option to work and there's no easy way to get it (or pass contextNormalizationGain) here, then I probably can't make a PR myself, as I am not familiar with Dart and this project enough. Otherwise, I'm willing to make a PR with fourth option if noone takes either approach.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions