From 3c80688bbedb336879619199feac05234f9b97a3 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Mon, 3 Oct 2022 20:40:22 -0400
Subject: [PATCH] audio: SDL_MixAudio has to respect app format, which we might
be faking.
Fixes #228.
---
src/SDL12_compat.c | 34 ++++++++++++++++++++++++++++++++--
src/SDL20_include_wrapper.h | 2 ++
src/SDL20_syms.h | 2 +-
3 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c
index f93c6bd60..db151fe1a 100644
--- a/src/SDL12_compat.c
+++ b/src/SDL12_compat.c
@@ -8844,7 +8844,7 @@ FakeCdRomAudioCallback(AudioCallbackWrapperData *data, Uint8 *stream, int len, c
SDL20_AudioStreamGet(data->cdrom_stream, stream, available);
} else {
SDL20_AudioStreamGet(data->cdrom_stream, data->mix_buffer, available);
- SDL20_MixAudio(stream, data->mix_buffer, available, SDL_MIX_MAXVOLUME);
+ SDL20_MixAudioFormat(stream, data->mix_buffer, audio_cbdata->device_format.format, available, SDL_MIX_MAXVOLUME);
}
data->cdrom_pcm_frames_written += (int) ((available / ((double) SDL_AUDIO_BITSIZE(data->device_format.format) / 8.0)) / data->device_format.channels);
@@ -9152,6 +9152,37 @@ SDL_GetAudioStatus(void)
return retval;
}
+DECLSPEC12 void SDLCALL
+SDL_MixAudio(Uint8 *dst, const Uint8 *src, Uint32 len, int volume)
+{
+ SDL_AudioFormat fmt;
+
+ if (volume == 0) {
+ return; /* nothing to do. */
+ }
+
+ /* in 1.2, if not the subsystem isn't initialized _at all_, it forces
+ format to AUDIO_S16. If it's initialized but the device isn't opened,
+ you get a format of zero and it returns an error without mixing
+ anything. */
+ SDL20_LockAudio();
+ if ((InitializedSubsystems20 & SDL_INIT_AUDIO) != SDL_INIT_AUDIO) {
+ fmt = AUDIO_S16; /* to quote 1.2: "HACK HACK HACK" */
+ } else if (!audio_cbdata || !audio_cbdata->app_callback_opened) {
+ fmt = 0; /* this will fail, but drop the lock first. */
+ } else {
+ fmt = audio_cbdata->app_callback_format.format;
+ }
+ SDL20_UnlockAudio();
+
+ if (fmt == 0) {
+ SDL_SetError("SDL_MixAudio(): unknown audio format"); /* this is the exact error 1.2 reports for this. */
+ } else {
+ SDL20_MixAudioFormat(dst, src, fmt, len, volume);
+ }
+}
+
+
DECLSPEC12 void SDLCALL
SDL_CloseAudio(void)
{
@@ -9166,7 +9197,6 @@ SDL_CloseAudio(void)
CloseSDL2AudioDevice();
}
-
static SDL_AudioCVT *
AudioCVT12to20(const SDL12_AudioCVT *cvt12, SDL_AudioCVT *cvt20)
{
diff --git a/src/SDL20_include_wrapper.h b/src/SDL20_include_wrapper.h
index 4d4be2220..adea80acc 100644
--- a/src/SDL20_include_wrapper.h
+++ b/src/SDL20_include_wrapper.h
@@ -113,6 +113,7 @@
#define SDL_VideoInit IGNORE_THIS_VERSION_OF_SDL_VideoInit
#define SDL_BuildAudioCVT IGNORE_THIS_VERSION_OF_SDL_BuildAudioCVT
#define SDL_ConvertAudio IGNORE_THIS_VERSION_OF_SDL_ConvertAudio
+#define SDL_MixAudio IGNORE_THIS_VERSION_OF_SDL_MixAudio
#define SDL_RegisterApp IGNORE_THIS_VERSION_OF_SDL_RegisterApp
#define SDL_UnregisterApp IGNORE_THIS_VERSION_OF_SDL_UnregisterApp
@@ -242,6 +243,7 @@ typedef void (__cdecl *pfnSDL_CurrentEndThread) (unsigned);
#undef SDL_VideoInit
#undef SDL_BuildAudioCVT
#undef SDL_ConvertAudio
+#undef SDL_MixAudio
#undef SDL_RegisterApp
#undef SDL_UnregisterApp
diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h
index e5469b8b5..cb54bdf0e 100644
--- a/src/SDL20_syms.h
+++ b/src/SDL20_syms.h
@@ -206,7 +206,7 @@ SDL20_SYM(void,PauseAudio,(int a),(a),)
SDL20_SYM_PASSTHROUGH(void,FreeWAV,(Uint8 *a),(a),)
SDL20_SYM(int,BuildAudioCVT,(SDL_AudioCVT *a, Uint16 b, Uint8 c, int d, Uint16 e, Uint8 f, int g),(a,b,c,d,e,f,g),return)
SDL20_SYM(int,ConvertAudio,(SDL_AudioCVT *a),(a),return)
-SDL20_SYM_PASSTHROUGH(void,MixAudio,(Uint8 *a, const Uint8 *b, Uint32 c, int d),(a,b,c,d),)
+SDL20_SYM(void,MixAudioFormat,(Uint8 *a, const Uint8 *b, SDL_AudioFormat c, Uint32 d, int e),(a,b,c,d,e),)
SDL20_SYM_PASSTHROUGH(void,LockAudio,(void),(),)
SDL20_SYM_PASSTHROUGH(void,UnlockAudio,(void),(),)