libASPL
Loading...
Searching...
No Matches
aspl::Device Class Reference

Audio device object. More...

#include <aspl/Device.hpp>

Inheritance diagram for aspl::Device:
aspl::Object

Public Member Functions

 Device (std::shared_ptr< const Context > context, const DeviceParameters &params={})
 Construct device.
 
Getters and setters
virtual std::string GetName () const
 Get device name. Human readable name of the device. Can be localized. By default returns DeviceParameters::Name.
 
virtual std::string GetManufacturer () const
 Get device manufacturer. Human readable name of the maker of the plug-in. Can be localized. By default returns DeviceParameters::Manufacturer.
 
virtual std::string GetDeviceUID () const
 Get device UID. Persistent token that can identify the same audio device across boot sessions. Two instances of the same device must have different values for this property. By default returns DeviceParameters::DeviceUID if it's non-empty, or otherwise generates random UID.
 
virtual std::string GetModelUID () const
 Get model UID. Persistent token that can identify audio devices of the same kind. Two instances of the same device must have the same value for this property. By default returns DeviceParameters::ModelUID.
 
virtual std::string GetSerialNumber () const
 Get serial number. Human readable serial number of the device. This is pure informational value which doesn't have to be unique. By default returns DeviceParameters::SerialNumber.
 
virtual std::string GetFirmwareVersion () const
 Get firmware version. Human readable firmware version of the device. This is pure informational value which doesn't have to be unique. By default returns DeviceParameters::FirmwareVersion.
 
virtual std::string GetIconURL () const
 Get device icon URL. Returns URL that points to the device icon, e.g in plugin resource bundle. By default returns DeviceParameters::IconURL.
 
virtual std::string GetConfigurationApplicationBundleID () const
 Get bundle ID of configuration application. The returned app should provides a GUI for configuring the device. By default returns DeviceParameters::ConfigurationApplicationBundleID.
 
virtual UInt32 GetTransportType () const
 Get device transport type. Represents how the device is attached to the system. Common values are defined in <CoreAudio/AudioHardwareBase.h>. Default is kAudioDeviceTransportTypeVirtual.
 
virtual std::vector< AudioObjectID > GetRelatedDeviceIDs () const
 Get related devices. By default returns a single-element list with own ID.
 
virtual bool GetClockIsStable () const
 Check whether the device clock should be considered stable. By default returns DeviceParameters::ClockIsStable.
 
virtual AudioDeviceClockAlgorithmSelector GetClockAlgorithm () const
 Get clock algorithm. By default returns DeviceParameters::ClockAlgorithm.
 
virtual UInt32 GetClockDomain () const
 Get clock domain. By default returns DeviceParameters::ClockDomain.
 
virtual UInt32 GetLatency () const
 Get presentation latency of the device. Measured in number of frames. By default returns the last value set by SetLatencyAsync(). Initial value is DeviceParameters::Latency.
 
OSStatus SetLatencyAsync (UInt32 latency)
 Asynchronously set presentation latency. Requests HAL to asynchronously invoke SetLatencyImpl().
 
virtual UInt32 GetSafetyOffset () const
 How close to now it is allowed to read and write. Measured in number of frames. By default returns the last value set by SetSafetyOffset(). Initial value is DeviceParameters::SafetyOffset.
 
OSStatus SetSafetyOffsetAsync (UInt32 offset)
 Asynchronously set safety offset. Requests HAL to asynchronously invoke SetSafetyOffsetImpl().
 
virtual UInt32 GetZeroTimeStampPeriod () const
 Difference between successive timestamps returned from GetZeroTimeStamp(). Measured in number of frames. By default returns the last value set by SetZeroTimeStampPeriodAsync(). Initial value is DeviceParameters::ZeroTimeStampPeriod if it's non-zero, or DeviceParameters::SampleRate otherwise.
 
OSStatus SetZeroTimeStampPeriodAsync (UInt32 period)
 Asynchronously set zero timestamp period. Requests HAL to asynchronously invoke SetZeroTimeStampPeriodImpl().
 
virtual Float64 GetNominalSampleRate () const
 Get nominal sample rate. By default returns the last value set by SetNominalSampleRateAsync(). Initial value is DeviceParameters::SampleRate. Note that each device stream can define its own sample rate in its physical and virtual formats.
 
OSStatus SetNominalSampleRateAsync (Float64 rate)
 Asynchronously set nominal sample rate. Requests HAL to asynchronously invoke SetNominalSampleRateImpl(). Fails if rate is not present in GetAvailableSampleRates(), which by default returns only one rate, provided during initialization. If you want to make your device supporting multiple rates, you typically need to override both of these methods.
 
virtual std::vector< AudioValueRange > GetAvailableSampleRates () const
 Get list of supported nominal sample rates. By default returns the list set by SetAvailableSampleRatesAsync(). If nothing was set, returns a single-element list with a range which min and max are both set to the value returned by GetNominalSampleRate().
 
OSStatus SetAvailableSampleRatesAsync (std::vector< AudioValueRange > rates)
 Asynchronously set list of supported nominal sample rates. See comments for GetAvailableSampleRates(). Requests HAL to asynchronously invoke SetAvailableSampleRatesImpl().
 
virtual std::array< UInt32, 2 > GetPreferredChannelsForStereo () const
 Return which two channels to use as left/right for stereo data by default. By default returns the last value set by SetPreferredChannelsForStereoAsync(). Initial value is {1, 2}. Channel numbers are 1-based.
 
OSStatus SetPreferredChannelsForStereoAsync (std::array< UInt32, 2 > channels)
 Asynchronously set channels for stereo. Channel numbers are 1-based. Requests HAL to asynchronously invoke SetPreferredChannelsForStereoImpl().
 
virtual UInt32 GetPreferredChannelCount () const
 Get preferred number of channels.
 
OSStatus SetPreferredChannelCountAsync (UInt32 channelCount)
 Asynchronously set preferred channel count. See comments for GetPreferredChannelCount(). Requests HAL to asynchronously invoke SetPreferredChannelCountImpl().
 
virtual std::vector< AudioChannelDescription > GetPreferredChannels () const
 Get preferred channels for device.
 
OSStatus SetPreferredChannelsAsync (std::vector< AudioChannelDescription > channels)
 Asynchronously set preferred channels array. See comments for GetPreferredChannels(). Requests HAL to asynchronously invoke SetPreferredChannelsImpl().
 
virtual std::vector< UInt8 > GetPreferredChannelLayout () const
 Get preferred AudioChannelLayout to use for the device.
 
OSStatus SetPreferredChannelLayoutAsync (std::vector< UInt8 > channelLayout)
 Asynchronously set preferred channel layout. See comments for GetPreferredChannelLayout(). The provided buffer should contain properly formatted AudioChannelLayout struct. Requests HAL to asynchronously invoke SetPreferredChannelLayoutImpl().
 
virtual bool GetIsRunning () const
 Check whether the device is doing I/O. By default, returns true if I/O was activated using StartIO().
 
virtual bool GetIsIdentifying () const
 Check whether device identification is in progress. A true value indicates that the device hardware is drawing attention to itself, typically by flashing or lighting up its front panel display. This makes it easy for a user to associate the physical hardware with its representation in an app. By default always returns false.
 
OSStatus SetIsIdentifying (bool)
 Start or stop device identification. Invokes SetIsIdentifyingImpl() and NotifyPropertyChanged().
 
virtual bool GetIsAlive () const
 Check whether the device is alive. By default returns the last value set by SetIsAlive(). Initial value is true.
 
OSStatus SetIsAlive (bool isAlive)
 Mark device as alive or dead. Invokes SetIsAliveImpl() and NotifyPropertyChanged().
 
virtual bool GetIsHidden () const
 Check whether the device is hidden from clients. By default returns the last value set by SetIsHidden(). Initial value is false.
 
OSStatus SetIsHidden (bool isHidden)
 Mark or unmark device as hidden. Invokes SetIsHiddenImpl() and NotifyPropertyChanged().
 
virtual bool GetCanBeDefaultDevice () const
 Check whether the device can be the default device for content. By default, returns the last value set by SetCanBeDefaultDevice(). Initial value is DeviceParameters::CanBeDefault.
 
OSStatus SetCanBeDefaultDevice (bool value)
 Set whether the device can be the default device for content. Invokes SetCanBeDefaultDeviceImpl() and NotifyPropertyChanged().
 
virtual bool GetCanBeDefaultSystemDevice () const
 Check whether the device can be the default device for system sounds. By default, returns the last value set by SetCanBeDefaultSystemDevice(). Initial value is DeviceParameters::CanBeDefaultForSystemSounds.
 
OSStatus SetCanBeDefaultSystemDevice (bool value)
 Set whether the device can be the default device for system sounds. Invokes SetCanBeDefaultSystemDeviceImpl() and NotifyPropertyChanged().
 
virtual std::vector< AudioObjectID > GetStreamIDs (AudioObjectPropertyScope scope=kAudioObjectPropertyScopeGlobal) const
 Get device streams. Returns the list of owned streams. Scope defines whether to return input streams, output streams, or both. Default implementation returns all owned objects of given scope and kAudioStreamClassID class.
 
virtual std::vector< AudioObjectID > GetControlIDs (AudioObjectPropertyScope scope=kAudioObjectPropertyScopeGlobal) const
 Get device controls. Returns the list of owned controls. Scope defines whether to return input controls, output controls, or both. Default implementation returns all owned objects of given scope and kAudioControlClassID class and its derivatives, including volume and mute controls.
 
Streams
UInt32 GetStreamCount (Direction dir) const
 Get number of streams for given direction.
 
std::shared_ptr< StreamGetStreamByIndex (Direction dir, UInt32 idx) const
 Get stream with given direction and zero-based index. Returns nullptr if there are less than idx+1 streams.
 
std::shared_ptr< StreamGetStreamByID (AudioObjectID streamID) const
 Get stream with given object ID. Returns nullptr if there is no such stream.
 
std::shared_ptr< StreamAddStreamWithControlsAsync (Direction dir)
 Add stream + volume control + mute control.
 
std::shared_ptr< StreamAddStreamWithControlsAsync (const StreamParameters &params)
 Add stream + volume control + mute control. Same as AddStreamWithControlsAsync(Direction), but allows to provide custom parameters.
 
std::shared_ptr< StreamAddStreamAsync (Direction dir)
 Add stream to device.
 
std::shared_ptr< StreamAddStreamAsync (const StreamParameters &params)
 Add stream to device. Same as AddStreamAsync(Direction), but allows to provide custom parameters.
 
void AddStreamAsync (std::shared_ptr< Stream > stream)
 Add stream to device. Same as AddStreamAsync(Direction), but allows to construct stream manually.
 
void RemoveStreamAsync (std::shared_ptr< Stream > stream)
 Remove stream from device.
 
Volume controls
UInt32 GetVolumeControlCount (AudioObjectPropertyScope scope) const
 Get number of volume controls for given scope.
 
std::shared_ptr< VolumeControlGetVolumeControlByIndex (AudioObjectPropertyScope scope, UInt32 idx) const
 Get volume control with given scope and zero-based index. Returns nullptr if there are less than idx+1 volume controls.
 
std::shared_ptr< VolumeControlGetVolumeControlByID (AudioObjectID controlID) const
 Get volume control with given object ID. Returns nullptr if there is no such control.
 
std::shared_ptr< VolumeControlAddVolumeControlAsync (AudioObjectPropertyScope scope)
 Add volume control to device.
 
std::shared_ptr< VolumeControlAddVolumeControlAsync (const VolumeControlParameters &params)
 Add volume control to device. Same as AddVolumeControlAsync(Direction), but allows to provide custom parameters.
 
void AddVolumeControlAsync (std::shared_ptr< VolumeControl > control)
 Add volume control to device. Same as AddVolumeControlAsync(Direction), but allows to construct control manually.
 
void RemoveVolumeControlAsync (std::shared_ptr< VolumeControl > control)
 Remove volume control from device.
 
Mute controls
UInt32 GetMuteControlCount (AudioObjectPropertyScope scope) const
 Get number of mute controls for given scope.
 
std::shared_ptr< MuteControlGetMuteControlByIndex (AudioObjectPropertyScope scope, UInt32 idx) const
 Get mute control with given scope and zero-based index. Returns nullptr if there are less than idx+1 mute controls.
 
std::shared_ptr< MuteControlGetMuteControlByID (AudioObjectID controlID) const
 Get mute control with given object ID. Returns nullptr if there is no such control.
 
std::shared_ptr< MuteControlAddMuteControlAsync (AudioObjectPropertyScope scope)
 Add mute control to device.
 
std::shared_ptr< MuteControlAddMuteControlAsync (const MuteControlParameters &params)
 Add mute control to device. Same as AddMuteControlAsync(Direction), but allows to provide custom parameters.
 
void AddMuteControlAsync (std::shared_ptr< MuteControl > control)
 Add mute control to device. Same as AddMuteControlAsync(Direction), but allows to construct control manually.
 
void RemoveMuteControlAsync (std::shared_ptr< MuteControl > control)
 Remove mute control from device.
 
Control operations
void SetControlHandler (std::shared_ptr< ControlRequestHandler > handler)
 Set handler for control requests. This is optional. You may provide a custom handler if you want to do custom processing or want to inject custom client implementation.
 
void SetControlHandler (ControlRequestHandler *handler)
 Set handler for control requests (raw pointer overload). This overload uses raw pointer instead of shared_ptr, and the user is responsible for keeping handler object alive until it's reset or Device is destroyed.
 
ControlRequestHandlerGetControlHandler () const
 Get pointer to configured control handler. Never returns null, if there is no handler, a no-op handler is used. For details about life-time, see SetControlHandler().
 
virtual OSStatus AddClient (AudioObjectID objectID, const AudioServerPlugInClientInfo *rawClientInfo)
 Called before new client start I/O with the device. Updates client map and invokes OnAddClient().
 
virtual OSStatus RemoveClient (AudioObjectID objectID, const AudioServerPlugInClientInfo *rawClientInfo)
 Called after a client finishes I/O with the device. Updates client map and invokes OnRemoveClient().
 
UInt32 GetClientCount () const
 Get number of clients.
 
std::vector< std::shared_ptr< Client > > GetClients () const
 Get all clients.
 
std::shared_ptr< ClientGetClientByID (UInt32 clientID) const
 Find client by client ID.
 
virtual OSStatus StartIO (AudioObjectID objectID, UInt32 clientID)
 Tell the device to start I/O. Invokes ControlRequestHandler::OnStartIO() and updates GetIsRunning(). GetIsRunning() will return true until at least one client is doing I/O.
 
virtual OSStatus StopIO (AudioObjectID objectID, UInt32 clientID)
 Tell the device to stop I/O. Invokes ControlRequestHandler::OnStopIO() and updates GetIsRunning(). GetIsRunning() will return true until at least one client is doing I/O.
 
I/O operations
void SetIOHandler (std::shared_ptr< IORequestHandler > handler)
 Set handler for I/O requests. Its methods will be invoked when an I/O operation is performed. They are always invoked on realtime thread, serialized. You need to provide your own implementation if you want your device to actually do something useful. Default implementation is suitable for a null / black hole device.
 
void SetIOHandler (IORequestHandler *handler)
 Set handler for I/O requests (raw pointer overload). This overload uses raw pointer instead of shared_ptr, and the user is responsible for keeping handler object alive until it's reset or Device is destroyed.
 
IORequestHandlerGetIOHandler () const
 Get pointer to configured I/O handler. Never returns null, if there is no handler, a no-op handler is used. For details about life-time, see SetIOHandler().
 
virtual OSStatus GetZeroTimeStamp (AudioObjectID objectID, UInt32 clientID, Float64 *outSampleTime, UInt64 *outHostTime, UInt64 *outSeed)
 Get the current zero time stamp for the device. In default implementation, the zero time stamp and host time are increased every GetZeroTimeStampPeriod() frames.
 
virtual OSStatus WillDoIOOperation (AudioObjectID objectID, UInt32 clientID, UInt32 operationID, Boolean *outWillDo, Boolean *outWillDoInPlace)
 Asks device whether it want to perform the given phase of the IO cycle. In default implementation, makes decision based on whether the device has input and output streams, and what is returned by DeviceParameters::EnableMixing.
 
virtual OSStatus BeginIOOperation (AudioObjectID objectID, UInt32 clientID, UInt32 operationID, UInt32 ioBufferFrameSize, const AudioServerPlugInIOCycleInfo *ioCycleInfo)
 Called before performing I/O operation. By default does nothing.
 
virtual OSStatus DoIOOperation (AudioObjectID objectID, AudioObjectID streamID, UInt32 clientID, UInt32 operationID, UInt32 ioBufferFrameSize, const AudioServerPlugInIOCycleInfo *ioCycleInfo, void *ioMainBuffer, void *ioSecondaryBuffer)
 Perform an IO operation for a particular stream. In default implementation, invokes corresponding method of I/O handler based on passed operation type, for example OnReadInput() or OnWriteMixedOutput().
 
virtual OSStatus EndIOOperation (AudioObjectID objectID, UInt32 clientID, UInt32 operationID, UInt32 ioBufferFrameSize, const AudioServerPlugInIOCycleInfo *ioCycleInfo)
 Called after performing I/O operation. By default does nothing.
 
Configuration
virtual void RequestConfigurationChange (std::function< void()> func={})
 Request HAL to perform configuration update.
 
virtual void RequestOwnershipChange (Object *owner, bool shouldHaveOwnership)
 Request device to change its owner.
 
virtual OSStatus PerformConfigurationChange (AudioObjectID objectID, UInt64 changeAction, void *changeInfo)
 Called by the Host to allow the device to perform a configuration change that had been previously requested via a call to the Host method, RequestDeviceConfigurationChange().
 
virtual OSStatus AbortConfigurationChange (AudioObjectID objectID, UInt64 changeAction, void *changeInfo)
 Called by the Host to tell the device not to perform a configuration change that had been requested via a call to the Host method, RequestDeviceConfigurationChange().
 
Property dispatch
AudioClassID GetClass () const override
 Get class ID.
 
AudioClassID GetBaseClass () const override
 Get base class ID.
 
bool IsInstance (AudioClassID classID) const override
 Check if this object is instance of given base class.
 
Boolean HasProperty (AudioObjectID objectID, pid_t clientPID, const AudioObjectPropertyAddress *address) const override
 Check whether given property is present.
 
OSStatus IsPropertySettable (AudioObjectID objectID, pid_t clientPID, const AudioObjectPropertyAddress *address, Boolean *outIsSettable) const override
 Check whether given property can be changed.
 
OSStatus GetPropertyDataSize (AudioObjectID objectID, pid_t clientPID, const AudioObjectPropertyAddress *address, UInt32 qualifierDataSize, const void *qualifierData, UInt32 *outDataSize) const override
 Get size of property value in bytes.
 
OSStatus GetPropertyData (AudioObjectID objectID, pid_t clientPID, const AudioObjectPropertyAddress *address, UInt32 qualifierDataSize, const void *qualifierData, UInt32 inDataSize, UInt32 *outDataSize, void *outData) const override
 Get property value.
 
OSStatus SetPropertyData (AudioObjectID objectID, pid_t clientPID, const AudioObjectPropertyAddress *address, UInt32 qualifierDataSize, const void *qualifierData, UInt32 inDataSize, const void *inData) override
 Change property value.
 
- Public Member Functions inherited from aspl::Object
 Object (std::shared_ptr< const Context > context, const char *className="Object", AudioObjectID objectID=kAudioObjectUnknown)
 Construct object. Class name is used for logging. It should be the name of the derived class. If objectID is kAudioObjectUnknown (zero), allocates new object ID. Otherwise uses given object ID.
 
 Object (const Object &)=delete
 
Objectoperator= (const Object &)=delete
 
std::shared_ptr< const ContextGetContext () const
 Get object context.
 
AudioObjectID GetID () const
 Get object ID. Returns objectID selected at construction time.
 
AudioObjectID GetOwnerID () const
 Get object owner. If the object has an owner, returns its ID. Otherwise, returns kAudioObjectUnknown (zero).
 
bool HasOwner () const
 Check if the object is part of the hierarchy. Returns true if GetOwnerID() is not equal to kAudioObjectUnknown.
 
std::vector< AudioObjectID > GetOwnedObjectIDs (AudioObjectPropertyScope scope=kAudioObjectPropertyScopeGlobal, AudioClassID classID=0) const
 Get owned objects. Returns the list of objects to which this object is the owner.
 
void AddOwnedObject (std::shared_ptr< Object > object, AudioObjectPropertyScope scope=kAudioObjectPropertyScopeGlobal)
 Add object to the list of owned objects. Also invokes SetOwner() on the added object.
 
void RemoveOwnedObject (AudioObjectID objectID)
 Remove object to the list of owned objects. Also invokes SetOwner() on the removed object.
 
void NotifyPropertyChanged (AudioObjectPropertySelector selector, AudioObjectPropertyScope scope=kAudioObjectPropertyScopeGlobal, AudioObjectPropertyElement element=kAudioObjectPropertyElementMain) const
 Notify HAL that a property was changed. This is automatically called by all setters.
 
void NotifyPropertiesChanged (std::vector< AudioObjectPropertySelector > selectors, AudioObjectPropertyScope scope=kAudioObjectPropertyScopeGlobal, AudioObjectPropertyElement element=kAudioObjectPropertyElementMain) const
 Notify HAL that some properties were changed. This is automatically called by all setters.
 
virtual std::vector< AudioServerPlugInCustomPropertyInfo > GetCustomProperties () const
 Get info about registered custom properties. Returns list of properties added using RegisterCustomProperty().
 
template<typename ObjectType , typename ValueType >
void RegisterCustomProperty (AudioObjectPropertySelector selector, ObjectType &object, GetterMethod< ObjectType, ValueType > getter, SetterMethod< ObjectType, ValueType > setter=nullptr)
 Register custom property with getter and optional setter.
 
template<typename GetterFunc >
void RegisterCustomProperty (AudioObjectPropertySelector selector, GetterFunc getter)
 Register custom property with getter and optional setter.
 
void RegisterCustomProperty (AudioObjectPropertySelector selector, std::function< CFStringRef()> getter, std::function< void(CFStringRef)> setter)
 Register custom property with getter and optional setter.
 
void RegisterCustomProperty (AudioObjectPropertySelector selector, std::function< CFPropertyListRef()> getter, std::function< void(CFPropertyListRef)> setter)
 Register custom property with getter and optional setter.
 

Protected Member Functions

Setters implementation
virtual OSStatus SetLatencyImpl (UInt32 latency)
 Set presentation latency. Invoked by SetLatencyAsync() to actually change latency. Default implementation just changes the value returned by GetLatency().
 
virtual OSStatus SetSafetyOffsetImpl (UInt32 offset)
 Set safety offset. Invoked by SetSafetyOffsetAsync() to actually change offset. Default implementation just changes the value returned by GetSafetyOffset().
 
virtual OSStatus SetZeroTimeStampPeriodImpl (UInt32 period)
 Set zero timestamp period. Invoked by SetZeroTimeStampPeriodAsync() to actually change period. Default implementation just changes the value returned by GetZeroTimeStampPeriod().
 
virtual OSStatus SetNominalSampleRateImpl (Float64 rate)
 Set nominal sample rate. Invoked by SetNominalSampleRateAsync() to actually change the rate. Default implementation just changes the value returned by GetNominalSampleRate().
 
virtual OSStatus SetAvailableSampleRatesImpl (std::vector< AudioValueRange > rates)
 Set list of supported nominal sample rates. Invoked by SetAvailableSampleRatesAsync() to actually change the list. Default implementation just updates the list returned by GetAvailableSampleRates().
 
virtual OSStatus SetPreferredChannelsForStereoImpl (std::array< UInt32, 2 > channels)
 Set channels for stereo. Invoked by SetPreferredChannelsForStereoAsync() to actually change the value. Default implementation just changes the value returned GetPreferredChannelsForStereo().
 
virtual OSStatus SetPreferredChannelCountImpl (UInt32 channelCount)
 Set preferred channel count. Invoked by SetPreferredChannelCountAsync() to actually change the value. Default implementation changes the value returned by GetPreferredChannelCount(). By default, it also affects values returned by GetPreferredChannels() and GetPreferredChannelLayout().
 
virtual OSStatus SetPreferredChannelsImpl (std::vector< AudioChannelDescription > channels)
 Invoked by SetPreferredChannelsAsync() to actually change the value. Default implementation changes the value returned by GetPreferredChannels(). By default, it also affects values returned by GetPreferredChannelCount() and GetPreferredChannelLayout().
 
virtual OSStatus SetPreferredChannelLayoutImpl (std::vector< UInt8 > channelLayout)
 Invoked by SetPreferredChannelLayoutAsync() to actually change the value. Default implementation changes the value returned by GetPreferredChannelLayout(). By default, it also affects values returned by GetPreferredChannelCount() and GetPreferredChannels().
 
virtual OSStatus SetIsIdentifyingImpl (bool isIdentifying)
 Start or stop device identification. This can be requested by UI, but probably makes little sense to virtual devices. By default always fails. Invoked by SetIsIdentifying().
 
virtual OSStatus SetIsAliveImpl (bool isAlive)
 Mark device as alive or dead. By default just changes the value returned by GetIsAlive(). Invoked by SetIsAlive().
 
virtual OSStatus SetIsHiddenImpl (bool isHidden)
 Mark or unmark device as hidden. By default just changes the value returned by GetIsHidden(). Invoked by SetIsHidden().
 
virtual OSStatus SetCanBeDefaultDeviceImpl (bool value)
 Set whether the device can be the default device for content. By default just changes the value returned by GetCanBeDefaultDevice(). Invoked by SetCanBeDefaultDevice().
 
virtual OSStatus SetCanBeDefaultSystemDeviceImpl (bool value)
 Set whether the device can be the default device for system sounds. By default just changes the value returned by GetCanBeDefaultSystemDevice(). Invoked by SetCanBeDefaultSystemDevice().
 
I/O implementation
virtual OSStatus StartIOImpl (UInt32 clientID, UInt32 startCount)
 Prepare device to start I/O. Invoked by StartIO().
 
virtual OSStatus StopIOImpl (UInt32 clientID, UInt32 startCount)
 Prepare device to finish I/O. Invoked by StopIO().
 
virtual OSStatus GetZeroTimeStampImpl (UInt32 clientID, Float64 *outSampleTime, UInt64 *outHostTime, UInt64 *outSeed)
 Get the current zero timestamp for the device. Invoked by GetZeroTimeStamp().
 
virtual OSStatus WillDoIOOperationImpl (UInt32 clientID, UInt32 operationID, Boolean *outWillDo, Boolean *outWillDoInPlace)
 Asks device whether it want to perform the given phase of the IO cycle. Invoked by WillDoIOOperation().
 
virtual OSStatus BeginIOOperationImpl (UInt32 clientID, UInt32 operationID, UInt32 ioBufferFrameSize, const AudioServerPlugInIOCycleInfo *ioCycleInfo)
 Called before performing I/O operation. Invoked by BeginIOOperation().
 
virtual OSStatus DoIOOperationImpl (AudioObjectID streamID, UInt32 clientID, UInt32 operationID, UInt32 ioBufferFrameSize, const AudioServerPlugInIOCycleInfo *ioCycleInfo, void *ioMainBuffer, void *ioSecondaryBuffer)
 Perform an IO operation for a particular stream. Invoked by DoIOOperation().
 
virtual OSStatus EndIOOperationImpl (UInt32 clientID, UInt32 operationID, UInt32 ioBufferFrameSize, const AudioServerPlugInIOCycleInfo *ioCycleInfo)
 Called after performing I/O operation. Invoked by EndIOOperation().
 

Additional Inherited Members

- Public Types inherited from aspl::Object
template<typename ObjectType , typename ValueType >
using GetterMethod = ValueType (ObjectType::*)() const
 Pointer to custom property getter method. Used in RegisterCustomProperty().
 
template<typename ObjectType , typename ValueType >
using SetterMethod = void (ObjectType::*)(ValueType)
 Pointer to custom property setter method. Used in RegisterCustomProperty().
 

Detailed Description

Audio device object.

Audio device is something to which applications (clients) can connect and do I/O.

Streams and controls

After creating device, and before publishing it to HAL, you should populate it with streams (Stream class) and controls (VolumeControl, MuteControl).

Each stream can be either input or output; control can be input, output, and global. Input streams allow client to read from device; output streams allow clients to write to device. Controls allow clients or user to adjust processing settings.

When a client performs I/O, it always specifies the stream. Each stream may represent its own source or destination of samples. Each stream also may have its own format, latency, and other attributes.

The meaning of controls is device-specific. If desired, you can attach controls to a stream, and stream will take them into account when applying per-stream processing. However you're free to treat streams and controls in any other way.

I/O operations

Unlike other objects, in addition to property dispatch operations, Device class has a bunch of I/O-related operations exported to HAL.

Default Device implementation performs some typical housekeeping by itself (like maintaining maps of clients and streams) and then delegates the principal part (like actually reading or writing samples) to two other classes: ControlRequestHandler (for non-realtime, control operations) and IORequestHandler (for realtime I/O operations).

Typically you'll need default implementation of Device and custom implementation of IORequestHandler and probably ControlRequestHandler. Though, if default Device implementation does not fit your needs, you can override how it handles control and I/O requests from HAL and drop IORequestHandler and ControlRequestHandler at all.

When you override IORequestHandler or Device I/O operations, remember that HAL invokes them on realtime thread and they should be realtime-safe.

Definition at line 167 of file Device.hpp.

Constructor & Destructor Documentation

◆ Device()

aspl::Device::Device ( std::shared_ptr< const Context > context,
const DeviceParameters & params = {} )
explicit

Construct device.

Member Function Documentation

◆ AbortConfigurationChange()

virtual OSStatus aspl::Device::AbortConfigurationChange ( AudioObjectID objectID,
UInt64 changeAction,
void * changeInfo )
virtual

Called by the Host to tell the device not to perform a configuration change that had been requested via a call to the Host method, RequestDeviceConfigurationChange().

Note
Invoked by HAL on non-realtime thread.

◆ AddClient()

virtual OSStatus aspl::Device::AddClient ( AudioObjectID objectID,
const AudioServerPlugInClientInfo * rawClientInfo )
virtual

Called before new client start I/O with the device. Updates client map and invokes OnAddClient().

◆ AddMuteControlAsync() [1/3]

std::shared_ptr< MuteControl > aspl::Device::AddMuteControlAsync ( AudioObjectPropertyScope scope)

Add mute control to device.

Remarks
Constructs a new MuteControl instance with default parameters, adjusted to the mute control scope and index. Also adds mute control to the owned object list.
Returns
added control.
Note
The addition is split into two parts: synchronous and asynchronous. Control is constructed and initialized synchronously, but is added to the owned objects list and published to HAL asynchronously (when HAL allows it). Hence, GetMuteControlCount() and GetMuteControlByIndex() are updated immediately, but GetOwnedObjectIDs(), GetControlIDs(), etc. are updated later.

◆ AddMuteControlAsync() [2/3]

std::shared_ptr< MuteControl > aspl::Device::AddMuteControlAsync ( const MuteControlParameters & params)

Add mute control to device. Same as AddMuteControlAsync(Direction), but allows to provide custom parameters.

◆ AddMuteControlAsync() [3/3]

void aspl::Device::AddMuteControlAsync ( std::shared_ptr< MuteControl > control)

Add mute control to device. Same as AddMuteControlAsync(Direction), but allows to construct control manually.

◆ AddStreamAsync() [1/3]

std::shared_ptr< Stream > aspl::Device::AddStreamAsync ( const StreamParameters & params)

Add stream to device. Same as AddStreamAsync(Direction), but allows to provide custom parameters.

◆ AddStreamAsync() [2/3]

std::shared_ptr< Stream > aspl::Device::AddStreamAsync ( Direction dir)

Add stream to device.

Remarks
Constructs a new Stream instance with default parameters, adjusted to the stream direction and index. Also adds stream to the owned object list.
Returns
added stream.
Note
The addition is split into two parts: synchronous and asynchronous. Stream is constructed and initialized synchronously, but is added to the owned objects list and published to HAL asynchronously (when HAL allows it). Hence, GetStreamCount() and GetStreamByIndex() are updated immediately, but GetOwnedObjectIDs(), GetStreamIDs(), etc. are updated some time later.

◆ AddStreamAsync() [3/3]

void aspl::Device::AddStreamAsync ( std::shared_ptr< Stream > stream)

Add stream to device. Same as AddStreamAsync(Direction), but allows to construct stream manually.

◆ AddStreamWithControlsAsync() [1/2]

std::shared_ptr< Stream > aspl::Device::AddStreamWithControlsAsync ( const StreamParameters & params)

Add stream + volume control + mute control. Same as AddStreamWithControlsAsync(Direction), but allows to provide custom parameters.

◆ AddStreamWithControlsAsync() [2/2]

std::shared_ptr< Stream > aspl::Device::AddStreamWithControlsAsync ( Direction dir)

Add stream + volume control + mute control.

Remarks
Constructs a new Stream, VolumeControl, and MuteControl instances with default parameters adjusted to the stream direction and index. Attaches volume and mute controls to the stream, so that Stream::ApplyProcessing(), called by IORequestHandler, will take volume and mute into account. Also adds constructed objects to the owned object list.
Returns
added stream.
Note
The addition is split into two parts: synchronous and asynchronous. Objects are constructed and initialized synchronously, but are added to the owned objects list and published to HAL asynchronously (when HAL allows it). Hence, GetStreamCount() and GetStreamByIndex() are updated immediately, but GetOwnedObjectIDs(), GetStreamIDs(), etc. are updated some time later.

◆ AddVolumeControlAsync() [1/3]

std::shared_ptr< VolumeControl > aspl::Device::AddVolumeControlAsync ( AudioObjectPropertyScope scope)

Add volume control to device.

Remarks
Constructs a new VolumeControl instance with default parameters, adjusted to the volume control scope and index. Also adds volume control to the owned object list.
Returns
added control.
Note
The addition is split into two parts: synchronous and asynchronous. Control is constructed and initialized synchronously, but is added to the owned objects list and published to HAL asynchronously (when HAL allows it). Hence, GetVolumeControlCount() and GetVolumeControlByIndex() are updated immediately, but GetOwnedObjectIDs(), GetControlIDs(), etc. are updated later.

◆ AddVolumeControlAsync() [2/3]

std::shared_ptr< VolumeControl > aspl::Device::AddVolumeControlAsync ( const VolumeControlParameters & params)

Add volume control to device. Same as AddVolumeControlAsync(Direction), but allows to provide custom parameters.

◆ AddVolumeControlAsync() [3/3]

void aspl::Device::AddVolumeControlAsync ( std::shared_ptr< VolumeControl > control)

Add volume control to device. Same as AddVolumeControlAsync(Direction), but allows to construct control manually.

◆ BeginIOOperation()

virtual OSStatus aspl::Device::BeginIOOperation ( AudioObjectID objectID,
UInt32 clientID,
UInt32 operationID,
UInt32 ioBufferFrameSize,
const AudioServerPlugInIOCycleInfo * ioCycleInfo )
virtual

Called before performing I/O operation. By default does nothing.

Note
Calls BeginIOOperationImpl(), which you can override if needed. See also comments for StartIO() and StopIO().
Invoked by HAL on realtime thread.

◆ BeginIOOperationImpl()

virtual OSStatus aspl::Device::BeginIOOperationImpl ( UInt32 clientID,
UInt32 operationID,
UInt32 ioBufferFrameSize,
const AudioServerPlugInIOCycleInfo * ioCycleInfo )
protectedvirtual

Called before performing I/O operation. Invoked by BeginIOOperation().

Remarks
Default implementation does nothing.

◆ DoIOOperation()

virtual OSStatus aspl::Device::DoIOOperation ( AudioObjectID objectID,
AudioObjectID streamID,
UInt32 clientID,
UInt32 operationID,
UInt32 ioBufferFrameSize,
const AudioServerPlugInIOCycleInfo * ioCycleInfo,
void * ioMainBuffer,
void * ioSecondaryBuffer )
virtual

Perform an IO operation for a particular stream. In default implementation, invokes corresponding method of I/O handler based on passed operation type, for example OnReadInput() or OnWriteMixedOutput().

Note
Calls DoIOOperationImpl(), which you can override if needed. See also comments for StartIO() and StopIO().
Invoked by HAL on realtime thread.

◆ DoIOOperationImpl()

virtual OSStatus aspl::Device::DoIOOperationImpl ( AudioObjectID streamID,
UInt32 clientID,
UInt32 operationID,
UInt32 ioBufferFrameSize,
const AudioServerPlugInIOCycleInfo * ioCycleInfo,
void * ioMainBuffer,
void * ioSecondaryBuffer )
protectedvirtual

Perform an IO operation for a particular stream. Invoked by DoIOOperation().

Remarks
In default implementation, invokes corresponding method of I/O handler based on passed operation type, for example OnReadInput() or OnWriteMixedOutput().

◆ EndIOOperation()

virtual OSStatus aspl::Device::EndIOOperation ( AudioObjectID objectID,
UInt32 clientID,
UInt32 operationID,
UInt32 ioBufferFrameSize,
const AudioServerPlugInIOCycleInfo * ioCycleInfo )
virtual

Called after performing I/O operation. By default does nothing.

Note
Calls EndIOOperationImpl(), which you can override if needed. See also comments for StartIO() and StopIO().
Invoked by HAL on realtime thread.

◆ EndIOOperationImpl()

virtual OSStatus aspl::Device::EndIOOperationImpl ( UInt32 clientID,
UInt32 operationID,
UInt32 ioBufferFrameSize,
const AudioServerPlugInIOCycleInfo * ioCycleInfo )
protectedvirtual

Called after performing I/O operation. Invoked by EndIOOperation().

Remarks
Default implementation does nothing.

◆ GetAvailableSampleRates()

virtual std::vector< AudioValueRange > aspl::Device::GetAvailableSampleRates ( ) const
virtual

Get list of supported nominal sample rates. By default returns the list set by SetAvailableSampleRatesAsync(). If nothing was set, returns a single-element list with a range which min and max are both set to the value returned by GetNominalSampleRate().

Remarks
Empty list means that any rate is allowed. For discrete sampler rates, the range should have the minimum value equal to the maximum value.
Note
Backs kAudioDevicePropertyAvailableNominalSampleRates property.

◆ GetBaseClass()

AudioClassID aspl::Device::GetBaseClass ( ) const
overridevirtual

Get base class ID.

Reimplemented from aspl::Object.

◆ GetCanBeDefaultDevice()

virtual bool aspl::Device::GetCanBeDefaultDevice ( ) const
virtual

Check whether the device can be the default device for content. By default, returns the last value set by SetCanBeDefaultDevice(). Initial value is DeviceParameters::CanBeDefault.

Remarks
Default device is configured via Sound Preferences. This is the device which applications will use to play their content or capture sound. Nearly all devices should allow for this.
Note
Backs kAudioDevicePropertyDeviceCanBeDefaultDevice property.

◆ GetCanBeDefaultSystemDevice()

virtual bool aspl::Device::GetCanBeDefaultSystemDevice ( ) const
virtual

Check whether the device can be the default device for system sounds. By default, returns the last value set by SetCanBeDefaultSystemDevice(). Initial value is DeviceParameters::CanBeDefaultForSystemSounds.

Remarks
Default system device is configured via Sound Preferences. It is used by applications to play interface sounds.
Note
Backs kAudioDevicePropertyDeviceCanBeDefaultSystemDevice property.

◆ GetClass()

AudioClassID aspl::Device::GetClass ( ) const
overridevirtual

Get class ID.

Reimplemented from aspl::Object.

◆ GetClientByID()

std::shared_ptr< Client > aspl::Device::GetClientByID ( UInt32 clientID) const

Find client by client ID.

◆ GetClientCount()

UInt32 aspl::Device::GetClientCount ( ) const

Get number of clients.

◆ GetClients()

std::vector< std::shared_ptr< Client > > aspl::Device::GetClients ( ) const

Get all clients.

◆ GetClockAlgorithm()

virtual AudioDeviceClockAlgorithmSelector aspl::Device::GetClockAlgorithm ( ) const
virtual

Get clock algorithm. By default returns DeviceParameters::ClockAlgorithm.

Remarks
This property defines what filtering the HAL applies to the values returned by GetZeroTimeStamp(). Possible values are defined in CoreAudio/AudioServerPlugIn.h.
Note
Backs kAudioDevicePropertyClockAlgorithm property.

◆ GetClockDomain()

virtual UInt32 aspl::Device::GetClockDomain ( ) const
virtual

Get clock domain. By default returns DeviceParameters::ClockDomain.

Remarks
This property allows the device to declare what other devices it is synchronized with in hardware. The way it works is that if two devices have the same value for this property and the value is not zero, then the two devices are synchronized in hardware. Note that a device that either can't be synchronized with others or doesn't know should return 0 for this property.
Note
Backs kAudioDevicePropertyClockDomain property.

◆ GetClockIsStable()

virtual bool aspl::Device::GetClockIsStable ( ) const
virtual

Check whether the device clock should be considered stable. By default returns DeviceParameters::ClockIsStable.

Remarks
The true value indicates that the device's clock runs at or very near the nominal sample rate with only small variations.
Note
Backs kAudioDevicePropertyClockIsStable property.

◆ GetConfigurationApplicationBundleID()

virtual std::string aspl::Device::GetConfigurationApplicationBundleID ( ) const
virtual

Get bundle ID of configuration application. The returned app should provides a GUI for configuring the device. By default returns DeviceParameters::ConfigurationApplicationBundleID.

Note
Backs kAudioDevicePropertyConfigurationApplication property.

◆ GetControlHandler()

ControlRequestHandler * aspl::Device::GetControlHandler ( ) const

Get pointer to configured control handler. Never returns null, if there is no handler, a no-op handler is used. For details about life-time, see SetControlHandler().

◆ GetControlIDs()

virtual std::vector< AudioObjectID > aspl::Device::GetControlIDs ( AudioObjectPropertyScope scope = kAudioObjectPropertyScopeGlobal) const
virtual

Get device controls. Returns the list of owned controls. Scope defines whether to return input controls, output controls, or both. Default implementation returns all owned objects of given scope and kAudioControlClassID class and its derivatives, including volume and mute controls.

Note
Backs kAudioObjectPropertyControlList property.

◆ GetDeviceUID()

virtual std::string aspl::Device::GetDeviceUID ( ) const
virtual

Get device UID. Persistent token that can identify the same audio device across boot sessions. Two instances of the same device must have different values for this property. By default returns DeviceParameters::DeviceUID if it's non-empty, or otherwise generates random UID.

Note
Backs kAudioDevicePropertyDeviceUID property.

◆ GetFirmwareVersion()

virtual std::string aspl::Device::GetFirmwareVersion ( ) const
virtual

Get firmware version. Human readable firmware version of the device. This is pure informational value which doesn't have to be unique. By default returns DeviceParameters::FirmwareVersion.

Note
Backs kAudioObjectPropertyFirmwareVersion property.

◆ GetIconURL()

virtual std::string aspl::Device::GetIconURL ( ) const
virtual

Get device icon URL. Returns URL that points to the device icon, e.g in plugin resource bundle. By default returns DeviceParameters::IconURL.

Note
Backs kAudioDevicePropertyIcon property.

◆ GetIOHandler()

IORequestHandler * aspl::Device::GetIOHandler ( ) const

Get pointer to configured I/O handler. Never returns null, if there is no handler, a no-op handler is used. For details about life-time, see SetIOHandler().

◆ GetIsAlive()

virtual bool aspl::Device::GetIsAlive ( ) const
virtual

Check whether the device is alive. By default returns the last value set by SetIsAlive(). Initial value is true.

Remarks
It is not uncommon for a device to be dead but still momentarily available in the device list.
Note
Backs kAudioDevicePropertyDeviceIsAlive property.

◆ GetIsHidden()

virtual bool aspl::Device::GetIsHidden ( ) const
virtual

Check whether the device is hidden from clients. By default returns the last value set by SetIsHidden(). Initial value is false.

Note
Backs kAudioDevicePropertyIsHidden property.

◆ GetIsIdentifying()

virtual bool aspl::Device::GetIsIdentifying ( ) const
virtual

Check whether device identification is in progress. A true value indicates that the device hardware is drawing attention to itself, typically by flashing or lighting up its front panel display. This makes it easy for a user to associate the physical hardware with its representation in an app. By default always returns false.

Note
Backs kAudioObjectPropertyIdentify property.

◆ GetIsRunning()

virtual bool aspl::Device::GetIsRunning ( ) const
virtual

Check whether the device is doing I/O. By default, returns true if I/O was activated using StartIO().

Note
Backs kAudioDevicePropertyDeviceIsRunning property.

◆ GetLatency()

virtual UInt32 aspl::Device::GetLatency ( ) const
virtual

Get presentation latency of the device. Measured in number of frames. By default returns the last value set by SetLatencyAsync(). Initial value is DeviceParameters::Latency.

Note
Backs kAudioDevicePropertyLatency property.

◆ GetManufacturer()

virtual std::string aspl::Device::GetManufacturer ( ) const
virtual

Get device manufacturer. Human readable name of the maker of the plug-in. Can be localized. By default returns DeviceParameters::Manufacturer.

Note
Backs kAudioObjectPropertyManufacturer property.

◆ GetModelUID()

virtual std::string aspl::Device::GetModelUID ( ) const
virtual

Get model UID. Persistent token that can identify audio devices of the same kind. Two instances of the same device must have the same value for this property. By default returns DeviceParameters::ModelUID.

Note
Backs kAudioDevicePropertyModelUID property.

◆ GetMuteControlByID()

std::shared_ptr< MuteControl > aspl::Device::GetMuteControlByID ( AudioObjectID controlID) const

Get mute control with given object ID. Returns nullptr if there is no such control.

◆ GetMuteControlByIndex()

std::shared_ptr< MuteControl > aspl::Device::GetMuteControlByIndex ( AudioObjectPropertyScope scope,
UInt32 idx ) const

Get mute control with given scope and zero-based index. Returns nullptr if there are less than idx+1 mute controls.

◆ GetMuteControlCount()

UInt32 aspl::Device::GetMuteControlCount ( AudioObjectPropertyScope scope) const

Get number of mute controls for given scope.

◆ GetName()

virtual std::string aspl::Device::GetName ( ) const
virtual

Get device name. Human readable name of the device. Can be localized. By default returns DeviceParameters::Name.

Note
Backs kAudioObjectPropertyName property.

◆ GetNominalSampleRate()

virtual Float64 aspl::Device::GetNominalSampleRate ( ) const
virtual

Get nominal sample rate. By default returns the last value set by SetNominalSampleRateAsync(). Initial value is DeviceParameters::SampleRate. Note that each device stream can define its own sample rate in its physical and virtual formats.

Note
Backs kAudioDevicePropertyNominalSampleRate property.

◆ GetPreferredChannelCount()

virtual UInt32 aspl::Device::GetPreferredChannelCount ( ) const
virtual

Get preferred number of channels.

GetPreferredChannelCount() and SetPreferredChannelCountAsync() are the most simple way to configure channels. Use them if all you need is to get/set number of channels.

If you need more precise configuration, see GetPreferredChannels() and GetPreferredChannelLayout(). If you don't, you can ignore them; their default implementation will use GetPreferredChannelCount().

Default implementation of this method automatically checks what channel parameters did you set (SetPreferredChannelCountAsync(), SetPreferredChannelsAsync(), SetPreferredChannelLayoutAsync()), and returns number of channels based on that.

If nothing was set, it just returns DeviceParameters::ChannelCount.

Note
Indirectly backs kAudioDevicePropertyPreferredChannelLayout property via GetPreferredChannels() / GetPreferredChannelLayout().

◆ GetPreferredChannelLayout()

virtual std::vector< UInt8 > aspl::Device::GetPreferredChannelLayout ( ) const
virtual

Get preferred AudioChannelLayout to use for the device.

This is the most precise way to configure channels, by providing custom AudioChannelLayout. In most cases, it is enough to use GetPreferredChannelCount() or GetPreferredChannels() instead.

Default implementation of this method automatically checks if you have set channel layout using SetPreferredChannelLayoutAsync(), and returns it.

If nothing was set, it constructs default channel layout based on the channels returned by GetPreferredChannels().

Remarks
AudioChannelLayout has variable size, which depends on the number of channels. Hence, this methods returns a byte array instead of AudioChannelLayout struct. The returned array contains a properly formatted AudioChannelLayout struct.
Note
Backs kAudioDevicePropertyPreferredChannelLayout property.

◆ GetPreferredChannels()

virtual std::vector< AudioChannelDescription > aspl::Device::GetPreferredChannels ( ) const
virtual

Get preferred channels for device.

GetPreferredChannels() and SetPreferredChannelsAsync() are a more precise way to configure channels. Use them if all you want to specify parameters of individual channels, defined in AudioChannelDescription struct.

If all you need is just to change number of channels, see GetPreferredChannelCount() instead. And if you need even more precise configuration, see GetPreferredChannelLayout().

Default implementation of this method automatically checks what channel parameters did you set (SetPreferredChannelsAsync(), SetPreferredChannelLayoutAsync()), and returns channel array based on that.

If nothing was set, it constructs channels with default parameters based on the number of channels returned by GetPreferredChannelCount().

Note
Indirectly backs kAudioDevicePropertyPreferredChannelLayout property via GetPreferredChannelLayout().

◆ GetPreferredChannelsForStereo()

virtual std::array< UInt32, 2 > aspl::Device::GetPreferredChannelsForStereo ( ) const
virtual

Return which two channels to use as left/right for stereo data by default. By default returns the last value set by SetPreferredChannelsForStereoAsync(). Initial value is {1, 2}. Channel numbers are 1-based.

Note
Backs kAudioDevicePropertyPreferredChannelsForStereo property.

◆ GetPropertyData()

OSStatus aspl::Device::GetPropertyData ( AudioObjectID objectID,
pid_t clientPID,
const AudioObjectPropertyAddress * address,
UInt32 qualifierDataSize,
const void * qualifierData,
UInt32 inDataSize,
UInt32 * outDataSize,
void * outData ) const
overridevirtual

Get property value.

Reimplemented from aspl::Object.

◆ GetPropertyDataSize()

OSStatus aspl::Device::GetPropertyDataSize ( AudioObjectID objectID,
pid_t clientPID,
const AudioObjectPropertyAddress * address,
UInt32 qualifierDataSize,
const void * qualifierData,
UInt32 * outDataSize ) const
overridevirtual

Get size of property value in bytes.

Reimplemented from aspl::Object.

◆ GetRelatedDeviceIDs()

virtual std::vector< AudioObjectID > aspl::Device::GetRelatedDeviceIDs ( ) const
virtual

Get related devices. By default returns a single-element list with own ID.

Remarks
The related devices property identifies device objects that are very closely related. Generally, this is for relating devices that are packaged together in the hardware such as when the input side and the output side of a piece of hardware can be clocked separately and therefore need to be represented as separate AudioDevice objects. In such case, both devices would report that they are related to each other. Note that at minimum, a device is related to itself, so this list will always be at least one item long.
Note
Backs kAudioDevicePropertyRelatedDevices property.

◆ GetSafetyOffset()

virtual UInt32 aspl::Device::GetSafetyOffset ( ) const
virtual

How close to now it is allowed to read and write. Measured in number of frames. By default returns the last value set by SetSafetyOffset(). Initial value is DeviceParameters::SafetyOffset.

Note
Backs kAudioDevicePropertySafetyOffset property.

◆ GetSerialNumber()

virtual std::string aspl::Device::GetSerialNumber ( ) const
virtual

Get serial number. Human readable serial number of the device. This is pure informational value which doesn't have to be unique. By default returns DeviceParameters::SerialNumber.

Note
Backs kAudioObjectPropertySerialNumber property.

◆ GetStreamByID()

std::shared_ptr< Stream > aspl::Device::GetStreamByID ( AudioObjectID streamID) const

Get stream with given object ID. Returns nullptr if there is no such stream.

◆ GetStreamByIndex()

std::shared_ptr< Stream > aspl::Device::GetStreamByIndex ( Direction dir,
UInt32 idx ) const

Get stream with given direction and zero-based index. Returns nullptr if there are less than idx+1 streams.

◆ GetStreamCount()

UInt32 aspl::Device::GetStreamCount ( Direction dir) const

Get number of streams for given direction.

◆ GetStreamIDs()

virtual std::vector< AudioObjectID > aspl::Device::GetStreamIDs ( AudioObjectPropertyScope scope = kAudioObjectPropertyScopeGlobal) const
virtual

Get device streams. Returns the list of owned streams. Scope defines whether to return input streams, output streams, or both. Default implementation returns all owned objects of given scope and kAudioStreamClassID class.

Note
Backs kAudioDevicePropertyStreams property.

◆ GetTransportType()

virtual UInt32 aspl::Device::GetTransportType ( ) const
virtual

Get device transport type. Represents how the device is attached to the system. Common values are defined in <CoreAudio/AudioHardwareBase.h>. Default is kAudioDeviceTransportTypeVirtual.

Note
Backs kAudioDevicePropertyTransportType property.

◆ GetVolumeControlByID()

std::shared_ptr< VolumeControl > aspl::Device::GetVolumeControlByID ( AudioObjectID controlID) const

Get volume control with given object ID. Returns nullptr if there is no such control.

◆ GetVolumeControlByIndex()

std::shared_ptr< VolumeControl > aspl::Device::GetVolumeControlByIndex ( AudioObjectPropertyScope scope,
UInt32 idx ) const

Get volume control with given scope and zero-based index. Returns nullptr if there are less than idx+1 volume controls.

◆ GetVolumeControlCount()

UInt32 aspl::Device::GetVolumeControlCount ( AudioObjectPropertyScope scope) const

Get number of volume controls for given scope.

◆ GetZeroTimeStamp()

virtual OSStatus aspl::Device::GetZeroTimeStamp ( AudioObjectID objectID,
UInt32 clientID,
Float64 * outSampleTime,
UInt64 * outHostTime,
UInt64 * outSeed )
virtual

Get the current zero time stamp for the device. In default implementation, the zero time stamp and host time are increased every GetZeroTimeStampPeriod() frames.

Remarks
The HAL models the timing of a device as a series of time stamps that relate the sample time to a host time. The zero time stamps are spaced such that the sample times are the value of kAudioDevicePropertyZeroTimeStampPeriod apart. This is often modeled using a ring buffer where the zero time stamp is updated when wrapping around the ring buffer.
Note
Calls GetZeroTimeStampImpl(), which you can override if needed. See also comments for StartIO() and StopIO().
Invoked by HAL on realtime thread.

◆ GetZeroTimeStampImpl()

virtual OSStatus aspl::Device::GetZeroTimeStampImpl ( UInt32 clientID,
Float64 * outSampleTime,
UInt64 * outHostTime,
UInt64 * outSeed )
protectedvirtual

Get the current zero timestamp for the device. Invoked by GetZeroTimeStamp().

Remarks
In default implementation, the zero time stamp and host time are increased every GetZeroTimeStampPeriod() frames. Default implementation also handles sample rate changes by checking GetNominalSampleRate().

◆ GetZeroTimeStampPeriod()

virtual UInt32 aspl::Device::GetZeroTimeStampPeriod ( ) const
virtual

Difference between successive timestamps returned from GetZeroTimeStamp(). Measured in number of frames. By default returns the last value set by SetZeroTimeStampPeriodAsync(). Initial value is DeviceParameters::ZeroTimeStampPeriod if it's non-zero, or DeviceParameters::SampleRate otherwise.

Remarks
If GetZeroTimeStamp() returned a sample time of X, we expect that the next valid returned timestamp will be X plus the value of this property.
Note
Backs kAudioDevicePropertyZeroTimeStampPeriod property.

◆ HasProperty()

Boolean aspl::Device::HasProperty ( AudioObjectID objectID,
pid_t clientPID,
const AudioObjectPropertyAddress * address ) const
overridevirtual

Check whether given property is present.

Reimplemented from aspl::Object.

◆ IsInstance()

bool aspl::Device::IsInstance ( AudioClassID classID) const
overridevirtual

Check if this object is instance of given base class.

Reimplemented from aspl::Object.

◆ IsPropertySettable()

OSStatus aspl::Device::IsPropertySettable ( AudioObjectID objectID,
pid_t clientPID,
const AudioObjectPropertyAddress * address,
Boolean * outIsSettable ) const
overridevirtual

Check whether given property can be changed.

Reimplemented from aspl::Object.

◆ PerformConfigurationChange()

virtual OSStatus aspl::Device::PerformConfigurationChange ( AudioObjectID objectID,
UInt64 changeAction,
void * changeInfo )
virtual

Called by the Host to allow the device to perform a configuration change that had been previously requested via a call to the Host method, RequestDeviceConfigurationChange().

Note
Invoked by HAL on non-realtime thread.

◆ RemoveClient()

virtual OSStatus aspl::Device::RemoveClient ( AudioObjectID objectID,
const AudioServerPlugInClientInfo * rawClientInfo )
virtual

Called after a client finishes I/O with the device. Updates client map and invokes OnRemoveClient().

◆ RemoveMuteControlAsync()

void aspl::Device::RemoveMuteControlAsync ( std::shared_ptr< MuteControl > control)

Remove mute control from device.

Remarks
Removes control from device and the owned object list.
Note
The removal is split into two parts: synchronous and asynchronous. Control is removed from the control list synchronously, but is excluded from the owned objects asynchronously (when HAL allows it). Hence, GetMuteControlCount() and GetMuteControlByIndex() are updated immediately, but GetOwnedObjectIDs(), GetControlIDs(), etc. are updated some time later.

◆ RemoveStreamAsync()

void aspl::Device::RemoveStreamAsync ( std::shared_ptr< Stream > stream)

Remove stream from device.

Remarks
Removes stream from device and the owned object list.
Note
The removal is split into two parts: synchronous and asynchronous. Stream is removed from the stream list synchronously, but is excluded from the owned objects asynchronously (when HAL allows it). Hence, GetStreamCount() and GetStreamByIndex() are updated immediately, but GetOwnedObjectIDs(), GetStreamIDs(), etc. are updated some time later.

◆ RemoveVolumeControlAsync()

void aspl::Device::RemoveVolumeControlAsync ( std::shared_ptr< VolumeControl > control)

Remove volume control from device.

Remarks
Removes control from device and the owned object list.
Note
The removal is split into two parts: synchronous and asynchronous. Control is removed from the control list synchronously, but is excluded from the owned objects asynchronously (when HAL allows it). Hence, GetVolumeControlCount() and GetVolumeControlByIndex() are updated immediately, but GetOwnedObjectIDs(), GetControlIDs(), etc. are updated some time later.

◆ RequestConfigurationChange()

virtual void aspl::Device::RequestConfigurationChange ( std::function< void()> func = {})
virtual

Request HAL to perform configuration update.

Remarks
This method is needed when we want to change parameters that can't be just changed on fly, e.g. set sample rate or add a stream. In this case, we ask HAL to schedule configuration update, defined by passed function, and some time later HAL invokes PerformConfigurationChange(), which runs the function. HAL may also invoke AbortConfigurationChange() instead.
Note
There are three cases when this method decides that it's safe to invoke the function immediately ("in-place") instead of enqueueing it:
  • If Context::Host is null, the method assumes that the entire plugin is not yet initialized and published to HAL, and thus HAL doesn't use Device.
  • If Device::HasOwner() is false, the method assumes that the device itself is not added to the plugin hierarchy yet, and thus HAL doesn't use Device.
  • If the method is invoked from PerformConfigurationChange(), it assumes that we're already at the point where it's safe to change configuration.

◆ RequestOwnershipChange()

virtual void aspl::Device::RequestOwnershipChange ( Object * owner,
bool shouldHaveOwnership )
virtual

Request device to change its owner.

Remarks
This method is called by Device owner (Plugin object) when device is added or removed to the plugin (and so becomes published or unpublished from HAL). This method implements thread-safe changing of the ownership and handles possible races with RequestConfigurationChange(). It is needed because RequestConfigurationChange() mechanism is tightly coupled with the ownership state and should be taken into account when ownership changes.
Note
Normally owner is always a pointer to Plugin, and shouldHaveOwnership is true when adding device and false when removing. This method is expected to do all necessary housekeeping and invoke owner->AddOwnedObject(this) or owner->RemoveOwnedObject(this).

◆ SetAvailableSampleRatesAsync()

OSStatus aspl::Device::SetAvailableSampleRatesAsync ( std::vector< AudioValueRange > rates)

Asynchronously set list of supported nominal sample rates. See comments for GetAvailableSampleRates(). Requests HAL to asynchronously invoke SetAvailableSampleRatesImpl().

◆ SetAvailableSampleRatesImpl()

virtual OSStatus aspl::Device::SetAvailableSampleRatesImpl ( std::vector< AudioValueRange > rates)
protectedvirtual

Set list of supported nominal sample rates. Invoked by SetAvailableSampleRatesAsync() to actually change the list. Default implementation just updates the list returned by GetAvailableSampleRates().

◆ SetCanBeDefaultDevice()

OSStatus aspl::Device::SetCanBeDefaultDevice ( bool value)

Set whether the device can be the default device for content. Invokes SetCanBeDefaultDeviceImpl() and NotifyPropertyChanged().

◆ SetCanBeDefaultDeviceImpl()

virtual OSStatus aspl::Device::SetCanBeDefaultDeviceImpl ( bool value)
protectedvirtual

Set whether the device can be the default device for content. By default just changes the value returned by GetCanBeDefaultDevice(). Invoked by SetCanBeDefaultDevice().

◆ SetCanBeDefaultSystemDevice()

OSStatus aspl::Device::SetCanBeDefaultSystemDevice ( bool value)

Set whether the device can be the default device for system sounds. Invokes SetCanBeDefaultSystemDeviceImpl() and NotifyPropertyChanged().

◆ SetCanBeDefaultSystemDeviceImpl()

virtual OSStatus aspl::Device::SetCanBeDefaultSystemDeviceImpl ( bool value)
protectedvirtual

Set whether the device can be the default device for system sounds. By default just changes the value returned by GetCanBeDefaultSystemDevice(). Invoked by SetCanBeDefaultSystemDevice().

◆ SetControlHandler() [1/2]

void aspl::Device::SetControlHandler ( ControlRequestHandler * handler)

Set handler for control requests (raw pointer overload). This overload uses raw pointer instead of shared_ptr, and the user is responsible for keeping handler object alive until it's reset or Device is destroyed.

◆ SetControlHandler() [2/2]

void aspl::Device::SetControlHandler ( std::shared_ptr< ControlRequestHandler > handler)

Set handler for control requests. This is optional. You may provide a custom handler if you want to do custom processing or want to inject custom client implementation.

◆ SetIOHandler() [1/2]

void aspl::Device::SetIOHandler ( IORequestHandler * handler)

Set handler for I/O requests (raw pointer overload). This overload uses raw pointer instead of shared_ptr, and the user is responsible for keeping handler object alive until it's reset or Device is destroyed.

◆ SetIOHandler() [2/2]

void aspl::Device::SetIOHandler ( std::shared_ptr< IORequestHandler > handler)

Set handler for I/O requests. Its methods will be invoked when an I/O operation is performed. They are always invoked on realtime thread, serialized. You need to provide your own implementation if you want your device to actually do something useful. Default implementation is suitable for a null / black hole device.

◆ SetIsAlive()

OSStatus aspl::Device::SetIsAlive ( bool isAlive)

Mark device as alive or dead. Invokes SetIsAliveImpl() and NotifyPropertyChanged().

◆ SetIsAliveImpl()

virtual OSStatus aspl::Device::SetIsAliveImpl ( bool isAlive)
protectedvirtual

Mark device as alive or dead. By default just changes the value returned by GetIsAlive(). Invoked by SetIsAlive().

◆ SetIsHidden()

OSStatus aspl::Device::SetIsHidden ( bool isHidden)

Mark or unmark device as hidden. Invokes SetIsHiddenImpl() and NotifyPropertyChanged().

◆ SetIsHiddenImpl()

virtual OSStatus aspl::Device::SetIsHiddenImpl ( bool isHidden)
protectedvirtual

Mark or unmark device as hidden. By default just changes the value returned by GetIsHidden(). Invoked by SetIsHidden().

◆ SetIsIdentifying()

OSStatus aspl::Device::SetIsIdentifying ( bool )

Start or stop device identification. Invokes SetIsIdentifyingImpl() and NotifyPropertyChanged().

Note
Backs kAudioObjectPropertyIdentify property.

◆ SetIsIdentifyingImpl()

virtual OSStatus aspl::Device::SetIsIdentifyingImpl ( bool isIdentifying)
protectedvirtual

Start or stop device identification. This can be requested by UI, but probably makes little sense to virtual devices. By default always fails. Invoked by SetIsIdentifying().

Note
Backs kAudioObjectPropertyIdentify property.

◆ SetLatencyAsync()

OSStatus aspl::Device::SetLatencyAsync ( UInt32 latency)

Asynchronously set presentation latency. Requests HAL to asynchronously invoke SetLatencyImpl().

◆ SetLatencyImpl()

virtual OSStatus aspl::Device::SetLatencyImpl ( UInt32 latency)
protectedvirtual

Set presentation latency. Invoked by SetLatencyAsync() to actually change latency. Default implementation just changes the value returned by GetLatency().

◆ SetNominalSampleRateAsync()

OSStatus aspl::Device::SetNominalSampleRateAsync ( Float64 rate)

Asynchronously set nominal sample rate. Requests HAL to asynchronously invoke SetNominalSampleRateImpl(). Fails if rate is not present in GetAvailableSampleRates(), which by default returns only one rate, provided during initialization. If you want to make your device supporting multiple rates, you typically need to override both of these methods.

Note
Backs kAudioDevicePropertyNominalSampleRate property.

◆ SetNominalSampleRateImpl()

virtual OSStatus aspl::Device::SetNominalSampleRateImpl ( Float64 rate)
protectedvirtual

Set nominal sample rate. Invoked by SetNominalSampleRateAsync() to actually change the rate. Default implementation just changes the value returned by GetNominalSampleRate().

Note
Backs kAudioDevicePropertyNominalSampleRate property.

◆ SetPreferredChannelCountAsync()

OSStatus aspl::Device::SetPreferredChannelCountAsync ( UInt32 channelCount)

Asynchronously set preferred channel count. See comments for GetPreferredChannelCount(). Requests HAL to asynchronously invoke SetPreferredChannelCountImpl().

Note
Indirectly backs kAudioDevicePropertyPreferredChannelLayout property via GetPreferredChannels() / GetPreferredChannelLayout().

◆ SetPreferredChannelCountImpl()

virtual OSStatus aspl::Device::SetPreferredChannelCountImpl ( UInt32 channelCount)
protectedvirtual

Set preferred channel count. Invoked by SetPreferredChannelCountAsync() to actually change the value. Default implementation changes the value returned by GetPreferredChannelCount(). By default, it also affects values returned by GetPreferredChannels() and GetPreferredChannelLayout().

◆ SetPreferredChannelLayoutAsync()

OSStatus aspl::Device::SetPreferredChannelLayoutAsync ( std::vector< UInt8 > channelLayout)

Asynchronously set preferred channel layout. See comments for GetPreferredChannelLayout(). The provided buffer should contain properly formatted AudioChannelLayout struct. Requests HAL to asynchronously invoke SetPreferredChannelLayoutImpl().

◆ SetPreferredChannelLayoutImpl()

virtual OSStatus aspl::Device::SetPreferredChannelLayoutImpl ( std::vector< UInt8 > channelLayout)
protectedvirtual

Invoked by SetPreferredChannelLayoutAsync() to actually change the value. Default implementation changes the value returned by GetPreferredChannelLayout(). By default, it also affects values returned by GetPreferredChannelCount() and GetPreferredChannels().

◆ SetPreferredChannelsAsync()

OSStatus aspl::Device::SetPreferredChannelsAsync ( std::vector< AudioChannelDescription > channels)

Asynchronously set preferred channels array. See comments for GetPreferredChannels(). Requests HAL to asynchronously invoke SetPreferredChannelsImpl().

Note
Indirectly backs kAudioDevicePropertyPreferredChannelLayout property via GetPreferredChannelLayout().

◆ SetPreferredChannelsForStereoAsync()

OSStatus aspl::Device::SetPreferredChannelsForStereoAsync ( std::array< UInt32, 2 > channels)

Asynchronously set channels for stereo. Channel numbers are 1-based. Requests HAL to asynchronously invoke SetPreferredChannelsForStereoImpl().

◆ SetPreferredChannelsForStereoImpl()

virtual OSStatus aspl::Device::SetPreferredChannelsForStereoImpl ( std::array< UInt32, 2 > channels)
protectedvirtual

Set channels for stereo. Invoked by SetPreferredChannelsForStereoAsync() to actually change the value. Default implementation just changes the value returned GetPreferredChannelsForStereo().

◆ SetPreferredChannelsImpl()

virtual OSStatus aspl::Device::SetPreferredChannelsImpl ( std::vector< AudioChannelDescription > channels)
protectedvirtual

Invoked by SetPreferredChannelsAsync() to actually change the value. Default implementation changes the value returned by GetPreferredChannels(). By default, it also affects values returned by GetPreferredChannelCount() and GetPreferredChannelLayout().

◆ SetPropertyData()

OSStatus aspl::Device::SetPropertyData ( AudioObjectID objectID,
pid_t clientPID,
const AudioObjectPropertyAddress * address,
UInt32 qualifierDataSize,
const void * qualifierData,
UInt32 inDataSize,
const void * inData )
overridevirtual

Change property value.

Reimplemented from aspl::Object.

◆ SetSafetyOffsetAsync()

OSStatus aspl::Device::SetSafetyOffsetAsync ( UInt32 offset)

Asynchronously set safety offset. Requests HAL to asynchronously invoke SetSafetyOffsetImpl().

◆ SetSafetyOffsetImpl()

virtual OSStatus aspl::Device::SetSafetyOffsetImpl ( UInt32 offset)
protectedvirtual

Set safety offset. Invoked by SetSafetyOffsetAsync() to actually change offset. Default implementation just changes the value returned by GetSafetyOffset().

◆ SetZeroTimeStampPeriodAsync()

OSStatus aspl::Device::SetZeroTimeStampPeriodAsync ( UInt32 period)

Asynchronously set zero timestamp period. Requests HAL to asynchronously invoke SetZeroTimeStampPeriodImpl().

◆ SetZeroTimeStampPeriodImpl()

virtual OSStatus aspl::Device::SetZeroTimeStampPeriodImpl ( UInt32 period)
protectedvirtual

Set zero timestamp period. Invoked by SetZeroTimeStampPeriodAsync() to actually change period. Default implementation just changes the value returned by GetZeroTimeStampPeriod().

◆ StartIO()

virtual OSStatus aspl::Device::StartIO ( AudioObjectID objectID,
UInt32 clientID )
virtual

Tell the device to start I/O. Invokes ControlRequestHandler::OnStartIO() and updates GetIsRunning(). GetIsRunning() will return true until at least one client is doing I/O.

Note
Calls StartIOImpl(), which you can override if needed. You can also replace I/O handling entirely by overriding top-level methods: StartIO(), StopIO(), GetZeroTimeStamp(), WillDoIOOperation(), BeginIOOperation(), DoIOOperation(), EndIOOperation(). If you override top-level (non-Impl) methods, you likely need to override all of them together and implement your own locking.
Invoked by HAL on non-realtime thread.

◆ StartIOImpl()

virtual OSStatus aspl::Device::StartIOImpl ( UInt32 clientID,
UInt32 startCount )
protectedvirtual

Prepare device to start I/O. Invoked by StartIO().

Remarks
StartIOImpl() is responsible for preparing to serve I/O requests. Default implementation invokes ControlRequestHandler::OnStartIO() and resets anchor timestamp and period counters, which are then used by GetZeroTimeStampImpl().
Note
startCount is incremented each time when StartIO() is called, and decremented when StopIO() is called. Zero startCount means that the device is switching from non-running to running state, and often only this case needs handling in StartIOImpl().
StartIOImpl() gets startCount before it's incremented.
For most uses cases, it is enough to provide ControlRequestHandler and there is no need to override this method.

◆ StopIO()

virtual OSStatus aspl::Device::StopIO ( AudioObjectID objectID,
UInt32 clientID )
virtual

Tell the device to stop I/O. Invokes ControlRequestHandler::OnStopIO() and updates GetIsRunning(). GetIsRunning() will return true until at least one client is doing I/O.

Note
Calls StopIOImpl(), which you can override if needed. You can also replace I/O handling entirely by overriding top-level methods: StartIO(), StopIO(), GetZeroTimeStamp(), WillDoIOOperation(), BeginIOOperation(), DoIOOperation(), EndIOOperation(). If you override top-level (non-Impl) methods, you likely need to override all of them together and implement your own locking.
Invoked by HAL on non-realtime thread.

◆ StopIOImpl()

virtual OSStatus aspl::Device::StopIOImpl ( UInt32 clientID,
UInt32 startCount )
protectedvirtual

Prepare device to finish I/O. Invoked by StopIO().

Remarks
StopIOImpl() is responsible for cleanup after serving I/O requests. Default implementation just invokes ControlRequestHandler::OnStopIO().
Note
startCount is incremented each time when StartIO() is called, and decremented when StopIO() is called. Zero startCount means that the device is switching from running to non-running state, and often only this case needs handling in StopIOImpl().
StopIOImpl() gets startCount after it's decremented.
For most uses cases, it is enough to provide ControlRequestHandler and there is no need to override this method.

◆ WillDoIOOperation()

virtual OSStatus aspl::Device::WillDoIOOperation ( AudioObjectID objectID,
UInt32 clientID,
UInt32 operationID,
Boolean * outWillDo,
Boolean * outWillDoInPlace )
virtual

Asks device whether it want to perform the given phase of the IO cycle. In default implementation, makes decision based on whether the device has input and output streams, and what is returned by DeviceParameters::EnableMixing.

Note
Calls WillDoIOOperationImpl(), which you can override if needed. See also comments for StartIO() and StopIO().
Invoked by HAL on realtime thread.

◆ WillDoIOOperationImpl()

virtual OSStatus aspl::Device::WillDoIOOperationImpl ( UInt32 clientID,
UInt32 operationID,
Boolean * outWillDo,
Boolean * outWillDoInPlace )
protectedvirtual

Asks device whether it want to perform the given phase of the IO cycle. Invoked by WillDoIOOperation().

Remarks
In default implementation, makes decision based on whether the device has input and output streams, and what is returned by DeviceParameters::EnableMixing.

The documentation for this class was generated from the following file: