audio: Added basic WAVE_FORMAT_EXTENSIBLE support to .wav loader.
authorRyan C. Gordon
Fri, 17 Feb 2017 02:25:37 -0500
changeset 10894748bedefb03f
parent 10893 54480745c410
child 10895 fd63ed9b0746
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.
src/audio/SDL_wave.c
src/audio/SDL_wave.h
     1.1 --- a/src/audio/SDL_wave.c	Thu Feb 16 16:59:07 2017 -0500
     1.2 +++ b/src/audio/SDL_wave.c	Fri Feb 17 02:25:37 2017 -0500
     1.3 @@ -403,6 +403,10 @@
     1.4      return (0);
     1.5  }
     1.6  
     1.7 +/* GUIDs that are used by WAVE_FORMAT_EXTENSIBLE */
     1.8 +static const Uint8 extensible_pcm_guid[16] = { 1, 0, 0, 0, 0, 0, 16, 0, 128, 0, 0, 170, 0, 56, 155, 113 };
     1.9 +static const Uint8 extensible_ieee_guid[16] = { 3, 0, 0, 0, 0, 0, 16, 0, 128, 0, 0, 170, 0, 56, 155, 113 };
    1.10 +
    1.11  SDL_AudioSpec *
    1.12  SDL_LoadWAV_RW(SDL_RWops * src, int freesrc,
    1.13                 SDL_AudioSpec * spec, Uint8 ** audio_buf, Uint32 * audio_len)
    1.14 @@ -421,6 +425,7 @@
    1.15  
    1.16      /* FMT chunk */
    1.17      WaveFMT *format = NULL;
    1.18 +    WaveExtensibleFMT *ext = NULL;
    1.19  
    1.20      SDL_zero(chunk);
    1.21  
    1.22 @@ -494,6 +499,24 @@
    1.23          }
    1.24          IMA_ADPCM_encoded = 1;
    1.25          break;
    1.26 +    case EXTENSIBLE_CODE:
    1.27 +        /* note that this ignores channel masks, smaller valid bit counts
    1.28 +           inside a larger container, and most subtypes. This is just enough
    1.29 +           to get things that didn't really _need_ WAVE_FORMAT_EXTENSIBLE
    1.30 +           to be useful working when they use this format flag. */
    1.31 +        ext = (WaveExtensibleFMT *) format;
    1.32 +        if (SDL_SwapLE16(ext->size) < 22) {
    1.33 +            SDL_SetError("bogus extended .wav header");
    1.34 +            was_error = 1;
    1.35 +            goto done;
    1.36 +        }
    1.37 +        if (SDL_memcmp(ext->subformat, extensible_pcm_guid, 16) == 0) {
    1.38 +            break;  /* cool. */
    1.39 +        } else if (SDL_memcmp(ext->subformat, extensible_ieee_guid, 16) == 0) {
    1.40 +            IEEE_float_encoded = 1;
    1.41 +            break;
    1.42 +        }
    1.43 +        break;
    1.44      case MP3_CODE:
    1.45          SDL_SetError("MPEG Layer 3 data not supported");
    1.46          was_error = 1;
     2.1 --- a/src/audio/SDL_wave.h	Thu Feb 16 16:59:07 2017 -0500
     2.2 +++ b/src/audio/SDL_wave.h	Fri Feb 17 02:25:37 2017 -0500
     2.3 @@ -38,6 +38,7 @@
     2.4  #define IEEE_FLOAT_CODE 0x0003
     2.5  #define IMA_ADPCM_CODE  0x0011
     2.6  #define MP3_CODE        0x0055
     2.7 +#define EXTENSIBLE_CODE 0xFFFE
     2.8  #define WAVE_MONO       1
     2.9  #define WAVE_STEREO     2
    2.10  
    2.11 @@ -64,4 +65,13 @@
    2.12      Uint8 *data;
    2.13  } Chunk;
    2.14  
    2.15 +typedef struct WaveExtensibleFMT
    2.16 +{
    2.17 +    WaveFMT format;
    2.18 +    Uint16 size;
    2.19 +    Uint16 validbits;
    2.20 +    Uint32 channelmask;
    2.21 +    Uint8 subformat[16];  /* a GUID. */
    2.22 +} WaveExtensibleFMT;
    2.23 +
    2.24  /* vi: set ts=4 sw=4 expandtab: */