using Amphora; using System; using System.Runtime.InteropServices; using UnitTestSharp; namespace Susurrus.XAudio2.UnitTests { public class XAudio2SoundTests : TestFixture { public static byte[] ReadBack(XAudio2Buffer buffer) { byte[] returnMe = new byte[buffer.AudioBytes]; Marshal.Copy(buffer.AudioData, returnMe, 0, returnMe.Length); return returnMe; } public class CtorTests : TestFixture { public void TakesItsShapeFromTheDecodedSound() { DecodedSound decoded = SilentSounds.Of( frameCount: 22050, channelCount: 2, sampleRate: 44100, format: SampleFormat.Float32); XAudio2Sound sound = new XAudio2Sound(decoded); CheckEqual(TimeSpan.FromSeconds(0.5), sound.Duration); CheckEqual(2, sound.ChannelCount); CheckEqual(44100, sound.SampleRate); CheckEqual(SampleFormat.Float32, sound.Format); CheckEqual(22050 * 2 * 4, sound.ByteCount); CheckEqual(22050, sound.FrameCount); } public void StartsUnheldAndUnpinned() { XAudio2Sound sound = new XAudio2Sound(SilentSounds.Short()); CheckEqual(0, sound.HoldCount); CheckFalse(sound.IsPinned); } public void Null_Throws() { CheckThrow(typeof(ArgumentNullException)); new XAudio2Sound(null); } } public class AcquireBufferTests : TestFixture { public void HoldsACopyOfTheSamples() { byte[] source = { 1, 2, 3, 4 }; XAudio2Sound sound = new XAudio2Sound(new DecodedSound( new ByteView(source), sampleRate: 8000, channelCount: 1, SampleFormat.Pcm16)); source[0] = 99; XAudio2Buffer buffer = sound.AcquireBuffer(); byte[] copy = ReadBack(buffer); sound.ReleaseBuffer(); CheckEqual(4, copy.Length); CheckEqual((byte)1, copy[0]); CheckEqual((byte)2, copy[1]); CheckEqual((byte)3, copy[2]); CheckEqual((byte)4, copy[3]); } public void CopiesOnlyTheViewedBytes() { byte[] source = { 9, 9, 5, 6, 9, 9 }; XAudio2Sound sound = new XAudio2Sound(new DecodedSound( new ByteView(source, startIndex: 2, endIndex: 4), sampleRate: 8000, channelCount: 1, SampleFormat.Pcm16)); XAudio2Buffer buffer = sound.AcquireBuffer(); byte[] copy = ReadBack(buffer); sound.ReleaseBuffer(); CheckEqual(2, copy.Length); CheckEqual((byte)5, copy[0]); CheckEqual((byte)6, copy[1]); } public void WithNoLoop_RepeatsNothing() { XAudio2Sound sound = new XAudio2Sound(SilentSounds.Short()); XAudio2Buffer buffer = sound.AcquireBuffer(); sound.ReleaseBuffer(); CheckEqual(0u, buffer.LoopCount); CheckEqual(0u, buffer.LoopLength); } public void AWholeLoop_RepeatsEveryFrameForever() { XAudio2Sound sound = new XAudio2Sound(SilentSounds.Short()); XAudio2Buffer buffer = sound.AcquireBuffer(Loop.Whole); sound.ReleaseBuffer(); CheckEqual(0u, buffer.LoopBegin); CheckEqual(480u, buffer.LoopLength); CheckEqual(XAudio2Buffer.LoopInfinite, buffer.LoopCount); } public void ARegion_RepeatsFromItsStartFrameToItsEndFrame() { XAudio2Sound sound = new XAudio2Sound(SilentSounds.Short()); Loop loop = new Loop(TimeSpan.FromMilliseconds(2), TimeSpan.FromMilliseconds(6)); XAudio2Buffer buffer = sound.AcquireBuffer(loop); sound.ReleaseBuffer(); CheckEqual(96u, buffer.LoopBegin); CheckEqual(192u, buffer.LoopLength); } public void ARegionWithNoEnd_RepeatsToTheLastFrame() { XAudio2Sound sound = new XAudio2Sound(SilentSounds.Short()); XAudio2Buffer buffer = sound.AcquireBuffer(new Loop(TimeSpan.FromMilliseconds(2))); sound.ReleaseBuffer(); CheckEqual(96u, buffer.LoopBegin); CheckEqual(384u, buffer.LoopLength); } public void AWholeLoop_CoversEveryFrameOfASoundWhoseDurationWasRoundedDown() { XAudio2Sound sound = new XAudio2Sound(SilentSounds.Of(frameCount: 1000, sampleRate: 44100)); XAudio2Buffer buffer = sound.AcquireBuffer(Loop.Whole); sound.ReleaseBuffer(); CheckEqual(1000u, buffer.LoopLength); } public void ALoopPastTheEndOfTheSound_Throws() { XAudio2Sound sound = new XAudio2Sound(SilentSounds.Short()); CheckThrow(typeof(ArgumentOutOfRangeException)); sound.AcquireBuffer(new Loop(TimeSpan.Zero, TimeSpan.FromSeconds(1))); } public void MarksTheEndOfTheStream() { XAudio2Sound sound = new XAudio2Sound(SilentSounds.Short()); CheckEqual(XAudio2Buffer.EndOfStream, sound.AcquireBuffer().Flags); sound.ReleaseBuffer(); } public void ASoundWithNoSamples_HasNoBytes() { XAudio2Sound sound = new XAudio2Sound(SilentSounds.Of(frameCount: 0)); XAudio2Buffer buffer = sound.AcquireBuffer(); sound.ReleaseBuffer(); CheckEqual((uint)0, buffer.AudioBytes); } public void PinsTheSamplesAndCountsTheHold() { XAudio2Sound sound = new XAudio2Sound(SilentSounds.Short()); sound.AcquireBuffer(); CheckEqual(1, sound.HoldCount); CheckTrue(sound.IsPinned); sound.ReleaseBuffer(); } public void ASecondHold_SharesTheAddress() { XAudio2Sound sound = new XAudio2Sound(SilentSounds.Short()); XAudio2Buffer first = sound.AcquireBuffer(); XAudio2Buffer second = sound.AcquireBuffer(); CheckEqual(2, sound.HoldCount); CheckTrue(first.AudioData == second.AudioData); sound.ReleaseBuffer(); sound.ReleaseBuffer(); } } public class ReleaseBufferTests : TestFixture { public void TheLastRelease_Unpins() { XAudio2Sound sound = new XAudio2Sound(SilentSounds.Short()); sound.AcquireBuffer(); sound.ReleaseBuffer(); CheckEqual(0, sound.HoldCount); CheckFalse(sound.IsPinned); } public void AnEarlierRelease_KeepsThePin() { XAudio2Sound sound = new XAudio2Sound(SilentSounds.Short()); sound.AcquireBuffer(); sound.AcquireBuffer(); sound.ReleaseBuffer(); CheckEqual(1, sound.HoldCount); CheckTrue(sound.IsPinned); sound.ReleaseBuffer(); } public void WithNoHold_Throws() { XAudio2Sound sound = new XAudio2Sound(SilentSounds.Short()); CheckThrow(typeof(InvalidOperationException)); sound.ReleaseBuffer(); } public void AfterTheLastRelease_AcquiringPinsAgain() { XAudio2Sound sound = new XAudio2Sound(SilentSounds.Short()); sound.AcquireBuffer(); sound.ReleaseBuffer(); sound.AcquireBuffer(); CheckTrue(sound.IsPinned); sound.ReleaseBuffer(); } } } }