From 9889bfa0f3b8a50765ec611b2a54bae898e54dcb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 27 Jul 2020 16:15:49 +0900 Subject: [PATCH] Stop playing samples on pause, resume looping on unpause --- osu.Game/Skinning/SkinnableSound.cs | 60 ++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index 11d1011ed8..f54eff51c2 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -12,6 +12,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Transforms; using osu.Game.Audio; +using osu.Game.Screens.Play; namespace osu.Game.Skinning { @@ -22,9 +23,13 @@ public class SkinnableSound : SkinReloadableDrawable [Resolved] private ISampleStore samples { get; set; } + private bool requestedPlaying; + public override bool RemoveWhenNotAlive => false; public override bool RemoveCompletedTransforms => false; + private readonly AudioContainer samplesContainer; + public SkinnableSound(ISampleInfo hitSamples) : this(new[] { hitSamples }) { @@ -36,9 +41,28 @@ public SkinnableSound(IEnumerable hitSamples) InternalChild = samplesContainer = new AudioContainer(); } - private bool looping; + private Bindable gameplayClockPaused; - private readonly AudioContainer samplesContainer; + [BackgroundDependencyLoader(true)] + private void load(GameplayClock gameplayClock) + { + // if in a gameplay context, pause sample playback when gameplay is paused. + gameplayClockPaused = gameplayClock?.IsPaused.GetBoundCopy(); + gameplayClockPaused?.BindValueChanged(paused => + { + if (requestedPlaying) + { + if (paused.NewValue) + stop(); + // it's not easy to know if a sample has finished playing (to end). + // to keep things simple only resume playing looping samples. + else if (Looping) + play(); + } + }); + } + + private bool looping; public bool Looping { @@ -53,20 +77,36 @@ public bool Looping } } - public void Play() => samplesContainer.ForEach(c => + public void Play() { - if (c.AggregateVolume.Value > 0) - c.Play(); - }); + requestedPlaying = true; + play(); + } - public void Stop() => samplesContainer.ForEach(c => c.Stop()); + private void play() + { + samplesContainer.ForEach(c => + { + if (c.AggregateVolume.Value > 0) + c.Play(); + }); + } + + public void Stop() + { + requestedPlaying = false; + stop(); + } + + private void stop() + { + samplesContainer.ForEach(c => c.Stop()); + } public override bool IsPresent => Scheduler.HasPendingTasks; protected override void SkinChanged(ISkinSource skin, bool allowFallback) { - bool wasPlaying = samplesContainer.Any(s => s.Playing); - var channels = hitSamples.Select(s => { var ch = skin.GetSample(s); @@ -91,7 +131,7 @@ protected override void SkinChanged(ISkinSource skin, bool allowFallback) samplesContainer.ChildrenEnumerable = channels.Select(c => new DrawableSample(c)); - if (wasPlaying) + if (requestedPlaying) Play(); }