audio: Added basic WAVE_FORMAT_EXTENSIBLE support to .wav loader. This is just enough to get you through a file that just used the extended header for float or int data. It doesn't handle all the other things that you expect from this header, like 24-bit samples inside a 32-bit container or speaker masks.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
diff --git a/src/audio/SDL_wave.c b/src/audio/SDL_wave.c
index 7ce00a5..a9e905c 100644
--- a/src/audio/SDL_wave.c
+++ b/src/audio/SDL_wave.c
@@ -403,6 +403,10 @@ IMA_ADPCM_decode(Uint8 ** audio_buf, Uint32 * audio_len)
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 };
+
SDL_AudioSpec *
SDL_LoadWAV_RW(SDL_RWops * src, int freesrc,
SDL_AudioSpec * spec, Uint8 ** audio_buf, Uint32 * audio_len)
@@ -421,6 +425,7 @@ SDL_LoadWAV_RW(SDL_RWops * src, int freesrc,
/* FMT chunk */
WaveFMT *format = NULL;
+ WaveExtensibleFMT *ext = NULL;
SDL_zero(chunk);
@@ -494,6 +499,24 @@ SDL_LoadWAV_RW(SDL_RWops * src, int freesrc,
}
IMA_ADPCM_encoded = 1;
break;
+ case EXTENSIBLE_CODE:
+ /* note that this ignores channel masks, smaller valid bit counts
+ inside a larger container, and most subtypes. This is just enough
+ to get things that didn't really _need_ WAVE_FORMAT_EXTENSIBLE
+ to be useful working when they use this format flag. */
+ ext = (WaveExtensibleFMT *) format;
+ if (SDL_SwapLE16(ext->size) < 22) {
+ SDL_SetError("bogus extended .wav header");
+ was_error = 1;
+ goto done;
+ }
+ if (SDL_memcmp(ext->subformat, extensible_pcm_guid, 16) == 0) {
+ break; /* cool. */
+ } else if (SDL_memcmp(ext->subformat, extensible_ieee_guid, 16) == 0) {
+ IEEE_float_encoded = 1;
+ break;
+ }
+ break;
case MP3_CODE:
SDL_SetError("MPEG Layer 3 data not supported");
was_error = 1;
diff --git a/src/audio/SDL_wave.h b/src/audio/SDL_wave.h
index fe55b4a..5762f51 100644
--- a/src/audio/SDL_wave.h
+++ b/src/audio/SDL_wave.h
@@ -38,6 +38,7 @@
#define IEEE_FLOAT_CODE 0x0003
#define IMA_ADPCM_CODE 0x0011
#define MP3_CODE 0x0055
+#define EXTENSIBLE_CODE 0xFFFE
#define WAVE_MONO 1
#define WAVE_STEREO 2
@@ -64,4 +65,13 @@ typedef struct Chunk
Uint8 *data;
} Chunk;
+typedef struct WaveExtensibleFMT
+{
+ WaveFMT format;
+ Uint16 size;
+ Uint16 validbits;
+ Uint32 channelmask;
+ Uint8 subformat[16]; /* a GUID. */
+} WaveExtensibleFMT;
+
/* vi: set ts=4 sw=4 expandtab: */