SDL: examples/audio/04-multiple-streams: Remove drag-and-drop support.

From 1fbb8e182448cfdcd65fe61134727ec0b1ade965 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Tue, 10 Dec 2024 20:51:54 -0500
Subject: [PATCH] examples/audio/04-multiple-streams: Remove drag-and-drop
 support.

I'm going to reuse that code for an actual drag/drop example later, but for
simplicity and accessibility of the examples, this is just going to load two
wavs and loop them, so you get the music with a sword-clinking sound mixed
over it.
---
 examples/CMakeLists.txt                       |   2 +-
 examples/audio/04-multiple-streams/README.txt |   8 +-
 .../04-multiple-streams/multiple-streams.c    | 132 ++++++++----------
 test/LICENSE.txt                              |   8 ++
 test/sword.wav                                | Bin 0 -> 91358 bytes
 5 files changed, 70 insertions(+), 80 deletions(-)
 create mode 100644 test/sword.wav

diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 23d91ff1c7bf8..2a13a038acad0 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -139,7 +139,7 @@ add_sdl_example_executable(renderer-debug-text SOURCES renderer/18-debug-text/de
 add_sdl_example_executable(audio-simple-playback SOURCES audio/01-simple-playback/simple-playback.c)
 add_sdl_example_executable(audio-simple-playback-callback SOURCES audio/02-simple-playback-callback/simple-playback-callback.c)
 add_sdl_example_executable(audio-load-wav SOURCES audio/03-load-wav/load-wav.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.wav)
-add_sdl_example_executable(audio-multiple-streams SOURCES audio/04-multiple-streams/multiple-streams.c)
+add_sdl_example_executable(audio-multiple-streams SOURCES audio/04-multiple-streams/multiple-streams.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.wav ${CMAKE_CURRENT_SOURCE_DIR}/../test/sword.wav)
 add_sdl_example_executable(input-joystick-polling SOURCES input/01-joystick-polling/joystick-polling.c)
 add_sdl_example_executable(input-joystick-events SOURCES input/02-joystick-events/joystick-events.c)
 add_sdl_example_executable(camera-read-and-draw SOURCES camera/01-read-and-draw/read-and-draw.c)
diff --git a/examples/audio/04-multiple-streams/README.txt b/examples/audio/04-multiple-streams/README.txt
index cdbc0202b7b6e..ecb82f56dc340 100644
--- a/examples/audio/04-multiple-streams/README.txt
+++ b/examples/audio/04-multiple-streams/README.txt
@@ -1,5 +1,3 @@
-This example code loads .wav files dropped onto the app window, puts
-them in an audio stream and binds them for playback. This shows several
-streams mixing into a single playback device.
-
-Drag several files while one is still playing!
+This example code loads two .wav files, puts them an audio streams and binds
+them for playback, repeating both sounds on loop. This shows several streams
+mixing into a single playback device.
diff --git a/examples/audio/04-multiple-streams/multiple-streams.c b/examples/audio/04-multiple-streams/multiple-streams.c
index b2c494f88d544..48109d301b977 100644
--- a/examples/audio/04-multiple-streams/multiple-streams.c
+++ b/examples/audio/04-multiple-streams/multiple-streams.c
@@ -1,6 +1,6 @@
 /*
- * This example code loads .wav files dropped onto the app window, puts
- * them in an audio stream and binds them for playback. This shows several
+ * This example code loads two .wav files, puts them an audio streams and
+ * binds them for playback, repeating both sounds on loop. This shows several
  * streams mixing into a single playback device.
  *
  * This code is public domain. Feel free to use it for any purpose!
@@ -14,12 +14,50 @@
 static SDL_Window *window = NULL;
 static SDL_Renderer *renderer = NULL;
 static SDL_AudioDeviceID audio_device = 0;
-static SDL_AudioStream **streams = NULL;
-static int num_streams = 0;
+
+/* things that are playing sound (the audiostream itself, plus the original data, so we can refill to loop. */
+typedef struct Sound {
+    Uint8 *wav_data;
+    Uint32 wav_data_len;
+    SDL_AudioStream *stream;
+} Sound;
+
+static Sound sounds[2];
+
+static bool init_sound(const char *fname, Sound *sound)
+{
+    bool retval = false;
+    SDL_AudioSpec spec;
+    char *wav_path = NULL;
+
+    /* Load the .wav files from wherever the app is being run from. */
+    SDL_asprintf(&wav_path, "%s%s", SDL_GetBasePath(), fname);  /* allocate a string of the full file path */
+    if (!SDL_LoadWAV(wav_path, &spec, &sound->wav_data, &sound->wav_data_len)) {
+        SDL_Log("Couldn't load .wav file: %s", SDL_GetError());
+        return false;
+    }
+
+    /* Create an audio stream. Set the source format to the wav's format (what
+       we'll input), leave the dest format NULL here (it'll change to what the
+       device wants once we bind it). */
+    sound->stream = SDL_CreateAudioStream(&spec, NULL);
+    if (!sound->stream) {
+        SDL_Log("Couldn't create audio stream: %s", SDL_GetError());
+    } else if (!SDL_BindAudioStream(audio_device, sound->stream)) {  /* once bound, it'll start playing when there is data available! */
+        SDL_Log("Failed to bind '%s' stream to device: %s", fname, SDL_GetError());
+    } else {
+        retval = true;  /* success! */
+    }
+
+    SDL_free(wav_path);  /* done with this string. */
+    return retval;
+}
+
 
 /* This function runs once at startup. */
 SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
 {
+
     SDL_SetAppMetadata("Example Audio Multiple Streams", "1.0", "com.example.audio-multiple-streams");
 
     if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) {
@@ -39,57 +77,13 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
         return SDL_APP_FAILURE;
     }
 
-    return SDL_APP_CONTINUE;  /* carry on with the program! */
-}
-
-static void load_wav_file(const char *fname)
-{
-    int idx;
-    SDL_AudioSpec spec;
-    Uint8 *wav_data = NULL;
-    Uint32 wav_data_len = 0;
-
-    /* Find an unused element in the streams array... */
-    for (idx = 0; idx < num_streams; idx++) {
-        if (streams[idx] == NULL) {
-            break;
-        }
-    }
-
-    /* No space? Grow the array. */
-    if (idx == num_streams) {
-        void *ptr = SDL_realloc(streams, (num_streams + 1) * sizeof (*streams));
-        if (!ptr) {
-            SDL_Log("Out of memory!");
-            return;  // oh well.
-        }
-        streams = (SDL_AudioStream **) ptr;
-        streams[idx] = NULL;
-        num_streams++;
-    }
-
-    /* Load the new .wav file */
-    if (!SDL_LoadWAV(fname, &spec, &wav_data, &wav_data_len)) {
-        SDL_Log("Failed to load '%s': %s", fname, SDL_GetError());
-        return;  // oh well.
-    }
-
-    /* Create an audio stream. Set the source format to the wav's format (what
-       we'll input), leave the dest format NULL here (it'll change to what the
-       device wants once we bind it). */
-    streams[idx] = SDL_CreateAudioStream(&spec, NULL);
-    if (!streams[idx]) {
-        SDL_Log("Couldn't create audio stream: %s", SDL_GetError());
-    } else if (!SDL_BindAudioStream(audio_device, streams[idx])) {  /* once bound, it'll start playing when there is data available! */
-        SDL_Log("Failed to bind '%s' stream to device: %s", fname, SDL_GetError());
-    } else if (!SDL_PutAudioStreamData(streams[idx], wav_data, (int) wav_data_len)) {
-        SDL_Log("Failed to put '%s' data into stream: %s", fname, SDL_GetError());
-    } else {
-        /* tell SDL we won't be sending more data to this stream, so don't hold back for resampling. */
-        SDL_FlushAudioStream(streams[idx]);
+    if (!init_sound("sample.wav", &sounds[0])) {
+        return SDL_APP_FAILURE;
+    } else if (!init_sound("sword.wav", &sounds[1])) {
+        return SDL_APP_FAILURE;
     }
 
-    SDL_free(wav_data);
+    return SDL_APP_CONTINUE;  /* carry on with the program! */
 }
 
 /* This function runs when a new event (mouse input, keypresses, etc) occurs. */
@@ -97,8 +91,6 @@ SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
 {
     if (event->type == SDL_EVENT_QUIT) {
         return SDL_APP_SUCCESS;  /* end the program, reporting success to the OS. */
-    } else if (event->type == SDL_EVENT_DROP_FILE) {
-        load_wav_file(event->drop.data);
     }
     return SDL_APP_CONTINUE;  /* carry on with the program! */
 }
@@ -106,26 +98,20 @@ SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
 /* This function runs once per frame, and is the heart of the program. */
 SDL_AppResult SDL_AppIterate(void *appstate)
 {
-    int winw = 640, winh = 480;
-    const char *text = "--> Drag and drop .wav files here <--";
-    float x, y;
     int i;
 
-    /* see if any streams have finished; destroy them if so. */
-    for (i = 0; i < num_streams; i++) {
-        if (streams[i] && (SDL_GetAudioStreamAvailable(streams[i]) == 0)) {
-            SDL_DestroyAudioStream(streams[i]);
-            streams[i] = NULL;
+    for (i = 0; i < SDL_arraysize(sounds); i++) {
+        /* If less than a full copy of the audio is queued for playback, put another copy in there.
+           This is overkill, but easy when lots of RAM is cheap. One could be more careful and
+           queue less at a time, as long as the stream doesn't run dry.  */
+        if (SDL_GetAudioStreamAvailable(sounds[i].stream) < sounds[i].wav_data_len) {
+            SDL_PutAudioStreamData(sounds[i].stream, sounds[i].wav_data, (int) sounds[i].wav_data_len);
         }
     }
 
+    /* just blank the screen. */
     SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
     SDL_RenderClear(renderer);
-    SDL_GetWindowSize(window, &winw, &winh);
-    x = (((float) winw) - (SDL_strlen(text) * SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE)) / 2.0f;
-    y = (((float) winh) - SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE) / 2.0f;
-    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
-    SDL_RenderDebugText(renderer, x, y, text);
     SDL_RenderPresent(renderer);
 
     return SDL_APP_CONTINUE;  /* carry on with the program! */
@@ -138,14 +124,12 @@ void SDL_AppQuit(void *appstate, SDL_AppResult result)
 
     SDL_CloseAudioDevice(audio_device);
 
-    /* see if any streams have finished; destroy them if so. */
-    for (i = 0; i < num_streams; i++) {
-        if (streams[i]) {
-            SDL_DestroyAudioStream(streams[i]);
+    for (i = 0; i < SDL_arraysize(sounds); i++) {
+        if (sounds[i].stream) {
+            SDL_DestroyAudioStream(sounds[i].stream);
         }
+        SDL_free(sounds[i].wav_data);
     }
 
-    SDL_free(streams);
-
     /* SDL will clean up the window/renderer for us. */
 }
diff --git a/test/LICENSE.txt b/test/LICENSE.txt
index 0cad4d3fd5fa3..472c6ad1a5edd 100644
--- a/test/LICENSE.txt
+++ b/test/LICENSE.txt
@@ -34,6 +34,14 @@ Thanks to Will for permitting us to distribute this sample with SDL!
 
 
 
+This directory contains sword.wav:
+
+  sword04.wav by Erdie
+  Original: https://freesound.org/s/27858/
+  License: https://creativecommons.org/licenses/by/4.0/
+
+
+
 The .bmp files used by testaudio.c were made by AlDraw:
 
 https://linktr.ee/AlexDraw
diff --git a/test/sword.wav b/test/sword.wav
new file mode 100644
index 0000000000000000000000000000000000000000..193cf5432044cd03f3d7289dd0d8a8e1809b1c7c
GIT binary patch
literal 91358
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

(Patch may be truncated, please check the link at the top of this post.)