diff --git a/NEWS b/NEWS index 996ac24fa..1579d0e0f 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,8 @@ ver 0.23 (not yet released) * decoder - openmpt: new plugin - wavpack: fix WVC file support +* player + - do not cross-fade songs shorter than 20 seconds * output - oss: support DSD over PCM - pipewire: new plugin diff --git a/src/player/CrossFade.cxx b/src/player/CrossFade.cxx index a6d14f348..1eeead4b2 100644 --- a/src/player/CrossFade.cxx +++ b/src/player/CrossFade.cxx @@ -34,6 +34,7 @@ inline bool CrossFadeSettings::CanCrossFadeSong(SignedSongTime total_time) const noexcept { return !total_time.IsNegative() && + duration >= MIN_TOTAL_TIME && duration >= std::chrono::duration_cast(total_time); } @@ -94,7 +95,8 @@ mixramp_interpolate(const char *ramp_list, float required_db) noexcept } unsigned -CrossFadeSettings::Calculate(SignedSongTime total_time, +CrossFadeSettings::Calculate(SignedSongTime current_total_time, + SignedSongTime next_total_time, float replay_gain_db, float replay_gain_prev_db, const char *mixramp_start, const char *mixramp_prev_end, const AudioFormat af, @@ -104,7 +106,8 @@ CrossFadeSettings::Calculate(SignedSongTime total_time, unsigned int chunks = 0; if (!IsEnabled() || - !CanCrossFadeSong(total_time) || + !CanCrossFadeSong(current_total_time) || + !CanCrossFadeSong(next_total_time) || /* we can't crossfade when the audio formats are different */ af != old_format) return 0; diff --git a/src/player/CrossFade.hxx b/src/player/CrossFade.hxx index 1934d0e91..8afda835c 100644 --- a/src/player/CrossFade.hxx +++ b/src/player/CrossFade.hxx @@ -26,6 +26,11 @@ struct AudioFormat; class SignedSongTime; struct CrossFadeSettings { + /** + * Songs shorter than this will never cross-fade. + */ + static constexpr SignedSongTime MIN_TOTAL_TIME{std::chrono::seconds{20}}; + /** * The configured cross fade duration [s]. */ @@ -46,7 +51,8 @@ struct CrossFadeSettings { /** * Calculate how many music pipe chunks should be used for crossfading. * - * @param total_time total_time the duration of the new song + * @param current_total_time the duration of the current song + * @param next_total_time the duration of the new song * @param replay_gain_db the ReplayGain adjustment used for this song * @param replay_gain_prev_db the ReplayGain adjustment used on the last song * @param mixramp_start the next songs mixramp_start tag @@ -58,7 +64,8 @@ struct CrossFadeSettings { * should be disabled for this song change */ [[gnu::pure]] - unsigned Calculate(SignedSongTime total_time, + unsigned Calculate(SignedSongTime current_total_time, + SignedSongTime next_total_time, float replay_gain_db, float replay_gain_prev_db, const char *mixramp_start, const char *mixramp_prev_end, diff --git a/src/player/Thread.cxx b/src/player/Thread.cxx index 19f92995b..95ab1626e 100644 --- a/src/player/Thread.cxx +++ b/src/player/Thread.cxx @@ -1049,7 +1049,8 @@ Player::Run() noexcept calculate how many chunks will be required for it */ cross_fade_chunks = - pc.cross_fade.Calculate(dc.total_time, + pc.cross_fade.Calculate(pc.total_time, + dc.total_time, dc.replay_gain_db, dc.replay_gain_prev_db, dc.GetMixRampStart(),