SDL: Added SDL_HINT_AUDIO_DISK_INPUT_FILE, SDL_HINT_AUDIO_DISK_OUTPUT_FILE, and SDL_HINT_AUDIO_DISK_TIMESCALE

From c9b2bfa7c105f29d45c3017c5da834f7e6bc8faf Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sat, 3 Aug 2024 09:22:44 -0700
Subject: [PATCH] Added SDL_HINT_AUDIO_DISK_INPUT_FILE,
 SDL_HINT_AUDIO_DISK_OUTPUT_FILE, and SDL_HINT_AUDIO_DISK_TIMESCALE

---
 docs/README-migration.md       |  3 +++
 include/SDL3/SDL_hints.h       | 33 +++++++++++++++++++++++++++++++++
 src/audio/disk/SDL_diskaudio.c | 20 +++++++++-----------
 3 files changed, 45 insertions(+), 11 deletions(-)

diff --git a/docs/README-migration.md b/docs/README-migration.md
index 4e43d01a19728..1de129e0dd7f7 100644
--- a/docs/README-migration.md
+++ b/docs/README-migration.md
@@ -808,6 +808,9 @@ The following environment variables have been renamed:
 
 The following environment variables have been removed:
 * SDL_AUDIO_ALSA_DEBUG - replaced by setting the hint SDL_HINT_LOGGING to "audio=debug"
+* SDL_DISKAUDIODELAY - replaced with the hint SDL_HINT_AUDIO_DISK_TIMESCALE which allows scaling the audio time rather than specifying an absolute delay.
+* SDL_DISKAUDIOFILE - replaced with the hint SDL_HINT_AUDIO_DISK_OUTPUT_FILE
+* SDL_DISKAUDIOFILEIN - replaced with the hint SDL_HINT_AUDIO_DISK_INPUT_FILE
 * SDL_DUMMYAUDIODELAY - replaced with the hint SDL_HINT_AUDIO_DUMMY_TIMESCALE which allows scaling the audio time rather than specifying an absolute delay.
 
 The following functions have been removed:
diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h
index 423fe485a2834..c33bdf29e2c76 100644
--- a/include/SDL3/SDL_hints.h
+++ b/include/SDL3/SDL_hints.h
@@ -335,6 +335,39 @@ extern "C" {
  */
 #define SDL_HINT_AUDIO_DEVICE_STREAM_ROLE "SDL_AUDIO_DEVICE_STREAM_ROLE"
 
+/**
+ * Specify the input file when recording audio using the disk audio driver.
+ *
+ * This defaults to "sdlaudio-in.raw"
+ *
+ * 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_DISK_INPUT_FILE "SDL_AUDIO_DISK_INPUT_FILE"
+
+/**
+ * Specify the output file when playing audio using the disk audio driver.
+ *
+ * This defaults to "sdlaudio.raw"
+ *
+ * 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_DISK_OUTPUT_FILE "SDL_AUDIO_DISK_OUTPUT_FILE"
+
+/**
+ * A variable controlling the audio rate when using the disk audio driver.
+ *
+ * The disk audio driver normally simulates real-time for the audio rate that was specified, but you can use this variable to adjust this rate higher or lower down to 0. The default value is "1.0".
+ *
+ * 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_DISK_TIMESCALE "SDL_AUDIO_DISK_TIMESCALE"
+
 /**
  * A variable that specifies an audio backend to use.
  *
diff --git a/src/audio/disk/SDL_diskaudio.c b/src/audio/disk/SDL_diskaudio.c
index 6dc5e40d6f521..1e8a485a99845 100644
--- a/src/audio/disk/SDL_diskaudio.c
+++ b/src/audio/disk/SDL_diskaudio.c
@@ -27,13 +27,8 @@
 #include "../SDL_sysaudio.h"
 #include "SDL_diskaudio.h"
 
-// !!! FIXME: these should be SDL hints, not environment variables.
-// environment variables and defaults.
-#define DISKENVR_OUTFILE    "SDL_DISKAUDIOFILE"
 #define DISKDEFAULT_OUTFILE "sdlaudio.raw"
-#define DISKENVR_INFILE     "SDL_DISKAUDIOFILEIN"
 #define DISKDEFAULT_INFILE  "sdlaudio-in.raw"
-#define DISKENVR_IODELAY    "SDL_DISKAUDIODELAY"
 
 static int DISKAUDIO_WaitDevice(SDL_AudioDevice *device)
 {
@@ -98,7 +93,7 @@ static void DISKAUDIO_CloseDevice(SDL_AudioDevice *device)
 
 static const char *get_filename(const SDL_bool recording)
 {
-    const char *devname = SDL_getenv(recording ? DISKENVR_INFILE : DISKENVR_OUTFILE);
+    const char *devname = SDL_GetHint(recording ? SDL_HINT_AUDIO_DISK_INPUT_FILE : SDL_HINT_AUDIO_DISK_OUTPUT_FILE);
     if (!devname) {
         devname = recording ? DISKDEFAULT_INFILE : DISKDEFAULT_OUTFILE;
     }
@@ -109,17 +104,20 @@ static int DISKAUDIO_OpenDevice(SDL_AudioDevice *device)
 {
     SDL_bool recording = device->recording;
     const char *fname = get_filename(recording);
-    const char *envr = SDL_getenv(DISKENVR_IODELAY);
 
     device->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, sizeof(*device->hidden));
     if (!device->hidden) {
         return -1;
     }
 
-    if (envr) {
-        device->hidden->io_delay = SDL_atoi(envr);
-    } else {
-        device->hidden->io_delay = ((device->sample_frames * 1000) / device->spec.freq);
+    device->hidden->io_delay = ((device->sample_frames * 1000) / device->spec.freq);
+
+    const char *hint = SDL_GetHint(SDL_HINT_AUDIO_DISK_TIMESCALE);
+    if (hint) {
+        double scale = SDL_atof(hint);
+        if (scale >= 0.0) {
+            device->hidden->io_delay = (Uint32)SDL_round(device->hidden->io_delay * scale);
+        }
     }
 
     // Open the "audio device"