// 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; using osu.Framework.Graphics; using osu.Framework.Graphics.Audio; using osu.Framework.Graphics.Transforms; namespace osu.Framework.Audio { public interface IAdjustableAudioComponent : IAggregateAudioAdjustment { /// /// The volume of this component. /// BindableNumber Volume { get; } /// /// The playback balance of this sample (-1 .. 1 where 0 is centered) /// BindableNumber Balance { get; } /// /// Rate at which the component is played back (affects pitch). 1 is 100% playback speed, or default frequency. /// BindableNumber Frequency { get; } /// /// Rate at which the component is played back (does not affect pitch). 1 is 100% playback speed. /// BindableNumber Tempo { get; } /// /// Bind all adjustments from an . /// /// The adjustment source. void BindAdjustments(IAggregateAudioAdjustment component); /// /// Unbind all adjustments from an . /// /// The adjustment source. void UnbindAdjustments(IAggregateAudioAdjustment component); /// /// Add a bindable adjustment source. /// /// The target type for this adjustment. /// The bindable adjustment. void AddAdjustment(AdjustableProperty type, IBindable adjustBindable); /// /// Remove a bindable adjustment source. /// /// The target type for this adjustment. /// The bindable adjustment. void RemoveAdjustment(AdjustableProperty type, IBindable adjustBindable); /// /// Removes all adjustments of a type. /// /// The target type to remove all adjustments of. void RemoveAllAdjustments(AdjustableProperty type); } public static class AdjustableAudioComponentExtensions { #region Easing /// /// Smoothly adjusts over time. /// /// A to which further transforms can be added. public static TransformSequence VolumeTo(this T component, double newVolume, double duration = 0, Easing easing = Easing.None) where T : class, IAdjustableAudioComponent, IDrawable => component.VolumeTo(newVolume, duration, new DefaultEasingFunction(easing)); /// /// Smoothly adjusts over time. /// /// A to which further transforms can be added. public static TransformSequence BalanceTo(this T component, double newBalance, double duration = 0, Easing easing = Easing.None) where T : class, IAdjustableAudioComponent, IDrawable => component.BalanceTo(newBalance, duration, new DefaultEasingFunction(easing)); /// /// Smoothly adjusts over time. /// /// A to which further transforms can be added. public static TransformSequence FrequencyTo(this T component, double newFrequency, double duration = 0, Easing easing = Easing.None) where T : class, IAdjustableAudioComponent, IDrawable => component.FrequencyTo(newFrequency, duration, new DefaultEasingFunction(easing)); /// /// Smoothly adjusts over time. /// /// A to which further transforms can be added. public static TransformSequence TempoTo(this T component, double newTempo, double duration = 0, Easing easing = Easing.None) where T : class, IAdjustableAudioComponent, IDrawable => component.TempoTo(newTempo, duration, new DefaultEasingFunction(easing)); /// /// Smoothly adjusts over time. /// /// A to which further transforms can be added. public static TransformSequence VolumeTo(this TransformSequence sequence, double newVolume, double duration = 0, Easing easing = Easing.None) where T : class, IAdjustableAudioComponent, IDrawable => sequence.VolumeTo(newVolume, duration, new DefaultEasingFunction(easing)); /// /// Smoothly adjusts over time. /// /// A to which further transforms can be added. public static TransformSequence BalanceTo(this TransformSequence sequence, double newBalance, double duration = 0, Easing easing = Easing.None) where T : class, IAdjustableAudioComponent, IDrawable => sequence.BalanceTo(newBalance, duration, new DefaultEasingFunction(easing)); /// /// Smoothly adjusts over time. /// /// A to which further transforms can be added. public static TransformSequence FrequencyTo(this TransformSequence sequence, double newFrequency, double duration = 0, Easing easing = Easing.None) where T : class, IAdjustableAudioComponent, IDrawable => sequence.FrequencyTo(newFrequency, duration, new DefaultEasingFunction(easing)); /// /// Smoothly adjusts over time. /// /// A to which further transforms can be added. public static TransformSequence TempoTo(this TransformSequence sequence, double newTempo, double duration = 0, Easing easing = Easing.None) where T : class, IAdjustableAudioComponent, IDrawable => sequence.TempoTo(newTempo, duration, new DefaultEasingFunction(easing)); #endregion #region Generic Easing /// /// Smoothly adjusts over time. /// /// A to which further transforms can be added. public static TransformSequence VolumeTo(this T component, double newVolume, double duration, TEasing easing) where T : class, IAdjustableAudioComponent, IDrawable where TEasing : IEasingFunction => component.TransformBindableTo(component.Volume, newVolume, duration, easing); /// /// Smoothly adjusts over time. /// /// A to which further transforms can be added. public static TransformSequence BalanceTo(this T component, double newBalance, double duration, TEasing easing) where T : class, IAdjustableAudioComponent, IDrawable where TEasing : IEasingFunction => component.TransformBindableTo(component.Balance, newBalance, duration, easing); /// /// Smoothly adjusts over time. /// /// A to which further transforms can be added. public static TransformSequence FrequencyTo(this T component, double newFrequency, double duration, TEasing easing) where T : class, IAdjustableAudioComponent, IDrawable where TEasing : IEasingFunction => component.TransformBindableTo(component.Frequency, newFrequency, duration, easing); /// /// Smoothly adjusts over time. /// /// A to which further transforms can be added. public static TransformSequence TempoTo(this T component, double newTempo, double duration, TEasing easing) where T : class, IAdjustableAudioComponent, IDrawable where TEasing : IEasingFunction => component.TransformBindableTo(component.Tempo, newTempo, duration, easing); /// /// Smoothly adjusts over time. /// /// A to which further transforms can be added. public static TransformSequence VolumeTo(this TransformSequence sequence, double newVolume, double duration, TEasing easing) where T : class, IAdjustableAudioComponent, IDrawable where TEasing : IEasingFunction => sequence.Append(o => o.TransformBindableTo(o.Volume, newVolume, duration, easing)); /// /// Smoothly adjusts over time. /// /// A to which further transforms can be added. public static TransformSequence BalanceTo(this TransformSequence sequence, double newBalance, double duration, TEasing easing) where T : class, IAdjustableAudioComponent, IDrawable where TEasing : IEasingFunction => sequence.Append(o => o.TransformBindableTo(o.Balance, newBalance, duration, easing)); /// /// Smoothly adjusts over time. /// /// A to which further transforms can be added. public static TransformSequence FrequencyTo(this TransformSequence sequence, double newFrequency, double duration, TEasing easing) where T : class, IAdjustableAudioComponent, IDrawable where TEasing : IEasingFunction => sequence.Append(o => o.TransformBindableTo(o.Frequency, newFrequency, duration, easing)); /// /// Smoothly adjusts over time. /// /// A to which further transforms can be added. public static TransformSequence TempoTo(this TransformSequence sequence, double newTempo, double duration, TEasing easing) where T : class, IAdjustableAudioComponent, IDrawable where TEasing : IEasingFunction => sequence.Append(o => o.TransformBindableTo(o.Tempo, newTempo, duration, easing)); #endregion } }