From 27af07b74be9a67b82bb8823d86f6044ef9ec044 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Jun 2023 16:17:45 +0900 Subject: [PATCH] Add basic implementation of argon osu!taiko hitsounds (volume / flourish / strong) --- .../Skinning/Argon/ArgonDrumSamplePlayer.cs | 70 +++++++++++++++++-- osu.Game/Audio/HitSampleInfo.cs | 6 ++ 2 files changed, 71 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonDrumSamplePlayer.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonDrumSamplePlayer.cs index 9ceea14802..b91e0f9901 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonDrumSamplePlayer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonDrumSamplePlayer.cs @@ -1,10 +1,13 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Collections.Generic; +using osu.Framework.Allocation; using osu.Game.Audio; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.UI; using osu.Game.Rulesets.UI; +using osu.Game.Skinning; namespace osu.Game.Rulesets.Taiko.Skinning.Argon { @@ -15,33 +18,90 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon public partial class ArgonDrumSampleTriggerSource : DrumSampleTriggerSource { + [Resolved] + private ISkinSource skinSource { get; set; } = null!; + public ArgonDrumSampleTriggerSource(HitObjectContainer hitObjectContainer, SampleBalance balance) : base(hitObjectContainer, balance) { + // TODO: pool flourish sample } public override void Play(HitType hitType) { - // let the magic begin... - TaikoHitObject? hitObject = GetMostValidObject() as TaikoHitObject; if (hitObject == null) return; - var baseSample = hitObject.CreateHitSampleInfo(hitType == HitType.Rim ? HitSampleInfo.HIT_CLAP : HitSampleInfo.HIT_NORMAL); + var baseSample = new VolumeAwareHitSampleInfo(hitObject.CreateHitSampleInfo(hitType == HitType.Rim ? HitSampleInfo.HIT_CLAP : HitSampleInfo.HIT_NORMAL)); + + // If the sample is provided by a legacy skin, we should not try and do anything special. + if (skinSource.FindProvider(s => s.GetSample(baseSample) != null) is LegacySkin) + { + base.Play(hitType); + return; + } + + // let the magic begin... if ((hitObject as TaikoStrongableHitObject)?.IsStrong == true || hitObject is StrongNestedHitObject) { PlaySamples(new ISampleInfo[] { - hitObject.CreateHitSampleInfo(hitType == HitType.Rim ? HitSampleInfo.HIT_WHISTLE : HitSampleInfo.HIT_FINISH), + new VolumeAwareHitSampleInfo(hitObject.CreateHitSampleInfo(hitType == HitType.Rim ? HitSampleInfo.HIT_CLAP : HitSampleInfo.HIT_NORMAL), true), + // TODO: flourish should only play every time_between_flourishes. + new VolumeAwareHitSampleInfo(hitObject.CreateHitSampleInfo(hitType == HitType.Rim ? HitSampleInfo.HIT_FLOURISH : string.Empty), true), baseSample }); } else { - PlaySamples(new ISampleInfo[] { baseSample }); + PlaySamples(new ISampleInfo[] { new VolumeAwareHitSampleInfo(baseSample) }); + } + } + + private class VolumeAwareHitSampleInfo : HitSampleInfo + { + public const int SAMPLE_VOLUME_THRESHOLD_HARD = 90; + public const int SAMPLE_VOLUME_THRESHOLD_MEDIUM = 60; + + public VolumeAwareHitSampleInfo(HitSampleInfo sampleInfo, bool isStrong = false) + : base(sampleInfo.Name, isStrong ? BANK_STRONG : getBank(sampleInfo.Bank, sampleInfo.Name, sampleInfo.Volume), sampleInfo.Suffix, sampleInfo.Volume) + { + } + + public override IEnumerable LookupNames + { + get + { + foreach (string name in base.LookupNames) + yield return name.Insert(name.LastIndexOf('/') + 1, "Argon/taiko-"); + } + } + + private static string getBank(string originalBank, string sampleName, int volume) + { + // So basically we're overwriting mapper's bank intentions here. + // The rationale is that most taiko beatmaps only use a single bank, but regularly adjust volume. + + switch (sampleName) + { + case HIT_NORMAL: + case HIT_CLAP: + { + if (volume >= SAMPLE_VOLUME_THRESHOLD_HARD) + return BANK_DRUM; + + if (volume >= SAMPLE_VOLUME_THRESHOLD_MEDIUM) + return BANK_NORMAL; + + return BANK_SOFT; + } + + default: + return originalBank; + } } } } diff --git a/osu.Game/Audio/HitSampleInfo.cs b/osu.Game/Audio/HitSampleInfo.cs index 9573a9a4aa..24cb1730bf 100644 --- a/osu.Game/Audio/HitSampleInfo.cs +++ b/osu.Game/Audio/HitSampleInfo.cs @@ -24,6 +24,12 @@ namespace osu.Game.Audio public const string BANK_SOFT = @"soft"; public const string BANK_DRUM = @"drum"; + // new sample used exclusively by taiko for now. + public const string HIT_FLOURISH = "hitflourish"; + + // new bank used exclusively by taiko for now. + public const string BANK_STRONG = @"strong"; + /// /// All valid sample addition constants. ///