mirror of
https://github.com/SK-la/osu-framework.git
synced 2026-03-13 11:20:31 +00:00
272 lines
7.1 KiB
C#
272 lines
7.1 KiB
C#
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
|
// See the LICENCE file in the repository root for full licence text.
|
|
|
|
#nullable disable
|
|
|
|
using System;
|
|
using System.Threading;
|
|
using ManagedBass;
|
|
using ManagedBass.Mix;
|
|
using NUnit.Framework;
|
|
using osu.Framework.Audio.Mixing.Bass;
|
|
using osu.Framework.Audio.Sample;
|
|
using osu.Framework.Audio.Track;
|
|
using osu.Framework.Extensions;
|
|
|
|
namespace osu.Framework.Tests.Audio
|
|
{
|
|
[TestFixture]
|
|
public class BassAudioMixerTest
|
|
{
|
|
private BassTestComponents bass;
|
|
private TrackBass track;
|
|
private SampleBass sample;
|
|
|
|
[SetUp]
|
|
public void Setup()
|
|
{
|
|
bass = new BassTestComponents();
|
|
track = bass.GetTrack();
|
|
sample = bass.GetSample();
|
|
|
|
bass.Update();
|
|
}
|
|
|
|
[TearDown]
|
|
public void Teardown()
|
|
{
|
|
bass?.Dispose();
|
|
}
|
|
|
|
[Test]
|
|
public void TestMixerInitialised()
|
|
{
|
|
Assert.That(bass.Mixer.Handle, Is.Not.Zero);
|
|
}
|
|
|
|
[Test]
|
|
public void TestAddedToGlobalMixerByDefault()
|
|
{
|
|
Assert.That(BassMix.ChannelGetMixer(getHandle()), Is.EqualTo(bass.Mixer.Handle));
|
|
}
|
|
|
|
[Test]
|
|
public void TestCannotBeRemovedFromGlobalMixer()
|
|
{
|
|
bass.Mixer.Remove(track);
|
|
bass.Update();
|
|
|
|
Assert.That(BassMix.ChannelGetMixer(getHandle()), Is.EqualTo(bass.Mixer.Handle));
|
|
}
|
|
|
|
[Test]
|
|
public void TestTrackIsMovedBetweenMixers()
|
|
{
|
|
var secondMixer = bass.CreateMixer();
|
|
|
|
secondMixer.Add(track);
|
|
bass.Update();
|
|
|
|
Assert.That(BassMix.ChannelGetMixer(getHandle()), Is.EqualTo(secondMixer.Handle));
|
|
|
|
bass.Mixer.Add(track);
|
|
bass.Update();
|
|
|
|
Assert.That(BassMix.ChannelGetMixer(getHandle()), Is.EqualTo(bass.Mixer.Handle));
|
|
}
|
|
|
|
[Test]
|
|
public void TestMovedToGlobalMixerWhenRemovedFromMixer()
|
|
{
|
|
var secondMixer = bass.CreateMixer();
|
|
|
|
secondMixer.Add(track);
|
|
secondMixer.Remove(track);
|
|
bass.Update();
|
|
|
|
Assert.That(BassMix.ChannelGetMixer(getHandle()), Is.EqualTo(bass.Mixer.Handle));
|
|
}
|
|
|
|
[Test]
|
|
public void TestVirtualTrackCanBeAddedAndRemoved()
|
|
{
|
|
var secondMixer = bass.CreateMixer();
|
|
var virtualTrack = bass.TrackStore.GetVirtual();
|
|
|
|
secondMixer.Add(virtualTrack);
|
|
bass.Update();
|
|
|
|
secondMixer.Remove(virtualTrack);
|
|
bass.Update();
|
|
}
|
|
|
|
[Test]
|
|
public void TestFreedChannelRemovedFromDefault()
|
|
{
|
|
track.Dispose();
|
|
bass.Update();
|
|
|
|
Assert.That(BassMix.ChannelGetMixer(getHandle()), Is.Zero);
|
|
}
|
|
|
|
[Test]
|
|
public void TestChannelMovedToGlobalMixerAfterDispose()
|
|
{
|
|
var secondMixer = bass.CreateMixer();
|
|
|
|
secondMixer.Add(track);
|
|
bass.Update();
|
|
|
|
secondMixer.Dispose();
|
|
bass.Update();
|
|
|
|
Assert.That(BassMix.ChannelGetMixer(getHandle()), Is.EqualTo(bass.Mixer.Handle));
|
|
}
|
|
|
|
[Test]
|
|
public void TestPlayPauseStop()
|
|
{
|
|
Assert.That(!track.IsRunning);
|
|
|
|
bass.RunOnAudioThread(() => track.Start());
|
|
bass.Update();
|
|
|
|
Assert.That(track.IsRunning);
|
|
|
|
bass.RunOnAudioThread(() => track.Stop());
|
|
bass.Update();
|
|
|
|
Assert.That(!track.IsRunning);
|
|
|
|
bass.RunOnAudioThread(() =>
|
|
{
|
|
track.Seek(track.Length - 1000);
|
|
track.Start();
|
|
});
|
|
|
|
bass.Update();
|
|
|
|
Assert.That(() =>
|
|
{
|
|
bass.Update();
|
|
return !track.IsRunning;
|
|
}, Is.True.After(3000));
|
|
}
|
|
|
|
[Test]
|
|
public void TestChannelRetainsPlayingStateWhenMovedBetweenMixers()
|
|
{
|
|
var secondMixer = bass.CreateMixer();
|
|
|
|
secondMixer.Add(track);
|
|
bass.Update();
|
|
|
|
Assert.That(!track.IsRunning);
|
|
|
|
bass.RunOnAudioThread(() => track.Start());
|
|
bass.Update();
|
|
|
|
Assert.That(track.IsRunning);
|
|
|
|
bass.Mixer.Add(track);
|
|
bass.Update();
|
|
|
|
Assert.That(track.IsRunning);
|
|
}
|
|
|
|
[Test]
|
|
public void TestTrackReferenceLostWhenTrackIsDisposed()
|
|
{
|
|
var trackReference = testDisposeTrackWithoutReference();
|
|
|
|
// The first update disposes the track, the second one removes the track from the TrackStore.
|
|
bass.Update();
|
|
bass.Update();
|
|
|
|
GC.Collect();
|
|
GC.WaitForPendingFinalizers();
|
|
|
|
Assert.That(!trackReference.TryGetTarget(out _));
|
|
}
|
|
|
|
private WeakReference<TrackBass> testDisposeTrackWithoutReference()
|
|
{
|
|
var weakRef = new WeakReference<TrackBass>(track);
|
|
|
|
track.Dispose();
|
|
track = null;
|
|
|
|
return weakRef;
|
|
}
|
|
|
|
[Test]
|
|
public void TestSampleChannelReferenceLostWhenSampleChannelIsDisposed()
|
|
{
|
|
var channelReference = runTest(sample);
|
|
|
|
// The first update disposes the track, the second one removes the track from the TrackStore.
|
|
bass.Update();
|
|
bass.Update();
|
|
|
|
GC.Collect();
|
|
GC.WaitForPendingFinalizers();
|
|
|
|
Assert.That(!channelReference.TryGetTarget(out _));
|
|
|
|
static WeakReference<SampleChannel> runTest(SampleBass sample)
|
|
{
|
|
var channel = sample.GetChannel();
|
|
|
|
channel.Play(); // Creates the handle/adds to mixer.
|
|
channel.Stop();
|
|
channel.Dispose();
|
|
|
|
return new WeakReference<SampleChannel>(channel);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestChannelDoesNotPlayIfReachedEndAndSeekedBackwards()
|
|
{
|
|
bass.RunOnAudioThread(() =>
|
|
{
|
|
track.Seek(track.Length - 1);
|
|
track.Start();
|
|
});
|
|
|
|
Thread.Sleep(50);
|
|
bass.Update();
|
|
|
|
Assert.That(bass.Mixer.ChannelIsActive(track), Is.Not.EqualTo(PlaybackState.Playing));
|
|
|
|
bass.RunOnAudioThread(() => track.SeekAsync(0).WaitSafely());
|
|
bass.Update();
|
|
|
|
Assert.That(bass.Mixer.ChannelIsActive(track), Is.Not.EqualTo(PlaybackState.Playing));
|
|
}
|
|
|
|
[Test]
|
|
public void TestChannelDoesNotPlayIfReachedEndAndMovedMixers()
|
|
{
|
|
bass.RunOnAudioThread(() =>
|
|
{
|
|
track.Seek(track.Length - 1);
|
|
track.Start();
|
|
});
|
|
|
|
Thread.Sleep(50);
|
|
bass.Update();
|
|
|
|
Assert.That(bass.Mixer.ChannelIsActive(track), Is.Not.EqualTo(PlaybackState.Playing));
|
|
|
|
var secondMixer = bass.CreateMixer();
|
|
secondMixer.Add(track);
|
|
bass.Update();
|
|
|
|
Assert.That(secondMixer.ChannelIsActive(track), Is.Not.EqualTo(PlaybackState.Playing));
|
|
}
|
|
|
|
private int getHandle() => ((IBassAudioChannel)track).Handle;
|
|
}
|
|
}
|