SDL_mixer: testaudiodecoder: Manually close the audio stream during quit.

From 14c63a5705eeb132a22211d9935c4ccf3377919e Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Tue, 2 Jun 2026 14:30:28 -0400
Subject: [PATCH] testaudiodecoder: Manually close the audio stream during
 quit.

Otherwise, it might fire its callback while MIX_Quit() is destroying the
audio decoder.

Fixes #861.
---
 test/testaudiodecoder.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/test/testaudiodecoder.c b/test/testaudiodecoder.c
index 57f7338f..22dac7b0 100644
--- a/test/testaudiodecoder.c
+++ b/test/testaudiodecoder.c
@@ -24,6 +24,7 @@
 #include <SDL3/SDL_main.h>
 #include "SDL3_mixer/SDL_mixer.h"
 
+static SDL_AudioStream *stream = NULL;
 static SDL_AtomicInt done;  /* the device callback happens in another thread, so use an atomic int for this flag. */
 static SDL_AudioSpec spec;
 
@@ -71,7 +72,7 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
         return SDL_APP_FAILURE;
     }
 
-    SDL_AudioStream *stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, NULL, AudioDeviceCallback, audiodecoder);
+    stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, NULL, AudioDeviceCallback, audiodecoder);
     if (!stream) {
         SDL_Log("Failed to open audio device: %s", SDL_GetError());
         return SDL_APP_FAILURE;
@@ -101,7 +102,10 @@ SDL_AppResult SDL_AppIterate(void *appstate)
 
 void SDL_AppQuit(void *appstate, SDL_AppResult result)
 {
-    // SDL will clean up the audio device for us.
+    // SDL and MIX_Quit will normally clean up everything we used here, but
+    //  we need to make sure the callback doesn't fire while MIX_Quit is
+    //  destroying things, so we destroy the audio stream manually.
+    SDL_DestroyAudioStream(stream);
     MIX_Quit();    // SDL_mixer will clean up the audiodecoder.
 }