Table of Contents

Class WasapiPlayer

Namespace
NAudio.Wave
Assembly
NAudio.Wasapi.dll

Modern WASAPI audio player with zero-copy buffer access, MMCSS thread priority, and IAudioClient3 low-latency support. Created via WasapiPlayerBuilder.

public class WasapiPlayer : IWavePlayer, IDisposable, IWavePosition, IWaveLatency, IAsyncDisposable
Inheritance
WasapiPlayer
Implements
Inherited Members
Extension Methods

Properties

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 the latency negotiated with the audio engine at Init(IWaveProvider) time. For the IAudioClient3 low-latency path this is the actual engine period selected by the driver, not the value originally requested.

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, which reports frames still in the endpoint buffer waiting to be rendered. Falls back to AverageLatency when not playing or when the audio client has not yet been initialised.

DeviceFriendlyName

The friendly name of the device this player was created on (e.g. "Speakers (Realtek High Definition Audio)"), captured at construction. Useful for display and logging. Null when following the default device with automatic stream routing — see DeviceId.

public string DeviceFriendlyName { get; }

Property Value

string

DeviceId

The endpoint ID of the device this player 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, such as an HDMI display returning from standby).

public string DeviceId { get; }

Property Value

string

Remarks

Null when following the default device with automatic stream routing (WithDefaultDeviceStreamRouting()): there is no fixed endpoint, and Windows may transparently reroute the stream at any time. To discover the current default endpoint in that mode, resolve it yourself via GetDefaultAudioEndpoint(DataFlow, Role) and track changes with an MMDeviceNotificationClient.

DeviceMixFormat

The device's preferred mix format (shared mode). This is always supported in shared mode.

public WaveFormat DeviceMixFormat { get; }

Property Value

WaveFormat

DeviceVolume

Device endpoint volume — controls the master volume for the audio device, affecting all applications playing through it. Includes per-channel levels, mute, volume step control, dB range information, and change notifications. Use with care: changes are system-wide and visible to the user. Available in both shared and exclusive modes.

public AudioEndpointVolume DeviceVolume { get; }

Property Value

AudioEndpointVolume

Exceptions

InvalidOperationException

Thrown when following the default device with automatic stream routing: there is no fixed endpoint, so endpoint-wide volume has no meaning. Use Volume/SessionVolume for per-application volume instead.

IsMuted

Gets or sets the session mute state. This is the mute toggle for your application in the Windows volume mixer. Delegates to SessionVolume.

public bool IsMuted { get; set; }

Property Value

bool

LatencyMilliseconds

The latency in milliseconds actually in use after Init(IWaveProvider). In low-latency mode this is derived from the engine period the device granted, so it may differ from the value requested via WithLatency(int).

public int LatencyMilliseconds { get; }

Property Value

int

LowLatencyActive

Whether IAudioClient3 low-latency shared mode is actually in use after Init(IWaveProvider). This is only ever true when WithLowLatency(bool) was requested and the device, share mode, and source format allowed it. When low latency was requested but could not be honoured, playback 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. a sample-rate mismatch that would require resampling). Null when low latency is active or was never requested.

public string LowLatencyUnavailableReason { get; }

Property Value

string

OutputWaveFormat

The output format being sent to the audio device.

public WaveFormat OutputWaveFormat { get; }

Property Value

WaveFormat

PlaybackState

Current playback state.

public PlaybackState PlaybackState { get; }

Property Value

PlaybackState

SessionVolume

Per-session volume and mute control. This is the volume slider shown for your application in the Windows volume mixer. Use this for simple volume/mute control that only affects your application.

public SimpleAudioVolume SessionVolume { get; }

Property Value

SimpleAudioVolume

Remarks

When following the default device with automatic stream routing (no fixed endpoint) this is obtained from the audio client itself, so it is only available after Init(IWaveProvider).

StreamVolume

Per-stream, per-channel volume control (0.0 to 1.0 per channel). Use this for balance, pan, or independent channel level adjustments. Only available in shared mode.

public AudioStreamVolume StreamVolume { get; }

Property Value

AudioStreamVolume

Exceptions

InvalidOperationException

Thrown when the player is using exclusive mode, where per-stream volume is not available.

Volume

Gets or sets the session volume (0.0 to 1.0). This controls your application's volume as shown in the Windows volume mixer, without affecting other applications. Delegates to SessionVolume.

public float Volume { get; set; }

Property Value

float

Methods

Dispose()

Stops playback (blocking) and releases all resources.

public void Dispose()

DisposeAsync()

Stops playback without blocking the calling thread, then releases all resources. Prefer this over Dispose() in async or UI contexts where blocking is undesirable.

public ValueTask DisposeAsync()

Returns

ValueTask

GetPlaybackCapability(WaveFormat)

Reports, without opening the stream, what Init(IWaveProvider) would do for a source of the given format: whether playback is possible at all, whether low latency would actually engage, the format the device would receive, and any latency-free conversions (bit depth / channels) that would be inserted. Call this before Init(IWaveProvider) to validate the chosen options.

public WasapiPlaybackCapability GetPlaybackCapability(WaveFormat sourceFormat)

Parameters

sourceFormat WaveFormat

The format of the source you intend to play.

Returns

WasapiPlaybackCapability

GetPosition()

Gets the current position in bytes from the wave output device. (This is not the same as the position within your reader stream.)

public long GetPosition()

Returns

long

GetSupportedExclusiveFormat(WaveFormat)

Finds a supported exclusive-mode format for this device, trying the preferred format first, then falling back through standard sample rates, bit depths, and multi-channel speaker configurations from the Windows Driver Kit (ksmedia.h). Use this to discover what format to provide to Init(IWaveProvider) when using exclusive mode.

public WaveFormatExtensible GetSupportedExclusiveFormat(WaveFormat preferredFormat)

Parameters

preferredFormat WaveFormat

The format you'd ideally like to use.

Returns

WaveFormatExtensible

A supported WaveFormatExtensible, or null if no supported format was found.

Init(IWaveProvider)

Initialize for playing the specified audio source.

public void Init(IWaveProvider source)

Parameters

source IWaveProvider

Remarks

The source's bit depth and channel count are adapted automatically (without resampling) to a format the device supports: in standard shared mode the audio engine does this for you; in exclusive and IAudioClient3 low-latency modes WasapiPlayer inserts the necessary conversion (PCM↔float, mono↔stereo). Sample rate is never changed — converting it would add latency — so exclusive mode throws if the device cannot accept the source's sample rate, and low latency silently falls back to standard shared mode (see LowLatencyActive and LowLatencyUnavailableReason). When the source already matches the device format, playback is zero-copy with no conversion inserted.

IsFormatSupported(WaveFormat)

Checks whether the specified format is supported by the device in the current share mode.

public bool IsFormatSupported(WaveFormat format)

Parameters

format WaveFormat

Returns

bool

IsFormatSupported(WaveFormat, out WaveFormat)

Checks whether the specified format is supported by the device in the current share mode.

public bool IsFormatSupported(WaveFormat format, out WaveFormat closestMatch)

Parameters

format WaveFormat

The format to check.

closestMatch WaveFormat

In shared mode, the closest supported format if the exact format isn't supported. Always null in exclusive mode.

Returns

bool

True if the format is supported.

Pause()

Pause playback without flushing buffers.

public void Pause()

Play()

Begin playback.

public void Play()

Stop()

Stop playback and flush buffers.

public void Stop()

Events

PlaybackStopped

Raised when playback stops, either because the source ended or an error occurred. If a SynchronizationContext was captured at construction, this event is raised on that context (e.g. the UI thread).

public event EventHandler<StoppedEventArgs> PlaybackStopped

Event Type

EventHandler<StoppedEventArgs>