SDL3pp
A slim C++ wrapper for SDL3
|
The opaque handle that represents an audio stream. More...
Public Member Functions | |
AudioStreamBase (OptionalRef< const AudioSpec > src_spec, OptionalRef< const AudioSpec > dst_spec) | |
Create a new audio stream. | |
AudioStreamBase (const AudioDeviceBase &devid, OptionalRef< const AudioSpec > spec=std::nullopt, AudioStreamCallback callback=nullptr, void *userdata=nullptr) | |
Convenience function for straightforward audio init for the common case. | |
AudioStreamBase (const AudioDeviceBase &devid, OptionalRef< const AudioSpec > spec, AudioStreamCB callback) | |
Convenience function for straightforward audio init for the common case. | |
PropertiesRef | GetProperties () const |
Get the properties associated with an audio stream. | |
AudioSpec | GetInputFormat () const |
Query the current input format of an audio stream. | |
AudioSpec | GetOutputFormat () const |
Query the current output format of an audio stream. | |
void | GetFormat (AudioSpec *src_spec, AudioSpec *dst_spec) const |
Query the current format of an audio stream. | |
void | SetInputFormat (const AudioSpec &spec) |
Change the input format of an audio stream. | |
void | SetOutputFormat (const AudioSpec &spec) |
Change the output format of an audio stream. | |
void | SetFormat (OptionalRef< const AudioSpec > src_spec, OptionalRef< const AudioSpec > dst_spec) |
Change the input and output formats of an audio stream. | |
float | GetFrequencyRatio () const |
Get the frequency ratio of an audio stream. | |
void | SetFrequencyRatio (float ratio) |
Change the frequency ratio of an audio stream. | |
float | GetGain () const |
Get the gain of an audio stream. | |
void | SetGain (float gain) |
Change the gain of an audio stream. | |
OwnArray< int > | GetInputChannelMap () const |
Get the current input channel map of an audio stream. | |
OwnArray< int > | GetOutputChannelMap () const |
Get the current output channel map of an audio stream. | |
void | SetInputChannelMap (std::span< int > chmap) |
Set the current input channel map of an audio stream. | |
void | SetOutputChannelMap (std::span< int > chmap) |
Set the current output channel map of an audio stream. | |
void | PutData (SourceBytes buf) |
Add data to the stream. | |
int | GetData (TargetBytes buf) |
Get converted/resampled data from the stream. | |
int | GetAvailable () const |
Get the number of converted/resampled bytes available. | |
int | GetQueued () const |
Get the number of bytes currently queued. | |
void | Flush () |
Tell the stream that you're done sending data, and anything being buffered should be converted/resampled and made available immediately. | |
void | Clear () |
Clear any pending data in the stream. | |
void | PauseDevice () |
Use this function to pause audio playback on the audio device associated with an audio stream. | |
void | ResumeDevice () |
Use this function to unpause audio playback on the audio device associated with an audio stream. | |
bool | DevicePaused () const |
Use this function to query if an audio device associated with a stream is paused. | |
AudioStreamLock | Lock () |
Lock an audio stream for serialized access. | |
void | SetGetCallback (AudioStreamCB callback) |
Set a callback that runs when data is requested from an audio stream. | |
void | SetGetCallback (AudioStreamCallback callback, void *userdata) |
Set a callback that runs when data is requested from an audio stream. | |
void | SetPutCallback (AudioStreamCB callback) |
Set a callback that runs when data is added to an audio stream. | |
void | SetPutCallback (AudioStreamCallback callback, void *userdata) |
Set a callback that runs when data is added to an audio stream. | |
void | Bind (AudioDeviceBase &devid) |
Bind a single audio stream to an audio device. | |
void | Unbind () |
Unbind a single audio stream from its audio device. | |
AudioDeviceRef | GetDevice () const |
Query an audio stream for its currently-bound device. | |
constexpr | Resource (T resource={}) |
Constructs the underlying resource. | |
constexpr | Resource (std::nullptr_t) |
Equivalent to default ctor. | |
constexpr | Resource (std::nullopt_t) |
Equivalent to default ctor. | |
Resource (const Resource &other)=delete | |
Resource (Resource &&other)=delete | |
![]() | |
constexpr | Resource (SDL_AudioStream * resource={}) |
Constructs the underlying resource. | |
constexpr | Resource (std::nullptr_t) |
Equivalent to default ctor. | |
constexpr | Resource (std::nullopt_t) |
Equivalent to default ctor. | |
Resource (const Resource &other)=delete | |
Resource (Resource &&other)=delete | |
Resource & | operator= (const Resource &other)=delete |
Resource & | operator= (Resource &&other)=delete |
constexpr | operator bool () const |
True if contains a valid resource. | |
constexpr bool | operator== (const Resource &other) const=default |
Comparison. | |
constexpr bool | operator== (std::nullopt_t) const |
Comparison. | |
constexpr bool | operator== (std::nullptr_t) const |
Comparison. | |
constexpr SDL_AudioStream * | get () const |
Return contained resource;. | |
constexpr SDL_AudioStream * | release (SDL_AudioStream * newResource={}) |
Return contained resource and empties or replace value. | |
constexpr const SDL_AudioStream * | operator-> () const |
Access to fields. | |
constexpr SDL_AudioStream * | operator-> () |
Access to fields. | |
AudioStreamBase is an audio conversion interface.
Audio streams are the core of the SDL3 audio interface. You create one or more of them, bind them to an opened audio device, and feed data to them (or for recording, consume data from them).
|
inline |
|
inline |
If all your app intends to do is provide a single source of PCM audio, this function allows you to do all your audio setup in a single call.
This is also intended to be a clean means to migrate apps from SDL2.
This function will open an audio device, create a stream and bind it. Unlike other methods of setup, the audio device will be closed when this stream is destroyed, so the app can treat the returned AudioStreamBase as the only object needed to manage audio playback.
Also unlike other functions, the audio device begins paused. This is to map more closely to SDL2-style behavior, since there is no extra step here to bind a stream to begin audio flowing. The audio device should be resumed with AudioStreamBase.ResumeDevice(stream);
This function works with both playback and recording devices.
The spec
parameter represents the app's side of the audio stream. That is, for recording audio, this will be the output format, and for playing audio, this will be the input format. If spec is nullptr, the system will choose the format, and the app can use AudioStreamBase.GetFormat() to obtain this information later.
If you don't care about opening a specific audio device, you can (and probably should), use AUDIO_DEVICE_DEFAULT_PLAYBACK for playback and AUDIO_DEVICE_DEFAULT_RECORDING for recording.
One can optionally provide a callback function; if nullptr, the app is expected to queue audio data for playback (or unqueue audio data if capturing). Otherwise, the callback will begin to fire once the device is unpaused.
Destroying the returned stream with AudioStreamRef.reset will also close the audio device associated with this stream.
devid | an audio device to open, or AUDIO_DEVICE_DEFAULT_PLAYBACK or AUDIO_DEVICE_DEFAULT_RECORDING. |
spec | the audio stream's data format. Can be std::nullopt. |
callback | a callback where the app will provide new data for playback, or receive new data for recording. Can be nullptr, in which case the app will need to call AudioStreamBase.PutData or AudioStreamBase.GetData as necessary. |
userdata | app-controlled pointer passed to callback. Can be nullptr. Ignored if callback is nullptr. |
Error | on failure. |
|
inline |
If all your app intends to do is provide a single source of PCM audio, this function allows you to do all your audio setup in a single call.
This is also intended to be a clean means to migrate apps from SDL2.
This function will open an audio device, create a stream and bind it. Unlike other methods of setup, the audio device will be closed when this stream is destroyed, so the app can treat the returned AudioStreamBase as the only object needed to manage audio playback.
Also unlike other functions, the audio device begins paused. This is to map more closely to SDL2-style behavior, since there is no extra step here to bind a stream to begin audio flowing. The audio device should be resumed with AudioStreamBase.ResumeDevice(stream);
This function works with both playback and recording devices.
The spec
parameter represents the app's side of the audio stream. That is, for recording audio, this will be the output format, and for playing audio, this will be the input format. If spec is nullptr, the system will choose the format, and the app can use AudioStreamBase.GetFormat() to obtain this information later.
If you don't care about opening a specific audio device, you can (and probably should), use AUDIO_DEVICE_DEFAULT_PLAYBACK for playback and AUDIO_DEVICE_DEFAULT_RECORDING for recording.
One can optionally provide a callback function; if nullptr, the app is expected to queue audio data for playback (or unqueue audio data if capturing). Otherwise, the callback will begin to fire once the device is unpaused.
Destroying the returned stream with AudioStreamRef.reset will also close the audio device associated with this stream.
devid | an audio device to open, or AUDIO_DEVICE_DEFAULT_PLAYBACK or AUDIO_DEVICE_DEFAULT_RECORDING. |
spec | the audio stream's data format. Can be std::nullopt. |
callback | a callback where the app will provide new data for playback, or receive new data for recording. Can not be nullptr. |
Error | on failure. |
|
inline |
This is a convenience function, equivalent to calling AudioDeviceBase.BindAudioStreams(devid, &stream, 1)
.
devid | the device to bind to. |
Error | on failure. |
|
inline |
|
inline |
Unlike in SDL2, audio devices start in an unpaused state, since an app has to bind a stream before any audio will flow.
|
inline |
It is legal to add more data to a stream after flushing, but there may be audio gaps in the output. Generally this is intended to signal the end of input, so the complete output becomes available.
Error | on failure. |
|
inline |
The stream may be buffering data behind the scenes until it has enough to resample correctly, so this number might be lower than what you expect, or even be zero. Add more data or flush the stream if you need the data now.
If the stream has so much data that it would overflow an int, the return value is clamped to a maximum value, but no queued data is lost; if there are gigabytes of data queued, the app might need to read some of it with AudioStreamBase.GetData before this function's return value is no longer clamped.
|
inline |
The input/output data format/channels/samplerate is specified when creating the stream, and can be changed after creation by calling AudioStreamBase.SetFormat.
Note that any conversion and resampling necessary is done during this call, and AudioStreamBase.PutData simply queues unconverted data for later. This is different than SDL2, where that work was done while inputting new data to the stream and requesting the output just copied the converted data.
buf | a buffer to fill with audio data. |
|
inline |
This reports the audio device that an audio stream is currently bound to.
If not bound, or invalid, this returns zero, which is not a valid device ID.
src_spec | where to store the input audio format; ignored if nullptr. |
dst_spec | where to store the output audio format; ignored if nullptr. |
Error | on failure. |
|
inline |
|
inline |
The gain of a stream is its volume; a larger gain means a louder output, with a gain of zero being silence.
Audio streams default to a gain of 1.0f (no change in output).
|
inline |
Channel maps are optional; most things do not need them, instead passing data in the order that SDL expects.
Audio streams default to no remapping applied. This is represented by returning nullptr, and does not signify an error.
|
inline |
Error | on failure. |
|
inline |
Channel maps are optional; most things do not need them, instead passing data in the order that SDL expects.
Audio streams default to no remapping applied. This is represented by returning nullptr, and does not signify an error.
|
inline |
Error | on failure. |
|
inline |
|
inline |
This is the number of bytes put into a stream as input, not the number that can be retrieved as output. Because of several details, it's not possible to calculate one number directly from the other. If you need to know how much usable data can be retrieved right now, you should use AudioStreamBase.GetAvailable() and not this function.
Note that audio streams can change their input format at any time, even if there is still data queued in a different format, so the returned byte count will not necessarily match the number of sample frames available. Users of this API should be aware of format changes they make when feeding a stream and plan accordingly.
Queued data is not converted until it is consumed by AudioStreamBase.GetData, so this value should be representative of the exact data that was put into the stream.
If the stream has so much data that it would overflow an int, the return value is clamped to a maximum value, but no queued data is lost; if there are gigabytes of data queued, the app might need to read some of it with AudioStreamBase.GetData before this function's return value is no longer clamped.
|
inline |
This function pauses audio processing for a given device. Any bound audio streams will not progress, and no audio will be generated. Pausing one device does not prevent other unpaused devices from running.
Pausing a device can be useful to halt all audio without unbinding all the audio streams. This might be useful while a game is paused, or a level is loading, etc.
Error | on failure. |
|
inline |
This data must match the format/channels/samplerate specified in the latest call to AudioStreamBase.SetFormat, or the format specified when creating the stream if it hasn't been changed.
Note that this call simply copies the unconverted data for later. This is different than SDL2, where data was converted during the Put call and the Get call would just dequeue the previously-converted data.
buf | a span with the audio data to add. |
Error | on failure. |
|
inline |
This function unpauses audio processing for a given device that has previously been paused. Once unpaused, any bound audio streams will begin to progress again, and audio can be generated.
Remember, AudioStreamBase.AudioStreamBase opens device in a paused state, so this function call is required for audio playback to begin on such device.
Error | on failure. |
|
inline |
Future calls to and AudioStreamBase.GetAvailable and AudioStreamBase.GetData will reflect the new format, and future calls to AudioStreamBase.PutData must provide data in the new input formats.
Data that was previously queued in the stream will still be operated on in the format that was current when it was added, which is to say you can put the end of a sound file in one format to a stream, change formats for the next sound file, and start putting that new data while the previous sound file is still queued, and everything will still play back correctly.
If a stream is bound to a device, then the format of the side of the stream bound to a device cannot be changed (src_spec for recording devices, dst_spec for playback devices). Attempts to make a change to this side will be ignored, but this will not report an error. The other side's format can be changed.
src_spec | the new format of the audio input; if std::nullopt, it is not changed. |
dst_spec | the new format of the audio output; if std::nullopt, it is not changed. |
Error | on failure. |
|
inline |
The frequency ratio is used to adjust the rate at which input data is consumed. Changing this effectively modifies the speed and pitch of the audio. A value greater than 1.0 will play the audio faster, and at a higher pitch. A value less than 1.0 will play the audio slower, and at a lower pitch.
This is applied during AudioStreamBase.GetData, and can be continuously changed to create various effects.
ratio | the frequency ratio. 1.0 is normal speed. Must be between 0.01 and 100. |
Error | on failure. |
|
inline |
The gain of a stream is its volume; a larger gain means a louder output, with a gain of zero being silence.
Audio streams default to a gain of 1.0f (no change in output).
This is applied during AudioStreamBase.GetData, and can be continuously changed to create various effects.
gain | the gain. 1.0f is no change, 0.0f is silence. |
Error | on failure. |
|
inline |
This callback is called before data is obtained from the stream, giving the callback the chance to add more on-demand.
The callback can (optionally) call AudioStreamBase.PutData() to add more audio to the stream during this call; if needed, the request that triggered this callback will obtain the new data immediately.
The callback's additional_amount
argument is roughly how many bytes of unconverted data (in the stream's input format) is needed by the caller, although this may overestimate a little for safety. This takes into account how much is already in the stream and only asks for any extra necessary to resolve the request, which means the callback may be asked for zero bytes, and a different amount on each call.
The callback is not required to supply exact amounts; it is allowed to supply too much or too little or none at all. The caller will get what's available, up to the amount they requested, regardless of this callback's outcome.
Clearing or flushing an audio stream does not call this callback.
This function obtains the stream's lock, which means any existing callback (get or put) in progress will finish running before setting the new callback.
Setting a nullptr function turns off the callback.
callback | the new callback function to call when data is requested from the stream. |
userdata | an opaque pointer provided to the callback for its own personal use. |
Error | on failure. |
|
inline |
This callback is called before data is obtained from the stream, giving the callback the chance to add more on-demand.
The callback can (optionally) call AudioStreamBase.PutData() to add more audio to the stream during this call; if needed, the request that triggered this callback will obtain the new data immediately.
The callback's additional_amount
argument is roughly how many bytes of unconverted data (in the stream's input format) is needed by the caller, although this may overestimate a little for safety. This takes into account how much is already in the stream and only asks for any extra necessary to resolve the request, which means the callback may be asked for zero bytes, and a different amount on each call.
The callback is not required to supply exact amounts; it is allowed to supply too much or too little or none at all. The caller will get what's available, up to the amount they requested, regardless of this callback's outcome.
Clearing or flushing an audio stream does not call this callback.
This function obtains the stream's lock, which means any existing callback (get or put) in progress will finish running before setting the new callback.
Setting a nullptr function turns off the callback.
callback | the new callback function to call when data is requested from the stream. |
Error | on failure. |
|
inline |
Channel maps are optional; most things do not need them, instead passing data in the order that SDL expects.
The input channel map reorders data that is added to a stream via AudioStreamBase.PutData. Future calls to AudioStreamBase.PutData must provide data in the new channel order.
Each item in the array represents an input channel, and its value is the channel that it should be remapped to. To reverse a stereo signal's left and right values, you'd have an array of { 1, 0 }
. It is legal to remap multiple channels to the same thing, so { 1, 1 }
would duplicate the right channel to both channels of a stereo signal. An element in the channel map set to -1 instead of a valid channel will mute that channel, setting it to a silence value.
You cannot change the number of channels through a channel map, just reorder/mute them.
Data that was previously queued in the stream will still be operated on in the order that was current when it was added, which is to say you can put the end of a sound file in one order to a stream, change orders for the next sound file, and start putting that new data while the previous sound file is still queued, and everything will still play back correctly.
Audio streams default to no remapping applied. Passing a nullptr channel map is legal, and turns off remapping.
SDL will copy the channel map; the caller does not have to save this array after this call.
If count
is not equal to the current number of channels in the audio stream's format, this will fail. This is a safety measure to make sure a race condition hasn't changed the format while this call is setting the channel map.
Unlike attempting to change the stream's format, the input channel map on a stream bound to a recording device is permitted to change at any time; any data added to the stream from the device after this call will have the new mapping, but previously-added data will still have the prior mapping.
chmap | the new channel map, nullptr to reset to default. |
Error | on failure. |
|
inline |
Future calls to and AudioStreamBase.GetAvailable and AudioStreamBase.GetData will reflect the new format, and future calls to AudioStreamBase.PutData must provide data in the new input formats.
Data that was previously queued in the stream will still be operated on in the format that was current when it was added, which is to say you can put the end of a sound file in one format to a stream, change formats for the next sound file, and start putting that new data while the previous sound file is still queued, and everything will still play back correctly.
If a stream is bound to a device, then the format of the side of the stream bound to a device cannot be changed (src_spec for recording devices, dst_spec for playback devices). Attempts to make a change to this side will be ignored, but this will not report an error. The other side's format can be changed.
spec | the new format of the audio input. |
Error | on failure. |
|
inline |
Channel maps are optional; most things do not need them, instead passing data in the order that SDL expects.
The output channel map reorders data that leaving a stream via AudioStreamBase.GetData.
Each item in the array represents an input channel, and its value is the channel that it should be remapped to. To reverse a stereo signal's left and right values, you'd have an array of { 1, 0 }
. It is legal to remap multiple channels to the same thing, so { 1, 1 }
would duplicate the right channel to both channels of a stereo signal. An element in the channel map set to -1 instead of a valid channel will mute that channel, setting it to a silence value.
You cannot change the number of channels through a channel map, just reorder/mute them.
The output channel map can be changed at any time, as output remapping is applied during AudioStreamBase.GetData.
Audio streams default to no remapping applied. Passing a nullptr channel map is legal, and turns off remapping.
SDL will copy the channel map; the caller does not have to save this array after this call.
If count
is not equal to the current number of channels in the audio stream's format, this will fail. This is a safety measure to make sure a race condition hasn't changed the format while this call is setting the channel map.
Unlike attempting to change the stream's format, the output channel map on a stream bound to a recording device is permitted to change at any time; any data added to the stream after this call will have the new mapping, but previously-added data will still have the prior mapping. When the channel map doesn't match the hardware's channel layout, SDL will convert the data before feeding it to the device for playback.
chmap | the new channel map, nullptr to reset to default. |
Error | on failure. |
|
inline |
Future calls to and AudioStreamBase.GetAvailable and AudioStreamBase.GetData will reflect the new format, and future calls to AudioStreamBase.PutData must provide data in the new input formats.
Data that was previously queued in the stream will still be operated on in the format that was current when it was added, which is to say you can put the end of a sound file in one format to a stream, change formats for the next sound file, and start putting that new data while the previous sound file is still queued, and everything will still play back correctly.
If a stream is bound to a device, then the format of the side of the stream bound to a device cannot be changed (src_spec for recording devices, dst_spec for playback devices). Attempts to make a change to this side will be ignored, but this will not report an error. The other side's format can be changed.
spec | the new format of the audio output. |
Error | on failure. |
|
inline |
This callback is called after the data is added to the stream, giving the callback the chance to obtain it immediately.
The callback can (optionally) call AudioStreamBase.GetData() to obtain audio from the stream during this call.
The callback's additional_amount
argument is how many bytes of converted data (in the stream's output format) was provided by the caller, although this may underestimate a little for safety. This value might be less than what is currently available in the stream, if data was already there, and might be less than the caller provided if the stream needs to keep a buffer to aid in resampling. Which means the callback may be provided with zero bytes, and a different amount on each call.
The callback may call AudioStreamBase.GetAvailable to see the total amount currently available to read from the stream, instead of the total provided by the current call.
The callback is not required to obtain all data. It is allowed to read less or none at all. Anything not read now simply remains in the stream for later access.
Clearing or flushing an audio stream does not call this callback.
This function obtains the stream's lock, which means any existing callback (get or put) in progress will finish running before setting the new callback.
Setting a nullptr function turns off the callback.
callback | the new callback function to call when data is added to the stream. |
userdata | an opaque pointer provided to the callback for its own personal use. |
Error | on failure. |
|
inline |
This callback is called after the data is added to the stream, giving the callback the chance to obtain it immediately.
The callback can (optionally) call AudioStreamBase.GetData() to obtain audio from the stream during this call.
The callback's additional_amount
argument is how many bytes of converted data (in the stream's output format) was provided by the caller, although this may underestimate a little for safety. This value might be less than what is currently available in the stream, if data was already there, and might be less than the caller provided if the stream needs to keep a buffer to aid in resampling. Which means the callback may be provided with zero bytes, and a different amount on each call.
The callback may call AudioStreamBase.GetAvailable to see the total amount currently available to read from the stream, instead of the total provided by the current call.
The callback is not required to obtain all data. It is allowed to read less or none at all. Anything not read now simply remains in the stream for later access.
Clearing or flushing an audio stream does not call this callback.
This function obtains the stream's lock, which means any existing callback (get or put) in progress will finish running before setting the new callback.
Setting a nullptr function turns off the callback.
callback | the new callback function to call when data is added to the stream. |
Error | on failure. |
|
inline |
This is a convenience function, equivalent to calling UnbindAudioStreams(&stream, 1)
.