Table of Contents

Class WasapiRecorder

Namespace
NAudio.Wave
Assembly
NAudio.Wasapi.dll

Modern WASAPI audio recorder with zero-copy buffer access, MMCSS thread priority, process-specific loopback capture, and IAsyncEnumerable support. Created via WasapiRecorderBuilder.

public class WasapiRecorder : IDisposable, IAsyncDisposable, IWaveLatency
Inheritance
WasapiRecorder
Implements
Inherited Members

Properties

AcousticEchoCancellationControl

Gets the acoustic echo cancellation (AEC) reference control for this capture stream, or null if the endpoint does not support controlling the AEC reference endpoint. Use it to change the render endpoint used as the echo cancellation reference stream while recording.

public AcousticEchoCancellationControl AcousticEchoCancellationControl { get; }

Property Value

AcousticEchoCancellationControl

Remarks

Only available after StartRecording() (or CaptureAsync(CancellationToken)) has initialized the audio client. Returns null before then. Requires Windows 11 build 22621 or later.

AverageLatency

The steady-state latency from a sample being queued for output to it being emitted by the audio hardware, assuming uninterrupted playback. This is a property of the buffer configuration and the driver, not of the current playback state.

public TimeSpan AverageLatency { get; }

Property Value

TimeSpan

Remarks

Uses LatencyMilliseconds once the audio client has been initialised (so it reflects the actual engine period — including any reduction from IAudioClient3 low-latency mode), falling back to the requested buffer length before then.

CaptureState

Current capture state.

public CaptureState CaptureState { get; }

Property Value

CaptureState

CurrentLatency

The time that has elapsed since the sample currently emerging from the hardware was queued for output. In steady state this is approximately equal to AverageLatency; it differs during start-up, after an underrun, or when the host is filling buffers irregularly. Implementations that cannot meaningfully distinguish from the average are permitted to return AverageLatency.

public TimeSpan CurrentLatency { get; }

Property Value

TimeSpan

Remarks

Derived from IAudioClient::GetCurrentPadding: on a capture stream this is the count of frames already captured but not yet read by the host. Falls back to AverageLatency when not recording or before the audio client is up.

DeviceFriendlyName

The friendly name of the device this recorder was created on (e.g. "Microphone (USB Audio Device)"), captured at construction. Useful for display and logging. Null when there is no fixed capture endpoint — see DeviceId.

public string DeviceFriendlyName { get; }

Property Value

string

DeviceId

The endpoint ID of the device this recorder was created on, captured at construction — the same string accepted by GetDevice(string). Persist it to reopen the same physical device later (for example after the endpoint is disabled and re-enabled).

public string DeviceId { get; }

Property Value

string

Remarks

Null when there is no fixed capture endpoint — that is, process-loopback capture (WithProcessLoopback(uint, ProcessLoopbackMode)) or when following the default device with automatic stream routing (WithDefaultDeviceStreamRouting()), where Windows may transparently reroute the stream at any time. To discover the current default endpoint in the routing case, resolve it yourself via GetDefaultAudioEndpoint(DataFlow, Role) and track changes with an MMDeviceNotificationClient.

LatencyMilliseconds

The effective latency in milliseconds in use after recording has been initialized. In standard mode this is the configured buffer length; in IAudioClient3 low-latency mode it is derived from the engine period the device granted, so it is typically much smaller. Zero before StartRecording() (or CaptureAsync(CancellationToken)) has initialized the audio client.

public int LatencyMilliseconds { get; }

Property Value

int

LowLatencyActive

Whether IAudioClient3 low-latency shared mode is actually in use after recording has been initialized. This is only ever true when WithLowLatency(bool) was requested and the device, share mode, and capture format allowed it. When low latency was requested but could not be honoured, capture silently falls back to standard shared mode and this remains false — check it to find out what you actually got.

public bool LowLatencyActive { get; }

Property Value

bool

LowLatencyUnavailableReason

When low latency was requested via WithLowLatency(bool) but could not be honoured, a short human-readable explanation of why (e.g. the requested capture format did not match the device mix format). Null when low latency is active or was never requested.

public string LowLatencyUnavailableReason { get; }

Property Value

string

WaveFormat

The capture format.

public WaveFormat WaveFormat { get; }

Property Value

WaveFormat

Methods

CaptureAsync(CancellationToken)

Capture audio as an async enumerable. Each yielded AudioBuffer contains a copy of the captured data (safe to store/process asynchronously). Use the DataAvailable event for zero-copy processing instead.

public IAsyncEnumerable<AudioBuffer> CaptureAsync(CancellationToken cancellationToken = default)

Parameters

cancellationToken CancellationToken

Returns

IAsyncEnumerable<AudioBuffer>

Dispose()

Dispose

public void Dispose()

DisposeAsync()

Async dispose.

public ValueTask DisposeAsync()

Returns

ValueTask

StartRecording()

Start recording.

public void StartRecording()

StopRecording()

Stop recording.

public void StopRecording()

Events

DataAvailable

Fired when captured audio data is available. The buffer span is only valid for the duration of the callback — copy it if you need to keep it. The handler also receives the packet's WASAPI device and QPC positions for timestamping.

public event CaptureDataAvailableHandler DataAvailable

Event Type

CaptureDataAvailableHandler

RecordingStopped

Fired when recording stops, either by request or due to an error.

public event EventHandler<StoppedEventArgs> RecordingStopped

Event Type

EventHandler<StoppedEventArgs>