// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using osu.Framework.Bindables; namespace osu.Framework.Audio { /// /// An audio component which allows for basic bindable adjustments to be applied. /// public class AdjustableAudioComponent : AudioComponent, IAdjustableAudioComponent { private readonly AudioAdjustments adjustments = new AudioAdjustments(); /// /// The volume of this component. /// public BindableNumber Volume => adjustments.Volume; /// /// The playback balance of this sample (-1 .. 1 where 0 is centered) /// public BindableNumber Balance => adjustments.Balance; /// /// Rate at which the component is played back (affects pitch). 1 is 100% playback speed, or default frequency. /// public BindableNumber Frequency => adjustments.Frequency; /// /// Rate at which the component is played back (does not affect pitch). 1 is 100% playback speed. /// public BindableNumber Tempo => adjustments.Tempo; protected AdjustableAudioComponent() { AggregateVolume.ValueChanged += InvalidateState; AggregateBalance.ValueChanged += InvalidateState; AggregateFrequency.ValueChanged += InvalidateState; AggregateTempo.ValueChanged += InvalidateState; } public void AddAdjustment(AdjustableProperty type, IBindable adjustBindable) => adjustments.AddAdjustment(type, adjustBindable); public void RemoveAdjustment(AdjustableProperty type, IBindable adjustBindable) => adjustments.RemoveAdjustment(type, adjustBindable); public void RemoveAllAdjustments(AdjustableProperty type) => adjustments.RemoveAllAdjustments(type); private bool invalidationPending; internal void InvalidateState(ValueChangedEvent valueChangedEvent = null) { if (CanPerformInline) OnStateChanged(); else invalidationPending = true; } internal virtual void OnStateChanged() { } protected override void UpdateState() { base.UpdateState(); if (invalidationPending) { invalidationPending = false; OnStateChanged(); } } public void BindAdjustments(IAggregateAudioAdjustment component) => adjustments.BindAdjustments(component); public void UnbindAdjustments(IAggregateAudioAdjustment component) => adjustments.UnbindAdjustments(component); public IBindable AggregateVolume => adjustments.AggregateVolume; public IBindable AggregateBalance => adjustments.AggregateBalance; public IBindable AggregateFrequency => adjustments.AggregateFrequency; public IBindable AggregateTempo => adjustments.AggregateTempo; protected override void Dispose(bool disposing) { base.Dispose(disposing); AggregateVolume.UnbindAll(); AggregateBalance.UnbindAll(); AggregateFrequency.UnbindAll(); AggregateTempo.UnbindAll(); } } public enum AdjustableProperty { Volume, Balance, Frequency, Tempo } }