Class AsioDevice
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
CurrentSampleRate
Sample rate the driver is currently running at, in Hz, as reported by the driver.
public int CurrentSampleRate { get; }
Property Value
DriverName
Name of the driver this device was opened with.
public string DriverName { get; }
Property Value
FramesPerBuffer
Number of audio frames per ASIO buffer for the current configuration. Valid after any successful Init* call.
public int FramesPerBuffer { get; }
Property Value
InputLatencySamples
Input latency in frames, reported by the driver.
public int InputLatencySamples { get; }
Property Value
OutputLatencySamples
Output latency in frames, reported by the driver.
public int OutputLatencySamples { get; }
Property Value
State
Current lifecycle state of the device.
public AsioDeviceState State { get; }
Property Value
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
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
optionsAsioDuplexOptions
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
optionsis 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
optionsAsioPlaybackOptions
Exceptions
- InvalidOperationException
Thrown if the device has already been configured.
- ArgumentNullException
Thrown if
optionsor itsSourceis 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
optionsAsioRecordingOptions
Exceptions
- InvalidOperationException
Thrown if the device has already been configured.
- ArgumentNullException
Thrown if
optionsis 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
sampleRateint
Returns
Open(int)
Opens the installed ASIO driver at the given zero-based index in GetDriverNames().
public static AsioDevice Open(int driverIndex)
Parameters
driverIndexint
Returns
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
driverNamestring
Returns
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
referenceint
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
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
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
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
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