SDL: SDL_audio.h: Documentation updates.

From 27333454229643fe62bf9c986458c47ce3aeb5da Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Thu, 25 Apr 2024 02:35:48 -0400
Subject: [PATCH] SDL_audio.h: Documentation updates.

---
 include/SDL3/SDL_audio.h | 232 ++++++++++++++++++++++++++++++---------
 1 file changed, 180 insertions(+), 52 deletions(-)

diff --git a/include/SDL3/SDL_audio.h b/include/SDL3/SDL_audio.h
index 8569cb3f15203..45ee6d4ba8fc5 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)
-#define SDL_AUDIO_ISLITTLEENDIAN(x)  (!SDL_AUDIO_ISBIGENDIAN(x))
-#define SDL_AUDIO_ISSIGNED(x)        ((x) & SDL_AUDIO_MASK_SIGNED)
-#define SDL_AUDIO_ISINT(x)           (!SDL_AUDIO_ISFLOAT(x))
-#define SDL_AUDIO_ISUNSIGNED(x)      (!SDL_AUDIO_ISSIGNED(x))
 
 /**
- *  \name Audio format flags
+ * 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.
  *
- *  Defaults to LSB byte order.
+ * \threadsafety It is safe to call this macro from any thread.
+ *
+ * \since This macro is available since SDL 3.0.0.
  */
-/* @{ */
-#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_ISLITTLEENDIAN(x)  (!SDL_AUDIO_ISBIGENDIAN(x))
 
 /**
- *  \name int32 support
+ * 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_S32LE     0x8020  /**< 32-bit integer samples */
-#define SDL_AUDIO_S32BE     0x9020  /**< As above, but big-endian byte order */
-/* @} */
+#define SDL_AUDIO_ISSIGNED(x)        ((x) & SDL_AUDIO_MASK_SIGNED)
 
 /**
- *  \name float32 support
+ * 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_F32LE     0x8120  /**< 32-bit floating point samples */
-#define SDL_AUDIO_F32BE     0x9120  /**< As above, but big-endian byte order */
-/* @} */
+#define SDL_AUDIO_ISINT(x)           (!SDL_AUDIO_ISFLOAT(x))
 
 /**
- *  \name Native audio byte ordering
+ * 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))
+
 #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