From 2cafbb2aba3181be6ac43cab21fdabce2f6a8327 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 3 Dec 2021 23:43:13 +0100 Subject: [PATCH] player/CrossFade: move code to CanCrossFade() --- src/player/CrossFade.cxx | 27 ++++++++++++++++----------- src/player/CrossFade.hxx | 21 +++++++++++++++------ src/player/Thread.cxx | 17 +++++++++++------ 3 files changed, 42 insertions(+), 23 deletions(-) diff --git a/src/player/CrossFade.cxx b/src/player/CrossFade.cxx index d61c0d0a5..1df8e978e 100644 --- a/src/player/CrossFade.cxx +++ b/src/player/CrossFade.cxx @@ -94,23 +94,28 @@ mixramp_interpolate(const char *ramp_list, float required_db) noexcept return FloatDuration(-1); } +bool +CrossFadeSettings::CanCrossFade(SignedSongTime current_total_time, + SignedSongTime next_total_time, + AudioFormat af, + AudioFormat old_format) const noexcept +{ + return IsEnabled() && + CanCrossFadeSong(current_total_time) && + CanCrossFadeSong(next_total_time) && + /* we can't crossfade when the audio formats are different */ + af == old_format; +} + unsigned -CrossFadeSettings::Calculate(SignedSongTime current_total_time, - SignedSongTime next_total_time, - float replay_gain_db, float replay_gain_prev_db, +CrossFadeSettings::Calculate(float replay_gain_db, float replay_gain_prev_db, const char *mixramp_start, const char *mixramp_prev_end, const AudioFormat af, - const AudioFormat old_format, unsigned max_chunks) const noexcept { - unsigned int chunks = 0; + assert(IsEnabled()); - if (!IsEnabled() || - !CanCrossFadeSong(current_total_time) || - !CanCrossFadeSong(next_total_time) || - /* we can't crossfade when the audio formats are different */ - af != old_format) - return 0; + unsigned int chunks = 0; assert(duration > FloatDuration::zero()); assert(af.IsValid()); diff --git a/src/player/CrossFade.hxx b/src/player/CrossFade.hxx index 38e919666..062c8cb49 100644 --- a/src/player/CrossFade.hxx +++ b/src/player/CrossFade.hxx @@ -53,27 +53,36 @@ struct CrossFadeSettings { } /** - * Calculate how many music pipe chunks should be used for crossfading. + * Determine whether cross-fading the two songs is possible. * * @param current_total_time the duration of the current song * @param next_total_time the duration of the new song + * @param af the audio format of the new song + * @param old_format the audio format of the current song + * @return true if cross-fading is possible + */ + [[gnu::pure]] + bool CanCrossFade(SignedSongTime current_total_time, + SignedSongTime next_total_time, + AudioFormat af, AudioFormat old_format) const noexcept; + + /** + * Calculate how many music pipe chunks should be used for crossfading. + * * @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 * @param mixramp_prev_end the last songs mixramp_end setting * @param af the audio format of the new song - * @param old_format the audio format of the current song * @param max_chunks the maximum number of chunks * @return the number of chunks for crossfading, or 0 if cross fading * should be disabled for this song change */ [[gnu::pure]] - unsigned Calculate(SignedSongTime current_total_time, - SignedSongTime next_total_time, - float replay_gain_db, float replay_gain_prev_db, + unsigned Calculate(float replay_gain_db, float replay_gain_prev_db, const char *mixramp_start, const char *mixramp_prev_end, - AudioFormat af, AudioFormat old_format, + AudioFormat af, unsigned max_chunks) const noexcept; private: diff --git a/src/player/Thread.cxx b/src/player/Thread.cxx index 56da75d62..18178bf63 100644 --- a/src/player/Thread.cxx +++ b/src/player/Thread.cxx @@ -804,24 +804,29 @@ Player::CheckCrossFade() noexcept can decide */ return; + if (!pc.cross_fade.CanCrossFade(pc.total_time, dc.total_time, + dc.out_audio_format, + play_audio_format)) { + /* cross fading is disabled or the next song is too + short */ + xfade_state = CrossFadeState::DISABLED; + return; + } + /* enable cross fading in this song? if yes, calculate how many chunks will be required for it */ cross_fade_chunks = - pc.cross_fade.Calculate(pc.total_time, - dc.total_time, - dc.replay_gain_db, + pc.cross_fade.Calculate(dc.replay_gain_db, dc.replay_gain_prev_db, dc.GetMixRampStart(), dc.GetMixRampPreviousEnd(), - dc.out_audio_format, play_audio_format, buffer.GetSize() - buffer_before_play); if (cross_fade_chunks > 0) xfade_state = CrossFadeState::ENABLED; else - /* cross fading is disabled or the - next song is too short */ + // TODO: eliminate this "else" branch xfade_state = CrossFadeState::DISABLED; }