Table of Contents

Class AsioDevice

Namespace
NAudio.Wave
Assembly
NAudio.Asio.dll

High-level wrapper for an ASIO driver. Configurable into one of three mutually-exclusive modes: playback (InitPlayback(AsioPlaybackOptions)), recording (InitRecording(AsioRecordingOptions)), or duplex processing (InitDuplex(AsioDuplexOptions)).

public sealed class AsioDevice : IDisposable
Inheritance
AsioDevice
Implements
Inherited Members

Remarks

Use Open(string) or Open(int) to obtain an instance, then call exactly one Init* method before Start(). Once configured, the device cannot be reconfigured into a different mode — dispose and create a new instance instead.

For simple playback with the legacy IWavePlayer interface, AsioOut remains available and is implemented as a facade over this class.

Properties

Capabilities

Capabilities of the underlying ASIO driver (channel counts, buffer sizes, sample rate, channel info).

public AsioDriverCapability Capabilities { get; }

Property Value

AsioDriverCapability

CurrentSampleRate

Sample rate the driver is currently running at, in Hz, as reported by the driver.

public int CurrentSampleRate { get; }

Property Value

int

DriverName

Name of the driver this device was opened with.

public string DriverName { get; }

Property Value

string

FramesPerBuffer

Number of audio frames per ASIO buffer for the current configuration. Valid after any successful Init* call.

public int FramesPerBuffer { get; }

Property Value

int

InputLatencySamples

Input latency in frames, reported by the driver.

public int InputLatencySamples { get; }

Property Value

int

OutputLatencySamples

Output latency in frames, reported by the driver.

public int OutputLatencySamples { get; }

Property Value

int

State

Current lifecycle state of the device.

public AsioDeviceState State { get; }

Property Value

AsioDeviceState

Methods

Dispose()

Releases the underlying COM ASIO driver. After disposal the device cannot be reused.

public void Dispose()

Remarks

Dispose synchronises with any in-flight buffer-switch callback (Phase 0 finding F2): the disposing flag forces new callbacks to short-circuit, Stop() waits for the in-flight callback to return per the ASIO contract, and a final wait on the idle signal acts as a safety net for drivers that don't fully honour that contract.

~AsioDevice()

Safety net for callers that forget to Dispose(). Releases only the unmanaged COM driver — managed objects (callbackIdle, syncContext, etc.) may already have been finalized, so they are not touched. Always prefer explicit Dispose / using.

protected ~AsioDevice()

GetClockSources()

Enumerates the clock sources reported by the driver. Pro interfaces typically expose Internal alongside Word Clock, S/PDIF, AES/EBU, and ADAT sync inputs; consumer interfaces usually report a single Internal source. The entry whose IsCurrentSource is non-zero is the one the driver is currently locked to.

public AsioClockSource[] GetClockSources()

Returns

AsioClockSource[]

GetDriverNames()

Gets the names of all installed ASIO drivers on this system.

public static string[] GetDriverNames()

Returns

string[]

InitDuplex(AsioDuplexOptions)

Configures the device for duplex operation: a single user-supplied callback receives input and writes output in the same buffer-switch. Used for low-latency real-time DSP (passthrough monitoring, effects, level metering with playback).

public void InitDuplex(AsioDuplexOptions options)

Parameters

options AsioDuplexOptions

Remarks

InputChannels may be empty (or null), which configures an output-only processor session: the callback writes independent per-channel Span<T> output via GetOutput(int) with no capture side. This is the route to driving each output channel individually (e.g. routing different channel pairs to different speakers) without feeding a single interleaved IWaveProvider as InitPlayback(AsioPlaybackOptions) requires. OutputChannels and Processor are always required.

Exceptions

InvalidOperationException

Thrown if the device has already been configured.

ArgumentNullException

Thrown if options is null.

ArgumentException

Thrown if the output channel selection is invalid or empty, the (optional) input channel selection is invalid, or the processor is missing.

NotSupportedException

Thrown if the selected channels use a native format outside Int16LSB/Int24LSB/Int32LSB/Float32LSB, or mix formats.

InitPlayback(AsioPlaybackOptions)

Configures the device for playback-only operation.

public void InitPlayback(AsioPlaybackOptions options)

Parameters

options AsioPlaybackOptions

Exceptions

InvalidOperationException

Thrown if the device has already been configured.

ArgumentNullException

Thrown if options or its Source is null.

ArgumentException

Thrown if the channel count or indices are invalid.

NotSupportedException

Thrown if the source format cannot be converted to the driver's native output format.

InitRecording(AsioRecordingOptions)

Configures the device for recording-only operation.

public void InitRecording(AsioRecordingOptions options)

Parameters

options AsioRecordingOptions

Exceptions

InvalidOperationException

Thrown if the device has already been configured.

ArgumentNullException

Thrown if options is null.

ArgumentException

Thrown if the channel indices are invalid or empty.

NotSupportedException

Thrown if the selected channels use a native format outside Int16LSB/Int24LSB/Int32LSB/Float32LSB, or mix formats.

IsSampleRateSupported(int)

Returns true if the driver supports the given sample rate.

public bool IsSampleRateSupported(int sampleRate)

Parameters

sampleRate int

Returns

bool

Open(int)

Opens the installed ASIO driver at the given zero-based index in GetDriverNames().

public static AsioDevice Open(int driverIndex)

Parameters

driverIndex int

Returns

AsioDevice

Exceptions

ArgumentException

Thrown if no drivers are installed or the index is out of range.

Open(string)

Opens the ASIO driver with the given name.

public static AsioDevice Open(string driverName)

Parameters

driverName string

Returns

AsioDevice

Exceptions

ArgumentException

Thrown if no driver with that name is installed.

Reinitialize()

Re-applies the most recent Init* configuration. The canonical use is recovering from a DriverResetRequest: Stop() → Reinitialize() → Start().

public void Reinitialize()

Remarks

The driver buffers are released and re-created against the (possibly changed) driver state, but the underlying COM driver instance is reused — there is no need to re-open the device. For playback mode the source IWaveProvider resumes from its current position.

Exceptions

InvalidOperationException

Thrown if no prior Init* succeeded, or if called while the device is Running.

ObjectDisposedException

Thrown if the device has been disposed.

SetClockSource(int)

Selects the clock source the driver should lock to. Pass an Index reported by GetClockSources(). The driver may respond by raising a reset request, which surfaces via DriverResetRequest — handle it with the standard Stop → Reinitialize → Start recovery pattern.

public void SetClockSource(int reference)

Parameters

reference int

ShowControlPanel()

Shows the driver's native control panel.

public void ShowControlPanel()

Start()

Starts the driver. The device must have been configured via one of the Init* methods.

public void Start()

Stop()

Stops the driver. Safe to call from any thread other than the ASIO buffer-switch callback.

public void Stop()

Exceptions

InvalidOperationException

Thrown if called from inside an ASIO buffer-switch callback.

Events

AudioCaptured

Raised per ASIO buffer-switch while recording. Dispatched synchronously on the ASIO driver thread for latency reasons; user code inside the handler must not call Stop(), Dispose(), or Reinitialize().

public event EventHandler<AsioAudioCapturedEventArgs> AudioCaptured

Event Type

EventHandler<AsioAudioCapturedEventArgs>

Remarks

Only fires when the device was configured via InitRecording(AsioRecordingOptions). In duplex mode, use the AsioProcessCallback supplied in AsioDuplexOptions instead.

DriverResetRequest

Raised when the driver reports that its settings have changed (e.g. the user opened the control panel and altered the sample rate, or the driver requested a buffer-size change). The recommended response is Stop() → Reinitialize() → Start(). Dispatched on the captured SynchronizationContext.

public event EventHandler DriverResetRequest

Event Type

EventHandler

Remarks

Buffer-size-change requests (kAsioBufferSizeChange) are folded into this event, since the recovery path is identical: Reinitialize() rebuilds the buffers against the driver's current preferred size.

LatenciesChanged

Raised when the driver reports that its input/output latencies have changed (e.g. after a clock-source switch via SetClockSource(int)). No buffer rebuild is required — the typical response is to re-read InputLatencySamples / OutputLatencySamples and refresh any UI that displays them. Dispatched on the captured SynchronizationContext.

public event EventHandler LatenciesChanged

Event Type

EventHandler

ResyncOccurred

Raised when the driver reports a clock dropout / xrun via kAsioResyncRequest. Informational — no recovery action is required, but applications that surface dropout diagnostics can log it here. Dispatched on the captured SynchronizationContext.

public event EventHandler ResyncOccurred

Event Type

EventHandler

Stopped

Raised once, on the captured SynchronizationContext, when the device stops — whether because of a user Stop(), end-of-stream with auto-stop, or an unrecoverable driver fault. Always dispatched off the ASIO callback thread, so handlers may safely Dispose() the device.

public event EventHandler<StoppedEventArgs> Stopped

Event Type

EventHandler<StoppedEventArgs>