public static void AddSilence(WAVParser input, TimeSpan duration) { var samplesCount = (int)input.GetFloorSamplesCount(duration); var buffer = new double[samplesCount]; foreach (var channel in input.Samples) { channel.AddRange(buffer); } }
public void ParseFiles( string filename, int channelCount, int sampleRate, int bitsPerSample, int sampleCount, string templateFilename, Tuple <int, double, bool> toneTest ) { WAVParser parser; using (var stream = File.Open(ResolveDataFile(filename), FileMode.Open)) { parser = new WAVParser(stream); Assert.Equal(channelCount, parser.ChannelCount); Assert.Equal((uint)sampleRate, parser.SampleRate); Assert.Equal(bitsPerSample, parser.BitsPerSample); Assert.NotNull(parser.ToString()); Assert.InRange(parser.StartDataSeek, 42, 1024); Assert.Equal(sampleCount, parser.SamplesCount); foreach (var list in parser.Samples) { Assert.Equal(sampleCount, list.Count); foreach (var sample in list) { Assert.InRange(sample, -1, 1); } } var durationDiff = parser.Duration - TimeSpan.FromSeconds(sampleCount * 1d / sampleRate); var durationDiffTicks = Math.Abs(durationDiff.Ticks); Assert.InRange(durationDiffTicks, 0, TimeSpan.TicksPerMillisecond - 1); Assert.Equal(TimeSpan.TicksPerSecond, parser.GetSpanForSamples(sampleRate).Ticks); Assert.Equal(sampleRate, parser.GetFloorSamplesCount(1)); } if (templateFilename != null) { Assert.NotEqual(filename, templateFilename); WAVParser parserTemplate; using (var stream = File.Open(ResolveDataFile(templateFilename), FileMode.Open)) { parserTemplate = new WAVParser(stream); } Assert.Equal(sampleCount, parserTemplate.SamplesCount); var minSampleRate = Math.Min(parserTemplate.BitsPerSample, parser.BitsPerSample); var minSampleRateC = 1 << (minSampleRate - 1); for (int channelId = 0; channelId < parser.Samples.Count; channelId++) { var sum = 0d; for (int i = 0; i < sampleCount; i++) { var expected = parserTemplate.Samples[channelId][i]; var real = parser.Samples[channelId][i]; var tE = (expected > 0) ? minSampleRateC - 1 : minSampleRateC; var tR = (real > 0) ? minSampleRateC - 1 : minSampleRateC; var expected1 = Math.Round(expected * tE) / tE; var real1 = Math.Round(real * tR) / tR; sum += Math.Pow(real1 - expected1, 2); } var rmse = Math.Sqrt(sum / sampleCount); Assert.InRange(rmse, 0, 0.006d); } } if (toneTest != null) { var(sinusoidHz, sinusoidValue, isSquare) = toneTest; var sinusoidHzR = Math.PI * 2 * sinusoidHz / parser.SampleRate; double minValue = double.NaN, maxValue = double.NaN; foreach (var channelSamples in parser.Samples) { var sum = 0d; var sumRMSE_Square = 0d; var sumRMSE_Sin = 0d; for (var i = 0; i < channelSamples.Count; i++) { var sample = channelSamples[i]; minValue = !double.IsNaN(minValue) ? Math.Min(sample, minValue) : sample; maxValue = !double.IsNaN(maxValue) ? Math.Max(sample, maxValue) : sample; sum += sample; if (isSquare) { sumRMSE_Square += Math.Pow(Math.Abs(sample) - sinusoidValue, 2); } else { var angleRad = i * sinusoidHzR; var expectedValue = Math.Sin(angleRad) * sinusoidValue; sumRMSE_Sin += Math.Pow(sample - expectedValue, 2); } } var averageValue = sum / channelSamples.Count; Assert.InRange(averageValue, 0, 0.000_02d); if (isSquare) { var rmse = Math.Sqrt(sumRMSE_Square / channelSamples.Count); Assert.InRange(rmse, 0, 0.000_1d); } else { var rmse = Math.Sqrt(sumRMSE_Sin / channelSamples.Count); Assert.InRange(rmse, 0, 0.000_1d); } } { var sinusoidValue_Min = Math.Min(sinusoidValue / 1.00037d, sinusoidValue); var sinusoidValue_Max = Math.Min(sinusoidValue * 1.00037d, 1); Assert.InRange(-minValue, sinusoidValue_Min, sinusoidValue_Max); Assert.InRange(maxValue, sinusoidValue_Min, sinusoidValue_Max); } } }