Add positional sound support for all rulesets

The SamplePlaybackBalance is calculated in a way that the balance
remains between -0.4 and 0.4.
Positional sound is not supported in osu!taiko.
This commit is contained in:
Fire937 2020-04-12 01:33:25 +02:00
parent c17e470266
commit f274ec297c
4 changed files with 28 additions and 18 deletions

View File

@ -70,6 +70,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
public float DisplayRadius => DrawSize.X / 2 * Scale.X * HitObject.Scale; public float DisplayRadius => DrawSize.X / 2 * Scale.X * HitObject.Scale;
protected override float SamplePlaybackBalance => 0.8f * HitObject.X - 0.4f;
protected DrawableCatchHitObject(CatchHitObject hitObject) protected DrawableCatchHitObject(CatchHitObject hitObject)
: base(hitObject) : base(hitObject)
{ {

View File

@ -5,8 +5,10 @@ using JetBrains.Annotations;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Rulesets.UI.Scrolling;
using osu.Game.Rulesets.Mania.UI;
namespace osu.Game.Rulesets.Mania.Objects.Drawables namespace osu.Game.Rulesets.Mania.Objects.Drawables
{ {
@ -24,6 +26,20 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
protected readonly IBindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>(); protected readonly IBindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>();
protected override float SamplePlaybackBalance
{
get
{
CompositeDrawable stage = this;
while (!(stage is Stage))
stage = stage.Parent;
var columnCount = ((Stage)stage).Columns.Count;
var columnIndex = HitObject.Column;
return 0.8f * columnIndex / (columnCount - 1) - 0.4f;
}
}
protected DrawableManiaHitObject(ManiaHitObject hitObject) protected DrawableManiaHitObject(ManiaHitObject hitObject)
: base(hitObject) : base(hitObject)
{ {

View File

@ -16,6 +16,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
// Must be set to update IsHovered as it's used in relax mdo to detect osu hit objects. // Must be set to update IsHovered as it's used in relax mdo to detect osu hit objects.
public override bool HandlePositionalInput => true; public override bool HandlePositionalInput => true;
protected override float SamplePlaybackBalance => (HitObject.X / 512f - 0.5f) * 0.8f;
protected DrawableOsuHitObject(OsuHitObject hitObject) protected DrawableOsuHitObject(OsuHitObject hitObject)
: base(hitObject) : base(hitObject)
{ {

View File

@ -33,11 +33,6 @@ 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;
@ -94,7 +89,9 @@ namespace osu.Game.Rulesets.Objects.Drawables
/// <summary> /// <summary>
/// The stereo balance of the samples played if <i>Positional hitsounds</i> is set. /// The stereo balance of the samples played if <i>Positional hitsounds</i> is set.
/// </summary> /// </summary>
protected virtual float PositionalSound => (Position.X / 512f - 0.5f) * 0.8f; protected virtual float SamplePlaybackBalance => 0;
private readonly BindableDouble samplePlaybackBalanceAdjustment = new BindableDouble();
private BindableList<HitSampleInfo> samplesBindable; private BindableList<HitSampleInfo> samplesBindable;
private Bindable<double> startTimeBindable; private Bindable<double> startTimeBindable;
@ -119,6 +116,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuConfigManager config) private void load(OsuConfigManager config)
{ {
userPositionalHitSounds = config.GetBindable<bool>(OsuSetting.PositionalHitSounds);
var judgement = HitObject.CreateJudgement(); var judgement = HitObject.CreateJudgement();
Result = CreateResult(judgement); Result = CreateResult(judgement);
@ -126,16 +124,6 @@ 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()
@ -179,7 +167,9 @@ namespace osu.Game.Rulesets.Objects.Drawables
+ $" This is an indication that {nameof(HitObject.ApplyDefaults)} has not been invoked on {this}."); + $" This is an indication that {nameof(HitObject.ApplyDefaults)} has not been invoked on {this}.");
} }
AddInternal(Samples = new SkinnableSound(samples.Select(s => HitObject.SampleControlPoint.ApplyTo(s)))); Samples = new SkinnableSound(samples.Select(s => HitObject.SampleControlPoint.ApplyTo(s)));
Samples.AddAdjustment(AdjustableProperty.Balance, samplePlaybackBalanceAdjustment);
AddInternal(Samples);
} }
private void onDefaultsApplied() => apply(HitObject); private void onDefaultsApplied() => apply(HitObject);
@ -378,7 +368,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
/// </summary> /// </summary>
public virtual void PlaySamples() public virtual void PlaySamples()
{ {
positionalSoundAdjustment.Value = PositionalSound; samplePlaybackBalanceAdjustment.Value = userPositionalHitSounds.Value ? SamplePlaybackBalance : 0;
Samples?.Play(); Samples?.Play();
} }