From a41ce8e3112d94e31c71851ecdef18fd70facb68 Mon Sep 17 00:00:00 2001
From: Sylvain <[EMAIL REDACTED]>
Date: Sat, 14 Jan 2023 15:35:06 +0100
Subject: [PATCH] Use SDL_AudioStream instead of AudioCVT for Mix_LoadWAV_RW()
---
src/mixer.c | 87 +++++++++++++++++++++++++++++++++--------------------
1 file changed, 54 insertions(+), 33 deletions(-)
diff --git a/src/mixer.c b/src/mixer.c
index abc1f9e3..b27fd698 100644
--- a/src/mixer.c
+++ b/src/mixer.c
@@ -278,7 +278,7 @@ int Mix_Init(int flags)
return result;
}
-void Mix_Quit()
+void Mix_Quit(void)
{
unload_music();
}
@@ -770,9 +770,6 @@ Mix_Chunk *Mix_LoadWAV_RW(SDL_RWops *src, int freesrc)
Uint8 magic[4];
Mix_Chunk *chunk;
SDL_AudioSpec wavespec, *loaded;
- SDL_AudioCVT wavecvt;
- int samplesize;
- Uint8 *resized_buf;
/* rcg06012001 Make sure src is valid */
if (!src) {
@@ -831,49 +828,73 @@ Mix_Chunk *Mix_LoadWAV_RW(SDL_RWops *src, int freesrc)
PrintFormat("-- Wave file", &wavespec);
#endif
+ chunk->allocated = 1;
+ chunk->volume = MIX_MAX_VOLUME;
+
/* Build the audio converter and create conversion buffers */
if (wavespec.format != mixer.format ||
wavespec.channels != mixer.channels ||
wavespec.freq != mixer.freq) {
- if (SDL_BuildAudioCVT(&wavecvt,
- wavespec.format, wavespec.channels, wavespec.freq,
- mixer.format, mixer.channels, mixer.freq) < 0) {
- SDL_free(chunk->abuf);
- SDL_free(chunk);
- return(NULL);
+ SDL_AudioStream *stream;
+ int src_samplesize, dst_samplesize;
+ Uint8 *dst_buf = NULL;
+ int src_len, dst_len, real_dst_len;
+
+ src_samplesize = (SDL_AUDIO_BITSIZE(wavespec.format) / 8) * wavespec.channels;
+ dst_samplesize = (SDL_AUDIO_BITSIZE(mixer.format) / 8) * mixer.channels;
+
+ stream = SDL_CreateAudioStream(wavespec.format, wavespec.channels, wavespec.freq,
+ mixer.format, mixer.channels, mixer.freq);
+ if (stream == NULL) {
+ goto failure;
}
- samplesize = ((wavespec.format & 0xFF)/8)*wavespec.channels;
- wavecvt.len = chunk->alen & ~(samplesize-1);
- wavecvt.buf = (Uint8 *)SDL_calloc(1, wavecvt.len*wavecvt.len_mult);
- if (wavecvt.buf == NULL) {
+
+ src_len = chunk->alen & ~(src_samplesize - 1);
+ dst_len = dst_samplesize * (src_len / src_samplesize);
+ if (wavespec.freq < mixer.freq) {
+ const double mult = ((double)mixer.freq) / ((double)wavespec.freq);
+ dst_len *= (int) SDL_ceil(mult);
+ }
+
+ dst_len = dst_len & ~(dst_samplesize - 1);
+ dst_buf = (Uint8 *)SDL_calloc(1, dst_len);
+ if (dst_buf == NULL) {
Mix_OutOfMemory();
- SDL_free(chunk->abuf);
- SDL_free(chunk);
- return(NULL);
+ goto failure;
}
- SDL_memcpy(wavecvt.buf, chunk->abuf, wavecvt.len);
- SDL_free(chunk->abuf);
/* Run the audio converter */
- if (SDL_ConvertAudio(&wavecvt) < 0) {
- SDL_free(wavecvt.buf);
- SDL_free(chunk);
- return(NULL);
+ if (SDL_PutAudioStreamData(stream, chunk->abuf, src_len) < 0 ||
+ SDL_FlushAudioStream(stream) < 0) {
+ goto failure;
}
- resized_buf = SDL_realloc(wavecvt.buf, wavecvt.len_cvt);
- if (resized_buf == NULL) {
- chunk->abuf = wavecvt.buf;
- } else {
- chunk->abuf = resized_buf;
+ real_dst_len = SDL_GetAudioStreamData(stream, dst_buf, dst_len);
+ if (real_dst_len < 0) {
+ goto failure;
}
- chunk->alen = wavecvt.len_cvt;
- }
- chunk->allocated = 1;
- chunk->volume = MIX_MAX_VOLUME;
+ SDL_DestroyAudioStream(stream);
+ SDL_free(chunk->abuf);
- return(chunk);
+ {
+ Uint8 *resized_buf = SDL_realloc(dst_buf, real_dst_len);
+ if (resized_buf) {
+ dst_buf = resized_buf;
+ }
+ }
+ chunk->abuf = dst_buf;
+ chunk->alen = real_dst_len;
+ return chunk;
+
+failure:
+ SDL_free(chunk->abuf);
+ SDL_free(chunk);
+ SDL_free(dst_buf);
+ return NULL;
+ }
+
+ return chunk;
}
Mix_Chunk *Mix_LoadWAV(const char *file)