src/audio/SDL_wave.c
author Sam Lantinga
Sat, 06 Oct 2012 11:23:47 -0700
changeset 6565 1f3c0df426dc
parent 6409 b85e863a507e
child 6885 700f1b25f77f
permissions -rw-r--r--
When using Xinerama, XVidMode always works on screen 0. Otherwise use the real X11 screen.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 #include "SDL_config.h"
    22 
    23 /* Microsoft WAVE file loading routines */
    24 
    25 #include "SDL_audio.h"
    26 #include "SDL_wave.h"
    27 
    28 
    29 static int ReadChunk(SDL_RWops * src, Chunk * chunk);
    30 
    31 struct MS_ADPCM_decodestate
    32 {
    33     Uint8 hPredictor;
    34     Uint16 iDelta;
    35     Sint16 iSamp1;
    36     Sint16 iSamp2;
    37 };
    38 static struct MS_ADPCM_decoder
    39 {
    40     WaveFMT wavefmt;
    41     Uint16 wSamplesPerBlock;
    42     Uint16 wNumCoef;
    43     Sint16 aCoeff[7][2];
    44     /* * * */
    45     struct MS_ADPCM_decodestate state[2];
    46 } MS_ADPCM_state;
    47 
    48 static int
    49 InitMS_ADPCM(WaveFMT * format)
    50 {
    51     Uint8 *rogue_feel;
    52     int i;
    53 
    54     /* Set the rogue pointer to the MS_ADPCM specific data */
    55     MS_ADPCM_state.wavefmt.encoding = SDL_SwapLE16(format->encoding);
    56     MS_ADPCM_state.wavefmt.channels = SDL_SwapLE16(format->channels);
    57     MS_ADPCM_state.wavefmt.frequency = SDL_SwapLE32(format->frequency);
    58     MS_ADPCM_state.wavefmt.byterate = SDL_SwapLE32(format->byterate);
    59     MS_ADPCM_state.wavefmt.blockalign = SDL_SwapLE16(format->blockalign);
    60     MS_ADPCM_state.wavefmt.bitspersample =
    61         SDL_SwapLE16(format->bitspersample);
    62     rogue_feel = (Uint8 *) format + sizeof(*format);
    63     if (sizeof(*format) == 16) {
    64         /*const Uint16 extra_info = ((rogue_feel[1] << 8) | rogue_feel[0]);*/
    65         rogue_feel += sizeof(Uint16);
    66     }
    67     MS_ADPCM_state.wSamplesPerBlock = ((rogue_feel[1] << 8) | rogue_feel[0]);
    68     rogue_feel += sizeof(Uint16);
    69     MS_ADPCM_state.wNumCoef = ((rogue_feel[1] << 8) | rogue_feel[0]);
    70     rogue_feel += sizeof(Uint16);
    71     if (MS_ADPCM_state.wNumCoef != 7) {
    72         SDL_SetError("Unknown set of MS_ADPCM coefficients");
    73         return (-1);
    74     }
    75     for (i = 0; i < MS_ADPCM_state.wNumCoef; ++i) {
    76         MS_ADPCM_state.aCoeff[i][0] = ((rogue_feel[1] << 8) | rogue_feel[0]);
    77         rogue_feel += sizeof(Uint16);
    78         MS_ADPCM_state.aCoeff[i][1] = ((rogue_feel[1] << 8) | rogue_feel[0]);
    79         rogue_feel += sizeof(Uint16);
    80     }
    81     return (0);
    82 }
    83 
    84 static Sint32
    85 MS_ADPCM_nibble(struct MS_ADPCM_decodestate *state,
    86                 Uint8 nybble, Sint16 * coeff)
    87 {
    88     const Sint32 max_audioval = ((1 << (16 - 1)) - 1);
    89     const Sint32 min_audioval = -(1 << (16 - 1));
    90     const Sint32 adaptive[] = {
    91         230, 230, 230, 230, 307, 409, 512, 614,
    92         768, 614, 512, 409, 307, 230, 230, 230
    93     };
    94     Sint32 new_sample, delta;
    95 
    96     new_sample = ((state->iSamp1 * coeff[0]) +
    97                   (state->iSamp2 * coeff[1])) / 256;
    98     if (nybble & 0x08) {
    99         new_sample += state->iDelta * (nybble - 0x10);
   100     } else {
   101         new_sample += state->iDelta * nybble;
   102     }
   103     if (new_sample < min_audioval) {
   104         new_sample = min_audioval;
   105     } else if (new_sample > max_audioval) {
   106         new_sample = max_audioval;
   107     }
   108     delta = ((Sint32) state->iDelta * adaptive[nybble]) / 256;
   109     if (delta < 16) {
   110         delta = 16;
   111     }
   112     state->iDelta = (Uint16) delta;
   113     state->iSamp2 = state->iSamp1;
   114     state->iSamp1 = (Sint16) new_sample;
   115     return (new_sample);
   116 }
   117 
   118 static int
   119 MS_ADPCM_decode(Uint8 ** audio_buf, Uint32 * audio_len)
   120 {
   121     struct MS_ADPCM_decodestate *state[2];
   122     Uint8 *freeable, *encoded, *decoded;
   123     Sint32 encoded_len, samplesleft;
   124     Sint8 nybble, stereo;
   125     Sint16 *coeff[2];
   126     Sint32 new_sample;
   127 
   128     /* Allocate the proper sized output buffer */
   129     encoded_len = *audio_len;
   130     encoded = *audio_buf;
   131     freeable = *audio_buf;
   132     *audio_len = (encoded_len / MS_ADPCM_state.wavefmt.blockalign) *
   133         MS_ADPCM_state.wSamplesPerBlock *
   134         MS_ADPCM_state.wavefmt.channels * sizeof(Sint16);
   135     *audio_buf = (Uint8 *) SDL_malloc(*audio_len);
   136     if (*audio_buf == NULL) {
   137         SDL_Error(SDL_ENOMEM);
   138         return (-1);
   139     }
   140     decoded = *audio_buf;
   141 
   142     /* Get ready... Go! */
   143     stereo = (MS_ADPCM_state.wavefmt.channels == 2);
   144     state[0] = &MS_ADPCM_state.state[0];
   145     state[1] = &MS_ADPCM_state.state[stereo];
   146     while (encoded_len >= MS_ADPCM_state.wavefmt.blockalign) {
   147         /* Grab the initial information for this block */
   148         state[0]->hPredictor = *encoded++;
   149         if (stereo) {
   150             state[1]->hPredictor = *encoded++;
   151         }
   152         state[0]->iDelta = ((encoded[1] << 8) | encoded[0]);
   153         encoded += sizeof(Sint16);
   154         if (stereo) {
   155             state[1]->iDelta = ((encoded[1] << 8) | encoded[0]);
   156             encoded += sizeof(Sint16);
   157         }
   158         state[0]->iSamp1 = ((encoded[1] << 8) | encoded[0]);
   159         encoded += sizeof(Sint16);
   160         if (stereo) {
   161             state[1]->iSamp1 = ((encoded[1] << 8) | encoded[0]);
   162             encoded += sizeof(Sint16);
   163         }
   164         state[0]->iSamp2 = ((encoded[1] << 8) | encoded[0]);
   165         encoded += sizeof(Sint16);
   166         if (stereo) {
   167             state[1]->iSamp2 = ((encoded[1] << 8) | encoded[0]);
   168             encoded += sizeof(Sint16);
   169         }
   170         coeff[0] = MS_ADPCM_state.aCoeff[state[0]->hPredictor];
   171         coeff[1] = MS_ADPCM_state.aCoeff[state[1]->hPredictor];
   172 
   173         /* Store the two initial samples we start with */
   174         decoded[0] = state[0]->iSamp2 & 0xFF;
   175         decoded[1] = state[0]->iSamp2 >> 8;
   176         decoded += 2;
   177         if (stereo) {
   178             decoded[0] = state[1]->iSamp2 & 0xFF;
   179             decoded[1] = state[1]->iSamp2 >> 8;
   180             decoded += 2;
   181         }
   182         decoded[0] = state[0]->iSamp1 & 0xFF;
   183         decoded[1] = state[0]->iSamp1 >> 8;
   184         decoded += 2;
   185         if (stereo) {
   186             decoded[0] = state[1]->iSamp1 & 0xFF;
   187             decoded[1] = state[1]->iSamp1 >> 8;
   188             decoded += 2;
   189         }
   190 
   191         /* Decode and store the other samples in this block */
   192         samplesleft = (MS_ADPCM_state.wSamplesPerBlock - 2) *
   193             MS_ADPCM_state.wavefmt.channels;
   194         while (samplesleft > 0) {
   195             nybble = (*encoded) >> 4;
   196             new_sample = MS_ADPCM_nibble(state[0], nybble, coeff[0]);
   197             decoded[0] = new_sample & 0xFF;
   198             new_sample >>= 8;
   199             decoded[1] = new_sample & 0xFF;
   200             decoded += 2;
   201 
   202             nybble = (*encoded) & 0x0F;
   203             new_sample = MS_ADPCM_nibble(state[1], nybble, coeff[1]);
   204             decoded[0] = new_sample & 0xFF;
   205             new_sample >>= 8;
   206             decoded[1] = new_sample & 0xFF;
   207             decoded += 2;
   208 
   209             ++encoded;
   210             samplesleft -= 2;
   211         }
   212         encoded_len -= MS_ADPCM_state.wavefmt.blockalign;
   213     }
   214     SDL_free(freeable);
   215     return (0);
   216 }
   217 
   218 struct IMA_ADPCM_decodestate
   219 {
   220     Sint32 sample;
   221     Sint8 index;
   222 };
   223 static struct IMA_ADPCM_decoder
   224 {
   225     WaveFMT wavefmt;
   226     Uint16 wSamplesPerBlock;
   227     /* * * */
   228     struct IMA_ADPCM_decodestate state[2];
   229 } IMA_ADPCM_state;
   230 
   231 static int
   232 InitIMA_ADPCM(WaveFMT * format)
   233 {
   234     Uint8 *rogue_feel;
   235 
   236     /* Set the rogue pointer to the IMA_ADPCM specific data */
   237     IMA_ADPCM_state.wavefmt.encoding = SDL_SwapLE16(format->encoding);
   238     IMA_ADPCM_state.wavefmt.channels = SDL_SwapLE16(format->channels);
   239     IMA_ADPCM_state.wavefmt.frequency = SDL_SwapLE32(format->frequency);
   240     IMA_ADPCM_state.wavefmt.byterate = SDL_SwapLE32(format->byterate);
   241     IMA_ADPCM_state.wavefmt.blockalign = SDL_SwapLE16(format->blockalign);
   242     IMA_ADPCM_state.wavefmt.bitspersample =
   243         SDL_SwapLE16(format->bitspersample);
   244     rogue_feel = (Uint8 *) format + sizeof(*format);
   245     if (sizeof(*format) == 16) {
   246         /*const Uint16 extra_info = ((rogue_feel[1] << 8) | rogue_feel[0]);*/
   247         rogue_feel += sizeof(Uint16);
   248     }
   249     IMA_ADPCM_state.wSamplesPerBlock = ((rogue_feel[1] << 8) | rogue_feel[0]);
   250     return (0);
   251 }
   252 
   253 static Sint32
   254 IMA_ADPCM_nibble(struct IMA_ADPCM_decodestate *state, Uint8 nybble)
   255 {
   256     const Sint32 max_audioval = ((1 << (16 - 1)) - 1);
   257     const Sint32 min_audioval = -(1 << (16 - 1));
   258     const int index_table[16] = {
   259         -1, -1, -1, -1,
   260         2, 4, 6, 8,
   261         -1, -1, -1, -1,
   262         2, 4, 6, 8
   263     };
   264     const Sint32 step_table[89] = {
   265         7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31,
   266         34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130,
   267         143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408,
   268         449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282,
   269         1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327,
   270         3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630,
   271         9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350,
   272         22385, 24623, 27086, 29794, 32767
   273     };
   274     Sint32 delta, step;
   275 
   276     /* Compute difference and new sample value */
   277     step = step_table[state->index];
   278     delta = step >> 3;
   279     if (nybble & 0x04)
   280         delta += step;
   281     if (nybble & 0x02)
   282         delta += (step >> 1);
   283     if (nybble & 0x01)
   284         delta += (step >> 2);
   285     if (nybble & 0x08)
   286         delta = -delta;
   287     state->sample += delta;
   288 
   289     /* Update index value */
   290     state->index += index_table[nybble];
   291     if (state->index > 88) {
   292         state->index = 88;
   293     } else if (state->index < 0) {
   294         state->index = 0;
   295     }
   296 
   297     /* Clamp output sample */
   298     if (state->sample > max_audioval) {
   299         state->sample = max_audioval;
   300     } else if (state->sample < min_audioval) {
   301         state->sample = min_audioval;
   302     }
   303     return (state->sample);
   304 }
   305 
   306 /* Fill the decode buffer with a channel block of data (8 samples) */
   307 static void
   308 Fill_IMA_ADPCM_block(Uint8 * decoded, Uint8 * encoded,
   309                      int channel, int numchannels,
   310                      struct IMA_ADPCM_decodestate *state)
   311 {
   312     int i;
   313     Sint8 nybble;
   314     Sint32 new_sample;
   315 
   316     decoded += (channel * 2);
   317     for (i = 0; i < 4; ++i) {
   318         nybble = (*encoded) & 0x0F;
   319         new_sample = IMA_ADPCM_nibble(state, nybble);
   320         decoded[0] = new_sample & 0xFF;
   321         new_sample >>= 8;
   322         decoded[1] = new_sample & 0xFF;
   323         decoded += 2 * numchannels;
   324 
   325         nybble = (*encoded) >> 4;
   326         new_sample = IMA_ADPCM_nibble(state, nybble);
   327         decoded[0] = new_sample & 0xFF;
   328         new_sample >>= 8;
   329         decoded[1] = new_sample & 0xFF;
   330         decoded += 2 * numchannels;
   331 
   332         ++encoded;
   333     }
   334 }
   335 
   336 static int
   337 IMA_ADPCM_decode(Uint8 ** audio_buf, Uint32 * audio_len)
   338 {
   339     struct IMA_ADPCM_decodestate *state;
   340     Uint8 *freeable, *encoded, *decoded;
   341     Sint32 encoded_len, samplesleft;
   342     unsigned int c, channels;
   343 
   344     /* Check to make sure we have enough variables in the state array */
   345     channels = IMA_ADPCM_state.wavefmt.channels;
   346     if (channels > SDL_arraysize(IMA_ADPCM_state.state)) {
   347         SDL_SetError("IMA ADPCM decoder can only handle %d channels",
   348                      SDL_arraysize(IMA_ADPCM_state.state));
   349         return (-1);
   350     }
   351     state = IMA_ADPCM_state.state;
   352 
   353     /* Allocate the proper sized output buffer */
   354     encoded_len = *audio_len;
   355     encoded = *audio_buf;
   356     freeable = *audio_buf;
   357     *audio_len = (encoded_len / IMA_ADPCM_state.wavefmt.blockalign) *
   358         IMA_ADPCM_state.wSamplesPerBlock *
   359         IMA_ADPCM_state.wavefmt.channels * sizeof(Sint16);
   360     *audio_buf = (Uint8 *) SDL_malloc(*audio_len);
   361     if (*audio_buf == NULL) {
   362         SDL_Error(SDL_ENOMEM);
   363         return (-1);
   364     }
   365     decoded = *audio_buf;
   366 
   367     /* Get ready... Go! */
   368     while (encoded_len >= IMA_ADPCM_state.wavefmt.blockalign) {
   369         /* Grab the initial information for this block */
   370         for (c = 0; c < channels; ++c) {
   371             /* Fill the state information for this block */
   372             state[c].sample = ((encoded[1] << 8) | encoded[0]);
   373             encoded += 2;
   374             if (state[c].sample & 0x8000) {
   375                 state[c].sample -= 0x10000;
   376             }
   377             state[c].index = *encoded++;
   378             /* Reserved byte in buffer header, should be 0 */
   379             if (*encoded++ != 0) {
   380                 /* Uh oh, corrupt data?  Buggy code? */ ;
   381             }
   382 
   383             /* Store the initial sample we start with */
   384             decoded[0] = (Uint8) (state[c].sample & 0xFF);
   385             decoded[1] = (Uint8) (state[c].sample >> 8);
   386             decoded += 2;
   387         }
   388 
   389         /* Decode and store the other samples in this block */
   390         samplesleft = (IMA_ADPCM_state.wSamplesPerBlock - 1) * channels;
   391         while (samplesleft > 0) {
   392             for (c = 0; c < channels; ++c) {
   393                 Fill_IMA_ADPCM_block(decoded, encoded,
   394                                      c, channels, &state[c]);
   395                 encoded += 4;
   396                 samplesleft -= 8;
   397             }
   398             decoded += (channels * 8 * 2);
   399         }
   400         encoded_len -= IMA_ADPCM_state.wavefmt.blockalign;
   401     }
   402     SDL_free(freeable);
   403     return (0);
   404 }
   405 
   406 SDL_AudioSpec *
   407 SDL_LoadWAV_RW(SDL_RWops * src, int freesrc,
   408                SDL_AudioSpec * spec, Uint8 ** audio_buf, Uint32 * audio_len)
   409 {
   410     int was_error;
   411     Chunk chunk;
   412     int lenread;
   413     int IEEE_float_encoded, MS_ADPCM_encoded, IMA_ADPCM_encoded;
   414     int samplesize;
   415 
   416     /* WAV magic header */
   417     Uint32 RIFFchunk;
   418     Uint32 wavelen = 0;
   419     Uint32 WAVEmagic;
   420     Uint32 headerDiff = 0;
   421 
   422     /* FMT chunk */
   423     WaveFMT *format = NULL;
   424 
   425     SDL_zero(chunk);
   426 
   427     /* Make sure we are passed a valid data source */
   428     was_error = 0;
   429     if (src == NULL) {
   430         was_error = 1;
   431         goto done;
   432     }
   433 
   434     /* Check the magic header */
   435     RIFFchunk = SDL_ReadLE32(src);
   436     wavelen = SDL_ReadLE32(src);
   437     if (wavelen == WAVE) {      /* The RIFFchunk has already been read */
   438         WAVEmagic = wavelen;
   439         wavelen = RIFFchunk;
   440         RIFFchunk = RIFF;
   441     } else {
   442         WAVEmagic = SDL_ReadLE32(src);
   443     }
   444     if ((RIFFchunk != RIFF) || (WAVEmagic != WAVE)) {
   445         SDL_SetError("Unrecognized file type (not WAVE)");
   446         was_error = 1;
   447         goto done;
   448     }
   449     headerDiff += sizeof(Uint32);       /* for WAVE */
   450 
   451     /* Read the audio data format chunk */
   452     chunk.data = NULL;
   453     do {
   454         if (chunk.data != NULL) {
   455             SDL_free(chunk.data);
   456             chunk.data = NULL;
   457         }
   458         lenread = ReadChunk(src, &chunk);
   459         if (lenread < 0) {
   460             was_error = 1;
   461             goto done;
   462         }
   463         /* 2 Uint32's for chunk header+len, plus the lenread */
   464         headerDiff += lenread + 2 * sizeof(Uint32);
   465     } while ((chunk.magic == FACT) || (chunk.magic == LIST));
   466 
   467     /* Decode the audio data format */
   468     format = (WaveFMT *) chunk.data;
   469     if (chunk.magic != FMT) {
   470         SDL_SetError("Complex WAVE files not supported");
   471         was_error = 1;
   472         goto done;
   473     }
   474     IEEE_float_encoded = MS_ADPCM_encoded = IMA_ADPCM_encoded = 0;
   475     switch (SDL_SwapLE16(format->encoding)) {
   476     case PCM_CODE:
   477         /* We can understand this */
   478         break;
   479     case IEEE_FLOAT_CODE:
   480         IEEE_float_encoded = 1;
   481         /* We can understand this */
   482         break;
   483     case MS_ADPCM_CODE:
   484         /* Try to understand this */
   485         if (InitMS_ADPCM(format) < 0) {
   486             was_error = 1;
   487             goto done;
   488         }
   489         MS_ADPCM_encoded = 1;
   490         break;
   491     case IMA_ADPCM_CODE:
   492         /* Try to understand this */
   493         if (InitIMA_ADPCM(format) < 0) {
   494             was_error = 1;
   495             goto done;
   496         }
   497         IMA_ADPCM_encoded = 1;
   498         break;
   499     case MP3_CODE:
   500         SDL_SetError("MPEG Layer 3 data not supported",
   501                      SDL_SwapLE16(format->encoding));
   502         was_error = 1;
   503         goto done;
   504     default:
   505         SDL_SetError("Unknown WAVE data format: 0x%.4x",
   506                      SDL_SwapLE16(format->encoding));
   507         was_error = 1;
   508         goto done;
   509     }
   510     SDL_memset(spec, 0, (sizeof *spec));
   511     spec->freq = SDL_SwapLE32(format->frequency);
   512 
   513     if (IEEE_float_encoded) {
   514         if ((SDL_SwapLE16(format->bitspersample)) != 32) {
   515             was_error = 1;
   516         } else {
   517             spec->format = AUDIO_F32;
   518         }
   519     } else {
   520         switch (SDL_SwapLE16(format->bitspersample)) {
   521         case 4:
   522             if (MS_ADPCM_encoded || IMA_ADPCM_encoded) {
   523                 spec->format = AUDIO_S16;
   524             } else {
   525                 was_error = 1;
   526             }
   527             break;
   528         case 8:
   529             spec->format = AUDIO_U8;
   530             break;
   531         case 16:
   532             spec->format = AUDIO_S16;
   533             break;
   534         case 32:
   535             spec->format = AUDIO_S32;
   536             break;
   537         default:
   538             was_error = 1;
   539             break;
   540         }
   541     }
   542 
   543     if (was_error) {
   544         SDL_SetError("Unknown %d-bit PCM data format",
   545                      SDL_SwapLE16(format->bitspersample));
   546         goto done;
   547     }
   548     spec->channels = (Uint8) SDL_SwapLE16(format->channels);
   549     spec->samples = 4096;       /* Good default buffer size */
   550 
   551     /* Read the audio data chunk */
   552     *audio_buf = NULL;
   553     do {
   554         if (*audio_buf != NULL) {
   555             SDL_free(*audio_buf);
   556             *audio_buf = NULL;
   557         }
   558         lenread = ReadChunk(src, &chunk);
   559         if (lenread < 0) {
   560             was_error = 1;
   561             goto done;
   562         }
   563         *audio_len = lenread;
   564         *audio_buf = chunk.data;
   565         if (chunk.magic != DATA)
   566             headerDiff += lenread + 2 * sizeof(Uint32);
   567     } while (chunk.magic != DATA);
   568     headerDiff += 2 * sizeof(Uint32);   /* for the data chunk and len */
   569 
   570     if (MS_ADPCM_encoded) {
   571         if (MS_ADPCM_decode(audio_buf, audio_len) < 0) {
   572             was_error = 1;
   573             goto done;
   574         }
   575     }
   576     if (IMA_ADPCM_encoded) {
   577         if (IMA_ADPCM_decode(audio_buf, audio_len) < 0) {
   578             was_error = 1;
   579             goto done;
   580         }
   581     }
   582 
   583     /* Don't return a buffer that isn't a multiple of samplesize */
   584     samplesize = ((SDL_AUDIO_BITSIZE(spec->format)) / 8) * spec->channels;
   585     *audio_len &= ~(samplesize - 1);
   586 
   587   done:
   588     if (format != NULL) {
   589         SDL_free(format);
   590     }
   591     if (src) {
   592         if (freesrc) {
   593             SDL_RWclose(src);
   594         } else {
   595             /* seek to the end of the file (given by the RIFF chunk) */
   596             SDL_RWseek(src, wavelen - chunk.length - headerDiff, RW_SEEK_CUR);
   597         }
   598     }
   599     if (was_error) {
   600         spec = NULL;
   601     }
   602     return (spec);
   603 }
   604 
   605 /* Since the WAV memory is allocated in the shared library, it must also
   606    be freed here.  (Necessary under Win32, VC++)
   607  */
   608 void
   609 SDL_FreeWAV(Uint8 * audio_buf)
   610 {
   611     if (audio_buf != NULL) {
   612         SDL_free(audio_buf);
   613     }
   614 }
   615 
   616 static int
   617 ReadChunk(SDL_RWops * src, Chunk * chunk)
   618 {
   619     chunk->magic = SDL_ReadLE32(src);
   620     chunk->length = SDL_ReadLE32(src);
   621     chunk->data = (Uint8 *) SDL_malloc(chunk->length);
   622     if (chunk->data == NULL) {
   623         SDL_Error(SDL_ENOMEM);
   624         return (-1);
   625     }
   626     if (SDL_RWread(src, chunk->data, chunk->length, 1) != 1) {
   627         SDL_Error(SDL_EFREAD);
   628         SDL_free(chunk->data);
   629         chunk->data = NULL;
   630         return (-1);
   631     }
   632     return (chunk->length);
   633 }
   634 
   635 /* vi: set ts=4 sw=4 expandtab: */