mirror of
https://github.com/ppy/osu.git
synced 2024-11-13 18:47:27 +08:00
Merge pull request #15073 from peppy/fix-player-loader-low-pass
Improve `PlayerLoader` audio and visual transitions
This commit is contained in:
commit
d88daf0cc2
@ -6,6 +6,7 @@ using NUnit.Framework;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Audio.Track;
|
using osu.Framework.Audio.Track;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
@ -18,16 +19,19 @@ namespace osu.Game.Tests.Visual.Audio
|
|||||||
{
|
{
|
||||||
public class TestSceneAudioFilter : OsuTestScene
|
public class TestSceneAudioFilter : OsuTestScene
|
||||||
{
|
{
|
||||||
private OsuSpriteText lowpassText;
|
private OsuSpriteText lowPassText;
|
||||||
private AudioFilter lowpassFilter;
|
private AudioFilter lowPassFilter;
|
||||||
|
|
||||||
private OsuSpriteText highpassText;
|
private OsuSpriteText highPassText;
|
||||||
private AudioFilter highpassFilter;
|
private AudioFilter highPassFilter;
|
||||||
|
|
||||||
private Track track;
|
private Track track;
|
||||||
|
|
||||||
private WaveformTestBeatmap beatmap;
|
private WaveformTestBeatmap beatmap;
|
||||||
|
|
||||||
|
private OsuSliderBar<int> lowPassSlider;
|
||||||
|
private OsuSliderBar<int> highPassSlider;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(AudioManager audio)
|
private void load(AudioManager audio)
|
||||||
{
|
{
|
||||||
@ -38,53 +42,89 @@ namespace osu.Game.Tests.Visual.Audio
|
|||||||
{
|
{
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
lowpassFilter = new AudioFilter(audio.TrackMixer),
|
lowPassFilter = new AudioFilter(audio.TrackMixer),
|
||||||
highpassFilter = new AudioFilter(audio.TrackMixer, BQFType.HighPass),
|
highPassFilter = new AudioFilter(audio.TrackMixer, BQFType.HighPass),
|
||||||
lowpassText = new OsuSpriteText
|
lowPassText = new OsuSpriteText
|
||||||
{
|
{
|
||||||
Padding = new MarginPadding(20),
|
Padding = new MarginPadding(20),
|
||||||
Text = $"Low Pass: {lowpassFilter.Cutoff.Value}hz",
|
Text = $"Low Pass: {lowPassFilter.Cutoff}hz",
|
||||||
Font = new FontUsage(size: 40)
|
Font = new FontUsage(size: 40)
|
||||||
},
|
},
|
||||||
new OsuSliderBar<int>
|
lowPassSlider = new OsuSliderBar<int>
|
||||||
{
|
{
|
||||||
Width = 500,
|
Width = 500,
|
||||||
Height = 50,
|
Height = 50,
|
||||||
Padding = new MarginPadding(20),
|
Padding = new MarginPadding(20),
|
||||||
Current = { BindTarget = lowpassFilter.Cutoff }
|
Current = new BindableInt
|
||||||
|
{
|
||||||
|
MinValue = 0,
|
||||||
|
MaxValue = AudioFilter.MAX_LOWPASS_CUTOFF,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
highpassText = new OsuSpriteText
|
highPassText = new OsuSpriteText
|
||||||
{
|
{
|
||||||
Padding = new MarginPadding(20),
|
Padding = new MarginPadding(20),
|
||||||
Text = $"High Pass: {highpassFilter.Cutoff.Value}hz",
|
Text = $"High Pass: {highPassFilter.Cutoff}hz",
|
||||||
Font = new FontUsage(size: 40)
|
Font = new FontUsage(size: 40)
|
||||||
},
|
},
|
||||||
new OsuSliderBar<int>
|
highPassSlider = new OsuSliderBar<int>
|
||||||
{
|
{
|
||||||
Width = 500,
|
Width = 500,
|
||||||
Height = 50,
|
Height = 50,
|
||||||
Padding = new MarginPadding(20),
|
Padding = new MarginPadding(20),
|
||||||
Current = { BindTarget = highpassFilter.Cutoff }
|
Current = new BindableInt
|
||||||
|
{
|
||||||
|
MinValue = 0,
|
||||||
|
MaxValue = AudioFilter.MAX_LOWPASS_CUTOFF,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
lowpassFilter.Cutoff.ValueChanged += e => lowpassText.Text = $"Low Pass: {e.NewValue}hz";
|
|
||||||
highpassFilter.Cutoff.ValueChanged += e => highpassText.Text = $"High Pass: {e.NewValue}hz";
|
lowPassSlider.Current.ValueChanged += e =>
|
||||||
|
{
|
||||||
|
lowPassText.Text = $"Low Pass: {e.NewValue}hz";
|
||||||
|
lowPassFilter.Cutoff = e.NewValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
highPassSlider.Current.ValueChanged += e =>
|
||||||
|
{
|
||||||
|
highPassText.Text = $"High Pass: {e.NewValue}hz";
|
||||||
|
highPassFilter.Cutoff = e.NewValue;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Overrides of Drawable
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
highPassSlider.Current.Value = highPassFilter.Cutoff;
|
||||||
|
lowPassSlider.Current.Value = lowPassFilter.Cutoff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
[SetUpSteps]
|
[SetUpSteps]
|
||||||
public void SetUpSteps()
|
public void SetUpSteps()
|
||||||
{
|
{
|
||||||
AddStep("Play Track", () => track.Start());
|
AddStep("Play Track", () => track.Start());
|
||||||
|
|
||||||
|
AddStep("Reset filters", () =>
|
||||||
|
{
|
||||||
|
lowPassFilter.Cutoff = AudioFilter.MAX_LOWPASS_CUTOFF;
|
||||||
|
highPassFilter.Cutoff = 0;
|
||||||
|
});
|
||||||
|
|
||||||
waitTrackPlay();
|
waitTrackPlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestLowPass()
|
public void TestLowPassSweep()
|
||||||
{
|
{
|
||||||
AddStep("Filter Sweep", () =>
|
AddStep("Filter Sweep", () =>
|
||||||
{
|
{
|
||||||
lowpassFilter.CutoffTo(AudioFilter.MAX_LOWPASS_CUTOFF).Then()
|
lowPassFilter.CutoffTo(AudioFilter.MAX_LOWPASS_CUTOFF).Then()
|
||||||
.CutoffTo(0, 2000, Easing.OutCubic);
|
.CutoffTo(0, 2000, Easing.OutCubic);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -92,7 +132,7 @@ namespace osu.Game.Tests.Visual.Audio
|
|||||||
|
|
||||||
AddStep("Filter Sweep (reverse)", () =>
|
AddStep("Filter Sweep (reverse)", () =>
|
||||||
{
|
{
|
||||||
lowpassFilter.CutoffTo(0).Then()
|
lowPassFilter.CutoffTo(0).Then()
|
||||||
.CutoffTo(AudioFilter.MAX_LOWPASS_CUTOFF, 2000, Easing.InCubic);
|
.CutoffTo(AudioFilter.MAX_LOWPASS_CUTOFF, 2000, Easing.InCubic);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -101,11 +141,11 @@ namespace osu.Game.Tests.Visual.Audio
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestHighPass()
|
public void TestHighPassSweep()
|
||||||
{
|
{
|
||||||
AddStep("Filter Sweep", () =>
|
AddStep("Filter Sweep", () =>
|
||||||
{
|
{
|
||||||
highpassFilter.CutoffTo(0).Then()
|
highPassFilter.CutoffTo(0).Then()
|
||||||
.CutoffTo(AudioFilter.MAX_LOWPASS_CUTOFF, 2000, Easing.InCubic);
|
.CutoffTo(AudioFilter.MAX_LOWPASS_CUTOFF, 2000, Easing.InCubic);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -113,7 +153,7 @@ namespace osu.Game.Tests.Visual.Audio
|
|||||||
|
|
||||||
AddStep("Filter Sweep (reverse)", () =>
|
AddStep("Filter Sweep (reverse)", () =>
|
||||||
{
|
{
|
||||||
highpassFilter.CutoffTo(AudioFilter.MAX_LOWPASS_CUTOFF).Then()
|
highPassFilter.CutoffTo(AudioFilter.MAX_LOWPASS_CUTOFF).Then()
|
||||||
.CutoffTo(0, 2000, Easing.OutCubic);
|
.CutoffTo(0, 2000, Easing.OutCubic);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using ManagedBass.Fx;
|
using ManagedBass.Fx;
|
||||||
using osu.Framework.Audio.Mixing;
|
using osu.Framework.Audio.Mixing;
|
||||||
using osu.Framework.Bindables;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Audio.Effects
|
namespace osu.Game.Audio.Effects
|
||||||
@ -21,10 +20,25 @@ namespace osu.Game.Audio.Effects
|
|||||||
private readonly BQFParameters filter;
|
private readonly BQFParameters filter;
|
||||||
private readonly BQFType type;
|
private readonly BQFType type;
|
||||||
|
|
||||||
|
private bool isAttached;
|
||||||
|
|
||||||
|
private int cutoff;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The current cutoff of this filter.
|
/// The cutoff frequency of this filter.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BindableNumber<int> Cutoff { get; }
|
public int Cutoff
|
||||||
|
{
|
||||||
|
get => cutoff;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == cutoff)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cutoff = value;
|
||||||
|
updateFilter(cutoff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A Component that implements a BASS FX BiQuad Filter Effect.
|
/// A Component that implements a BASS FX BiQuad Filter Effect.
|
||||||
@ -36,102 +50,96 @@ namespace osu.Game.Audio.Effects
|
|||||||
this.mixer = mixer;
|
this.mixer = mixer;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
|
||||||
int initialCutoff;
|
|
||||||
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case BQFType.HighPass:
|
|
||||||
initialCutoff = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BQFType.LowPass:
|
|
||||||
initialCutoff = MAX_LOWPASS_CUTOFF;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
initialCutoff = 500; // A default that should ensure audio remains audible for other filters.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Cutoff = new BindableNumber<int>(initialCutoff)
|
|
||||||
{
|
|
||||||
MinValue = 1,
|
|
||||||
MaxValue = MAX_LOWPASS_CUTOFF
|
|
||||||
};
|
|
||||||
|
|
||||||
filter = new BQFParameters
|
filter = new BQFParameters
|
||||||
{
|
{
|
||||||
lFilter = type,
|
lFilter = type,
|
||||||
fCenter = initialCutoff,
|
|
||||||
fBandwidth = 0,
|
fBandwidth = 0,
|
||||||
fQ = 0.7f // This allows fCenter to go up to 22049hz (nyquist - 1hz) without overflowing and causing weird filter behaviour (see: https://www.un4seen.com/forum/?topic=19542.0)
|
// This allows fCenter to go up to 22049hz (nyquist - 1hz) without overflowing and causing weird filter behaviour (see: https://www.un4seen.com/forum/?topic=19542.0)
|
||||||
|
fQ = 0.7f
|
||||||
};
|
};
|
||||||
|
|
||||||
// Don't start attached if this is low-pass or high-pass filter (as they have special auto-attach/detach logic)
|
Cutoff = getInitialCutoff(type);
|
||||||
if (type != BQFType.LowPass && type != BQFType.HighPass)
|
|
||||||
attachFilter();
|
|
||||||
|
|
||||||
Cutoff.ValueChanged += updateFilter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void attachFilter()
|
private int getInitialCutoff(BQFType type)
|
||||||
{
|
{
|
||||||
Debug.Assert(!mixer.Effects.Contains(filter));
|
switch (type)
|
||||||
mixer.Effects.Add(filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void detachFilter()
|
|
||||||
{
|
|
||||||
Debug.Assert(mixer.Effects.Contains(filter));
|
|
||||||
mixer.Effects.Remove(filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateFilter(ValueChangedEvent<int> cutoff)
|
|
||||||
{
|
|
||||||
// Workaround for weird behaviour when rapidly setting fCenter of a low-pass filter to nyquist - 1hz.
|
|
||||||
if (type == BQFType.LowPass)
|
|
||||||
{
|
{
|
||||||
if (cutoff.NewValue >= MAX_LOWPASS_CUTOFF)
|
case BQFType.HighPass:
|
||||||
{
|
return 1;
|
||||||
detachFilter();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cutoff.OldValue >= MAX_LOWPASS_CUTOFF && cutoff.NewValue < MAX_LOWPASS_CUTOFF)
|
case BQFType.LowPass:
|
||||||
attachFilter();
|
return MAX_LOWPASS_CUTOFF;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 500; // A default that should ensure audio remains audible for other filters.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateFilter(int newValue)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case BQFType.LowPass:
|
||||||
|
// Workaround for weird behaviour when rapidly setting fCenter of a low-pass filter to nyquist - 1hz.
|
||||||
|
if (newValue >= MAX_LOWPASS_CUTOFF)
|
||||||
|
{
|
||||||
|
ensureDetached();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Workaround for weird behaviour when rapidly setting fCenter of a high-pass filter to 1hz.
|
||||||
|
case BQFType.HighPass:
|
||||||
|
if (newValue <= 1)
|
||||||
|
{
|
||||||
|
ensureDetached();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Workaround for weird behaviour when rapidly setting fCenter of a high-pass filter to 1hz.
|
ensureAttached();
|
||||||
if (type == BQFType.HighPass)
|
|
||||||
{
|
|
||||||
if (cutoff.NewValue <= 1)
|
|
||||||
{
|
|
||||||
detachFilter();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cutoff.OldValue <= 1 && cutoff.NewValue > 1)
|
|
||||||
attachFilter();
|
|
||||||
}
|
|
||||||
|
|
||||||
var filterIndex = mixer.Effects.IndexOf(filter);
|
var filterIndex = mixer.Effects.IndexOf(filter);
|
||||||
|
|
||||||
if (filterIndex < 0) return;
|
if (filterIndex < 0) return;
|
||||||
|
|
||||||
if (mixer.Effects[filterIndex] is BQFParameters existingFilter)
|
if (mixer.Effects[filterIndex] is BQFParameters existingFilter)
|
||||||
{
|
{
|
||||||
existingFilter.fCenter = cutoff.NewValue;
|
existingFilter.fCenter = newValue;
|
||||||
|
|
||||||
// required to update effect with new parameters.
|
// required to update effect with new parameters.
|
||||||
mixer.Effects[filterIndex] = existingFilter;
|
mixer.Effects[filterIndex] = existingFilter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ensureAttached()
|
||||||
|
{
|
||||||
|
if (isAttached)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Debug.Assert(!mixer.Effects.Contains(filter));
|
||||||
|
mixer.Effects.Add(filter);
|
||||||
|
isAttached = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ensureDetached()
|
||||||
|
{
|
||||||
|
if (!isAttached)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Debug.Assert(mixer.Effects.Contains(filter));
|
||||||
|
mixer.Effects.Remove(filter);
|
||||||
|
isAttached = false;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
protected override void Dispose(bool isDisposing)
|
||||||
{
|
{
|
||||||
base.Dispose(isDisposing);
|
base.Dispose(isDisposing);
|
||||||
|
ensureDetached();
|
||||||
if (mixer.Effects.Contains(filter))
|
|
||||||
detachFilter();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using osu.Framework.Bindables;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Transforms;
|
using osu.Framework.Graphics.Transforms;
|
||||||
|
|
||||||
@ -12,7 +11,7 @@ namespace osu.Game.Audio.Effects
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The filter cutoff.
|
/// The filter cutoff.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
BindableNumber<int> Cutoff { get; }
|
int Cutoff { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class FilterableAudioComponentExtensions
|
public static class FilterableAudioComponentExtensions
|
||||||
@ -40,7 +39,7 @@ namespace osu.Game.Audio.Effects
|
|||||||
public static TransformSequence<T> CutoffTo<T, TEasing>(this T component, int newCutoff, double duration, TEasing easing)
|
public static TransformSequence<T> CutoffTo<T, TEasing>(this T component, int newCutoff, double duration, TEasing easing)
|
||||||
where T : class, ITransformableFilter, IDrawable
|
where T : class, ITransformableFilter, IDrawable
|
||||||
where TEasing : IEasingFunction
|
where TEasing : IEasingFunction
|
||||||
=> component.TransformBindableTo(component.Cutoff, newCutoff, duration, easing);
|
=> component.TransformTo(nameof(component.Cutoff), newCutoff, duration, easing);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Smoothly adjusts filter cutoff over time.
|
/// Smoothly adjusts filter cutoff over time.
|
||||||
@ -49,6 +48,6 @@ namespace osu.Game.Audio.Effects
|
|||||||
public static TransformSequence<T> CutoffTo<T, TEasing>(this TransformSequence<T> sequence, int newCutoff, double duration, TEasing easing)
|
public static TransformSequence<T> CutoffTo<T, TEasing>(this TransformSequence<T> sequence, int newCutoff, double duration, TEasing easing)
|
||||||
where T : class, ITransformableFilter, IDrawable
|
where T : class, ITransformableFilter, IDrawable
|
||||||
where TEasing : IEasingFunction
|
where TEasing : IEasingFunction
|
||||||
=> sequence.Append(o => o.TransformBindableTo(o.Cutoff, newCutoff, duration, easing));
|
=> sequence.Append(o => o.TransformTo(nameof(o.Cutoff), newCutoff, duration, easing));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,8 @@ namespace osu.Game.Screens.Play
|
|||||||
{
|
{
|
||||||
protected const float BACKGROUND_BLUR = 15;
|
protected const float BACKGROUND_BLUR = 15;
|
||||||
|
|
||||||
|
private const double content_out_duration = 300;
|
||||||
|
|
||||||
public override bool HideOverlaysOnEnter => hideOverlays;
|
public override bool HideOverlaysOnEnter => hideOverlays;
|
||||||
|
|
||||||
public override bool DisallowExternalBeatmapRulesetChanges => true;
|
public override bool DisallowExternalBeatmapRulesetChanges => true;
|
||||||
@ -135,36 +137,39 @@ namespace osu.Game.Screens.Play
|
|||||||
muteWarningShownOnce = sessionStatics.GetBindable<bool>(Static.MutedAudioNotificationShownOnce);
|
muteWarningShownOnce = sessionStatics.GetBindable<bool>(Static.MutedAudioNotificationShownOnce);
|
||||||
batteryWarningShownOnce = sessionStatics.GetBindable<bool>(Static.LowBatteryNotificationShownOnce);
|
batteryWarningShownOnce = sessionStatics.GetBindable<bool>(Static.LowBatteryNotificationShownOnce);
|
||||||
|
|
||||||
InternalChild = (content = new LogoTrackingContainer
|
InternalChildren = new Drawable[]
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
(content = new LogoTrackingContainer
|
||||||
Origin = Anchor.Centre,
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
}).WithChildren(new Drawable[]
|
|
||||||
{
|
|
||||||
MetadataInfo = new BeatmapMetadataDisplay(Beatmap.Value, Mods, content.LogoFacade)
|
|
||||||
{
|
{
|
||||||
Alpha = 0,
|
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
},
|
RelativeSizeAxes = Axes.Both,
|
||||||
PlayerSettings = new FillFlowContainer<PlayerSettingsGroup>
|
}).WithChildren(new Drawable[]
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopRight,
|
MetadataInfo = new BeatmapMetadataDisplay(Beatmap.Value, Mods, content.LogoFacade)
|
||||||
Origin = Anchor.TopRight,
|
|
||||||
AutoSizeAxes = Axes.Both,
|
|
||||||
Direction = FillDirection.Vertical,
|
|
||||||
Spacing = new Vector2(0, 20),
|
|
||||||
Margin = new MarginPadding(25),
|
|
||||||
Children = new PlayerSettingsGroup[]
|
|
||||||
{
|
{
|
||||||
VisualSettings = new VisualSettings(),
|
Alpha = 0,
|
||||||
new InputSettings()
|
Anchor = Anchor.Centre,
|
||||||
}
|
Origin = Anchor.Centre,
|
||||||
},
|
},
|
||||||
idleTracker = new IdleTracker(750),
|
PlayerSettings = new FillFlowContainer<PlayerSettingsGroup>
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopRight,
|
||||||
|
Origin = Anchor.TopRight,
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Spacing = new Vector2(0, 20),
|
||||||
|
Margin = new MarginPadding(25),
|
||||||
|
Children = new PlayerSettingsGroup[]
|
||||||
|
{
|
||||||
|
VisualSettings = new VisualSettings(),
|
||||||
|
new InputSettings()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
idleTracker = new IdleTracker(750),
|
||||||
|
}),
|
||||||
lowPassFilter = new AudioFilter(audio.TrackMixer)
|
lowPassFilter = new AudioFilter(audio.TrackMixer)
|
||||||
});
|
};
|
||||||
|
|
||||||
if (Beatmap.Value.BeatmapInfo.EpilepsyWarning)
|
if (Beatmap.Value.BeatmapInfo.EpilepsyWarning)
|
||||||
{
|
{
|
||||||
@ -195,7 +200,6 @@ namespace osu.Game.Screens.Play
|
|||||||
epilepsyWarning.DimmableBackground = b;
|
epilepsyWarning.DimmableBackground = b;
|
||||||
});
|
});
|
||||||
|
|
||||||
lowPassFilter.CutoffTo(500, 100, Easing.OutCubic);
|
|
||||||
Beatmap.Value.Track.AddAdjustment(AdjustableProperty.Volume, volumeAdjustment);
|
Beatmap.Value.Track.AddAdjustment(AdjustableProperty.Volume, volumeAdjustment);
|
||||||
|
|
||||||
content.ScaleTo(0.7f);
|
content.ScaleTo(0.7f);
|
||||||
@ -240,15 +244,15 @@ namespace osu.Game.Screens.Play
|
|||||||
public override bool OnExiting(IScreen next)
|
public override bool OnExiting(IScreen next)
|
||||||
{
|
{
|
||||||
cancelLoad();
|
cancelLoad();
|
||||||
|
contentOut();
|
||||||
|
|
||||||
content.ScaleTo(0.7f, 150, Easing.InQuint);
|
// Ensure the screen doesn't expire until all the outwards fade operations have completed.
|
||||||
this.FadeOut(150);
|
this.Delay(content_out_duration).FadeOut();
|
||||||
|
|
||||||
ApplyToBackground(b => b.IgnoreUserSettings.Value = true);
|
ApplyToBackground(b => b.IgnoreUserSettings.Value = true);
|
||||||
|
|
||||||
BackgroundBrightnessReduction = false;
|
BackgroundBrightnessReduction = false;
|
||||||
Beatmap.Value.Track.RemoveAdjustment(AdjustableProperty.Volume, volumeAdjustment);
|
Beatmap.Value.Track.RemoveAdjustment(AdjustableProperty.Volume, volumeAdjustment);
|
||||||
lowPassFilter.CutoffTo(AudioFilter.MAX_LOWPASS_CUTOFF, 100, Easing.InCubic);
|
|
||||||
|
|
||||||
return base.OnExiting(next);
|
return base.OnExiting(next);
|
||||||
}
|
}
|
||||||
@ -344,6 +348,7 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
content.FadeInFromZero(400);
|
content.FadeInFromZero(400);
|
||||||
content.ScaleTo(1, 650, Easing.OutQuint).Then().Schedule(prepareNewPlayer);
|
content.ScaleTo(1, 650, Easing.OutQuint).Then().Schedule(prepareNewPlayer);
|
||||||
|
lowPassFilter.CutoffTo(1000, 650, Easing.OutQuint);
|
||||||
|
|
||||||
ApplyToBackground(b => b?.FadeColour(Color4.White, 800, Easing.OutQuint));
|
ApplyToBackground(b => b?.FadeColour(Color4.White, 800, Easing.OutQuint));
|
||||||
}
|
}
|
||||||
@ -353,8 +358,9 @@ namespace osu.Game.Screens.Play
|
|||||||
// Ensure the logo is no longer tracking before we scale the content
|
// Ensure the logo is no longer tracking before we scale the content
|
||||||
content.StopTracking();
|
content.StopTracking();
|
||||||
|
|
||||||
content.ScaleTo(0.7f, 300, Easing.InQuint);
|
content.ScaleTo(0.7f, content_out_duration * 2, Easing.OutQuint);
|
||||||
content.FadeOut(250);
|
content.FadeOut(content_out_duration, Easing.OutQuint);
|
||||||
|
lowPassFilter.CutoffTo(AudioFilter.MAX_LOWPASS_CUTOFF, content_out_duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pushWhenLoaded()
|
private void pushWhenLoaded()
|
||||||
@ -381,7 +387,7 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
contentOut();
|
contentOut();
|
||||||
|
|
||||||
TransformSequence<PlayerLoader> pushSequence = this.Delay(250);
|
TransformSequence<PlayerLoader> pushSequence = this.Delay(content_out_duration);
|
||||||
|
|
||||||
// only show if the warning was created (i.e. the beatmap needs it)
|
// only show if the warning was created (i.e. the beatmap needs it)
|
||||||
// and this is not a restart of the map (the warning expires after first load).
|
// and this is not a restart of the map (the warning expires after first load).
|
||||||
@ -400,6 +406,11 @@ namespace osu.Game.Screens.Play
|
|||||||
})
|
})
|
||||||
.Delay(EpilepsyWarning.FADE_DURATION);
|
.Delay(EpilepsyWarning.FADE_DURATION);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// This goes hand-in-hand with the restoration of low pass filter in contentOut().
|
||||||
|
this.TransformBindableTo(volumeAdjustment, 0, content_out_duration, Easing.OutCubic);
|
||||||
|
}
|
||||||
|
|
||||||
pushSequence.Schedule(() =>
|
pushSequence.Schedule(() =>
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user