Class BassWasapi
Wraps basswasapi.dll: Windows Audio Session API driver library
Namespace: System.Dynamic.ExpandoObject
Assembly: ManagedBass.Wasapi.dll
Syntax
public static class BassWasapi : object
Remarks
BASSWASAPI is basically a wrapper for Windows Audio Session API drivers, with the addition of channel joining, format conversion and resampling.
BASSWASAPI requires a soundcard with a Windows Session API drivers installed (Vista or above). It also makes use of SSE2 and 3DNow optimizations, but is fully functional without them. BASS is not required by BASSWASAPI, but BASS can of course be used to decode, apply DSP/FX, etc.
Fields
DefaultDevice
DefaultInputDevice
Identifier for Default Recording Device.
Declaration
public const int DefaultInputDevice = null
Field Value
Int32
|
DefaultLoopbackDevice
Identifier for Default Loopback Device.
Declaration
public const int DefaultLoopbackDevice = null
Field Value
Int32
|
Properties
CPUUsage
Retrieves the current CPU usage of BASSWASAPI.
Declaration
public static double CPUUsage { get; }
Property Value
Double
The BASSWASAPI CPU usage as a percentage of total CPU time. |
Remarks
This function includes the time taken by the WasapiProcedure callback functions.
CurrentDevice
Gets or Sets the Wasapi device to use for susequent calls in the current thread... 0 = first device. Use LastError to get the error code.
Declaration
public static int CurrentDevice { get; set; }
Property Value
Int32
|
Remarks
Throws BassException on Error setting value.
Simultaneously using multiple devices is supported in the BASS API via a context switching system; instead of there being an extra "device" parameter in the function calls, the device to be used is set prior to calling the functions. The device setting is local to the current thread, so calling functions with different devices simultaneously in multiple threads is not a problem.
All of the BassWasapi functions that do not have their own "device" parameter make use of this device selection. When one of them is called, BassWasapi will check the current thread's device setting, and if no device is selected (or the selected device is not initialized), BassWasapi will automatically select the lowest device that is initialized. This means that when using a single device, there is no need to use this function; BassWasapi will automatically use the device that is initialized. Even if you free the device, and initialize another, BassWasapi will automatically switch to the one that is initialized.
DeviceCount
Gets the total number of available Wasapi devices.
Declaration
public static int DeviceCount { get; }
Property Value
Int32
|
Info
Retrieves information on the Wasapi device being used.
Declaration
public static WasapiInfo Info { get; }
Property Value
WasapiInfo
An instance of the WasapiInfo structure is returned. Throws BassException on Error. |
Remarks
This method can be used to get the effective settings used with an initialized Wasapi device (endpoint).
When using multiple devices, the current thread's device setting (as set with CurrentDevice) determines which device this function call applies to.
IsStarted
Checks, if the current Wasapi device/driver (endpoint) has been already started (via Start()).
Declaration
public static bool IsStarted { get; }
Property Value
Boolean
Returns true, if the device has been started, else false is returned. Use LastError to get the error code. |
Remarks
When using multiple devices, the current thread's device setting (as set with CurrentDevice) determines which device this function call applies to.
Version
Gets the Version of BassWasapi that is loaded.
Declaration
public static Version Version { get; }
Property Value
Version
|
Methods
CheckFormat(Int32, Int32, Int32, WasapiInitFlags)
Checks if a particular sample format is supported by a device (endpoint).
Declaration
public static WasapiFormat CheckFormat(int Device, int Frequency, int Channels, WasapiInitFlags Flags)
Parameters
Int32
Device
The device to use... 0 = first device, -1 = default device, -2 = default input device. GetDeviceInfo(Int32, out WasapiDeviceInfo) can be used to enumerate the available devices. |
Int32
Frequency
The sample rate to check. |
Int32
Channels
The number of channels to check... 1 = mono, 2 = stereo, etc. |
WasapiInitFlags
Flags
Any combination of Shared and Exclusive. The HIWORD can be used to limit the sample formats that are checked in exclusive mode. The default is to check 32-bit floating-point, 32-bit integer, 24-bit integer, 16-bit integer, 8-bit integer, in that order. A WasapiFormat value can be used to bypass the formats that precede it in that list. |
Returns
WasapiFormat
If the sample format is supported, the maximum supported resolution (a WasapiFormat value) is returned, else -1 is returned. Use LastError to get the error code. |
Remarks
Call this method prior to Init(Int32, Int32, Int32, WasapiInitFlags, Single, Single, WasapiProcedure, IntPtr) in order to make sure the requested format is supported by the Wasapi output device/driver (endpoint).
Shared and exclusive modes may have different sample formats available. Only the "mix format" (available from GetDeviceInfo(Int32, out WasapiDeviceInfo)) is generally supported in shared mode.
Free()
Frees the Wasapi device/driver (endpoint).
Declaration
public static bool Free()
Returns
Boolean
If successful, then true is returned, else false is returned. Use LastError to get the error code. |
Remarks
This function should be called for all initialized devices before the program closes. Freed devices do not need to have been stopped with Stop(Boolean) beforehand.
When using multiple devices, the current thread's device setting (as set with CurrentDevice) determines which device this function call applies to.
GetBassDevice(Int32)
Gets the Bass device index for a Wasapi Device.
Declaration
public static int GetBassDevice(int WasapiDevice)
Parameters
Int32
WasapiDevice
|
Returns
Int32
|
GetData(IntPtr, Int32)
Retrieves the immediate sample data (or an FFT representation of it) of the current Wasapi device/driver (endpoint).
Declaration
public static int GetData(IntPtr Buffer, int Length)
Parameters
IntPtr
Buffer
An |
Int32
Length
Number of bytes wanted, and/or DataFlags. |
Returns
Int32
If an error occurs, -1 is returned, use LastError to get the error code. When requesting FFT data, the number of bytes read from the device (to perform the FFT) is returned. When requesting sample data, the number of bytes written to buffer will be returned (not necessarily the same as the number of bytes read when using the Float flag). When using the Available flag, the number of bytes in the device's buffer is returned. |
Remarks
This function is like the standard
Internally, a BASS stream is used for that, so the usual DataFlags are supported. That also means that BASS needs to have been initialized first; it specifically uses the NoSoundDevice. If the device is subsequently freed, this method call will fail.
As in BASS, simultaneously using multiple devices is supported in the BASSWASAPI API via a context switching system - instead of there being an extra "device" parameter in the function calls, the device to be used needs to be set via CurrentDevice prior to calling the function. The device setting is local to the current thread, so calling functions with different devices simultaneously in multiple threads is not a problem.
GetData(Single[], Int32)
Retrieves the immediate sample data (or an FFT representation of it) of the current Wasapi device/driver (endpoint).
Declaration
public static int GetData(float[] Buffer, int Length)
Parameters
Single[]
Buffer
A float[] to write the data to. |
Int32
Length
Number of bytes wanted, and/or DataFlags. |
Returns
Int32
If an error occurs, -1 is returned, use LastError to get the error code. When requesting FFT data, the number of bytes read from the device (to perform the FFT) is returned. When requesting sample data, the number of bytes written to buffer will be returned (not necessarily the same as the number of bytes read when using the Float flag). When using the Available flag, the number of bytes in the device's buffer is returned. |
Remarks
This function is like the standard
Internally, a BASS stream is used for that, so the usual DataFlags are supported. That also means that BASS needs to have been initialized first; it specifically uses the NoSoundDevice. If the device is subsequently freed, this method call will fail.
As in BASS, simultaneously using multiple devices is supported in the BASSWASAPI API via a context switching system - instead of there being an extra "device" parameter in the function calls, the device to be used needs to be set via CurrentDevice prior to calling the function. The device setting is local to the current thread, so calling functions with different devices simultaneously in multiple threads is not a problem.
GetDeviceInfo(Int32)
Retrieves information on a Wasapi device (endpoint).
Declaration
public static WasapiDeviceInfo GetDeviceInfo(int Device)
Parameters
Int32
Device
The device to get the information of... 0 = first. |
Returns
WasapiDeviceInfo
An instance of WasapiDeviceInfo structure is returned. Throws BassException on Error. |
Remarks
This function can be used to enumerate the available Wasapi devices (endpoints) for a setup dialog.
Note: Input (capture) devices can be determined by evaluating IsInput and IsLoopback members.
GetDeviceInfo(Int32, out WasapiDeviceInfo)
Retrieves information on a Wasapi device (endpoint).
Declaration
public static bool GetDeviceInfo(int Device, out WasapiDeviceInfo Info)
Parameters
Int32
Device
The device to get the information of... 0 = first. |
WasapiDeviceInfo
Info
An instance of the WasapiDeviceInfo class to store the information at. |
Returns
Boolean
If successful, then true is returned, else false is returned. Use LastError to get the error code. |
Remarks
This function can be used to enumerate the available Wasapi devices (endpoints) for a setup dialog.
Note: Input (capture) devices can be determined by evaluating IsInput and IsLoopback members.
GetDeviceLevel(Int32, Int32)
Gets the audio meter information of the current Wasapi device/driver (endpoint).
Declaration
public static float GetDeviceLevel(int Device, int Channel = null)
Parameters
Int32
Device
The device to use... 0 = first device. GetDeviceInfo(Int32, out WasapiDeviceInfo) can be used to get the total number of devices. |
Int32
Channel
The channel number to get the audio level meter information from (0=first, -1=all). |
Returns
Single
The audio level between 0.0 (silence) and 1.0 (maximum). |
Remarks
This method returns the global session level for the device which might include the level of other applications using the same device in shared-mode.
This function gets the level from the device/driver, or WASAPI if the device does not have its own level meter. If the latter case, the level will be unavailable when exclusive mode is active.
GetInfo(out WasapiInfo)
Retrieves information on the Wasapi device being used.
Declaration
public static bool GetInfo(out WasapiInfo Info)
Parameters
WasapiInfo
Info
An instance of the WasapiInfo structure to store the information at. |
Returns
Boolean
If successful, then true is returned, else false is returned. Use LastError to get the error code. |
Remarks
This method can be used to get the effective settings used with an initialized Wasapi device (endpoint).
When using multiple devices, the current thread's device setting (as set with CurrentDevice) determines which device this function call applies to.
GetLevel()
Retrieves the level (peak amplitude) of the current Wasapi device/driver (endpoint).
Declaration
public static int GetLevel()
Returns
Int32
If an error occurs, -1 is returned, use LastError to get the error code. If successful, the level of the left channel is returned in the low word (low 16-bits), and the level of the right channel is returned in the high word (high 16-bits). If the channel is mono, then the low word is duplicated in the high word. The level ranges linearly from 0 (silent) to 32768 (max). 0 will be returned when a channel is stalled. |
Remarks
This function is like the standard
GetLevel(Single[], Single, LevelRetrievalFlags)
Retreives the level
Declaration
public static int GetLevel(float[] Levels, float Length, LevelRetrievalFlags Flags)
Parameters
Single[]
Levels
An array to receive the levels. |
Single
Length
|
LevelRetrievalFlags
Flags
|
Returns
Int32
true on success, else false. Use LastError to get the Error code. |
Remarks
This function uses
GetMute(WasapiVolumeTypes)
Gets the mute status of the current Wasapi device/driver (endpoint).
Declaration
public static bool GetMute(WasapiVolumeTypes Mode = default (WasapiVolumeTypes))
Parameters
WasapiVolumeTypes
Mode
The type of volume to get. |
Returns
Boolean
true, if the device/session is muted and false if unmuted, else -1. Use LastError to get the error code. |
Remarks
When using multiple devices, the current thread's device setting (as set with CurrentDevice) determines which device this function call applies to.
GetVolume(WasapiVolumeTypes)
Retrieves the current volume level.
Declaration
public static float GetVolume(WasapiVolumeTypes Curve = default (WasapiVolumeTypes))
Parameters
WasapiVolumeTypes
Curve
Volume curve to use. |
Returns
Single
If successful, the volume level is returned, else -1 is returned. Use LastError to get the error code. |
Remarks
Session volume always uses WindowsHybridCurve.
When using multiple devices, the current thread's device setting (as set with CurrentDevice) determines which device this function call applies to.
Init(Int32, Int32, Int32, WasapiInitFlags, Single, Single, WasapiProcedure, IntPtr)
Initializes a Wasapi device/driver (endpoint).
Declaration
public static bool Init(int Device, int Frequency = 0, int Channels = 0, WasapiInitFlags Flags = WasapiInitFlags.Shared, float Buffer = null, float Period = null, WasapiProcedure Procedure = null, IntPtr User = null)
Parameters
Int32
Device
The device to use... 0 = first device, -1 = default output device, -2 = default input device. GetDeviceInfo(Int32, out WasapiDeviceInfo) can be used to enumerate the available devices. |
Int32
Frequency
The sample rate to use... 0 = "mix format" sample rate. |
Int32
Channels
The number of channels to use... 0 = "mix format" channels, 1 = mono, 2 = stereo, etc. |
WasapiInitFlags
Flags
A combination of WasapiInitFlags. |
Single
Buffer
The length of the device's buffer in seconds. This is a minimum and the driver may choose to use a larger buffer; Info can be used to confirm what the buffer size is. For an output device, the buffer size determines the latency. |
Single
Period
The interval (in seconds) between callback function calls... 0 = use default. If the specified period is below the minimum update period, it will automatically be raised to that. The update period specifies the time between WasapiProcedure calls. The WasapiDeviceInfo (see GetDeviceInfo(Int32, out WasapiDeviceInfo)) "minperiod" and "defperiod" values are actually minimum/default update periods. |
WasapiProcedure
Procedure
The user defined function to process the channel. Use null to create a Wasapi "push" device (to which you can feed sample data via PutData(IntPtr, Int32)). |
IntPtr
User
User instance data to pass to the callback function. |
Returns
Boolean
If the device was successfully initialized, true is returned, else false is returned. Use LastError to get the error code. |
Remarks
For convenience, devices are always initialized to use their highest sample resolution and that is then converted to 32-bit floating-point, so that WasapiProcedure callback functions and the PutData(IntPtr, Int32) and GetData(IntPtr, Int32) functions are always dealing with the same sample format. The device's sample format can be obtained via Info.
WASAPI does not support arbitrary sample formats, like DirectSound does. In particular, only the "mix format" (available from GetDeviceInfo(Int32, out WasapiDeviceInfo)) is generally supported in shared mode. CheckFormat(Int32, Int32, Int32, WasapiInitFlags) can be used to check whether a particular sample format is supported. The BASSmix add-on can be used to play (or record) in otherwise unsupported sample formats, as well as playing multiple sources.
The initialized device will not begin processing data until Start() is called.
Simultaneously using multiple devices is supported in the BASS API via a context switching system; instead of there being an extra "device" parameter in the function calls, the device to be used is set prior to calling the functions. CurrentDevice is used to switch the current device. When successful, Init(Int32, Int32, Int32, WasapiInitFlags, Single, Single, WasapiProcedure, IntPtr) automatically sets the current thread's device to the one that was just initialized.
When using the default output or input device, CurrentDevice can be used to find out which device it was mapped to.
In SHARED mode you must initialize the device with the current WASAPI mixer sample rate and number of channels (see the WasapiDeviceInfo "mixfreq" and "mixchans" properties).
In EXCLUSIVE mode you might use any sample rate and number of channels which are supported by the device/driver.
This function must be successfully called before any input or output can be performed.
In EXCLUSIVE mode, the "period" value will affect what's an acceptable "buffer" value (it appears that the buffer must be at least 4x the period). In SHARED mode, it's the other way round, the "period" will be reduced to fit the "buffer" if necessary (with a minimum of the "defperiod" value). The system will limit them to an acceptable range, so for example, you could use a very small value (eg. 0.0001) for both, to get the minimum possible latency.
Note: When initializing an input (capture or loopback) device, it might be the case, that the device is automatically muted once initialized. You can use the GetMute(WasapiVolumeTypes)/SetMute(WasapiVolumeTypes, Boolean) methods to check and probably toggle this.
Lock(Boolean)
Locks the device to the current thread.
Declaration
public static bool Lock(bool State = true)
Parameters
Boolean
State
If false, unlock WASAPI, else lock it. |
Returns
Boolean
If successful, true is returned, else false is returned. Use LastError to get the error code. |
Remarks
Locking a device prevents other threads from accessing the device buffer, including a WasapiProcedure. Other threads wanting to access a locked device will block until it is unlocked, so a device should only be locked very briefly. A device must be unlocked in the same thread that it was locked.
PutData(IntPtr, Int32)
Adds sample data to an output device buffer ("push" device).
Declaration
public static int PutData(IntPtr Buffer, int Length)
Parameters
IntPtr
Buffer
The pointer to the sample data to provide. |
Int32
Length
The amount of data in bytes. GetData(IntPtr, Int32) with the Available flag can be used to check how much data is queued. |
Returns
Int32
If successful, the the amount of data copied from the provided buffer will be returned (which may be less than requested if it doesn't all fit in the device buffer, see the BufferLength property), else -1 is returned. Use LastError to get the error code. |
Remarks
You must have initialized the device via Init(Int32, Int32, Int32, WasapiInitFlags, Single, Single, WasapiProcedure, IntPtr) with WasapiProcedure = null.
As much data as possible will be placed in the device's buffer; this function will have to be called again for any remainder.
Data should be provided at a rate sufficent to sustain playback. If the buffer gets exhausted, ouput will stall until more data is provided. GetData(IntPtr, Int32) with the Available flag can be used to check how much data is buffered.
PutData(Single[], Int32)
Adds sample data to an output device buffer ("push" device).
Declaration
public static int PutData(float[] Buffer, int Length)
Parameters
Single[]
Buffer
float[] providing the sample data. |
Int32
Length
The amount of data in bytes. GetData(IntPtr, Int32) with the Available flag can be used to check how much data is queued. |
Returns
Int32
If successful, the the amount of data copied from the provided buffer will be returned (which may be less than requested if it doesn't all fit in the device buffer, see the BufferLength property), else -1 is returned. Use LastError to get the error code. |
Remarks
You must have initialized the device via Init(Int32, Int32, Int32, WasapiInitFlags, Single, Single, WasapiProcedure, IntPtr) with WasapiProcedure = null.
As much data as possible will be placed in the device's buffer; this function will have to be called again for any remainder.
Data should be provided at a rate sufficent to sustain playback. If the buffer gets exhausted, ouput will stall until more data is provided. GetData(IntPtr, Int32) with the Available flag can be used to check how much data is buffered.
SetMute(WasapiVolumeTypes, Boolean)
Sets the mute status of the current Wasapi device/driver (endpoint).
Declaration
public static bool SetMute(WasapiVolumeTypes Mode, bool Mute)
Parameters
WasapiVolumeTypes
Mode
The type of volume to set. |
Boolean
Mute
true to mute the device, false to unmute the device. |
Returns
Boolean
If successful, then true is returned, else false is returned. Use LastError to get the error code. |
Remarks
When using multiple devices, the current thread's device setting (as set with CurrentDevice) determines which device this function call applies to.
SetNotify(WasapiNotifyProcedure, IntPtr)
Sets a device change notification callback.
Declaration
public static bool SetNotify(WasapiNotifyProcedure Procedure, IntPtr User = null)
Parameters
WasapiNotifyProcedure
Procedure
User defined notification function... null = disable notifications. |
IntPtr
User
User instance data to pass to the callback function. |
Returns
Boolean
If successful, true is returned, else false is returned. Use LastError to get the error code. |
Remarks
A previously set notification callback can be changed (or removed) at any time, by calling this function again.
SetVolume(WasapiVolumeTypes, Single)
Sets the volume of the current Wasapi device/driver (endpoint).
Declaration
public static bool SetVolume(WasapiVolumeTypes Curve, float Volume)
Parameters
WasapiVolumeTypes
Curve
Volume curve to use. |
Single
Volume
The new volume to set between 0.0 (silent) and 1.0 (maximum) if linear, or else a dB level. |
Returns
Boolean
Returns true on success, else false is returned. Use LastError to get the error code. |
Remarks
Session volume only affects the current process, so other users of the device are unaffected. It has no effect on exclusive mode output, and maps to the device volume with input devices (so does affect other users). Session volume always uses WindowsHybridCurve. If you need to control the volume of the stream only, you need to apply that directly within the WasapiProcedure yourself.
When using multiple devices, the current thread's device setting (as set with CurrentDevice) determines which device this function call applies to.
Start()
Starts processing the current Wasapi device/driver (endpoint).
Declaration
public static bool Start()
Returns
Boolean
If successful, then true is returned, else false is returned. Use LastError to get the error code. |
Remarks
Before starting the device, it must be initialized using Init(Int32, Int32, Int32, WasapiInitFlags, Single, Single, WasapiProcedure, IntPtr). Use Stop(Boolean) to stop processing the device.
When using multiple devices, the current thread's device setting (as set with CurrentDevice) determines which device this function call applies to.
Stop(Boolean)
Stops the current Wasapi device/driver (endpoint).
Declaration
public static bool Stop(bool Reset = true)
Parameters
Boolean
Reset
Flush the device buffer? true will clear the output buffer. Otherwise it is like pausing, eg. Start() will resume playing the buffered data. |
Returns
Boolean
If successful, then true is returned, else false is returned. Use LastError to get the error code. |
Remarks
If the device buffer is left unflushed (Reset
= false), a subsequent Start() call will resume things with the buffered data, otherwise it will resume with fresh data.
When using multiple devices, the current thread's device setting (as set with CurrentDevice) determines which device this function call applies to.