src/audio/SDL_wave.c
author Sam Lantinga <slouken@libsdl.org>
Tue, 18 Jun 2013 00:50:35 -0700
changeset 7313 c7346a060a7d
parent 7037 3fedf1f25b94
child 7677 871d43c6968a
permissions -rw-r--r--
Fixed bug 1913 - state->index may get negative in SDL_wave.c file.

Nitz

In function:
static Sint32
IMA_ADPCM_nibble(struct IMA_ADPCM_decodestate *state, Uint8 nybble)
{
const Sint32 max_audioval = ((1 << (16 - 1)) - 1);
const Sint32 min_audioval = -(1 << (16 - 1));
const int index_table[16] = {
-1, -1, -1, -1,
2, 4, 6, 8,
-1, -1, -1, -1,
2, 4, 6, 8
};
const Sint32 step_table[89] = {
7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31,
34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130,
143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408,
449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282,
1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327,
3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630,
9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350,
22385, 24623, 27086, 29794, 32767
};
Sint32 delta, step;

/* Compute difference and new sample value */
step = step_table[state->index];
// Some Code
}

Here step_table array have the state->index, which might be negative, so it is unsafe to assign this index to step_table array directly.
There would be a check before that to confirm its value.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2013 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         return SDL_OutOfMemory();
   138     }
   139     decoded = *audio_buf;
   140 
   141     /* Get ready... Go! */
   142     stereo = (MS_ADPCM_state.wavefmt.channels == 2);
   143     state[0] = &MS_ADPCM_state.state[0];
   144     state[1] = &MS_ADPCM_state.state[stereo];
   145     while (encoded_len >= MS_ADPCM_state.wavefmt.blockalign) {
   146         /* Grab the initial information for this block */
   147         state[0]->hPredictor = *encoded++;
   148         if (stereo) {
   149             state[1]->hPredictor = *encoded++;
   150         }
   151         state[0]->iDelta = ((encoded[1] << 8) | encoded[0]);
   152         encoded += sizeof(Sint16);
   153         if (stereo) {
   154             state[1]->iDelta = ((encoded[1] << 8) | encoded[0]);
   155             encoded += sizeof(Sint16);
   156         }
   157         state[0]->iSamp1 = ((encoded[1] << 8) | encoded[0]);
   158         encoded += sizeof(Sint16);
   159         if (stereo) {
   160             state[1]->iSamp1 = ((encoded[1] << 8) | encoded[0]);
   161             encoded += sizeof(Sint16);
   162         }
   163         state[0]->iSamp2 = ((encoded[1] << 8) | encoded[0]);
   164         encoded += sizeof(Sint16);
   165         if (stereo) {
   166             state[1]->iSamp2 = ((encoded[1] << 8) | encoded[0]);
   167             encoded += sizeof(Sint16);
   168         }
   169         coeff[0] = MS_ADPCM_state.aCoeff[state[0]->hPredictor];
   170         coeff[1] = MS_ADPCM_state.aCoeff[state[1]->hPredictor];
   171 
   172         /* Store the two initial samples we start with */
   173         decoded[0] = state[0]->iSamp2 & 0xFF;
   174         decoded[1] = state[0]->iSamp2 >> 8;
   175         decoded += 2;
   176         if (stereo) {
   177             decoded[0] = state[1]->iSamp2 & 0xFF;
   178             decoded[1] = state[1]->iSamp2 >> 8;
   179             decoded += 2;
   180         }
   181         decoded[0] = state[0]->iSamp1 & 0xFF;
   182         decoded[1] = state[0]->iSamp1 >> 8;
   183         decoded += 2;
   184         if (stereo) {
   185             decoded[0] = state[1]->iSamp1 & 0xFF;
   186             decoded[1] = state[1]->iSamp1 >> 8;
   187             decoded += 2;
   188         }
   189 
   190         /* Decode and store the other samples in this block */
   191         samplesleft = (MS_ADPCM_state.wSamplesPerBlock - 2) *
   192             MS_ADPCM_state.wavefmt.channels;
   193         while (samplesleft > 0) {
   194             nybble = (*encoded) >> 4;
   195             new_sample = MS_ADPCM_nibble(state[0], nybble, coeff[0]);
   196             decoded[0] = new_sample & 0xFF;
   197             new_sample >>= 8;
   198             decoded[1] = new_sample & 0xFF;
   199             decoded += 2;
   200 
   201             nybble = (*encoded) & 0x0F;
   202             new_sample = MS_ADPCM_nibble(state[1], nybble, coeff[1]);
   203             decoded[0] = new_sample & 0xFF;
   204             new_sample >>= 8;
   205             decoded[1] = new_sample & 0xFF;
   206             decoded += 2;
   207 
   208             ++encoded;
   209             samplesleft -= 2;
   210         }
   211         encoded_len -= MS_ADPCM_state.wavefmt.blockalign;
   212     }
   213     SDL_free(freeable);
   214     return (0);
   215 }
   216 
   217 struct IMA_ADPCM_decodestate
   218 {
   219     Sint32 sample;
   220     Sint8 index;
   221 };
   222 static struct IMA_ADPCM_decoder
   223 {
   224     WaveFMT wavefmt;
   225     Uint16 wSamplesPerBlock;
   226     /* * * */
   227     struct IMA_ADPCM_decodestate state[2];
   228 } IMA_ADPCM_state;
   229 
   230 static int
   231 InitIMA_ADPCM(WaveFMT * format)
   232 {
   233     Uint8 *rogue_feel;
   234 
   235     /* Set the rogue pointer to the IMA_ADPCM specific data */
   236     IMA_ADPCM_state.wavefmt.encoding = SDL_SwapLE16(format->encoding);
   237     IMA_ADPCM_state.wavefmt.channels = SDL_SwapLE16(format->channels);
   238     IMA_ADPCM_state.wavefmt.frequency = SDL_SwapLE32(format->frequency);
   239     IMA_ADPCM_state.wavefmt.byterate = SDL_SwapLE32(format->byterate);
   240     IMA_ADPCM_state.wavefmt.blockalign = SDL_SwapLE16(format->blockalign);
   241     IMA_ADPCM_state.wavefmt.bitspersample =
   242         SDL_SwapLE16(format->bitspersample);
   243     rogue_feel = (Uint8 *) format + sizeof(*format);
   244     if (sizeof(*format) == 16) {
   245         /*const Uint16 extra_info = ((rogue_feel[1] << 8) | rogue_feel[0]);*/
   246         rogue_feel += sizeof(Uint16);
   247     }
   248     IMA_ADPCM_state.wSamplesPerBlock = ((rogue_feel[1] << 8) | rogue_feel[0]);
   249     return (0);
   250 }
   251 
   252 static Sint32
   253 IMA_ADPCM_nibble(struct IMA_ADPCM_decodestate *state, Uint8 nybble)
   254 {
   255     const Sint32 max_audioval = ((1 << (16 - 1)) - 1);
   256     const Sint32 min_audioval = -(1 << (16 - 1));
   257     const int index_table[16] = {
   258         -1, -1, -1, -1,
   259         2, 4, 6, 8,
   260         -1, -1, -1, -1,
   261         2, 4, 6, 8
   262     };
   263     const Sint32 step_table[89] = {
   264         7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31,
   265         34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130,
   266         143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408,
   267         449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282,
   268         1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327,
   269         3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630,
   270         9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350,
   271         22385, 24623, 27086, 29794, 32767
   272     };
   273     Sint32 delta, step;
   274 
   275     /* Compute difference and new sample value */
   276     if (state->index > 88) {
   277         state->index = 88;
   278     } else if (state->index < 0) {
   279         state->index = 0;
   280     }
   281     step = step_table[state->index];
   282     delta = step >> 3;
   283     if (nybble & 0x04)
   284         delta += step;
   285     if (nybble & 0x02)
   286         delta += (step >> 1);
   287     if (nybble & 0x01)
   288         delta += (step >> 2);
   289     if (nybble & 0x08)
   290         delta = -delta;
   291     state->sample += delta;
   292 
   293     /* Update index value */
   294     state->index += index_table[nybble];
   295 
   296     /* Clamp output sample */
   297     if (state->sample > max_audioval) {
   298         state->sample = max_audioval;
   299     } else if (state->sample < min_audioval) {
   300         state->sample = min_audioval;
   301     }
   302     return (state->sample);
   303 }
   304 
   305 /* Fill the decode buffer with a channel block of data (8 samples) */
   306 static void
   307 Fill_IMA_ADPCM_block(Uint8 * decoded, Uint8 * encoded,
   308                      int channel, int numchannels,
   309                      struct IMA_ADPCM_decodestate *state)
   310 {
   311     int i;
   312     Sint8 nybble;
   313     Sint32 new_sample;
   314 
   315     decoded += (channel * 2);
   316     for (i = 0; i < 4; ++i) {
   317         nybble = (*encoded) & 0x0F;
   318         new_sample = IMA_ADPCM_nibble(state, nybble);
   319         decoded[0] = new_sample & 0xFF;
   320         new_sample >>= 8;
   321         decoded[1] = new_sample & 0xFF;
   322         decoded += 2 * numchannels;
   323 
   324         nybble = (*encoded) >> 4;
   325         new_sample = IMA_ADPCM_nibble(state, nybble);
   326         decoded[0] = new_sample & 0xFF;
   327         new_sample >>= 8;
   328         decoded[1] = new_sample & 0xFF;
   329         decoded += 2 * numchannels;
   330 
   331         ++encoded;
   332     }
   333 }
   334 
   335 static int
   336 IMA_ADPCM_decode(Uint8 ** audio_buf, Uint32 * audio_len)
   337 {
   338     struct IMA_ADPCM_decodestate *state;
   339     Uint8 *freeable, *encoded, *decoded;
   340     Sint32 encoded_len, samplesleft;
   341     unsigned int c, channels;
   342 
   343     /* Check to make sure we have enough variables in the state array */
   344     channels = IMA_ADPCM_state.wavefmt.channels;
   345     if (channels > SDL_arraysize(IMA_ADPCM_state.state)) {
   346         SDL_SetError("IMA ADPCM decoder can only handle %d channels",
   347                      SDL_arraysize(IMA_ADPCM_state.state));
   348         return (-1);
   349     }
   350     state = IMA_ADPCM_state.state;
   351 
   352     /* Allocate the proper sized output buffer */
   353     encoded_len = *audio_len;
   354     encoded = *audio_buf;
   355     freeable = *audio_buf;
   356     *audio_len = (encoded_len / IMA_ADPCM_state.wavefmt.blockalign) *
   357         IMA_ADPCM_state.wSamplesPerBlock *
   358         IMA_ADPCM_state.wavefmt.channels * sizeof(Sint16);
   359     *audio_buf = (Uint8 *) SDL_malloc(*audio_len);
   360     if (*audio_buf == NULL) {
   361         return SDL_OutOfMemory();
   362     }
   363     decoded = *audio_buf;
   364 
   365     /* Get ready... Go! */
   366     while (encoded_len >= IMA_ADPCM_state.wavefmt.blockalign) {
   367         /* Grab the initial information for this block */
   368         for (c = 0; c < channels; ++c) {
   369             /* Fill the state information for this block */
   370             state[c].sample = ((encoded[1] << 8) | encoded[0]);
   371             encoded += 2;
   372             if (state[c].sample & 0x8000) {
   373                 state[c].sample -= 0x10000;
   374             }
   375             state[c].index = *encoded++;
   376             /* Reserved byte in buffer header, should be 0 */
   377             if (*encoded++ != 0) {
   378                 /* Uh oh, corrupt data?  Buggy code? */ ;
   379             }
   380 
   381             /* Store the initial sample we start with */
   382             decoded[0] = (Uint8) (state[c].sample & 0xFF);
   383             decoded[1] = (Uint8) (state[c].sample >> 8);
   384             decoded += 2;
   385         }
   386 
   387         /* Decode and store the other samples in this block */
   388         samplesleft = (IMA_ADPCM_state.wSamplesPerBlock - 1) * channels;
   389         while (samplesleft > 0) {
   390             for (c = 0; c < channels; ++c) {
   391                 Fill_IMA_ADPCM_block(decoded, encoded,
   392                                      c, channels, &state[c]);
   393                 encoded += 4;
   394                 samplesleft -= 8;
   395             }
   396             decoded += (channels * 8 * 2);
   397         }
   398         encoded_len -= IMA_ADPCM_state.wavefmt.blockalign;
   399     }
   400     SDL_free(freeable);
   401     return (0);
   402 }
   403 
   404 SDL_AudioSpec *
   405 SDL_LoadWAV_RW(SDL_RWops * src, int freesrc,
   406                SDL_AudioSpec * spec, Uint8 ** audio_buf, Uint32 * audio_len)
   407 {
   408     int was_error;
   409     Chunk chunk;
   410     int lenread;
   411     int IEEE_float_encoded, MS_ADPCM_encoded, IMA_ADPCM_encoded;
   412     int samplesize;
   413 
   414     /* WAV magic header */
   415     Uint32 RIFFchunk;
   416     Uint32 wavelen = 0;
   417     Uint32 WAVEmagic;
   418     Uint32 headerDiff = 0;
   419 
   420     /* FMT chunk */
   421     WaveFMT *format = NULL;
   422 
   423     SDL_zero(chunk);
   424 
   425     /* Make sure we are passed a valid data source */
   426     was_error = 0;
   427     if (src == NULL) {
   428         was_error = 1;
   429         goto done;
   430     }
   431 
   432     /* Check the magic header */
   433     RIFFchunk = SDL_ReadLE32(src);
   434     wavelen = SDL_ReadLE32(src);
   435     if (wavelen == WAVE) {      /* The RIFFchunk has already been read */
   436         WAVEmagic = wavelen;
   437         wavelen = RIFFchunk;
   438         RIFFchunk = RIFF;
   439     } else {
   440         WAVEmagic = SDL_ReadLE32(src);
   441     }
   442     if ((RIFFchunk != RIFF) || (WAVEmagic != WAVE)) {
   443         SDL_SetError("Unrecognized file type (not WAVE)");
   444         was_error = 1;
   445         goto done;
   446     }
   447     headerDiff += sizeof(Uint32);       /* for WAVE */
   448 
   449     /* Read the audio data format chunk */
   450     chunk.data = NULL;
   451     do {
   452         if (chunk.data != NULL) {
   453             SDL_free(chunk.data);
   454             chunk.data = NULL;
   455         }
   456         lenread = ReadChunk(src, &chunk);
   457         if (lenread < 0) {
   458             was_error = 1;
   459             goto done;
   460         }
   461         /* 2 Uint32's for chunk header+len, plus the lenread */
   462         headerDiff += lenread + 2 * sizeof(Uint32);
   463     } while ((chunk.magic == FACT) || (chunk.magic == LIST));
   464 
   465     /* Decode the audio data format */
   466     format = (WaveFMT *) chunk.data;
   467     if (chunk.magic != FMT) {
   468         SDL_SetError("Complex WAVE files not supported");
   469         was_error = 1;
   470         goto done;
   471     }
   472     IEEE_float_encoded = MS_ADPCM_encoded = IMA_ADPCM_encoded = 0;
   473     switch (SDL_SwapLE16(format->encoding)) {
   474     case PCM_CODE:
   475         /* We can understand this */
   476         break;
   477     case IEEE_FLOAT_CODE:
   478         IEEE_float_encoded = 1;
   479         /* We can understand this */
   480         break;
   481     case MS_ADPCM_CODE:
   482         /* Try to understand this */
   483         if (InitMS_ADPCM(format) < 0) {
   484             was_error = 1;
   485             goto done;
   486         }
   487         MS_ADPCM_encoded = 1;
   488         break;
   489     case IMA_ADPCM_CODE:
   490         /* Try to understand this */
   491         if (InitIMA_ADPCM(format) < 0) {
   492             was_error = 1;
   493             goto done;
   494         }
   495         IMA_ADPCM_encoded = 1;
   496         break;
   497     case MP3_CODE:
   498         SDL_SetError("MPEG Layer 3 data not supported",
   499                      SDL_SwapLE16(format->encoding));
   500         was_error = 1;
   501         goto done;
   502     default:
   503         SDL_SetError("Unknown WAVE data format: 0x%.4x",
   504                      SDL_SwapLE16(format->encoding));
   505         was_error = 1;
   506         goto done;
   507     }
   508     SDL_memset(spec, 0, (sizeof *spec));
   509     spec->freq = SDL_SwapLE32(format->frequency);
   510 
   511     if (IEEE_float_encoded) {
   512         if ((SDL_SwapLE16(format->bitspersample)) != 32) {
   513             was_error = 1;
   514         } else {
   515             spec->format = AUDIO_F32;
   516         }
   517     } else {
   518         switch (SDL_SwapLE16(format->bitspersample)) {
   519         case 4:
   520             if (MS_ADPCM_encoded || IMA_ADPCM_encoded) {
   521                 spec->format = AUDIO_S16;
   522             } else {
   523                 was_error = 1;
   524             }
   525             break;
   526         case 8:
   527             spec->format = AUDIO_U8;
   528             break;
   529         case 16:
   530             spec->format = AUDIO_S16;
   531             break;
   532         case 32:
   533             spec->format = AUDIO_S32;
   534             break;
   535         default:
   536             was_error = 1;
   537             break;
   538         }
   539     }
   540 
   541     if (was_error) {
   542         SDL_SetError("Unknown %d-bit PCM data format",
   543                      SDL_SwapLE16(format->bitspersample));
   544         goto done;
   545     }
   546     spec->channels = (Uint8) SDL_SwapLE16(format->channels);
   547     spec->samples = 4096;       /* Good default buffer size */
   548 
   549     /* Read the audio data chunk */
   550     *audio_buf = NULL;
   551     do {
   552         if (*audio_buf != NULL) {
   553             SDL_free(*audio_buf);
   554             *audio_buf = NULL;
   555         }
   556         lenread = ReadChunk(src, &chunk);
   557         if (lenread < 0) {
   558             was_error = 1;
   559             goto done;
   560         }
   561         *audio_len = lenread;
   562         *audio_buf = chunk.data;
   563         if (chunk.magic != DATA)
   564             headerDiff += lenread + 2 * sizeof(Uint32);
   565     } while (chunk.magic != DATA);
   566     headerDiff += 2 * sizeof(Uint32);   /* for the data chunk and len */
   567 
   568     if (MS_ADPCM_encoded) {
   569         if (MS_ADPCM_decode(audio_buf, audio_len) < 0) {
   570             was_error = 1;
   571             goto done;
   572         }
   573     }
   574     if (IMA_ADPCM_encoded) {
   575         if (IMA_ADPCM_decode(audio_buf, audio_len) < 0) {
   576             was_error = 1;
   577             goto done;
   578         }
   579     }
   580 
   581     /* Don't return a buffer that isn't a multiple of samplesize */
   582     samplesize = ((SDL_AUDIO_BITSIZE(spec->format)) / 8) * spec->channels;
   583     *audio_len &= ~(samplesize - 1);
   584 
   585   done:
   586     if (format != NULL) {
   587         SDL_free(format);
   588     }
   589     if (src) {
   590         if (freesrc) {
   591             SDL_RWclose(src);
   592         } else {
   593             /* seek to the end of the file (given by the RIFF chunk) */
   594             SDL_RWseek(src, wavelen - chunk.length - headerDiff, RW_SEEK_CUR);
   595         }
   596     }
   597     if (was_error) {
   598         spec = NULL;
   599     }
   600     return (spec);
   601 }
   602 
   603 /* Since the WAV memory is allocated in the shared library, it must also
   604    be freed here.  (Necessary under Win32, VC++)
   605  */
   606 void
   607 SDL_FreeWAV(Uint8 * audio_buf)
   608 {
   609     if (audio_buf != NULL) {
   610         SDL_free(audio_buf);
   611     }
   612 }
   613 
   614 static int
   615 ReadChunk(SDL_RWops * src, Chunk * chunk)
   616 {
   617     chunk->magic = SDL_ReadLE32(src);
   618     chunk->length = SDL_ReadLE32(src);
   619     chunk->data = (Uint8 *) SDL_malloc(chunk->length);
   620     if (chunk->data == NULL) {
   621         return SDL_OutOfMemory();
   622     }
   623     if (SDL_RWread(src, chunk->data, chunk->length, 1) != 1) {
   624         SDL_free(chunk->data);
   625         chunk->data = NULL;
   626         return SDL_Error(SDL_EFREAD);
   627     }
   628     return (chunk->length);
   629 }
   630 
   631 /* vi: set ts=4 sw=4 expandtab: */