carb::audio::IAudioPlayback

Defined in carb/audio/IAudioPlayback.h

struct IAudioPlayback

Low-Level Audio Playback Plugin Interface.

See these pages for more detail:

Public Members

size_t (*getDeviceCount)()

retrieves the current audio output device count for the system.

Note

The device count is a potentially volatile value. This can change at any time without notice due to user action. For example, the user could remove an audio device from the system or add a new one at any time. Thus it is a good idea to open the device as quickly as possible after choosing the device index. There is no guarantee that the device list will even remain stable during a single device enumeration loop. The only device index that is guaranteed to be valid is the system default device index of 0.

Return

the number of audio output devices that are currently connected to the system. Device 0 in the list will be the system’s default or preferred device.

AudioResult (*getDeviceCaps)(size_t deviceIndex, DeviceCaps *caps)

retrieves the capabilities and information about a single audio output device.

Remark

This retrieves information about a single audio output device. The information will be returned in the info buffer. This may fail if the device corresponding to the requested index has been removed from the system.

Param deviceIndex

[in] the index of the device to retrieve info for. This must be between 0 and the most recent return value from getDeviceCount().

Param caps

[out] receives the device information. The thisSize value must be set to sizeof(DeviceCaps) before calling.

Return

AudioResult::eOk if the device info was successfully retrieved.

Return

AudioResult::eInvalidParameter if the thisSize value is not properly initialized in caps or caps is nullptr.

Return

AudioResult::eOutOfRange if the requested device index is out of range of the system’s current device count.

Return

AudioResult::eNotSupported if a device is found but it requires an unsupported sample format.

Return

an AudioResult::* error code if the requested device index was out of range or the info buffer was invalid.

Context *(*createContext)(const PlaybackContextDesc *desc)

creates a new audio output context object.

Remark

This creates a new audio output context object. This object is responsible for managing all access to a single instance of the audio context. Note that there will be a separate audio engine thread associated with each instance of this context object.

Remark

Upon creation, this object will be in a default state. This means that the selected device will be opened and its processing engine created. It will output at the chosen device’s default frame rate and channel count. If needed, a new device may be selected with setOutput(). If a custom speaker mask (ie: not one of the standard preset kSpeakerMode* modes) was specified when creating the context or a device or speaker mask with more than Speaker::eCount channels was used, the caller must make a call to setSpeakerDirections() before any spatial sounds can be played. Failing to do so will result in undefined behavior in the final audio output.

Note

If selecting a device fails during context creation, the context will still be created successfully and be valid for future operations. The caller will have to select another valid device at a later point before any audio will be output however. A caller can check if a device has been opened successfully by calling getContextCaps() and checking the selectedDevice.flags member to see if it has been set to something other than fDeviceFlagNotOpen.

Param desc

[in] a description of the initial settings and capabilities to use for the new context object. Set this to nullptr to use all default context settings.

Return

the newly created audio output context object.

AudioResult (*destroyContext)(Context *context)

destroys an audio output context object.

Remark

This destroys an audio output context object that was previously created with createContext(). If the context is still active and has a running mixer, it will be stopped before the object is destroyed. All resources associated with the device will be both invalidated and destroyed as well. Only audio data buffers that were queued on voices will be left (it is the caller’s responsibility to destroy those).

Param context

[in] the context object to be destroyed. Upon return, this object will no longer be valid.

Retval AudioResult::eOk.

const ContextCaps *(*getContextCaps)(Context *context)

retrieves the current capabilities and settings for a context object.

Remark

This retrieves the current capabilities and settings for a context object. Some of these settings may change depending on whether the context has opened an output device or not.

Param context

[in] the context object to retrieve the capabilities for.

Return

the context’s current capabilities and settings. This includes the speaker mode, speaker positions, maximum bus count, and information about the output device that is opened (if any).

Return

nullptr if context is nullptr.

void (*setContextParameters)(Context *context, ContextParamFlags paramsToSet, const ContextParams *params)

sets one or more parameters on a context.

Remark

This sets one or more context parameters in a single call. Only parameters that have their corresponding flag set in paramsToSet will be modified. If a change is to be relative to the context’s current parameter value, the current value should be retrieved first, modified, then set.

Param context

[in] the context to set the parameter(s) on. This may not be nullptr.

Param paramsToSet

[in] the set of flags to indicate which parameters in the parameter block params are valid and should be set on the context. This may be zero or more of the fContextParam* flags. If this is 0, the call will be treated as a no-op.

Param params

[in] the parameter(s) to be set on the context. The flags indicating which parameters need to be set are given in paramsToSet. Undefined behavior may occur if a flag is set but its corresponding value(s) have not been properly initialized. This may not be nullptr.

Return

no return value.

void (*getContextParameters)(Context *context, ContextParamFlags paramsToGet, ContextParams *params)

retrieves one or more parameters for a context.

Remark

This retrieves the current values of one or more of a context’s parameters. Only the parameter values listed in paramsToGet flags will be guaranteed to be valid upon return.

Param context

[in] the context to retrieve parameters for. This may not be nullptr.

Param paramsToGet

[in] flags indicating which parameter values need to be retrieved.

Param params

[out] receives the requested parameter values. This may not be nullptr.

Return

no return value.

bool (*setBusCount)(Context *ctx, size_t count)

Change the maximum number of voices that have their output mixed to the audio device.

Note

This call needs to stop the audio engine, so this will block for 10-20ms if any voices are still playing actively.

Note

This should be called infrequently and only in cases where destroying the context is not an option.

Note

To use this function without introducing audio artifacts, this function can only be called after all voices playing on buses have become silent or have stopped. The easiest way to ensure this is to set the master volume on the context to 0.0. At least 10ms must elapse between the volume reduction and this call to ensure that the changes have taken effect. If voices are being stopped, 20ms must occur between the last stopped voice and this call.

Param ctx

[in] The context to modify.

Param count

[in] The new number of buses to select. This will be clamped to PlaybackContextDesc::maxBuses, if count exceeds it. This cannot be set to 0.

Return

true if the max bus count was successfully changed.

Return

false if any voices are still playing on buses.

Return

false if the operation failed for any other reason (e.g. out of memory).

bool (*setSpeakerDirections)(Context *context, const SpeakerDirectionDesc *desc)

sets the [real biological] listener-relative position for all speakers.

Remark

This allows a custom user-relative direction to be set for all speakers. Note that these represent the positions of the speakers in the real physical world not an entity in the simulated world. A speaker direction is specified as a 3-space vector with a left-to-right position, a front-to-back position, and a top-to-bottom position. Each coordinate is expected to be within the range -1.0 (left, back, or bottom) to 1.0 (right, front, or top). Each speaker direction is specified with these three explicit positions instead of an X/Y/Z vector to avoid confusion between various common coordinate systems (ie: graphics systems often treat negative Z as forward into the screen whereas audio systems often treat Z as up).

Remark

When a new device is selected with setOutput(), any previous custom speaker directions will be reset to the implicit positions of the new speaker mode. The new speaker directions are defined on a cube where the origin (ie: the point (0, 0, 0)) represents the position of the user at the center of the cube. All values should range from -1.0 to 1.0. The given speaker direction vectors do not need to be normalized - this will be done internally. The distance from the origin is not important and does not affect spatial sound calculations. Only the speaker directions from the user are important.

Remark

These speaker directions are used to affect how spatial audio calculations map from the simulated world to the physical world. They will affect the left-to- right, front-to-back, and top-to-bottom balancing of the different sound channels in each spatial sound calculation.

Note

For most applications, setting custom speaker directions is not necessary. This would be necessary in situations that use custom speaker modes, situations where the expected speaker layout is drastically different from any of the standard speaker modes that may be chosen (ie: a car speaker system), or when the speaker count does not map to a standard kSpeakerMode* speaker mode.

Note

An output must have been successfully selected on the context before this call can succeed. This can be checked by verifying that the context caps block’s selectedDevice.flags member is not fDeviceFlagNotOpen.

Param context

[in] the context object to set the speaker positions for. This may not be nullptr.

Param desc

[in] a descriptor of the new speaker directions to set for the context. This may be nullptr to restore the default speaker directions for the currently selected device if it supports a standard speaker mode channel count.

Return

true if the new speaker layout is successfully set.

Return

false if the call fails or the given speaker mode doesn’t match what the device was opened at.

AudioResult (*setOutput)(Context *context, const OutputDesc *desc)

opens a requested audio output device and begins output.

Remark

This sets the index of the audio output device that will be opened and attempts to open it. An index of 0 will open the system’s default audio output device. Note that the device index value is volatile and could change at any time due to user activity. It is suggested that the device index be chosen as closely as possible to when the device will be opened.

Remark

This allows an existing audio context object to switch to using a different audio device for its output after creation without having to destroy and recreate the current state of the context. Once a new device is selected, it will be available to start processing and outputting audio. Note that switching audio devices dynamically may cause an audible pop to occur on both the old device and new device depending on the current state of the context. To avoid this, all active voices could be muted or paused briefly during the device switch, then resumed or un-muted after it completes.

Note

If selecting the new device fails, the context will be left without a device to play its output on. Upon failure, an attempt to open the system’s default device may be made by the caller to restore the playback. Note that even choosing the system default device may fail for various reasons (ie: the speaker mode of the new device cannot be mapped properly, the device is no longer available in the system, etc). In this case, all audio processing will still continue but the final audio data will just be dropped until a valid output target is connected.

Param context

[in] the context object that will have its device index set. This is returned from a previous call to createContext(). This must not be nullptr.

Param desc

[in] the descriptor of the output to open. This may be nullptr to use the default system output device.

Retval AudioResult::eOk

if the requested device is successfully opened.

Retval AudioResult::eOutOfRange

if the device index is invalid.

Return

an AudioResult::* error code if the operation fails for any other reason. See the notes below for more information on failures.

AudioResult (*update)(Context *context)

performs required frequent updates for the audio context.

Remark

This performs common update tasks. Updates need to be performed frequently. This will perform any pending callbacks and will ensure that all pending parameter changes have been updated in the engine context. This should still be called periodically even if no object parameter changes occur.

Remark

All non-realtime voice callbacks will be performed during this call. All device change callbacks on the context will also be performed here. Failing to call this periodically may cause events to be lost.

Param context

[in] the context object to perform update tasks on.

Retval AudioResult::eOk

if the update is performed successfully.

Retval AudioResult::eDeviceDisconnected

or AudioResult::eDeviceLost if the currently selected device has been removed from the system.

Retval AudioResult::eDeviceNotOpen

if no device has been opened.

Retval AudioResult::eInvalidParameter

if an invalid context is passed in.

Return

an AudioResult::* error code if the update fails for any other reason.

void (*startProcessing)(Context *context)

starts the audio processing engine for a context.

Remark

This starts the audio processing engine for a context. When creating a playback context, the processing engine will always be automatically started. When creating a baking context, the processing engine must always be started explicitly. This allows the baking operation to be fully setup (ie: queue all sounds to be played, set all parameters, etc) before any audio is processed. This prevents the baked result from containing an indeterminate amount of silence at the start of its stream.

Remark

When using a playback context, this does not need to be called unless the engine is being restarted after calling stopProcessing().

Param context

[in] the context to start the processing engine for. This must not be nullptr.

Return

no return value.

void (*stopProcessing)(Context *context)

stops the processing engine for a context.

Remark

This stops the audio processing engine for a context. For a playback context, this is not necessary unless all processing needs to be halted for some reason. For a baking context, this is only necessary if the fContextFlagManualStop flag was used when creating the context. If that flags is used, the processing engine will be automatically stopped any time it runs out of data to process.

Note

Stopping the engine is not the same as pausing the output. Stopping the engine will cause any open streamers to be closed and will likely cause an audible pop when restarting the engine with startProcessing().

Param context

[in] the context to stop the processing engine for. This must not be nullptr.

Return

no return value.

Voice *(*playSound)(Context *context, const PlaySoundDesc *desc)

schedules a sound to be played on a voice.

Remark

This schedules a sound object to be played on a voice. The sounds current settings (ie: volume, pitch, playback frame rate, pan, etc) will be assigned to the voice as ‘defaults’ before playing. Further changes can be made to the voice’s state at a later time without affecting the sound’s default settings.

Remark

Once the sound finishes playing, it will be implicitly unassigned from the voice. If the sound or voice have a callback set, a notification will be received for the sound having ended.

Remark

If the playback of this sound needs to be stopped, it must be explicitly stopped from the returned voice object using stopVoice(). This can be called on a single voice or a voice group.

Param context

[in] the context to play the new sound on. This must not be nullptr.

Param desc

[in] the descriptor of the play task to be performed. This may not be nullptr.

Return

a new voice handle representing the playing sound. Note that if no buses are currently available to play on or the voice’s initial parameters indicated that it is not currently audible, the voice will be virtual and will not be played. The voice handle will still be valid in this case and can be operated on, but no sound will be heard from it until it is determined that it should be converted to a real voice. This can only occur when the update() function is called. This voice handle does not need to be closed or destroyed. If the voice finishes its play task, any future calls attempting to modify the voice will simply fail.

Return

nullptr if the requested sound is already at or above its instance limit and the fPlayFlagMaxInstancesSimulate flag is not used.

Return

nullptr if the play task was invalid or could not be started properly. This can most often occur in the case of streaming sounds if the sound’s original data could not be opened or decoded properly.

void (*stopVoice)(Voice *voice)

stops playback on a voice.

Remark

This stops a voice from playing its current sound. This will be silently ignored for any voice that is already stopped or for an invalid voice handle. Once stopped, the voice will be returned to a ‘free’ state and its sound data object unassigned from it. The voice will be immediately available to be assigned a new sound object to play from.

Note

This will only schedule the voice to be stopped. Its volume will be implicitly set to silence to avoid a popping artifact on stop. The voice will continue to play for one more engine cycle until the volume level reaches zero, then the voice will be fully stopped and recycled. At most, 1ms of additional audio will be played from the voice’s sound.

Param voice

[in] the voice to stop.

Return

no return value.

SoundData *(*getPlayingSound)(Voice *voice)

retrieves the sound (if any) that is currently active on a voice.

Remark

This retrieves the sound data object that is currently being processed on a voice. This can be used to make a connection between a voice and the sound data object it is currently processing.

Note

If voice ends, the returned sound will be freed in the next update() call. It is the caller’s responsibility to call IAudioData::acquire() if the object is going to be held until after that update() call. It is also the caller’s responsibility to ensure acquiring this reference is done in a thread safe manner with respect to the update() call.

Param voice

[in] the voice to retrieve the active sound for.

Return

the sound object that is currently playing on the requested voice.

Return

nullptr if the voice is not currently playing any sound object.

Return

nullptr if the given voice handle is no longer valid.

bool (*isPlaying)(Voice *voice)

checks the playing state of a voice.

Remark

This checks if a voice is currently playing. A voice is considered playing if it has a currently active sound data object assigned to it, it is not paused, and its play task has not completed yet. This will start failing immediately upon the voice completing its play task instead of waiting for the voice to be recycled on the next update() call.

Param voice

[in] the voice to check the playing state for.

Return

true if the requested voice is playing.

Return

false if the requested voice is not playing or is paused.

Return

false if the given voice handle is no longer valid.

bool (*setLoopPoint)(Voice *voice, const LoopPointDesc *desc)

sets a new loop point as current on a voice.

Remark

This sets a new loop point for a playing voice. This allows for behavior such as sound atlases or sound playlists to be played out on a single voice. Ideally this should be called from a VoiceCallbackType::eLoopPoint callback to ensure the new buffer is queued without allowing the voice to finish on its own and to prevent a potential race condition between the engine and the host app setting the new loop point. Calling this in a real-time callback would guarantee no race would occur, however it could still be done safely in a non-real-time callback if the voice’s current loop region is long enough and the update() function is called frequently enough.

Remark

This could also be called from a VoiceCallbackType::eSoundEnded callback, but only if it is done in a real-time callback. In a non-real-time callback the voice handle will already have been invalidated by the time the update() function performs the callback.

Remark

When desc is nullptr or the contents of the descriptor do not specify a new loop point, this will immediately break the loop that is currently playing on the voice. This will have the effect of setting the voice’s current loop count to zero. The sound on the voice will continue to play out its current loop iteration, but will not loop again when it reaches its end. This is useful for stopping a voice that is playing an infinite loop or to prematurely stop a voice that was set to loop a specific number of times. This call will effectively be ignored if passed in a voice that is not currently looping.

Note

For streaming voices, updating a loop point will have a delay due to buffering the decoded data. The sound will loop an extra time if the loop point is changed after the buffering has started to consume another loop. The default buffer time for streaming sounds is currently 200 milliseconds, so this is the minimum slack time that needs to be given for a loop change. This means that changing a loop point in a VoiceCallbackType::eLoopPoint callback will result in an extra loop occurring for a streaming sound.

Param voice

[in] the voice to set the loop point on. This may not be nullptr.

Param desc

[in] descriptor of the new loop point to set. This may contain a loop or event point from the sound itself or an explicitly specified loop point. This may be nullptr to indicate that the current loop point should be removed and the current loop broken. Similarly, an empty loop point descriptor could be passed in to remove the current loop point.

Return

true if the new loop point is successfully set.

Return

false if the voice handle is invalid or the voice has already stopped on its own.

Return

false if the new loop point is invalid, not found in the sound data object, or specifies a starting point or length that is outside the range of the sound data object’s buffer.

size_t (*getPlayCursor)(Voice *voice, UnitType type)

retrieves the current play cursor position of a voice.

Remark

This retrieves the current play position for a voice. This is not necessarily the position in the buffer being played, but rather the position in the sound data object’s stream. For streaming sounds, this will be the offset from the start of the stream. For non-streaming sounds, this will be the offset from the beginning of the sound data object’s buffer.

Note

If the loop point for the voice changes during playback, the results of this call can be unexpected. Once the loop point changes, there is no longer a consistent time base for the voice and the results will reflect the current position based off of the original loop’s time base. As long as the voice’s original loop point remains (ie: setLoopPoint() is never called on the voice), the calculated position should be correct.

Note

It is the caller’s responsibility to ensure that this is not called at the same time as changing the loop point on the voice or stopping the voice.

Param voice

[in] the voice to retrieve the play position for.

Param type

[in] the units to retrieve the current position in.

Return

the current position of the voice in the requested units.

Return

0 if the voice does not have a sound assigned to it.

Return

the last play cursor position if the voice is paused.

void (*setVoiceParameters)(Voice *voice, VoiceParamFlags paramsToSet, const VoiceParams *params)

sets one or more parameters on a voice.

Remark

This sets one or more voice parameters in a single call. Only parameters that have their corresponding flag set in paramsToSet will be modified. If a change is to be relative to the voice’s current parameter value, the current value should be retrieved first, modified, then set.

Note

only one of fPlaybackModeSimulatePosition or fPlaybackModeNoPositionSimulation can be set in the playback mode. If none or both of the flags are set, the previous value of those two bits will be used.

Param voice

[in] the voice to set the parameter(s) on.

Param paramsToSet

[in] flags to indicate which of the parameters need to be updated. This may be one or more of the fVoiceParam* flags. If this is 0, this will simply be a no-op.

Param params

[in] the parameter(s) to be set on the voice. The flags indicating which parameters need to be set must be set in paramsToSet by the caller. Undefined behavior may occur if a flag is set but its corresponding value(s) have not been properly initialized. This may not be nullptr.

Return

no return value.

void (*getVoiceParameters)(Voice *voice, VoiceParamFlags paramsToGet, VoiceParams *params)

retrieves one or more parameters for a voice.

Remark

This retrieves the current values of one or more of a voice’s parameters. Only the parameter values listed in paramsToGet flags will be guaranteed to be valid upon return.

Param voice

[in] the voice to retrieve parameters for.

Param paramsToGet

[in] flags indicating which parameter values need to be retrieved.

Param params

[out] receives the requested parameter values. This may not be nullptr.

Return

no return value.

void (*stopAllVoices)(Context *context)

stops playback on all voices in a given context.

Remark

The input context parameter can be nullptr, meaning to stop playback on all voices in all contexts in the context table.

Param context

[in] the context where to stop playback the voices.

Public Static Functions

static inline constexpr carb::InterfaceDesc getInterfaceDesc() noexcept

Returns information about this interface.

Auto-generated by CARB_PLUGIN_INTERFACE() or CARB_PLUGIN_INTERFACE_EX.

Returns

The carb::InterfaceDesc struct with information about this interface.

static inline constexpr carb::InterfaceDesc getLatestInterfaceDesc() noexcept

Returns information about the latest version of this interface.

Auto-generated by CARB_PLUGIN_INTERFACE() or CARB_PLUGIN_INTERFACE_EX.

Returns

The carb::InterfaceDesc struct with information about the latest version of this interface.