SSPC-Tester/Driver/PCIE8586/Pcie8586Probe/Acquisition/Recorder.cs

80 lines
2.1 KiB
C#
Raw Permalink Normal View History

using Pcie8586Probe.Models;
namespace Pcie8586Probe.Acquisition;
public sealed class Recorder
{
private readonly object _gate = new();
private readonly List<SampleBlock> _blocks = new();
private long _targetSamplesPerChannel;
private bool _armed;
private bool _completed;
private double _sampleRateHz;
public bool IsRecording
{
get
{
lock (_gate)
{
return _armed && !_completed;
}
}
}
public double Progress
{
get
{
lock (_gate)
{
if (_targetSamplesPerChannel <= 0)
{
return 0;
}
var count = _blocks.Sum(static block => (long)block.SamplesPerChannel);
return Math.Clamp((double)count / _targetSamplesPerChannel, 0, 1);
}
}
}
public void Start(TimeSpan duration, double sampleRateHz)
{
if (duration <= TimeSpan.Zero) throw new ArgumentOutOfRangeException(nameof(duration));
if (sampleRateHz <= 0) throw new ArgumentOutOfRangeException(nameof(sampleRateHz));
lock (_gate)
{
_blocks.Clear();
_sampleRateHz = sampleRateHz;
_targetSamplesPerChannel = Math.Max(1, (long)Math.Round(sampleRateHz * duration.TotalSeconds));
_armed = true;
_completed = false;
}
}
public SampleBlock? Add(SampleBlock block)
{
lock (_gate)
{
if (!_armed || _completed)
{
return null;
}
_blocks.Add(block);
var count = _blocks.Sum(static item => (long)item.SamplesPerChannel);
if (count < _targetSamplesPerChannel)
{
return null;
}
_completed = true;
_armed = false;
var merged = SampleBlockAssembler.Concat(_blocks);
return SampleBlockAssembler.Slice(merged, 0, (int)_targetSamplesPerChannel) with { SampleRateHz = _sampleRateHz };
}
}
}