From 3895550264a1c82b398cb4f04072adf884fa4bd5 Mon Sep 17 00:00:00 2001
From: Ozkan Sezer <[EMAIL REDACTED]>
Date: Wed, 3 Mar 2021 23:00:10 +0300
Subject: [PATCH] first shot at fixing the SDL_OpenAudio and SDL_LoadWAV_RW
FIXME()s:
* SDL1.2 doesn't support AUDIO_S32 or AUDIO_F32 formats:
- SDL_LoadWAV_RW: Reject WAV files with such formats.
- Always pass NULL as the 'obtained' pointer to SDL_OpenAudio().
If a field of the spec is 0, assign some reasonable default to
it.
* Library is leaking AudioCallbackWrapper data:
- Store the data in a global var, change SDL_CloseAudio to not
be a passthrough, free the data from SDL_CloseAudio.
---
src/SDL12_compat.c | 48 ++++++++++++++++++++++++++++++++--------------
src/SDL20_syms.h | 4 +---
2 files changed, 35 insertions(+), 17 deletions(-)
diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c
index ab09646..6be21d2 100644
--- a/src/SDL12_compat.c
+++ b/src/SDL12_compat.c
@@ -4441,7 +4441,12 @@ SDL_LoadWAV_RW(SDL12_RWops *rwops12, int freerwops12,
{
SDL_RWops *rwops20 = RWops12to20(rwops12);
SDL_AudioSpec *retval = SDL20_LoadWAV_RW(rwops20, freerwops12, spec, buf, len);
- FIXME("deal with non-1.2 formats, like float32");
+ if (retval && retval->format & 0x20) {
+ SDL20_SetError("Unsupported 32-bit PCM data format");
+ SDL20_FreeWAV(*buf);
+ *buf = NULL;
+ retval = NULL;
+ }
if (!freerwops12) /* free our wrapper if SDL2 didn't close it. */
SDL20_FreeRW(rwops20);
return retval;
@@ -4454,11 +4459,13 @@ typedef struct
Uint8 silence;
} AudioCallbackWrapperData;
+static AudioCallbackWrapperData *audio_cbdata = NULL;
+
static void SDLCALL
AudioCallbackWrapper(void *userdata, Uint8 *stream, int len)
{
AudioCallbackWrapperData *data = (AudioCallbackWrapperData *) userdata;
- SDL_memset(stream, data->silence, len); // SDL2 doesn't clear the stream before calling in here, but 1.2 expects it.
+ SDL_memset(stream, data->silence, len); /* SDL2 doesn't clear the stream before calling in here, but 1.2 expects it. */
data->app_callback(data->app_userdata, stream, len);
}
@@ -4469,7 +4476,7 @@ SDL_OpenAudio(SDL_AudioSpec *want, SDL_AudioSpec *obtained)
AudioCallbackWrapperData *data;
int retval;
- // SDL2 uses a NULL callback to mean "we play to use SDL_QueueAudio()"
+ /* SDL2 uses a NULL callback to mean "we play to use SDL_QueueAudio()" */
if (want && (want->callback == NULL)) {
return SDL20_SetError("Callback can't be NULL");
}
@@ -4482,28 +4489,41 @@ SDL_OpenAudio(SDL_AudioSpec *want, SDL_AudioSpec *obtained)
data->app_userdata = want->userdata;
want->callback = AudioCallbackWrapper;
want->userdata = data;
-
- FIXME("Don't allow int32 or float32");
- FIXME("clamp output to mono/stereo");
- retval = SDL20_OpenAudio(want, obtained);
+ /* to avoid receiving a possible incompatible configuration
+ * from SDL2, always pass NULL as the 'obtained' pointer. */
+ if (!want->format) {
+ want->format = AUDIO_S16SYS;
+ }
+ if (!want->freq) {
+ want->freq = 22050;
+ }
+ if (!want->channels) {
+ want->channels = 2;
+ }
+ retval = SDL20_OpenAudio(want, NULL);
want->callback = data->app_callback;
want->userdata = data->app_userdata;
if (retval < 0) {
SDL20_free(data);
} else {
- FIXME("memory leak on callback data");
- if (!obtained) {
- data->silence = want->silence;
- } else {
- data->silence = obtained->silence;
- obtained->callback = data->app_callback;
- obtained->userdata = data->app_userdata;
+ data->silence = want->silence;
+ audio_cbdata = data;
+ if (obtained) {
+ SDL_memcpy(obtained, want, sizeof (SDL_AudioSpec));
}
}
return retval;
}
+DECLSPEC void SDLCALL
+SDL_CloseAudio(void)
+{
+ SDL20_CloseAudio();
+ SDL20_free(audio_cbdata);
+ audio_cbdata = NULL;
+}
+
/* !!! FIXME: these are just stubs for now, but Sam thinks that maybe these
were added at Loki for Heavy Gear 2's UI. They just make GL calls. */
DECLSPEC void SDLCALL
diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h
index 1f1359a..8204724 100644
--- a/src/SDL20_syms.h
+++ b/src/SDL20_syms.h
@@ -149,10 +149,8 @@ SDL20_SYM(SDL_Thread *,CreateThread,(SDL_ThreadFunction a, const char *b, void *
#else
SDL20_SYM(SDL_Thread *,CreateThread,(SDL_ThreadFunction a, const char *b, void *c),(a,b,c),return)
#endif
-
SDL20_SYM(unsigned long,GetThreadID,(SDL_Thread *a),(a),return)
SDL20_SYM(unsigned long,ThreadID,(void),(),return)
-
SDL20_SYM_PASSTHROUGH(void,WaitThread,(SDL_Thread *a, int *b),(a,b),)
SDL20_SYM_PASSTHROUGH(SDL_mutex*,CreateMutex,(void),(),return)
SDL20_SYM(int,LockMutex,(SDL_mutex *a),(a),return)
@@ -174,6 +172,7 @@ SDL20_SYM_PASSTHROUGH(int,CondWaitTimeout,(SDL_cond *a, SDL_mutex *b, Uint32 c),
SDL20_SYM(SDL_AudioSpec *,LoadWAV_RW,(SDL_RWops *a, int b, SDL_AudioSpec *c, Uint8 **d, Uint32 *e),(a,b,c,d,e),return)
SDL20_SYM(int,OpenAudio,(SDL_AudioSpec *a, SDL_AudioSpec *b),(a,b),return)
+SDL20_SYM(void,CloseAudio,(void),(),)
SDL20_SYM_PASSTHROUGH(SDL_AudioStatus,GetAudioStatus,(void),(),return)
SDL20_SYM_PASSTHROUGH(void,PauseAudio,(int a),(a),)
SDL20_SYM_PASSTHROUGH(void,FreeWAV,(Uint8 *a),(a),)
@@ -182,7 +181,6 @@ SDL20_SYM_PASSTHROUGH(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_PASSTHROUGH(void,LockAudio,(void),(),)
SDL20_SYM_PASSTHROUGH(void,UnlockAudio,(void),(),)
-SDL20_SYM_PASSTHROUGH(void,CloseAudio,(void),(),)
SDL20_SYM_PASSTHROUGH(void*,LoadObject,(const char *a),(a),return)
SDL20_SYM_PASSTHROUGH(void*,LoadFunction,(void *a, const char *b),(a,b),return)