using System.Buffers.Binary; using System.IO; using System.Text.Json; using Pcie8586Probe.Models; namespace Pcie8586Probe.Acquisition; public static class WaveformWriter { public static async Task WriteAsync(SampleBlock block, string outputDirectory, string name, InputRange range, CancellationToken cancellationToken) { Directory.CreateDirectory(outputDirectory); var safeName = string.Join("_", name.Split(Path.GetInvalidFileNameChars(), StringSplitOptions.RemoveEmptyEntries)); if (string.IsNullOrWhiteSpace(safeName)) { safeName = "capture"; } var basePath = Path.Combine(outputDirectory, safeName); var binaryPath = basePath + ".bin"; var metadataPath = basePath + ".json"; await using (var stream = File.Create(binaryPath)) { var bytes = new byte[4]; for (var sample = 0; sample < block.SamplesPerChannel; sample++) { for (var channel = 0; channel < block.ChannelCount; channel++) { BinaryPrimitives.WriteSingleLittleEndian(bytes, (float)block.Channels[channel][sample]); await stream.WriteAsync(bytes, cancellationToken); } } } var duration = TimeSpan.FromSeconds(block.SamplesPerChannel / block.SampleRateHz); var metadata = new { channel_count = block.ChannelCount, sample_rate_hz = block.SampleRateHz, input_range = range == InputRange.PlusMinus5V ? "5V" : "1V", samples_per_channel = block.SamplesPerChannel, dtype = "float32", layout = "interleaved", unit = "volt", recorded_at = DateTimeOffset.Now.ToString("O"), duration_ms = duration.TotalMilliseconds }; var json = JsonSerializer.Serialize(metadata, new JsonSerializerOptions { WriteIndented = true }); await File.WriteAllTextAsync(metadataPath, json, cancellationToken); return new RecordingResult(block, basePath, binaryPath, metadataPath, duration); } }