88 lines
1.8 KiB
C#
88 lines
1.8 KiB
C#
using System;
|
|
|
|
namespace FractalVisualizer.Audio;
|
|
|
|
public sealed class AudioSampleRingBuffer
|
|
{
|
|
private readonly float[] _buffer;
|
|
private readonly object _sync = new();
|
|
|
|
private int _writeIndex;
|
|
private int _readIndex;
|
|
private int _count;
|
|
|
|
public AudioSampleRingBuffer(int capacity)
|
|
{
|
|
if (capacity <= 0)
|
|
{
|
|
throw new ArgumentOutOfRangeException(nameof(capacity));
|
|
}
|
|
|
|
_buffer = new float[capacity];
|
|
}
|
|
|
|
public int Capacity => _buffer.Length;
|
|
|
|
public int Count
|
|
{
|
|
get
|
|
{
|
|
lock (_sync)
|
|
{
|
|
return _count;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
lock (_sync)
|
|
{
|
|
_writeIndex = 0;
|
|
_readIndex = 0;
|
|
_count = 0;
|
|
}
|
|
}
|
|
|
|
public void Write(ReadOnlySpan<float> samples)
|
|
{
|
|
lock (_sync)
|
|
{
|
|
for (int i = 0; i < samples.Length; i++)
|
|
{
|
|
_buffer[_writeIndex] = samples[i];
|
|
_writeIndex = (_writeIndex + 1) % _buffer.Length;
|
|
|
|
if (_count == _buffer.Length)
|
|
{
|
|
_readIndex = (_readIndex + 1) % _buffer.Length;
|
|
}
|
|
else
|
|
{
|
|
_count++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool TryRead(Span<float> destination)
|
|
{
|
|
lock (_sync)
|
|
{
|
|
if (_count < destination.Length)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
for (int i = 0; i < destination.Length; i++)
|
|
{
|
|
destination[i] = _buffer[_readIndex];
|
|
_readIndex = (_readIndex + 1) % _buffer.Length;
|
|
}
|
|
|
|
_count -= destination.Length;
|
|
return true;
|
|
}
|
|
}
|
|
}
|