// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. #nullable enable using osu.Framework.Audio.Mixing; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; using osu.Framework.Lists; namespace osu.Framework.Graphics.Audio { /// /// A wrapper to allow insertion in the draw hierarchy to allow transforms, lifetime management etc. /// public class DrawableSample : DrawableAudioWrapper, ISample { private readonly WeakList playingChannels = new WeakList(); private readonly ISample sample; /// /// Construct a new drawable sample instance. /// /// The audio sample to wrap. /// Whether the sample should be automatically disposed on drawable disposal/expiry. public DrawableSample(ISample sample, bool disposeSampleOnDisposal = true) : base(sample, disposeSampleOnDisposal) { this.sample = sample; PlaybackConcurrency.BindTo(sample.PlaybackConcurrency); } public SampleChannel Play() { var channel = GetChannel(); channel.Play(); return channel; } public SampleChannel GetChannel() { var channel = sample.GetChannel(); playingChannels.Add(channel); mixer?.Add(channel); return channel; } public double Length => sample.Length; public Bindable PlaybackConcurrency { get; } = new Bindable(Sample.DEFAULT_CONCURRENCY); private IAudioMixer? mixer; protected override void OnMixerChanged(ValueChangedEvent mixer) { base.OnMixerChanged(mixer); this.mixer = mixer.NewValue; foreach (var channel in playingChannels) { mixer.OldValue?.Remove(channel); mixer.NewValue?.Add(channel); } } } }