71 lines
2.8 KiB
C#
71 lines
2.8 KiB
C#
using VoiceCat.Dsp;
|
|
using System.Text.Json;
|
|
|
|
namespace VoiceCat.Tests;
|
|
|
|
public sealed class DspTests
|
|
{
|
|
[Fact]
|
|
public void SuppressesNoiseAndPreservesUnsupportedSampleRates()
|
|
{
|
|
using var processor = new RnnoiseProcessor();
|
|
short[] pcm = new short[960];
|
|
uint random = 0x12345678;
|
|
double inputEnergy = 0, outputEnergy = 0;
|
|
for (int frame = 0; frame < 200; frame++)
|
|
{
|
|
FillNoise(pcm, ref random);
|
|
if (frame >= 60) foreach (short value in pcm) inputEnergy += (double)value * value;
|
|
processor.Process(pcm);
|
|
if (frame >= 60) foreach (short value in pcm) outputEnergy += (double)value * value;
|
|
}
|
|
Assert.True(Math.Sqrt(outputEnergy / inputEnergy) < 0.2);
|
|
using var fixture = JsonDocument.Parse(File.ReadAllText(Path.Combine(AppContext.BaseDirectory, "Fixtures", "cpp-noise.json")));
|
|
short[] expected = fixture.RootElement.GetProperty("samples").EnumerateArray().Select(value => value.GetInt16()).ToArray();
|
|
Assert.Equal(pcm.Length, expected.Length);
|
|
for (int i = 0; i < pcm.Length; i++) Assert.InRange(Math.Abs(pcm[i] - expected[i]), 0, 1);
|
|
FillNoise(pcm, ref random);
|
|
short[] original = (short[])pcm.Clone();
|
|
processor.Process(pcm, 16000);
|
|
Assert.Equal(original, pcm);
|
|
Assert.Throws<ArgumentException>(() => processor.Process(new short[481]));
|
|
processor.Dispose();
|
|
Assert.Throws<ObjectDisposedException>(() => processor.Process(pcm));
|
|
}
|
|
|
|
[Fact]
|
|
public void VadStartsClosedAndUsesMonotonicHangTime()
|
|
{
|
|
var clock = new ManualTimeProvider();
|
|
var processor = new EnergyVadProcessor(0.02f, TimeSpan.FromMilliseconds(300), clock);
|
|
Assert.False(processor.Process(new short[480]));
|
|
Assert.True(processor.Process(new short[] { 32767 }));
|
|
clock.Advance(299);
|
|
Assert.True(processor.Process([]));
|
|
clock.Advance(1);
|
|
Assert.False(processor.Process(new short[480]));
|
|
processor.Threshold = 0.5f;
|
|
Assert.False(processor.Process(new short[] { 1000 }));
|
|
Assert.Throws<ArgumentOutOfRangeException>(() => processor.Threshold = float.NaN);
|
|
}
|
|
|
|
internal static void FillNoise(Span<short> pcm, ref uint random)
|
|
{
|
|
for (int i = 0; i < pcm.Length; i++)
|
|
{
|
|
random ^= random << 13;
|
|
random ^= random >> 17;
|
|
random ^= random << 5;
|
|
pcm[i] = (short)((int)(random % 6001) - 3000);
|
|
}
|
|
}
|
|
|
|
private sealed class ManualTimeProvider : TimeProvider
|
|
{
|
|
private long timestamp;
|
|
public override long TimestampFrequency => 1000;
|
|
public override long GetTimestamp() => timestamp;
|
|
public void Advance(int milliseconds) => timestamp += milliseconds;
|
|
}
|
|
}
|