mirror of https://github.com/ppy/osu
Adjust ducking API to use a parameters `record`
This commit is contained in:
parent
0d858ce8f8
commit
554740af10
|
@ -24,7 +24,7 @@ public partial class ManageCollectionsDialog : OsuFocusedOverlayContainer
|
|||
protected override string PopInSampleName => @"UI/overlay-big-pop-in";
|
||||
protected override string PopOutSampleName => @"UI/overlay-big-pop-out";
|
||||
|
||||
private IDisposable? audioDucker;
|
||||
private IDisposable? duckOperation;
|
||||
|
||||
[Resolved]
|
||||
private MusicController? musicController { get; set; }
|
||||
|
@ -120,12 +120,17 @@ private void load(OsuColour colours)
|
|||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
audioDucker?.Dispose();
|
||||
duckOperation?.Dispose();
|
||||
}
|
||||
|
||||
protected override void PopIn()
|
||||
{
|
||||
audioDucker = musicController?.Duck(100, 1f, unduckDuration: 100);
|
||||
duckOperation = musicController?.Duck(new DuckParameters
|
||||
{
|
||||
DuckDuration = 100,
|
||||
DuckVolumeTo = 1,
|
||||
RestoreDuration = 100,
|
||||
});
|
||||
|
||||
this.FadeIn(enter_duration, Easing.OutQuint);
|
||||
this.ScaleTo(0.9f).Then().ScaleTo(1f, enter_duration, Easing.OutQuint);
|
||||
|
@ -135,7 +140,7 @@ protected override void PopOut()
|
|||
{
|
||||
base.PopOut();
|
||||
|
||||
audioDucker?.Dispose();
|
||||
duckOperation?.Dispose();
|
||||
|
||||
this.FadeOut(exit_duration, Easing.OutQuint);
|
||||
this.ScaleTo(0.9f, exit_duration);
|
||||
|
|
|
@ -32,7 +32,7 @@ public partial class DialogOverlay : OsuFocusedOverlayContainer, IDialogOverlay
|
|||
|| dialogContainer.Children.Count > 0;
|
||||
|
||||
[CanBeNull]
|
||||
private IDisposable audioDucker;
|
||||
private IDisposable duckOperation;
|
||||
|
||||
public DialogOverlay()
|
||||
{
|
||||
|
@ -53,7 +53,7 @@ public DialogOverlay()
|
|||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
audioDucker?.Dispose();
|
||||
duckOperation?.Dispose();
|
||||
}
|
||||
|
||||
public void Push(PopupDialog dialog)
|
||||
|
@ -106,13 +106,18 @@ void dismiss()
|
|||
|
||||
protected override void PopIn()
|
||||
{
|
||||
audioDucker = musicController.Duck(100, 1f, unduckDuration: 100);
|
||||
duckOperation = musicController?.Duck(new DuckParameters
|
||||
{
|
||||
DuckDuration = 100,
|
||||
DuckVolumeTo = 1,
|
||||
RestoreDuration = 100,
|
||||
});
|
||||
}
|
||||
|
||||
protected override void PopOut()
|
||||
{
|
||||
base.PopOut();
|
||||
audioDucker?.Dispose();
|
||||
duckOperation?.Dispose();
|
||||
|
||||
// PopOut gets called initially, but we only want to hide dialog when we have been loaded and are present.
|
||||
if (IsLoaded && CurrentDialog?.State.Value == Visibility.Visible)
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.ObjectExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Audio;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
|
@ -263,59 +262,53 @@ public void NextTrack(Action? onSuccess = null) => Schedule(() =>
|
|||
/// <summary>
|
||||
/// Attenuates the volume and/or filters the currently playing track.
|
||||
/// </summary>
|
||||
/// <param name="duration">Duration of the ducking transition, in ms.</param>
|
||||
/// <param name="duckVolumeTo">Level to drop volume to (1.0 = 100%).</param>
|
||||
/// <param name="duckCutoffTo">Cutoff frequency to drop `AudioFilter` to. Use `null` to skip filter effect.</param>
|
||||
/// <param name="easing">Easing for the ducking transition.</param>
|
||||
/// <param name="unduckDuration">Duration of the unducking transition, in ms.</param>
|
||||
/// <param name="unduckEasing">Easing for the unducking transition.</param>
|
||||
public IDisposable? Duck(int duration = 0, float duckVolumeTo = 0.25f, int? duckCutoffTo = 300, Easing easing = Easing.Out, int unduckDuration = 500, Easing unduckEasing = Easing.In)
|
||||
public IDisposable? Duck(DuckParameters? parameters = null)
|
||||
{
|
||||
parameters ??= new DuckParameters();
|
||||
|
||||
if (audioDuckActive) return null;
|
||||
|
||||
audioDuckActive = true;
|
||||
|
||||
Schedule(() =>
|
||||
{
|
||||
if (duckCutoffTo.IsNotNull())
|
||||
audioDuckFilter?.CutoffTo((int)duckCutoffTo, duration, easing);
|
||||
if (parameters.DuckCutoffTo != null)
|
||||
audioDuckFilter?.CutoffTo(parameters.DuckCutoffTo.Value, parameters.DuckDuration, parameters.DuckEasing);
|
||||
|
||||
this.TransformBindableTo(audioDuckVolume, duckVolumeTo, duration, easing);
|
||||
this.TransformBindableTo(audioDuckVolume, parameters.DuckVolumeTo, parameters.DuckDuration, parameters.DuckEasing);
|
||||
});
|
||||
|
||||
return new InvokeOnDisposal(() => unduck(unduckDuration, unduckEasing));
|
||||
return new InvokeOnDisposal(restoreDucking);
|
||||
|
||||
void restoreDucking()
|
||||
{
|
||||
if (!audioDuckActive) return;
|
||||
|
||||
audioDuckActive = false;
|
||||
|
||||
Schedule(() =>
|
||||
{
|
||||
audioDuckFilter?.CutoffTo(AudioFilter.MAX_LOWPASS_CUTOFF, parameters.RestoreDuration, parameters.RestoreEasing);
|
||||
this.TransformBindableTo(audioDuckVolume, 1, parameters.RestoreDuration, parameters.RestoreEasing);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A convenience method that ducks the currently playing track, then after a delay, unducks it.
|
||||
/// A convenience method that ducks the currently playing track, then after a delay, restores automatically.
|
||||
/// </summary>
|
||||
/// <param name="delay">Delay after audio is ducked before unducking begins, in ms.</param>
|
||||
/// <param name="unduckDuration">Duration of the unducking transition, in ms.</param>
|
||||
/// <param name="unduckEasing">Easing for the unducking transition.</param>
|
||||
/// <param name="duckVolumeTo">Level to drop volume to (1.0 = 100%).</param>
|
||||
/// <param name="duckCutoffTo">Cutoff frequency to drop `AudioFilter` to. Use `null` to skip filter effect.</param>
|
||||
/// <param name="duckDuration">Duration of the ducking transition, in ms.</param>
|
||||
/// <param name="duckEasing">Easing for the ducking transition.</param>
|
||||
public void DuckMomentarily(int delay, int unduckDuration = 500, Easing unduckEasing = Easing.In, float duckVolumeTo = 0.25f, int? duckCutoffTo = 300, int duckDuration = 0,
|
||||
Easing duckEasing = Easing.Out)
|
||||
/// <param name="delayUntilRestore">A delay in milliseconds which defines how long to delay restoration after ducking completes.</param>
|
||||
/// <param name="parameters">Parameters defining the ducking operation.</param>
|
||||
public void DuckMomentarily(double delayUntilRestore, DuckParameters? parameters = null)
|
||||
{
|
||||
if (audioDuckActive) return;
|
||||
parameters ??= new DuckParameters();
|
||||
|
||||
Duck(duckDuration, duckVolumeTo, duckCutoffTo, duckEasing);
|
||||
Scheduler.AddDelayed(() => unduck(unduckDuration, unduckEasing), delay);
|
||||
}
|
||||
IDisposable? duckOperation = Duck(parameters);
|
||||
|
||||
private void unduck(int duration, Easing easing)
|
||||
{
|
||||
if (!audioDuckActive) return;
|
||||
if (duckOperation == null)
|
||||
return;
|
||||
|
||||
audioDuckActive = false;
|
||||
|
||||
Schedule(() =>
|
||||
{
|
||||
audioDuckFilter?.CutoffTo(AudioFilter.MAX_LOWPASS_CUTOFF, duration, easing);
|
||||
this.TransformBindableTo(audioDuckVolume, 1, duration, easing);
|
||||
});
|
||||
Scheduler.AddDelayed(() => duckOperation.Dispose(), delayUntilRestore);
|
||||
}
|
||||
|
||||
private bool next()
|
||||
|
@ -491,6 +484,45 @@ public void ResetTrackAdjustments()
|
|||
}
|
||||
}
|
||||
|
||||
public record DuckParameters
|
||||
{
|
||||
/// <summary>
|
||||
/// The duration of the ducking transition in milliseconds.
|
||||
/// Defaults to no duration (immediate ducking).
|
||||
/// </summary>
|
||||
public double DuckDuration = 0;
|
||||
|
||||
/// <summary>
|
||||
/// The final volume which should be reached during ducking, when 0 is silent and 1 is original volume.
|
||||
/// Defaults to 25%.
|
||||
/// </summary>
|
||||
public float DuckVolumeTo = 0.25f;
|
||||
|
||||
/// <summary>
|
||||
/// The low-pass cutoff frequency which should be reached during ducking. Use `null` to skip filter effect.
|
||||
/// Defaults to 300 Hz.
|
||||
/// </summary>
|
||||
public int? DuckCutoffTo = 300;
|
||||
|
||||
/// <summary>
|
||||
/// The easing curve to be applied during ducking.
|
||||
/// Defaults to <see cref="Easing.Out"/>.
|
||||
/// </summary>
|
||||
public Easing DuckEasing = Easing.Out;
|
||||
|
||||
/// <summary>
|
||||
/// The duration of the restoration transition in milliseconds.
|
||||
/// Defaults to 500 ms.
|
||||
/// </summary>
|
||||
public double RestoreDuration = 500;
|
||||
|
||||
/// <summary>
|
||||
/// The easing curve to be applied during restoration.
|
||||
/// Defaults to <see cref="Easing.In"/>.
|
||||
/// </summary>
|
||||
public Easing RestoreEasing = Easing.In;
|
||||
}
|
||||
|
||||
public enum TrackChangeDirection
|
||||
{
|
||||
None,
|
||||
|
|
Loading…
Reference in New Issue