mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 12:57:36 +08:00
Add a low-pass filter effect to music when certain popup dialogs are shown
This commit is contained in:
parent
8bbd8cd948
commit
94e2dbd7e7
75
osu.Game/Audio/Effects/LowPassFilter.cs
Normal file
75
osu.Game/Audio/Effects/LowPassFilter.cs
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
using ManagedBass.Fx;
|
||||||
|
using osu.Framework.Audio.Mixing;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Audio.Effects
|
||||||
|
{
|
||||||
|
public class LowPassFilter : Component
|
||||||
|
{
|
||||||
|
private const float filter_cutoff_start = 2000;
|
||||||
|
private const float filter_cutoff_end = 150;
|
||||||
|
private const float filter_sweep_duration = 100;
|
||||||
|
private readonly Bindable<float> filterFreq = new Bindable<float>(filter_cutoff_start);
|
||||||
|
private readonly AudioMixer mixer;
|
||||||
|
private readonly BQFParameters filter;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A toggle-able low-pass filter with a subtle filter-sweep effect when toggled that can be attached to an <see cref="AudioMixer"/>.
|
||||||
|
/// </summary>
|
||||||
|
public LowPassFilter(AudioMixer mixer)
|
||||||
|
{
|
||||||
|
this.mixer = mixer;
|
||||||
|
filter = new BQFParameters
|
||||||
|
{
|
||||||
|
lFilter = BQFType.LowPass,
|
||||||
|
fCenter = filterFreq.Value
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Enable()
|
||||||
|
{
|
||||||
|
attachFilter();
|
||||||
|
this.TransformBindableTo(filterFreq, filter_cutoff_end, filter_sweep_duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Disable()
|
||||||
|
{
|
||||||
|
this.TransformBindableTo(filterFreq, filter_cutoff_start, filter_sweep_duration)
|
||||||
|
.OnComplete(_ => detatchFilter());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void attachFilter()
|
||||||
|
{
|
||||||
|
mixer.Effects.Add(filter);
|
||||||
|
filterFreq.ValueChanged += updateFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void detatchFilter()
|
||||||
|
{
|
||||||
|
filterFreq.ValueChanged -= updateFilter;
|
||||||
|
mixer.Effects.Remove(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateFilter(ValueChangedEvent<float> cutoff)
|
||||||
|
{
|
||||||
|
var filterIndex = mixer.Effects.IndexOf(filter);
|
||||||
|
if (filterIndex < 0) return;
|
||||||
|
|
||||||
|
var existingFilter = mixer.Effects[filterIndex] as BQFParameters;
|
||||||
|
if (existingFilter == null) return;
|
||||||
|
|
||||||
|
existingFilter.fCenter = cutoff.NewValue;
|
||||||
|
mixer.Effects[filterIndex] = existingFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool isDisposing)
|
||||||
|
{
|
||||||
|
base.Dispose(isDisposing);
|
||||||
|
detatchFilter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,10 @@ using osu.Game.Overlays.Dialog;
|
|||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Input.Bindings;
|
using osu.Game.Input.Bindings;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
|
using osu.Game.Audio.Effects;
|
||||||
|
|
||||||
namespace osu.Game.Overlays
|
namespace osu.Game.Overlays
|
||||||
{
|
{
|
||||||
@ -18,6 +21,8 @@ namespace osu.Game.Overlays
|
|||||||
protected override string PopInSampleName => "UI/dialog-pop-in";
|
protected override string PopInSampleName => "UI/dialog-pop-in";
|
||||||
protected override string PopOutSampleName => "UI/dialog-pop-out";
|
protected override string PopOutSampleName => "UI/dialog-pop-out";
|
||||||
|
|
||||||
|
private LowPassFilter filter;
|
||||||
|
|
||||||
public PopupDialog CurrentDialog { get; private set; }
|
public PopupDialog CurrentDialog { get; private set; }
|
||||||
|
|
||||||
public DialogOverlay()
|
public DialogOverlay()
|
||||||
@ -34,6 +39,12 @@ namespace osu.Game.Overlays
|
|||||||
Origin = Anchor.BottomCentre;
|
Origin = Anchor.BottomCentre;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(AudioManager audio)
|
||||||
|
{
|
||||||
|
AddInternal(filter = new LowPassFilter(audio.TrackMixer));
|
||||||
|
}
|
||||||
|
|
||||||
public void Push(PopupDialog dialog)
|
public void Push(PopupDialog dialog)
|
||||||
{
|
{
|
||||||
if (dialog == CurrentDialog || dialog.State.Value != Visibility.Visible) return;
|
if (dialog == CurrentDialog || dialog.State.Value != Visibility.Visible) return;
|
||||||
@ -71,12 +82,16 @@ namespace osu.Game.Overlays
|
|||||||
{
|
{
|
||||||
base.PopIn();
|
base.PopIn();
|
||||||
this.FadeIn(PopupDialog.ENTER_DURATION, Easing.OutQuint);
|
this.FadeIn(PopupDialog.ENTER_DURATION, Easing.OutQuint);
|
||||||
|
filter.Enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void PopOut()
|
protected override void PopOut()
|
||||||
{
|
{
|
||||||
base.PopOut();
|
base.PopOut();
|
||||||
|
|
||||||
|
if (IsLoaded)
|
||||||
|
filter.Disable();
|
||||||
|
|
||||||
if (CurrentDialog?.State.Value == Visibility.Visible)
|
if (CurrentDialog?.State.Value == Visibility.Visible)
|
||||||
{
|
{
|
||||||
CurrentDialog.Hide();
|
CurrentDialog.Hide();
|
||||||
|
Loading…
Reference in New Issue
Block a user