-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDelayLineTests.cs
More file actions
157 lines (136 loc) · 3.95 KB
/
Copy pathDelayLineTests.cs
File metadata and controls
157 lines (136 loc) · 3.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// Copyright (c) ktsu.dev
// All rights reserved.
// Licensed under the MIT license.
namespace ktsu.Containers.Tests;
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public class DelayLineTests
{
[TestMethod]
public void Constructor_NonPositiveCapacity_Throws()
{
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => new DelayLine(0));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => new DelayLine(-4));
}
[TestMethod]
public void Capacity_MatchesRequestedMaxDelay()
{
DelayLine line = new(100);
Assert.AreEqual(100, line.Capacity);
}
[TestMethod]
public void NewDelayLine_ReadsZero()
{
DelayLine line = new(8);
for (int delay = 0; delay <= line.Capacity; delay++)
{
Assert.AreEqual(0f, line.Read(delay));
}
}
[TestMethod]
public void Read_ReturnsSampleNSamplesInThePast()
{
DelayLine line = new(8);
line.Write(1f);
line.Write(2f);
line.Write(3f);
// Delay 0 == most recent, delay 2 == oldest of the three writes.
Assert.AreEqual(3f, line.Read(0));
Assert.AreEqual(2f, line.Read(1));
Assert.AreEqual(1f, line.Read(2));
}
[TestMethod]
public void Process_OutputsInputFromExactlyDelaySamplesEarlier()
{
DelayLine line = new(4);
// Process(x, 4) yields x[n - 4]: zero until the line has been primed with 4 samples.
Assert.AreEqual(0f, line.Process(10f, 4));
Assert.AreEqual(0f, line.Process(20f, 4));
Assert.AreEqual(0f, line.Process(30f, 4));
Assert.AreEqual(0f, line.Process(40f, 4));
Assert.AreEqual(10f, line.Process(50f, 4));
Assert.AreEqual(20f, line.Process(60f, 4));
}
[TestMethod]
public void Process_ZeroDelay_ReturnsInput()
{
DelayLine line = new(4);
Assert.AreEqual(7f, line.Process(7f, 0));
Assert.AreEqual(9f, line.Process(9f, 0));
}
[TestMethod]
public void Read_OutOfRange_Throws()
{
DelayLine line = new(8);
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => line.Read(-1));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => line.Read(9));
}
[TestMethod]
public void ReadInterpolated_HalfwayBetweenSamples_AveragesNeighbours()
{
DelayLine line = new(8);
line.Write(0f);
line.Write(10f);
// delay 0 -> 10 (newest), delay 1 -> 0 (older). 0.5 interpolates halfway.
Assert.AreEqual(5f, line.ReadInterpolated(0.5f), 1e-6f);
}
[TestMethod]
public void ReadInterpolated_IntegerDelay_MatchesRead()
{
DelayLine line = new(8);
line.Write(3f);
line.Write(7f);
line.Write(11f);
Assert.AreEqual(line.Read(1), line.ReadInterpolated(1f), 1e-6f);
}
[TestMethod]
public void ReadInterpolated_OutOfRange_Throws()
{
DelayLine line = new(8);
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => line.ReadInterpolated(-0.5f));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => line.ReadInterpolated(8.5f));
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => line.ReadInterpolated(float.NaN));
}
[TestMethod]
public void Write_FlushesDenormalsToZero()
{
DelayLine line = new(4);
float denormal = float.Epsilon; // smallest subnormal float, well below the threshold
line.Write(denormal);
Assert.AreEqual(0f, line.Read(0), "Denormal input must be flushed to zero.");
}
[TestMethod]
public void Write_KeepsNormalSmallValues()
{
DelayLine line = new(4);
const float audible = 1e-6f; // ~ -120 dBFS, a normal float that must be preserved
line.Write(audible);
Assert.AreEqual(audible, line.Read(0));
}
[TestMethod]
public void Clear_ZeroesAllSamples()
{
DelayLine line = new(4);
line.Write(1f);
line.Write(2f);
line.Clear();
for (int delay = 0; delay <= line.Capacity; delay++)
{
Assert.AreEqual(0f, line.Read(delay));
}
}
[TestMethod]
public void WrapAround_LongStreamReadsCorrectDelay()
{
DelayLine line = new(3);
float previous = 0f;
for (int i = 1; i <= 1000; i++)
{
// Process(i, 1) returns the value written on the previous call (i - 1), 0 on the first.
float output = line.Process(i, 1);
Assert.AreEqual(i - 1, output);
previous = output;
}
Assert.AreEqual(999f, previous);
}
}