From 27333454229643fe62bf9c986458c47ce3aeb5da Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 25 Apr 2024 02:35:48 -0400 Subject: [PATCH] SDL_audio.h: Documentation updates. --- include/SDL3/SDL_audio.h | 248 +++++++++++++++++++++++++++++---------- 1 file changed, 188 insertions(+), 60 deletions(-) diff --git a/include/SDL3/SDL_audio.h b/include/SDL3/SDL_audio.h index 8569cb3f15..45ee6d4ba8 100644 --- a/include/SDL3/SDL_audio.h +++ b/include/SDL3/SDL_audio.h @@ -74,59 +74,145 @@ extern "C" { * There are macros to query these bits. * * \since This datatype is available since SDL 3.0.0. + * + * \sa SDL_AUDIO_BITSIZE + * \sa SDL_AUDIO_BYTESIZE + * \sa SDL_AUDIO_ISINT + * \sa SDL_AUDIO_ISFLOAT + * \sa SDL_AUDIO_ISBIGENDIAN + * \sa SDL_AUDIO_ISLITTLEENDIAN + * \sa SDL_AUDIO_ISSIGNED + * \sa SDL_AUDIO_ISUNSIGNED */ typedef Uint16 SDL_AudioFormat; +#define SDL_AUDIO_U8 0x0008 /**< Unsigned 8-bit samples */ +#define SDL_AUDIO_S8 0x8008 /**< Signed 8-bit samples */ +#define SDL_AUDIO_S16LE 0x8010 /**< Signed 16-bit samples */ +#define SDL_AUDIO_S16BE 0x9010 /**< As above, but big-endian byte order */ +#define SDL_AUDIO_S32LE 0x8020 /**< 32-bit integer samples */ +#define SDL_AUDIO_S32BE 0x9020 /**< As above, but big-endian byte order */ +#define SDL_AUDIO_F32LE 0x8120 /**< 32-bit floating point samples */ +#define SDL_AUDIO_F32BE 0x9120 /**< As above, but big-endian byte order */ -/** - * \name Audio flags - */ -/* @{ */ #define SDL_AUDIO_MASK_BITSIZE (0xFF) #define SDL_AUDIO_MASK_FLOAT (1<<8) #define SDL_AUDIO_MASK_BIG_ENDIAN (1<<12) #define SDL_AUDIO_MASK_SIGNED (1<<15) + + +/** + * Retrieve the size, in bits, from an SDL_AudioFormat. + * + * For example, `SDL_AUDIO_BITSIZE(SDL_AUDIO_S16)` returns 16. + * + * \param x an SDL_AudioFormat value + * \returns data size in bits + * + * \threadsafety It is safe to call this macro from any thread. + * + * \since This macro is available since SDL 3.0.0. + */ #define SDL_AUDIO_BITSIZE(x) ((x) & SDL_AUDIO_MASK_BITSIZE) + +/** + * Retrieve the size, in bytes, from an SDL_AudioFormat. + * + * For example, `SDL_AUDIO_BYTESIZE(SDL_AUDIO_S16)` returns 2. + * + * \param x an SDL_AudioFormat value + * \returns data size in bytes + * + * \threadsafety It is safe to call this macro from any thread. + * + * \since This macro is available since SDL 3.0.0. + */ #define SDL_AUDIO_BYTESIZE(x) (SDL_AUDIO_BITSIZE(x) / 8) + +/** + * Determine if an SDL_AudioFormat represents floating point data. + * + * For example, `SDL_AUDIO_ISFLOAT(SDL_AUDIO_S16)` returns 0. + * + * \param x an SDL_AudioFormat value + * \returns non-zero if format is floating point, zero otherwise. + * + * \threadsafety It is safe to call this macro from any thread. + * + * \since This macro is available since SDL 3.0.0. + */ #define SDL_AUDIO_ISFLOAT(x) ((x) & SDL_AUDIO_MASK_FLOAT) + +/** + * Determine if an SDL_AudioFormat represents bigendian data. + * + * For example, `SDL_AUDIO_ISBIGENDIAN(SDL_AUDIO_S16LE)` returns 0. + * + * \param x an SDL_AudioFormat value + * \returns non-zero if format is bigendian, zero otherwise. + * + * \threadsafety It is safe to call this macro from any thread. + * + * \since This macro is available since SDL 3.0.0. + */ #define SDL_AUDIO_ISBIGENDIAN(x) ((x) & SDL_AUDIO_MASK_BIG_ENDIAN) + +/** + * Determine if an SDL_AudioFormat represents littleendian data. + * + * For example, `SDL_AUDIO_ISLITTLEENDIAN(SDL_AUDIO_S16BE)` returns 0. + * + * \param x an SDL_AudioFormat value + * \returns non-zero if format is littleendian, zero otherwise. + * + * \threadsafety It is safe to call this macro from any thread. + * + * \since This macro is available since SDL 3.0.0. + */ #define SDL_AUDIO_ISLITTLEENDIAN(x) (!SDL_AUDIO_ISBIGENDIAN(x)) + +/** + * Determine if an SDL_AudioFormat represents signed data. + * + * For example, `SDL_AUDIO_ISSIGNED(SDL_AUDIO_U8)` returns 0. + * + * \param x an SDL_AudioFormat value + * \returns non-zero if format is signed, zero otherwise. + * + * \threadsafety It is safe to call this macro from any thread. + * + * \since This macro is available since SDL 3.0.0. + */ #define SDL_AUDIO_ISSIGNED(x) ((x) & SDL_AUDIO_MASK_SIGNED) + +/** + * Determine if an SDL_AudioFormat represents integer data. + * + * For example, `SDL_AUDIO_ISINT(SDL_AUDIO_F32)` returns 0. + * + * \param x an SDL_AudioFormat value + * \returns non-zero if format is integer, zero otherwise. + * + * \threadsafety It is safe to call this macro from any thread. + * + * \since This macro is available since SDL 3.0.0. + */ #define SDL_AUDIO_ISINT(x) (!SDL_AUDIO_ISFLOAT(x)) + +/** + * Determine if an SDL_AudioFormat represents unsigned data. + * + * For example, `SDL_AUDIO_ISUNSIGNED(SDL_AUDIO_S16)` returns 0. + * + * \param x an SDL_AudioFormat value + * \returns non-zero if format is unsigned, zero otherwise. + * + * \threadsafety It is safe to call this macro from any thread. + * + * \since This macro is available since SDL 3.0.0. + */ #define SDL_AUDIO_ISUNSIGNED(x) (!SDL_AUDIO_ISSIGNED(x)) -/** - * \name Audio format flags - * - * Defaults to LSB byte order. - */ -/* @{ */ -#define SDL_AUDIO_U8 0x0008 /**< Unsigned 8-bit samples */ -#define SDL_AUDIO_S8 0x8008 /**< Signed 8-bit samples */ -#define SDL_AUDIO_S16LE 0x8010 /**< Signed 16-bit samples */ -#define SDL_AUDIO_S16BE 0x9010 /**< As above, but big-endian byte order */ -/* @} */ - -/** - * \name int32 support - */ -/* @{ */ -#define SDL_AUDIO_S32LE 0x8020 /**< 32-bit integer samples */ -#define SDL_AUDIO_S32BE 0x9020 /**< As above, but big-endian byte order */ -/* @} */ - -/** - * \name float32 support - */ -/* @{ */ -#define SDL_AUDIO_F32LE 0x8120 /**< 32-bit floating point samples */ -#define SDL_AUDIO_F32BE 0x9120 /**< As above, but big-endian byte order */ -/* @} */ - -/** - * \name Native audio byte ordering - */ -/* @{ */ #if SDL_BYTEORDER == SDL_LIL_ENDIAN #define SDL_AUDIO_S16 SDL_AUDIO_S16LE #define SDL_AUDIO_S32 SDL_AUDIO_S32LE @@ -136,18 +222,36 @@ typedef Uint16 SDL_AudioFormat; #define SDL_AUDIO_S32 SDL_AUDIO_S32BE #define SDL_AUDIO_F32 SDL_AUDIO_F32BE #endif -/* @} */ - -/* @} *//* Audio flags */ /** * SDL Audio Device instance IDs. * + * Zero is used to signify an invalid/null device. + * * \since This datatype is available since SDL 3.0.0. */ typedef Uint32 SDL_AudioDeviceID; +/** + * A value used to request a default output audio device. + * + * Several functions that require an SDL_AudioDeviceID will accept this + * value to signify the app just wants the system to choose a default + * device instead of the app providing a specific one. + * + * \since This macro is available since SDL 3.0.0. + */ #define SDL_AUDIO_DEVICE_DEFAULT_OUTPUT ((SDL_AudioDeviceID) 0xFFFFFFFF) + +/** + * A value used to request a default capture audio device. + * + * Several functions that require an SDL_AudioDeviceID will accept this + * value to signify the app just wants the system to choose a default + * device instead of the app providing a specific one. + * + * \since This macro is available since SDL 3.0.0. + */ #define SDL_AUDIO_DEVICE_DEFAULT_CAPTURE ((SDL_AudioDeviceID) 0xFFFFFFFE) /** @@ -164,7 +268,19 @@ typedef struct SDL_AudioSpec int freq; /**< sample rate: sample frames per second */ } SDL_AudioSpec; -/* Calculate the size of each audio frame (in bytes) */ +/** + * Calculate the size of each audio frame (in bytes) from an SDL_AudioSpec. + * + * This reports on the size of an audio sample frame: stereo Sint16 data + * (2 channels of 2 bytes each) would be 4 bytes per frame, for example. + * + * \param x an SDL_AudioSpec to query. + * \returns the number of bytes used per sample frame. + * + * \threadsafety It is safe to call this macro from any thread. + * + * \since This macro is available since SDL 3.0.0. + */ #define SDL_AUDIO_FRAMESIZE(x) (SDL_AUDIO_BYTESIZE((x).format) * (x).channels) /** @@ -615,7 +731,7 @@ extern DECLSPEC int SDLCALL SDL_BindAudioStream(SDL_AudioDeviceID devid, SDL_Aud * * The streams being unbound do not all have to be on the same device. All * streams on the same device will be unbound atomically (data will stop - * flowing through them all unbound streams on the same device at the same + * flowing through all unbound streams on the same device at the same * time). * * Unbinding a stream that isn't bound to a device is a legal no-op. @@ -667,7 +783,6 @@ extern DECLSPEC void SDLCALL SDL_UnbindAudioStream(SDL_AudioStream *stream); */ extern DECLSPEC SDL_AudioDeviceID SDLCALL SDL_GetAudioStreamDevice(SDL_AudioStream *stream); - /** * Create a new audio stream. * @@ -727,6 +842,13 @@ extern DECLSPEC int SDLCALL SDL_GetAudioStreamFormat(SDL_AudioStream *stream, * will reflect the new format, and future calls to SDL_PutAudioStreamData * 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. + * * \param stream The stream the format is being changed * \param src_spec The new format of the audio input; if NULL, it is not * changed. @@ -909,7 +1031,7 @@ extern DECLSPEC int SDLCALL SDL_GetAudioStreamQueued(SDL_AudioStream *stream); * Tell the stream that you're done sending data, and anything being buffered * should be converted/resampled and made available immediately. * - * It is legal to add more data to a stream after flushing, but there will be + * 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. * @@ -926,7 +1048,10 @@ extern DECLSPEC int SDLCALL SDL_GetAudioStreamQueued(SDL_AudioStream *stream); extern DECLSPEC int SDLCALL SDL_FlushAudioStream(SDL_AudioStream *stream); /** - * Clear any pending data in the stream without converting it. + * Clear any pending data in the stream. + * + * This drops any queued data, so there will be nothing to read from + * the stream until more is added. * * \param stream The audio stream to clear * \returns 0 on success or a negative error code on failure; call @@ -956,7 +1081,7 @@ extern DECLSPEC int SDLCALL SDL_ClearAudioStream(SDL_AudioStream *stream); * protect shared data during those callbacks, locking the stream guarantees * that the callback is not running while the lock is held. * - * As this is just a wrapper over SDL_LockMutex for an internal lock, it has + * As this is just a wrapper over SDL_LockMutex for an internal lock; it has * all the same attributes (recursive locks are allowed, etc). * * \param stream The audio stream to lock. @@ -1129,7 +1254,15 @@ extern DECLSPEC int SDLCALL SDL_SetAudioStreamPutCallback(SDL_AudioStream *strea /** * Free an audio stream. * - * \param stream The audio stream to free + * This will release all allocated data, including any audio that is still + * queued. You do not need to manually clear the stream first. + * + * If this stream was bound to an audio device, it is unbound during this + * call. If this stream was created with SDL_OpenAudioDeviceStream, the + * audio device that was opened alongside this stream's creation will be + * closed, too. + * + * \param stream The audio stream to destroy. * * \threadsafety It is safe to call this function from any thread. * @@ -1146,7 +1279,7 @@ extern DECLSPEC void SDLCALL SDL_DestroyAudioStream(SDL_AudioStream *stream); * 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 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 @@ -1154,9 +1287,9 @@ extern DECLSPEC void SDLCALL SDL_DestroyAudioStream(SDL_AudioStream *stream); * 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 + * 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 SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(stream)); + * with `SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(stream));` * * This function works with both playback and capture devices. * @@ -1196,7 +1329,6 @@ extern DECLSPEC void SDLCALL SDL_DestroyAudioStream(SDL_AudioStream *stream); */ extern DECLSPEC SDL_AudioStream *SDLCALL SDL_OpenAudioDeviceStream(SDL_AudioDeviceID devid, const SDL_AudioSpec *spec, SDL_AudioStreamCallback callback, void *userdata); - /** * A callback that fires when data is about to be fed to an audio device. * @@ -1345,10 +1477,9 @@ extern DECLSPEC int SDLCALL SDL_SetAudioPostmixCallback(SDL_AudioDeviceID devid, * function * \param audio_len A pointer filled with the length of the audio data buffer * in bytes - * \returns This function, if successfully called, returns 0. `audio_buf` will - * be filled with a pointer to an allocated buffer containing the - * audio data, and `audio_len` is filled with the length of that - * audio buffer in bytes. + * \returns 0 on success. `audio_buf` will be filled with a pointer to an + * allocated buffer containing the audio data, and `audio_len` is + * filled with the length of that audio buffer in bytes. * * This function returns -1 if the .WAV file cannot be opened, uses * an unknown data format, or is corrupt; call SDL_GetError() for @@ -1377,8 +1508,6 @@ extern DECLSPEC int SDLCALL SDL_LoadWAV_IO(SDL_IOStream * src, SDL_bool closeio, * SDL_LoadWAV_IO(SDL_IOFromFile(path, "rb"), 1, spec, audio_buf, audio_len); * ``` * - * Note that in SDL2, this was a preprocessor macro and not a real function. - * * \param path The file path of the WAV file to open. * \param spec A pointer to an SDL_AudioSpec that will be set to the WAVE * data's format details on successful return. @@ -1386,10 +1515,9 @@ extern DECLSPEC int SDLCALL SDL_LoadWAV_IO(SDL_IOStream * src, SDL_bool closeio, * function. * \param audio_len A pointer filled with the length of the audio data buffer * in bytes - * \returns This function, if successfully called, returns 0. `audio_buf` will - * be filled with a pointer to an allocated buffer containing the - * audio data, and `audio_len` is filled with the length of that - * audio buffer in bytes. + * \returns 0 on success. `audio_buf` will be filled with a pointer to an + * allocated buffer containing the audio data, and `audio_len` is + * filled with the length of that audio buffer in bytes. * * This function returns -1 if the .WAV file cannot be opened, uses * an unknown data format, or is corrupt; call SDL_GetError() for