player/CrossFade: move code to CanCrossFade()

This commit is contained in:
Max Kellermann 2021-12-03 23:43:13 +01:00
parent b78c64376f
commit 2cafbb2aba
3 changed files with 42 additions and 23 deletions

View File

@ -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());

View File

@ -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:

View File

@ -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;
}