audio: Replace SDL_CreateAndBindAudioStream with SDL_OpenAudioDeviceStream.

This is meant to offer a simplified API for people that are either migrating
directly from SDL2 with minimal effort or just want to make noise without
any of the fancy new API features.

Users of this API can just deal with a single SDL_AudioStream as their only
object/handle into the audio subsystem.

They are still allowed to open multiple devices (or open the same device
multiple times), but cannot change stream bindings on logical devices opened
through this function.

Destroying the single audio stream will also close the logical device behind
the scenes.
This commit is contained in:
Ryan C. Gordon
2023-08-27 13:32:33 -04:00
parent bd088c2f99
commit 1e775e0eef
13 changed files with 164 additions and 137 deletions

View File

@@ -1031,33 +1031,55 @@ extern DECLSPEC void SDLCALL SDL_DestroyAudioStream(SDL_AudioStream *stream);
/**
* Convenience function to create and bind an audio stream in one step.
* Convenience function for straightforward audio init for the common case.
*
* This manages the creation of an audio stream, and setting its format
* correctly to match both the app and the audio device's needs. This is
* optional, but slightly less cumbersome to set up for a common use case.
* 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 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 SDL_AudioStream
* 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, and since there is no extra
* step here to bind a stream to begin audio flowing.
*
* This function works with both playback and capture 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. This function will set the other side
* of the audio stream to the device's format.
* audio, this will be the input format.
*
* \param devid an audio device to bind a stream to. This must be an opened
* device, and can not be zero.
* \param spec the audio stream's input format
* \returns a bound audio stream on success, ready to use. NULL on error; call
* SDL_GetError() for more information.
* If you don't care about opening a specific audio device, you can (and
* probably _should_), use SDL_AUDIO_DEVICE_DEFAULT_OUTPUT for playback and
* SDL_AUDIO_DEVICE_DEFAULT_CAPTURE for recording.
*
* One can optionally provide a callback function; if NULL, 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.
*
* \param devid an audio device to open, or SDL_AUDIO_DEVICE_DEFAULT_OUTPUT
* or SDL_AUDIO_DEVICE_DEFAULT_CAPTURE.
* \param spec the audio stream's input format. Required.
* \param callback A callback where the app will provide new data for playback,
* or receive new data for capture. Can be NULL, in which case
* the app will need to call SDL_PutAudioStreamData or
* SDL_GetAudioStreamData as necessary.
* \param userdata App-controlled pointer passed to callback. Can be NULL.
* Ignored if callback is NULL.
* \returns an audio stream on success, ready to use. NULL on error; call
* SDL_GetError() for more information. When done with this stream,
* call SDL_DestroyAudioStream to free resources and close the device.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_BindAudioStreams
* \sa SDL_UnbindAudioStreams
* \sa SDL_UnbindAudioStream
*/
extern DECLSPEC SDL_AudioStream *SDLCALL SDL_CreateAndBindAudioStream(SDL_AudioDeviceID devid, const SDL_AudioSpec *spec);
extern DECLSPEC SDL_AudioStream *SDLCALL SDL_OpenAudioDeviceStream(SDL_AudioDeviceID devid, const SDL_AudioSpec *spec, SDL_AudioStreamRequestCallback callback, void *userdata);
/**
* Load the audio data of a WAVE file into memory.