diff --git a/src/audio/SDL_wave.c b/src/audio/SDL_wave.c
index a9e905c1c..2c286aa34 100644
--- a/src/audio/SDL_wave.c
+++ b/src/audio/SDL_wave.c
@@ -403,6 +403,43 @@ IMA_ADPCM_decode(Uint8 ** audio_buf, Uint32 * audio_len)
     return (0);
 }
 
+
+static int
+ConvertSint24ToSint32(Uint8 ** audio_buf, Uint32 * audio_len)
+{
+    const double DIVBY8388608 = 0.00000011920928955078125;
+    const Uint32 original_len = *audio_len;
+    const Uint32 samples = original_len / 3;
+    const Uint32 expanded_len = samples * sizeof (Uint32);
+    Uint8 *ptr = (Uint8 *) SDL_realloc(*audio_buf, expanded_len);
+    const Uint8 *src;
+    Uint32 *dst;
+    Uint32 i;
+
+    if (!ptr) {
+        return SDL_OutOfMemory();
+    }
+
+    *audio_buf = ptr;
+    *audio_len = expanded_len;
+
+    /* work from end to start, since we're expanding in-place. */
+    src = (ptr + original_len) - 3;
+    dst = ((Uint32 *) (ptr + expanded_len)) - 1;
+    for (i = 0; i < samples; i++) {
+        /* There's probably a faster way to do all this. */
+        const Sint32 converted = ((Sint32) ( (((Uint32) src[2]) << 24) |
+                                             (((Uint32) src[1]) << 16) |
+                                             (((Uint32) src[0]) << 8) )) >> 8;
+        const double scaled = (((double) converted) * DIVBY8388608);
+        src -= 3;
+        *(dst--) = (Sint32) (scaled * 2147483647.0);
+    }
+
+    return 0;
+}
+
+
 /* GUIDs that are used by WAVE_FORMAT_EXTENSIBLE */
 static const Uint8 extensible_pcm_guid[16] = { 1, 0, 0, 0, 0, 0, 16, 0, 128, 0, 0, 170, 0, 56, 155, 113 };
 static const Uint8 extensible_ieee_guid[16] = { 3, 0, 0, 0, 0, 0, 16, 0, 128, 0, 0, 170, 0, 56, 155, 113 };
@@ -551,6 +588,9 @@ SDL_LoadWAV_RW(SDL_RWops * src, int freesrc,
         case 16:
             spec->format = AUDIO_S16;
             break;
+        case 24:  /* convert this. */
+            spec->format = AUDIO_S32;
+            break;
         case 32:
             spec->format = AUDIO_S32;
             break;
@@ -598,6 +638,13 @@ SDL_LoadWAV_RW(SDL_RWops * src, int freesrc,
         }
     }
 
+    if (SDL_SwapLE16(format->bitspersample) == 24) {
+        if (ConvertSint24ToSint32(audio_buf, audio_len) < 0) {
+            was_error = 1;
+            goto done;
+        }
+    }
+
     /* Don't return a buffer that isn't a multiple of samplesize */
     samplesize = ((SDL_AUDIO_BITSIZE(spec->format)) / 8) * spec->channels;
     *audio_len &= ~(samplesize - 1);