Skip to content

Add support for LayeredHitSounds skin option#8683

Closed
Fire937 wants to merge 20 commits intoppy:masterfrom
Fire937:audio-rework-mania
Closed

Add support for LayeredHitSounds skin option#8683
Fire937 wants to merge 20 commits intoppy:masterfrom
Fire937:audio-rework-mania

Conversation

@Fire937
Copy link
Copy Markdown
Contributor

@Fire937 Fire937 commented Apr 8, 2020

Closes #8595

The current behaviour of osu!lazer is to add the hitnormal sample on top of the other samples for every single skin/beatmap/ruleset/hitobject, even in osu!mania, that is what causes the issue. Moreover osu!stable uses a LayeredHitSounds skin property that tells osu! whether it should add the hitnormal sample artificially or not based on the skin used (defaults to yes). LayeredHitSounds is also ignored when in osu!mania mode: osu!stable never adds the hitnormal sample artificially in osu!mania mode.

Currently the LayeredHitSounds property is included in LegacySkinConfiguration, however i am not sure about whether it belongs here or not. Maybe it should be moved to SkinInfo.
A ruleset can override the value of AllowsLayeredHitSounds in its ConvertHitObjectParser to disable the LayeredHitSounds property.

Fire937 added 10 commits April 6, 2020 18:04
The 5th argument of a timing point was not read properly. When equal to
0 the sample used should be osu!'s default hitsound. This commit
resolves this problem by adding an 'IsCustom' attribute to
HitSampleInfo.
As suggested by @bdach it makes much more sense to test the IsCustom
attribute to LegacySkin, that way SkinnableSound doesn't need to know
how the skin is supposed to behave.
The LayeredHitSounds option if set to 1 will force hitnormal to be
played along all the other hitsounds on each hitobject.

This option is disabled in osu:mania. In order to implement this
behaviour, an AllowsLayeredHitSounds attribute was added to the
ConvertHitObjectParser so that it knows if it has to artificially add
the hitnormal sample or not. LegacySkin can then verify if a hitsample
was artificially added thanks to HitSampleInfo's IsLayered attribute. It
can then decide to return the hitsample or not based on the value of
LayeredHitSounds.
…rk-mania

These two branches are tightly related for the most part because of the
changes to LegacySkin:GetSample.
LayeredHitSounds was previously in SkinInfo but that caused some issues
so it was moved to LegacySkinConfiguration.
Comment thread osu.Game/Skinning/LegacySkinConfiguration.cs Outdated
Comment thread osu.Game/Skinning/LegacySkin.cs Outdated
Comment thread osu.Game/Skinning/LegacySkin.cs Outdated
Comment thread osu.Game/Audio/HitSampleInfo.cs Outdated
Comment thread osu.Game/Skinning/LegacySkin.cs Outdated
Fire937 added 2 commits April 8, 2020 19:47
The use of a LayeredHitSounds property in Configuration was redundant.
The value of the LayeredHitSounds property could already be retrieved
from SkinConfiguration:ConfigDictionary.
The LayeredHitSounds property can now be accessed via the LegacySetting
enum rather than by string.
Copy link
Copy Markdown
Collaborator

@bdach bdach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really dislike how complicated LegacySkin.GetSample() is starting to be. I'd say it needs unit tests at the least, and a refactoring on top to decrease complexity if possible.

Comment thread osu.Game/Audio/HitSampleInfo.cs Outdated
Comment thread osu.Game/Skinning/LegacySkin.cs Outdated
Comment thread osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs Outdated
Comment thread osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitObjectParser.cs Outdated
}
};
CustomSampleBank = bankInfo.CustomSampleBank,
IsLayered = !type.HasFlag(LegacyHitSoundType.Normal)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this is backwards. Shouldn't this just use AllowsLayeredHitSounds? If both the flag is set and AllowsLayeredHitSounds is true, won't this wrongly consider the sample non-layered?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The thing is that the beatmap could actually explicitly indicate that the sample to be played (among others) should be hitnormal. In this case, whether AllowLayeredHitSounds is true or false should not affect the fact that the sample is not layered. That means it should always be played even in osu!mania. That's why this problem doesn't appear in other beatmap as they use hitnormal as opposed to this map that uses hitfinish and the others but not hitnormal.
I'm actually concerned about the naming of this flag, maybe IsForced would make more sense?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With application of the above comments, the outer condition can once again be removed and this can remain here.

Fire937 added 6 commits April 9, 2020 03:20
This test makes sure the layered hitsounds are handled properly by
LegacySkin:GetSample.
- If the LayeredHitSounds skin property is set to true, the sample
  should be played whether it is layered or not.
- If the LayeredHitSounds skin property is set to false, the sample
  should be played only if it is not layered.
Makes sure that LegacySkin.GetSample() returns the right samples
according to the IsCustom flag.
Comment on lines +122 to +123
case LegacySkinConfiguration.LegacySetting legacySetting when legacySetting == LegacySkinConfiguration.LegacySetting.Version:
return SkinUtils.As<TValue>(new Bindable<decimal>(Configuration.LegacyVersion ?? LegacySkinConfiguration.LATEST_VERSION));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is less readable than the original, and there may be even more legacy settings. please revert.

/// <summary>
/// Whether the sample is custom or if it uses osu!'s default hitsounds.
/// </summary>
public bool IsCustom { get; set; }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not exist. Please update this branch using the changes made in #8756

Comment on lines +174 to +176
// 0 means osu!'s default hitsounds
baseInfo.IsCustom = CustomSampleBank != 0;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, can be removed


protected bool FirstObject { get; private set; } = true;

protected bool AllowLayeredHitSounds { get; set; } = true;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This cannot exist in the parser - it should only exist within the legacy skin itself.

The mania override can be done inside LegacyManiaSkinTransformer.

That is to say, layered hitsounds should always be added.

/// True if the sample is a <c>hitnormal</c> sample added artificially due to the skin having
/// the <see cref="osu.Game.Skinning.LegacySkinConfiguration.LegacySetting.LayeredHitSounds"/> option set.
/// </summary>
public bool IsLayered { get; set; }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This must only exist within ConvertHitObjectParser.LegacyHitSampleInfo.

}
};
CustomSampleBank = bankInfo.CustomSampleBank,
IsLayered = !type.HasFlag(LegacyHitSoundType.Normal)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With application of the above comments, the outer condition can once again be removed and this can remain here.

public ConvertHitObjectParser(double offset, int formatVersion)
: base(offset, formatVersion)
{
AllowLayeredHitSounds = false;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See other comments.

namespace osu.Game.Tests.Skins
{
[HeadlessTest]
public class TestSceneLegacySkin : OsuTestScene
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This testing is inadequate because it doesn't test the result of gameplay loading. You want to add a test to TestSceneHitObjectSamples.

I'm fairly certain the implementation in this PR (inside LegacySkin) will fail, since SkinnableSound will fall back to the default lazer sample store if null is returned.

foreach (var lookup in sampleInfo.LookupNames)
var hsi = sampleInfo as HitSampleInfo;

if (hsi?.IsLayered == true && GetConfig<LegacySkinConfiguration.LegacySetting, bool>(LegacySkinConfiguration.LegacySetting.LayeredHitSounds)?.Value == false)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't being read from the skin configuration. You need to add a value to the LegacySetting switch above.

@pull-request-size pull-request-size Bot added size/L and removed size/M labels Apr 17, 2020
@peppy
Copy link
Copy Markdown
Member

peppy commented Jun 3, 2020

@Fire937 just looping back – are you intending to apply the remaining review?

@Fire937
Copy link
Copy Markdown
Contributor Author

Fire937 commented Jun 5, 2020

@peppy yes I will try and commit in not too long.

@bdach
Copy link
Copy Markdown
Collaborator

bdach commented Jun 18, 2020

Seeing that there stlll has been no changes here in a while, I would be looking to supersede this PR over the coming days. I don't usually do that but this one would take too much work to fix up - I would basically have to revert all of the changes here, and even then there are major issues left unaddressed (such as how to make the sample fallback logic stick to a silent sample if layered hit sounds are to be disabled).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

skin hitsounds overlap beatmap hitsounds

5 participants