1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-13 12:02:54 +08:00

Add and implement IApplicableToRate interface

This commit is contained in:
Bartłomiej Dach 2021-01-31 17:43:16 +01:00
parent 68c20a2a37
commit 7daeacaff2
3 changed files with 35 additions and 8 deletions

View File

@ -0,0 +1,20 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
namespace osu.Game.Rulesets.Mods
{
/// <summary>
/// Interface that should be implemented by mods that affect the track playback speed,
/// and in turn, values of the track rate.
/// </summary>
public interface IApplicableToRate : IApplicableToAudio
{
/// <summary>
/// Returns the playback rate at <paramref name="time"/> after this mod is applied.
/// </summary>
/// <param name="time">The time instant at which the playback rate is queried.</param>
/// <param name="rate">The playback rate before applying this mod.</param>
/// <returns>The playback rate after applying this mod.</returns>
double ApplyToRate(double time, double rate = 1);
}
}

View File

@ -8,7 +8,7 @@ using osu.Framework.Graphics.Audio;
namespace osu.Game.Rulesets.Mods
{
public abstract class ModRateAdjust : Mod, IApplicableToAudio
public abstract class ModRateAdjust : Mod, IApplicableToRate
{
public abstract BindableNumber<double> SpeedChange { get; }
@ -22,6 +22,8 @@ namespace osu.Game.Rulesets.Mods
sample.AddAdjustment(AdjustableProperty.Frequency, SpeedChange);
}
public double ApplyToRate(double time, double rate) => rate * SpeedChange.Value;
public override string SettingDescription => SpeedChange.IsDefault ? string.Empty : $"{SpeedChange.Value:N2}x";
}
}

View File

@ -14,7 +14,7 @@ using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets.Mods
{
public abstract class ModTimeRamp : Mod, IUpdatableByPlayfield, IApplicableToBeatmap, IApplicableToAudio
public abstract class ModTimeRamp : Mod, IUpdatableByPlayfield, IApplicableToBeatmap, IApplicableToRate
{
/// <summary>
/// The point in the beatmap at which the final ramping rate should be reached.
@ -47,7 +47,7 @@ namespace osu.Game.Rulesets.Mods
protected ModTimeRamp()
{
// for preview purpose at song select. eventually we'll want to be able to update every frame.
FinalRate.BindValueChanged(val => applyRateAdjustment(1), true);
FinalRate.BindValueChanged(val => applyRateAdjustment(double.PositiveInfinity), true);
AdjustPitch.BindValueChanged(applyPitchAdjustment);
}
@ -75,17 +75,22 @@ namespace osu.Game.Rulesets.Mods
finalRateTime = firstObjectStart + FINAL_RATE_PROGRESS * (lastObjectEnd - firstObjectStart);
}
public double ApplyToRate(double time, double rate = 1)
{
double amount = (time - beginRampTime) / Math.Max(1, finalRateTime - beginRampTime);
double ramp = InitialRate.Value + (FinalRate.Value - InitialRate.Value) * Math.Clamp(amount, 0, 1);
return rate * ramp;
}
public virtual void Update(Playfield playfield)
{
applyRateAdjustment((track.CurrentTime - beginRampTime) / Math.Max(1, finalRateTime - beginRampTime));
applyRateAdjustment(track.CurrentTime);
}
/// <summary>
/// Adjust the rate along the specified ramp
/// Adjust the rate along the specified ramp.
/// </summary>
/// <param name="amount">The amount of adjustment to apply (from 0..1).</param>
private void applyRateAdjustment(double amount) =>
SpeedChange.Value = InitialRate.Value + (FinalRate.Value - InitialRate.Value) * Math.Clamp(amount, 0, 1);
private void applyRateAdjustment(double time) => SpeedChange.Value = ApplyToRate(time);
private void applyPitchAdjustment(ValueChangedEvent<bool> adjustPitchSetting)
{