SDL_mixer: Added Mix_PauseAudio() call

From fd2bf70afafbae69f6b4b18b8936f6fb58a6bdfb Mon Sep 17 00:00:00 2001
From: Wohlstand <[EMAIL REDACTED]>
Date: Wed, 13 Jul 2022 18:55:03 +0300
Subject: [PATCH] Added Mix_PauseAudio() call

This call allows cheaper pausing/resuming of the whole audio processing without pausing every playing channel or music stream.

For example, this call can be used to pause the entire audio playback when the game is not focused.
---
 include/SDL_mixer.h |  9 +++++++++
 src/mixer.c         |  9 +++++++++
 src/music.c         | 17 +++++++++++++++++
 src/music.h         |  1 +
 4 files changed, 36 insertions(+)

diff --git a/include/SDL_mixer.h b/include/SDL_mixer.h
index bd877535..51c2c636 100644
--- a/include/SDL_mixer.h
+++ b/include/SDL_mixer.h
@@ -461,6 +461,15 @@ extern DECLSPEC int SDLCALL Mix_OpenAudio(int frequency, Uint16 format, int chan
  */
 extern DECLSPEC int SDLCALL Mix_OpenAudioDevice(int frequency, Uint16 format, int channels, int chunksize, const char* device, int allowed_changes);
 
+/**
+ * Suspend or resume the whole audio output.
+ *
+ * \since This function is available since SDL_mixer 2.8.0.
+ *
+ * @param pause_on Set audio output to pause, 1 (to pause) or 0 (to resume)
+ */
+extern DECLSPEC void SDLCALL Mix_PauseAudio(int pause_on);
+
 /**
  * Find out what the actual audio device parameters are.
  *
diff --git a/src/mixer.c b/src/mixer.c
index 41997e69..d713df50 100644
--- a/src/mixer.c
+++ b/src/mixer.c
@@ -533,6 +533,15 @@ int Mix_OpenAudio(int frequency, Uint16 format, int nchannels, int chunksize)
                                 SDL_AUDIO_ALLOW_CHANNELS_CHANGE);
 }
 
+/* Pause or resume the audio streaming */
+void Mix_PauseAudio(int pause_on)
+{
+    SDL_PauseAudioDevice(audio_device, pause_on);
+    Mix_LockAudio();
+    pause_async_music(pause_on);
+    Mix_UnlockAudio();
+}
+
 /* Dynamically change the number of channels managed by the mixer.
    If decreasing the number of channels, the upper channels are
    stopped.
diff --git a/src/music.c b/src/music.c
index 86700bde..d6291c2e 100644
--- a/src/music.c
+++ b/src/music.c
@@ -378,6 +378,23 @@ void SDLCALL music_mixer(void *udata, Uint8 *stream, int len)
     }
 }
 
+void pause_async_music(int pause_on)
+{
+    if (!music_active || !music_playing || !music_playing->interface) {
+        return;
+    }
+
+    if (pause_on) {
+        if (music_playing->interface->Pause) {
+            music_playing->interface->Pause(music_playing->context);
+        }
+    } else {
+        if (music_playing->interface->Resume) {
+            music_playing->interface->Resume(music_playing->context);
+        }
+    }
+}
+
 /* Load the music interface libraries for a given music type */
 SDL_bool load_music_type(Mix_MusicType type)
 {
diff --git a/src/music.h b/src/music.h
index 7751140d..674871b7 100644
--- a/src/music.h
+++ b/src/music.h
@@ -163,6 +163,7 @@ extern void open_music(const SDL_AudioSpec *spec);
 extern int music_pcm_getaudio(void *context, void *data, int bytes, int volume,
                               int (*GetSome)(void *context, void *data, int bytes, SDL_bool *done));
 extern void SDLCALL music_mixer(void *udata, Uint8 *stream, int len);
+extern void pause_async_music(int pause_on);
 extern void close_music(void);
 extern void unload_music(void);