Add stereo shifted hitsound playback support

There is now a setting in the general settings called "Positional
hitsounds". If the setting is enabled, the hitsounds playback will be
shifted according to their position on the beatmap.
This commit is contained in:
Fire937 2020-04-09 18:12:15 +02:00
parent e8f836a410
commit 2201e9b4ae
3 changed files with 32 additions and 1 deletions

View File

@ -88,6 +88,7 @@ namespace osu.Game.Configuration
Set(OsuSetting.ShowProgressGraph, true); Set(OsuSetting.ShowProgressGraph, true);
Set(OsuSetting.ShowHealthDisplayWhenCantFail, true); Set(OsuSetting.ShowHealthDisplayWhenCantFail, true);
Set(OsuSetting.KeyOverlay, false); Set(OsuSetting.KeyOverlay, false);
Set(OsuSetting.PositionalHitSounds, true);
Set(OsuSetting.ScoreMeter, ScoreMeterType.HitErrorBoth); Set(OsuSetting.ScoreMeter, ScoreMeterType.HitErrorBoth);
Set(OsuSetting.FloatingComments, false); Set(OsuSetting.FloatingComments, false);
@ -176,6 +177,7 @@ namespace osu.Game.Configuration
LightenDuringBreaks, LightenDuringBreaks,
ShowStoryboard, ShowStoryboard,
KeyOverlay, KeyOverlay,
PositionalHitSounds,
ScoreMeter, ScoreMeter,
FloatingComments, FloatingComments,
ShowInterface, ShowInterface,

View File

@ -57,6 +57,11 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
LabelText = "Always show key overlay", LabelText = "Always show key overlay",
Bindable = config.GetBindable<bool>(OsuSetting.KeyOverlay) Bindable = config.GetBindable<bool>(OsuSetting.KeyOverlay)
}, },
new SettingsCheckbox
{
LabelText = "Positional hitsounds",
Bindable = config.GetBindable<bool>(OsuSetting.PositionalHitSounds)
},
new SettingsEnumDropdown<ScoreMeterType> new SettingsEnumDropdown<ScoreMeterType>
{ {
LabelText = "Score meter type", LabelText = "Score meter type",

View File

@ -12,11 +12,13 @@ using osu.Framework.Extensions.TypeExtensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Primitives;
using osu.Framework.Threading; using osu.Framework.Threading;
using osu.Framework.Audio;
using osu.Game.Audio; using osu.Game.Audio;
using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Scoring;
using osu.Game.Skinning; using osu.Game.Skinning;
using osu.Game.Configuration;
using osuTK.Graphics; using osuTK.Graphics;
namespace osu.Game.Rulesets.Objects.Drawables namespace osu.Game.Rulesets.Objects.Drawables
@ -31,6 +33,11 @@ namespace osu.Game.Rulesets.Objects.Drawables
/// </summary> /// </summary>
public readonly Bindable<Color4> AccentColour = new Bindable<Color4>(Color4.Gray); public readonly Bindable<Color4> AccentColour = new Bindable<Color4>(Color4.Gray);
/// <summary>
/// The stereo balance of the samples if the <i>Positional hitsounds</i> setting is set.
/// </summary>
private readonly BindableDouble positionalSoundAdjustment = new BindableDouble();
protected SkinnableSound Samples { get; private set; } protected SkinnableSound Samples { get; private set; }
protected virtual IEnumerable<HitSampleInfo> GetSamples() => HitObject.Samples; protected virtual IEnumerable<HitSampleInfo> GetSamples() => HitObject.Samples;
@ -84,8 +91,14 @@ namespace osu.Game.Rulesets.Objects.Drawables
/// </summary> /// </summary>
public JudgementResult Result { get; private set; } public JudgementResult Result { get; private set; }
/// <summary>
/// The stereo balance of the samples played if <i>Positional hitsounds</i> is set.
/// </summary>
protected virtual float PositionalSound => (HitObject is IHasXPosition position) ? (position.X / 512f - 0.5f) * 0.8f : 0;
private BindableList<HitSampleInfo> samplesBindable; private BindableList<HitSampleInfo> samplesBindable;
private Bindable<double> startTimeBindable; private Bindable<double> startTimeBindable;
private Bindable<bool> userPositionalHitSounds;
private Bindable<int> comboIndexBindable; private Bindable<int> comboIndexBindable;
public override bool RemoveWhenNotAlive => false; public override bool RemoveWhenNotAlive => false;
@ -101,10 +114,11 @@ namespace osu.Game.Rulesets.Objects.Drawables
protected DrawableHitObject([NotNull] HitObject hitObject) protected DrawableHitObject([NotNull] HitObject hitObject)
{ {
HitObject = hitObject ?? throw new ArgumentNullException(nameof(hitObject)); HitObject = hitObject ?? throw new ArgumentNullException(nameof(hitObject));
positionalSoundAdjustment.Value = PositionalSound;
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load(OsuConfigManager config)
{ {
var judgement = HitObject.CreateJudgement(); var judgement = HitObject.CreateJudgement();
@ -113,6 +127,16 @@ namespace osu.Game.Rulesets.Objects.Drawables
throw new InvalidOperationException($"{GetType().ReadableName()} must provide a {nameof(JudgementResult)} through {nameof(CreateResult)}."); throw new InvalidOperationException($"{GetType().ReadableName()} must provide a {nameof(JudgementResult)} through {nameof(CreateResult)}.");
loadSamples(); loadSamples();
userPositionalHitSounds = config.GetBindable<bool>(OsuSetting.PositionalHitSounds);
userPositionalHitSounds.BindValueChanged(positional =>
{
if (positional.NewValue)
Samples?.AddAdjustment(AdjustableProperty.Balance, positionalSoundAdjustment);
else
Samples?.RemoveAdjustment(AdjustableProperty.Balance, positionalSoundAdjustment);
});
userPositionalHitSounds.TriggerChange();
} }
protected override void LoadComplete() protected override void LoadComplete()