SDL: Added SDL_HINT_AUDIO_FREQUENCY, SDL_HINT_AUDIO_CHANNELS, and SDL_HINT_AUDIO_FORMAT

From 5aa1a48ac3d40327599b1a36e87190a1805b17e3 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sat, 3 Aug 2024 08:24:36 -0700
Subject: [PATCH] Added SDL_HINT_AUDIO_FREQUENCY, SDL_HINT_AUDIO_CHANNELS, and
 SDL_HINT_AUDIO_FORMAT

---
 include/SDL3/SDL_hints.h | 46 ++++++++++++++++++++++++++++++++++++++++
 src/audio/SDL_audio.c    | 15 +++++++------
 2 files changed, 54 insertions(+), 7 deletions(-)

diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h
index 79aa0089e3788..447beb1f184cb 100644
--- a/include/SDL3/SDL_hints.h
+++ b/include/SDL3/SDL_hints.h
@@ -215,6 +215,17 @@ extern "C" {
  */
 #define SDL_HINT_AUDIO_CATEGORY   "SDL_AUDIO_CATEGORY"
 
+/**
+ * A variable controlling the default audio channel count.
+ *
+ * If the application doesn't specify the audio channel count when opening the device, this hint can be used to specify a default channel count that will be used. This defaults to "1" for recording and "2" for playback devices.
+ *
+ * This hint should be set before an audio device is opened.
+ *
+ * \since This hint is available since SDL 3.0.0.
+ */
+#define SDL_HINT_AUDIO_CHANNELS "SDL_AUDIO_CHANNELS"
+
 /**
  * Specify an application icon name for an audio device.
  *
@@ -327,6 +338,41 @@ extern "C" {
  */
 #define SDL_HINT_AUDIO_DRIVER "SDL_AUDIO_DRIVER"
 
+/**
+ * A variable controlling the default audio format.
+ *
+ * If the application doesn't specify the audio format when opening the device, this hint can be used to specify a default format that will be used.
+ *
+ * The variable can be set to the following values:
+ * - "U8": Unsigned 8-bit audio
+ * - "S8": Signed 8-bit audio
+ * - "S16LE": Signed 16-bit little-endian audio
+ * - "S16BE": Signed 16-bit big-endian audio
+ * - "S16": Signed 16-bit native-endian audio (default)
+ * - "S32LE": Signed 32-bit little-endian audio
+ * - "S32BE": Signed 32-bit big-endian audio
+ * - "S32": Signed 32-bit native-endian audio
+ * - "F32LE": Floating point little-endian audio
+ * - "F32BE": Floating point big-endian audio
+ * - "F32": Floating point native-endian audio
+ *
+ * This hint should be set before an audio device is opened.
+ *
+ * \since This hint is available since SDL 3.0.0.
+ */
+#define SDL_HINT_AUDIO_FORMAT "SDL_AUDIO_FORMAT"
+
+/**
+ * A variable controlling the default audio frequency.
+ *
+ * If the application doesn't specify the audio frequency when opening the device, this hint can be used to specify a default frequency that will be used. This defaults to "44100".
+ *
+ * This hint should be set before an audio device is opened.
+ *
+ * \since This hint is available since SDL 3.0.0.
+ */
+#define SDL_HINT_AUDIO_FREQUENCY "SDL_AUDIO_FREQUENCY"
+
 /**
  * A variable that causes SDL to not ignore audio "monitors".
  *
diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c
index 505a8a22570b2..b27df57058439 100644
--- a/src/audio/SDL_audio.c
+++ b/src/audio/SDL_audio.c
@@ -1577,9 +1577,9 @@ static void PrepareAudioFormat(SDL_bool recording, SDL_AudioSpec *spec)
     if (spec->freq == 0) {
         spec->freq = recording ? DEFAULT_AUDIO_RECORDING_FREQUENCY : DEFAULT_AUDIO_PLAYBACK_FREQUENCY;
 
-        const char *env = SDL_getenv("SDL_AUDIO_FREQUENCY");  // !!! FIXME: should be a hint?
-        if (env) {
-            const int val = SDL_atoi(env);
+        const char *hint = SDL_GetHint(SDL_HINT_AUDIO_FREQUENCY);
+        if (hint) {
+            const int val = SDL_atoi(hint);
             if (val > 0) {
                 spec->freq = val;
             }
@@ -1588,9 +1588,10 @@ static void PrepareAudioFormat(SDL_bool recording, SDL_AudioSpec *spec)
 
     if (spec->channels == 0) {
         spec->channels = recording ? DEFAULT_AUDIO_RECORDING_CHANNELS : DEFAULT_AUDIO_PLAYBACK_CHANNELS;;
-        const char *env = SDL_getenv("SDL_AUDIO_CHANNELS");
-        if (env) {
-            const int val = SDL_atoi(env);
+
+        const char *hint = SDL_GetHint(SDL_HINT_AUDIO_CHANNELS);
+        if (hint) {
+            const int val = SDL_atoi(hint);
             if (val > 0) {
                 spec->channels = val;
             }
@@ -1598,7 +1599,7 @@ static void PrepareAudioFormat(SDL_bool recording, SDL_AudioSpec *spec)
     }
 
     if (spec->format == 0) {
-        const SDL_AudioFormat val = ParseAudioFormatString(SDL_getenv("SDL_AUDIO_FORMAT"));
+        const SDL_AudioFormat val = ParseAudioFormatString(SDL_GetHint(SDL_HINT_AUDIO_FORMAT));
         spec->format = (val != 0) ? val : (recording ? DEFAULT_AUDIO_RECORDING_FORMAT : DEFAULT_AUDIO_PLAYBACK_FORMAT);
     }
 }