Table of Contents

Class AudioRingBuffer

Namespace
PluginUI.Dsp
Assembly
PluginUI.dll

Lock-free single-producer / single-consumer sample ring buffer that carries audio from the audio thread (Write(ReadOnlySpan<float>), wait-free, no allocation) to the UI thread (CopyLatest(Span<float>), Read(Span<float>)). Feeds the oscilloscope, the spectrum analyzer and custom visualizations.

public sealed class AudioRingBuffer
Inheritance
AudioRingBuffer
Inherited Members

Examples

var scopeBuffer = new AudioRingBuffer(8192);          // created once, shared with the editor

// Audio thread, in ProcessMain:
scopeBuffer.WriteMono(left[..sampleCount], right[..sampleCount]);

// Editor:
var scope = new Oscilloscope { Source = scopeBuffer };
var analyzer = new SpectrumAnalyzer { Source = scopeBuffer };

Remarks

When the UI does not keep up, the oldest samples are overwritten: visualizations always see the latest audio. Copies are done in at most two contiguous segments (block copies, vectorized by the runtime) rather than sample by sample with index masking.

Constructors

AudioRingBuffer(int)

Creates a buffer holding at least capacity samples (rounded up to a power of two).

public AudioRingBuffer(int capacity = 8192)

Parameters

capacity int

Properties

Available

Number of unread samples (for Read(Span<float>)).

public int Available { get; }

Property Value

int

Capacity

Capacity in samples.

public int Capacity { get; }

Property Value

int

TotalWritten

Total number of samples written since creation.

public long TotalWritten { get; }

Property Value

long

Methods

CopyLatest(Span<float>)

UI thread: copies the most recent destination.Length samples (oldest first). Returns the count copied.

public int CopyLatest(Span<float> destination)

Parameters

destination Span<float>

Returns

int

Remarks

Request at most half the capacity for tear-free copies: if the writer laps the oldest copied samples during the copy, the copy is retried (up to three times).

Read(Span<float>)

UI thread: reads the samples written since the previous Read(Span<float>) (up to the destination size).

public int Read(Span<float> destination)

Parameters

destination Span<float>

Returns

int

Write(ReadOnlySpan<float>)

Audio thread: appends samples (overwrites the oldest when full).

public void Write(ReadOnlySpan<float> samples)

Parameters

samples ReadOnlySpan<float>

WriteMono(ReadOnlySpan<float>, ReadOnlySpan<float>)

Audio thread: appends the average of two channels (stereo to mono display).

public void WriteMono(ReadOnlySpan<float> left, ReadOnlySpan<float> right)

Parameters

left ReadOnlySpan<float>
right ReadOnlySpan<float>