using System; using UnitTestSharp; namespace Susurrus.XAudio2.UnitTests { public class OutputMatrixTests : TestFixture { public const float Stale = 9f; public static float[] Stales(int length) { float[] returnMe = new float[length]; for (int i = 0; i < length; ++i) { returnMe[i] = Stale; } return returnMe; } public static bool LevelsAre(float[] actual, params float[] expected) { for (int i = 0; i < expected.Length; ++i) { if (Math.Abs(expected[i] - actual[i]) > 1e-6f) { return false; } } return true; } public class FillTests : TestFixture { public static readonly PanMatrix Distinct = new PanMatrix(0.1f, 0.2f, 0.3f, 0.4f); public static readonly PanMatrix MonoSplit = new PanMatrix(0.6f, 0.8f, 0f, 0f); public void MonoOnAStereoDevice_SendsEachSideItsGain() { float[] levels = Stales(2); OutputMatrix.Fill(levels, MonoSplit, sourceChannels: 1, deviceChannels: 2); CheckTrue(LevelsAre(levels, 0.6f, 0.8f)); } public void StereoOnAStereoDevice_HasARowForEachDeviceChannel() { float[] levels = Stales(4); OutputMatrix.Fill(levels, Distinct, sourceChannels: 2, deviceChannels: 2); CheckTrue(LevelsAre(levels, 0.1f, 0.3f, 0.2f, 0.4f)); } public void MonoOnASurroundDevice_PlaysOnlyOnTheFirstTwoChannels() { float[] levels = Stales(6); OutputMatrix.Fill(levels, MonoSplit, sourceChannels: 1, deviceChannels: 6); CheckTrue(LevelsAre(levels, 0.6f, 0.8f, 0f, 0f, 0f, 0f)); } public void StereoOnASurroundDevice_PlaysOnlyOnTheFirstTwoChannels() { float[] levels = Stales(12); OutputMatrix.Fill(levels, Distinct, sourceChannels: 2, deviceChannels: 6); CheckTrue(LevelsAre(levels, 0.1f, 0.3f, 0.2f, 0.4f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f)); } public void MonoOnAMonoDevice_KeepsItsPower() { float[] levels = Stales(1); OutputMatrix.Fill(levels, MonoSplit, sourceChannels: 1, deviceChannels: 1); CheckTrue(LevelsAre(levels, 1f)); } public void StereoOnAMonoDevice_SharesPowerBetweenTheChannels() { float[] levels = Stales(2); OutputMatrix.Fill(levels, new PanMatrix(1f, 0f, 0f, 1f), sourceChannels: 2, deviceChannels: 1); CheckTrue(LevelsAre(levels, 0.70710678f, 0.70710678f)); } public void StereoOnAMonoDevice_FollowsEachChannelsOwnGains() { float[] levels = Stales(2); OutputMatrix.Fill(levels, new PanMatrix(0.6f, 0.8f, 0f, 0f), sourceChannels: 2, deviceChannels: 1); CheckTrue(LevelsAre(levels, 0.70710678f, 0f)); } public void LeavesLevelsBeyondTheMatrixAlone() { float[] levels = Stales(4); OutputMatrix.Fill(levels, MonoSplit, sourceChannels: 1, deviceChannels: 2); CheckEqual(Stale, levels[2]); CheckEqual(Stale, levels[3]); } public void NullLevels_Throws() { CheckThrow(typeof(ArgumentNullException)); OutputMatrix.Fill(null, MonoSplit, sourceChannels: 1, deviceChannels: 2); } public void LevelsThatAreTooShort_Throw() { CheckThrow(typeof(ArgumentException)); OutputMatrix.Fill(new float[3], Distinct, sourceChannels: 2, deviceChannels: 2); } public void NoSourceChannels_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); OutputMatrix.Fill(new float[2], MonoSplit, sourceChannels: 0, deviceChannels: 2); } public void ThreeSourceChannels_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); OutputMatrix.Fill(new float[6], MonoSplit, sourceChannels: 3, deviceChannels: 2); } public void NoDeviceChannels_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); OutputMatrix.Fill(new float[2], MonoSplit, sourceChannels: 1, deviceChannels: 0); } } } }