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); 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 unsigned
CrossFadeSettings::Calculate(SignedSongTime current_total_time, CrossFadeSettings::Calculate(float replay_gain_db, float replay_gain_prev_db,
SignedSongTime next_total_time,
float replay_gain_db, float replay_gain_prev_db,
const char *mixramp_start, const char *mixramp_prev_end, const char *mixramp_start, const char *mixramp_prev_end,
const AudioFormat af, const AudioFormat af,
const AudioFormat old_format,
unsigned max_chunks) const noexcept unsigned max_chunks) const noexcept
{ {
unsigned int chunks = 0; assert(IsEnabled());
if (!IsEnabled() || unsigned int chunks = 0;
!CanCrossFadeSong(current_total_time) ||
!CanCrossFadeSong(next_total_time) ||
/* we can't crossfade when the audio formats are different */
af != old_format)
return 0;
assert(duration > FloatDuration::zero()); assert(duration > FloatDuration::zero());
assert(af.IsValid()); 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 current_total_time the duration of the current song
* @param next_total_time the duration of the new 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_db the ReplayGain adjustment used for this song
* @param replay_gain_prev_db the ReplayGain adjustment used on the last 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_start the next songs mixramp_start tag
* @param mixramp_prev_end the last songs mixramp_end setting * @param mixramp_prev_end the last songs mixramp_end setting
* @param af the audio format of the new song * @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 * @param max_chunks the maximum number of chunks
* @return the number of chunks for crossfading, or 0 if cross fading * @return the number of chunks for crossfading, or 0 if cross fading
* should be disabled for this song change * should be disabled for this song change
*/ */
[[gnu::pure]] [[gnu::pure]]
unsigned Calculate(SignedSongTime current_total_time, unsigned Calculate(float replay_gain_db, float replay_gain_prev_db,
SignedSongTime next_total_time,
float replay_gain_db, float replay_gain_prev_db,
const char *mixramp_start, const char *mixramp_start,
const char *mixramp_prev_end, const char *mixramp_prev_end,
AudioFormat af, AudioFormat old_format, AudioFormat af,
unsigned max_chunks) const noexcept; unsigned max_chunks) const noexcept;
private: private:

View File

@ -804,24 +804,29 @@ Player::CheckCrossFade() noexcept
can decide */ can decide */
return; 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 /* enable cross fading in this song? if yes, calculate how
many chunks will be required for it */ many chunks will be required for it */
cross_fade_chunks = cross_fade_chunks =
pc.cross_fade.Calculate(pc.total_time, pc.cross_fade.Calculate(dc.replay_gain_db,
dc.total_time,
dc.replay_gain_db,
dc.replay_gain_prev_db, dc.replay_gain_prev_db,
dc.GetMixRampStart(), dc.GetMixRampStart(),
dc.GetMixRampPreviousEnd(), dc.GetMixRampPreviousEnd(),
dc.out_audio_format,
play_audio_format, play_audio_format,
buffer.GetSize() - buffer.GetSize() -
buffer_before_play); buffer_before_play);
if (cross_fade_chunks > 0) if (cross_fade_chunks > 0)
xfade_state = CrossFadeState::ENABLED; xfade_state = CrossFadeState::ENABLED;
else else
/* cross fading is disabled or the // TODO: eliminate this "else" branch
next song is too short */
xfade_state = CrossFadeState::DISABLED; xfade_state = CrossFadeState::DISABLED;
} }