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
4using System;
5using NUnit.Framework;
6using osu.Framework.Allocation;
7using osu.Framework.Audio.Sample;
8using osu.Framework.Platform;
9using osu.Framework.Threading;
10
11namespace osu.Framework.Tests.Visual.Audio
12{
13 public class TestSceneSampleChannels : FrameworkTestScene
14 {
15 [Resolved]
16 private ISampleStore sampleStore { get; set; }
17
18 [Resolved]
19 private GameHost host { get; set; }
20
21 private Sample sample;
22
23 [BackgroundDependencyLoader]
24 private void load()
25 {
26 sample = sampleStore.Get("long.mp3");
27 }
28
29 [Test]
30 public void TestPlay()
31 {
32 AddStep("play sample", () => sample.Play());
33 }
34
35 [Test]
36 public void TestDoesNotRestart()
37 {
38 SampleChannel channel = null;
39
40 AddStep("play channel 1 sample", () => channel = sample.Play());
41 AddUntilStep("wait for channel 1 to end", () => !channel.Playing);
42 AddStep("play channel 1 again", () => channel.Play());
43
44 int audioFrames = 0;
45 AddStep("begin tracking audio frames", () =>
46 {
47 audioFrames = 0;
48
49 ScheduledDelegate del = null;
50 del = host.AudioThread.Scheduler.AddDelayed(() =>
51 {
52 // ReSharper disable once AccessToModifiedClosure
53 if (++audioFrames >= 2)
54 del?.Cancel();
55 }, 0, true);
56 });
57
58 AddUntilStep("wait for two audio frames", () => audioFrames >= 2);
59 AddAssert("channel 1 not playing", () => !channel.Playing);
60 }
61
62 [Test]
63 public void TestPlayLoopingSample()
64 {
65 SampleChannel channel = null;
66 AddStep("play sample", () =>
67 {
68 channel = sample.GetChannel();
69 channel.Looping = true;
70 channel.Play();
71 });
72
73 AddWaitStep("wait for loop", 20);
74 AddAssert("still playing", () => channel.Playing);
75 AddStep("stop playing", () => channel.Stop());
76 }
77
78 [Test]
79 public void TestTogglePlaying()
80 {
81 SampleChannel channel = null;
82 AddStep("play sample", () => channel = sample.Play());
83 AddStep("stop channel", () => channel.Stop());
84 AddStep("start channel", () => channel.Play());
85 AddAssert("still playing", () => channel.Playing);
86 }
87
88 [Test]
89 public void TestChannelWithNoReferenceDisposedAfterPlaybackFinished()
90 {
91 var channelRef = new WeakReference<SampleChannel>(null);
92 AddStep("play sample", () => channelRef.SetTarget(sample.Play()));
93 AddUntilStep("reference lost", () =>
94 {
95 GC.Collect();
96 GC.WaitForPendingFinalizers();
97 return !channelRef.TryGetTarget(out _);
98 });
99 }
100
101 [Test]
102 public void TestSampleWithNoReferenceDisposedAfterPlaybackFinished()
103 {
104 var sampleRef = new WeakReference<Sample>(null);
105
106 AddStep("play sample", () =>
107 {
108 var sample2 = sampleStore.Get("long.mp3");
109
110 sampleRef.SetTarget(sample2);
111 sample2.Play();
112 });
113
114 AddUntilStep("reference lost", () =>
115 {
116 GC.Collect();
117 GC.WaitForPendingFinalizers();
118 return !sampleRef.TryGetTarget(out _);
119 });
120 }
121 }
122}