A game framework written with osu! in mind.
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
2// See the LICENCE file in the repository root for full licence text.
3
4#nullable enable
5
6using System;
7using osu.Framework.Audio;
8using osu.Framework.Audio.Mixing;
9using osu.Framework.Audio.Track;
10using osu.Framework.Bindables;
11
12namespace osu.Framework.Graphics.Audio
13{
14 /// <summary>
15 /// A <see cref="Track"/> wrapper to allow insertion in the draw hierarchy to allow transforms, lifetime management etc.
16 /// </summary>
17 public class DrawableTrack : DrawableAudioWrapper, ITrack
18 {
19 private readonly Track track;
20
21 /// <summary>
22 /// Construct a new drawable track instance.
23 /// </summary>
24 /// <param name="track">The audio track to wrap.</param>
25 /// <param name="disposeTrackOnDisposal">Whether the track should be automatically disposed on drawable disposal/expiry.</param>
26 public DrawableTrack(Track track, bool disposeTrackOnDisposal = true)
27 : base(track, disposeTrackOnDisposal)
28 {
29 this.track = track;
30 }
31
32 public event Action Completed
33 {
34 add => track.Completed += value;
35 remove => track.Completed -= value;
36 }
37
38 public event Action Failed
39 {
40 add => track.Failed += value;
41 remove => track.Failed -= value;
42 }
43
44 public bool Looping
45 {
46 get => track.Looping;
47 set => track.Looping = value;
48 }
49
50 public bool IsDummyDevice => track.IsDummyDevice;
51
52 public double RestartPoint
53 {
54 get => track.RestartPoint;
55 set => track.RestartPoint = value;
56 }
57
58 public double CurrentTime => track.CurrentTime;
59
60 public double Rate
61 {
62 get => track.Rate;
63 set => track.Rate = value;
64 }
65
66 public double Length
67 {
68 get => track.Length;
69 set => track.Length = value;
70 }
71
72 public int? Bitrate => track.Bitrate;
73
74 public bool IsRunning => track.IsRunning;
75
76 public bool IsReversed => track.IsReversed;
77
78 public bool HasCompleted => track.HasCompleted;
79
80 public void Reset()
81 {
82 Volume.Value = 1;
83
84 ResetSpeedAdjustments();
85
86 Stop();
87 Seek(0);
88 }
89
90 public void Restart() => track.Restart();
91
92 public void ResetSpeedAdjustments()
93 {
94 RemoveAllAdjustments(AdjustableProperty.Frequency);
95 RemoveAllAdjustments(AdjustableProperty.Tempo);
96 }
97
98 public bool Seek(double seek) => track.Seek(seek);
99
100 public void Start() => track.Start();
101
102 public void Stop() => track.Stop();
103
104 public ChannelAmplitudes CurrentAmplitudes => track.CurrentAmplitudes;
105
106 /// <summary>
107 /// Whether the underlying track is loaded.
108 /// </summary>
109 public bool TrackLoaded => track.IsLoaded;
110
111 protected override void OnMixerChanged(ValueChangedEvent<IAudioMixer> mixer)
112 {
113 base.OnMixerChanged(mixer);
114
115 mixer.OldValue?.Remove(track);
116 mixer.NewValue?.Add(track);
117 }
118 }
119}