Skip to content

Commit

Permalink
Downmix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
VoidXH committed Dec 21, 2023
1 parent fc4edf9 commit a26b2a7
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 19 deletions.
28 changes: 14 additions & 14 deletions Cavern/Utilities/WaveformUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public static void Delay(float[] signal, float samples, FFTCache cache) {
fft.InPlaceFFT(cache);
Delay(fft, samples);
fft.InPlaceIFFT(cache);
for (int i = 0; i < signal.Length; ++i) {
for (int i = 0; i < signal.Length; i++) {
signal[i] = fft[i].Real;
}
}
Expand All @@ -63,7 +63,7 @@ public static void Delay(float[] signal, float samples, FFTCache cache) {
/// </summary>
public static void Delay(Complex[] signal, float samples) {
float cycle = 2 * (float)Math.PI * samples / signal.Length;
for (int i = 1; i < signal.Length / 2; ++i) {
for (int i = 1; i < signal.Length / 2; i++) {
float phase = cycle * i;
signal[i].Rotate(-phase);
signal[^i].Rotate(phase);
Expand All @@ -75,12 +75,12 @@ public static void Delay(Complex[] signal, float samples) {
/// </summary>
/// <param name="source">Audio to downmix</param>
/// <param name="channels">Source channel count</param>
public static float[] Downmix(float[] source, int channels) {
public static float[] Downmix(this float[] source, int channels) {
int length = source.Length / channels;
float[] target = new float[length];
for (int sample = 0; sample < length; ++sample) {
for (int channel = 0; channel < channels; ++channel) {
target[sample] = source[channels * sample + channel];
for (int sample = 0; sample < length; sample++) {
for (int channel = 0; channel < channels; channel++) {
target[sample] += source[channels * sample + channel];
}
}
return target;
Expand All @@ -96,13 +96,13 @@ public static float[] Downmix(float[] source, int channels) {
public static void Downmix(float[] from, float[] to, int toChannels) {
int samplesPerChannel = to.Length / toChannels,
fromChannels = Listener.Channels.Length;
for (int channel = 0; channel < fromChannels; ++channel) {
for (int channel = 0; channel < fromChannels; channel++) {
if (toChannels > 4 || (Listener.Channels[channel].Y != 0 && !Listener.Channels[channel].LFE)) {
for (int sample = 0, overflow = channel % toChannels; sample < samplesPerChannel; ++sample) {
for (int sample = 0, overflow = channel % toChannels; sample < samplesPerChannel; sample++) {
to[sample * toChannels + overflow] += from[sample * fromChannels + channel];
}
} else {
for (int sample = 0; sample < samplesPerChannel; ++sample) {
for (int sample = 0; sample < samplesPerChannel; sample++) {
float copySample = from[sample * fromChannels + channel];
to[sample * toChannels] += copySample;
to[sample * toChannels + 1] += copySample;
Expand Down Expand Up @@ -173,7 +173,7 @@ public static unsafe void ExtractChannel(float[] from, long offset, float[] to,
/// <param name="value">Multiplier</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Gain(float[] target, float value) {
for (int i = 0; i < target.Length; ++i) {
for (int i = 0; i < target.Length; i++) {
target[i] *= value;
}
}
Expand Down Expand Up @@ -369,9 +369,9 @@ public static unsafe void Insert(float[] source, int sourceChannel, int sourceCh
public static void InterlacedToMultichannel(float[] source, float[][] target) {
int channels = target.Length,
perChannel = target[0].Length;
for (int channel = 0; channel < channels; ++channel) {
for (int channel = 0; channel < channels; channel++) {
float[] targetChannel = target[channel];
for (long sample = 0; sample < perChannel; ++sample) {
for (long sample = 0; sample < perChannel; sample++) {
targetChannel[sample] = source[channel + channels * sample];
}
}
Expand All @@ -381,7 +381,7 @@ public static void InterlacedToMultichannel(float[] source, float[][] target) {
/// Invert an audio signal.
/// </summary>
public static void Invert(float[] target) {
for (int i = 0; i < target.Length; ++i) {
for (int i = 0; i < target.Length; i++) {
target[i] = -target[i];
}
}
Expand Down Expand Up @@ -543,7 +543,7 @@ public static void MultichannelToInterlaced(float[][] source, long from, long to
/// <param name="destination">Track to subtract from</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Subtract(this float[] source, float[] destination) {
for (int i = 0; i < source.Length; ++i) {
for (int i = 0; i < source.Length; i++) {
destination[i] -= source[i];
}
}
Expand Down
15 changes: 10 additions & 5 deletions Tests/Test.Cavern/Consts/Consts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,29 @@ static class Consts {
/// <summary>
/// Some samples used where audio samples are needed.
/// </summary>
internal static readonly float[] samples = { .1f, .2f, .3f, .4f, .5f };
internal static readonly float[] samples = [.1f, .2f, .3f, .4f, .5f];

/// <summary>
/// Some other samples used where different audio signals are needed.
/// </summary>
internal static readonly float[] samples2 = { .6f, .7f, .8f, .9f, 1 };
internal static readonly float[] samples2 = [.6f, .7f, .8f, .9f, 1];

/// <summary>
/// A 4-sample interlaced stereo signal for stereo tests.
/// </summary>
internal static readonly float[] stereoSamples = [.1f, .1f, 0, .2f, .1f, .3f, .1f, .5f];

/// <summary>
/// The result of convolving <see cref="samples"/> with <see cref="samples2"/>.
/// </summary>
internal static readonly float[] convolved = { .06f, .19f, .4f, .7f, 1.1f, 1.14f, 1.06f, .85f, .5f, 0 };
internal static readonly float[] convolved = [.06f, .19f, .4f, .7f, 1.1f, 1.14f, 1.06f, .85f, .5f, 0];

/// <summary>
/// Some complex samples used where complex samples are needed.
/// </summary>
internal static readonly Complex[] complexSamples = {
internal static readonly Complex[] complexSamples = [
new Complex(.1f, .6f), new Complex(.2f, .7f), new Complex(.3f, .8f), new Complex(.4f, .9f), new Complex(.5f, 1)
};
];

/// <summary>
/// The two sample arrays as a stereo signal for multichannel tests.
Expand Down
26 changes: 26 additions & 0 deletions Tests/Test.Cavern/WaveformUtils_Tests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Cavern;
using Cavern.Channels;
using Cavern.Utilities;

namespace Test.Cavern {
Expand All @@ -7,6 +8,31 @@ namespace Test.Cavern {
/// </summary>
[TestClass]
public class WaveformUtils_Tests {
/// <summary>
/// Tests if <see cref="WaveformUtils.Downmix(float[], int)"/> works as intended.
/// </summary>
[TestMethod, Timeout(1000)]
public void Downmix() {
float[] downmix = Consts.stereoSamples.Downmix(2);
Assert.AreEqual(.2f, downmix[0]);
Assert.AreEqual(.2f, downmix[1]);
Assert.AreEqual(.4f, downmix[2]);
Assert.AreEqual(.6f, downmix[3]);
}

/// <summary>
/// Tests if <see cref="WaveformUtils.Downmix(float[], float[], int)"/> works for playing quadro on a 5.1 system.
/// It's called downmix as it's mostly downmixing, but actually mixes to a channel count without knowledge of their layout.
/// </summary>
[TestMethod, Timeout(1000)]
public void DownmixUp() {
Listener.ReplaceChannels(ChannelPrototype.ToLayout(ChannelPrototype.GetStandardMatrix(4)));
float[] result = new float[Consts.stereoSamples.Length / 4 * 6];
WaveformUtils.Downmix(Consts.stereoSamples, result, 6);
float[] expected = [.1f, .1f, 0, 0, 0, .2f, .1f, .3f, 0, 0, .1f, .5f];
CollectionAssert.AreEqual(expected, result);
}

/// <summary>
/// Tests if <see cref="WaveformUtils.GetPeak(float[])"/> works at any index.
/// </summary>
Expand Down

0 comments on commit a26b2a7

Please sign in to comment.