namespace FluidSim.Audio { internal class RingBuffer { private readonly float[] buffer; private volatile int readPos; private volatile int writePos; public RingBuffer(int capacity) { if ((capacity & (capacity - 1)) != 0) throw new ArgumentException("Capacity must be a power of two."); buffer = new float[capacity]; } public int Count => (writePos - readPos) & (buffer.Length - 1); public int Space => (readPos - writePos - 1) & (buffer.Length - 1); public int Write(float[] data, int count) { int space = Space; int toWrite = Math.Min(count, space); int mask = buffer.Length - 1; for (int i = 0; i < toWrite; i++) buffer[(writePos + i) & mask] = data[i]; writePos = (writePos + toWrite) & mask; return toWrite; } public int Read(float[] destination, int count) { int available = Count; int toRead = Math.Min(count, available); int mask = buffer.Length - 1; for (int i = 0; i < toRead; i++) destination[i] = buffer[(readPos + i) & mask]; readPos = (readPos + toRead) & mask; return toRead; } } }