80 lines
2.1 KiB
C#
80 lines
2.1 KiB
C#
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 };
|
|
}
|
|
}
|
|
}
|