music_flac.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 17 Jun 2015 00:11:41 -0700
changeset 705 fe757163b8f7
parent 642 dae7bb0a66b1
child 711 f40c5ac95b12
permissions -rw-r--r--
Fixed bug 3018 - Loading MIDI music using FluidSynth leaks memory.

Philipp Wiesemann

There is a memory leak in fluidsynth.c and fluidsynth_loadsong_RW_internal(). The allocated temporary buffer is not deleted if fluid_player_add_mem() returns FLUID_OK.
     1 /*
     2   SDL_mixer:  An audio mixer library based on the SDL library
     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   This file is used to support SDL_LoadMUS playback of FLAC files.
    22     ~ Austen Dicken (admin@cvpcs.org)
    23 */
    24 
    25 #ifdef FLAC_MUSIC
    26 
    27 #include <stdio.h>
    28 #include <stdlib.h>
    29 #include <string.h>
    30 
    31 #include "SDL_mixer.h"
    32 #include "dynamic_flac.h"
    33 #include "music_flac.h"
    34 
    35 /* This is the format of the audio mixer data */
    36 static SDL_AudioSpec mixer;
    37 
    38 /* Initialize the FLAC player, with the given mixer settings
    39    This function returns 0, or -1 if there was an error.
    40  */
    41 int FLAC_init(SDL_AudioSpec *mixerfmt)
    42 {
    43     mixer = *mixerfmt;
    44     return(0);
    45 }
    46 
    47 /* Set the volume for an FLAC stream */
    48 void FLAC_setvolume(FLAC_music *music, int volume)
    49 {
    50     music->volume = volume;
    51 }
    52 
    53 static FLAC__StreamDecoderReadStatus flac_read_music_cb(
    54                                     const FLAC__StreamDecoder *decoder,
    55                                     FLAC__byte buffer[],
    56                                     size_t *bytes,
    57                                     void *client_data)
    58 {
    59     FLAC_music *data = (FLAC_music*)client_data;
    60 
    61     // make sure there is something to be reading
    62     if (*bytes > 0) {
    63         *bytes = SDL_RWread (data->src, buffer, sizeof (FLAC__byte), *bytes);
    64 
    65         if (*bytes == 0 ) { // error or no data was read (EOF)
    66             return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
    67         } else { // data was read, continue
    68             return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
    69         }
    70     } else {
    71         return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
    72     }
    73 }
    74 
    75 static FLAC__StreamDecoderSeekStatus flac_seek_music_cb(
    76                                     const FLAC__StreamDecoder *decoder,
    77                                     FLAC__uint64 absolute_byte_offset,
    78                                     void *client_data)
    79 {
    80     FLAC_music *data = (FLAC_music*)client_data;
    81 
    82     if (SDL_RWseek (data->src, absolute_byte_offset, RW_SEEK_SET) < 0) {
    83         return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
    84     } else {
    85         return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
    86     }
    87 }
    88 
    89 static FLAC__StreamDecoderTellStatus flac_tell_music_cb(
    90                                     const FLAC__StreamDecoder *decoder,
    91                                     FLAC__uint64 *absolute_byte_offset,
    92                                     void *client_data )
    93 {
    94     FLAC_music *data = (FLAC_music*)client_data;
    95 
    96     Sint64 pos = SDL_RWtell (data->src);
    97 
    98     if (pos < 0) {
    99         return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
   100     } else {
   101         *absolute_byte_offset = (FLAC__uint64)pos;
   102         return FLAC__STREAM_DECODER_TELL_STATUS_OK;
   103     }
   104 }
   105 
   106 static FLAC__StreamDecoderLengthStatus flac_length_music_cb (
   107                                     const FLAC__StreamDecoder *decoder,
   108                                     FLAC__uint64 *stream_length,
   109                                     void *client_data)
   110 {
   111     FLAC_music *data = (FLAC_music*)client_data;
   112 
   113     Sint64 pos = SDL_RWtell (data->src);
   114     Sint64 length = SDL_RWseek (data->src, 0, RW_SEEK_END);
   115 
   116     if (SDL_RWseek (data->src, pos, RW_SEEK_SET) != pos || length < 0) {
   117         /* there was an error attempting to return the stream to the original
   118          * position, or the length was invalid. */
   119         return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
   120     } else {
   121         *stream_length = (FLAC__uint64)length;
   122         return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
   123     }
   124 }
   125 
   126 static FLAC__bool flac_eof_music_cb(
   127                                 const FLAC__StreamDecoder *decoder,
   128                                 void *client_data )
   129 {
   130     FLAC_music *data = (FLAC_music*)client_data;
   131 
   132     Sint64 pos = SDL_RWtell (data->src);
   133     Sint64 end = SDL_RWseek (data->src, 0, RW_SEEK_END);
   134 
   135     // was the original position equal to the end (a.k.a. the seek didn't move)?
   136     if (pos == end) {
   137         // must be EOF
   138         return true;
   139     } else {
   140         // not EOF, return to the original position
   141         SDL_RWseek (data->src, pos, RW_SEEK_SET);
   142         return false;
   143     }
   144 }
   145 
   146 static FLAC__StreamDecoderWriteStatus flac_write_music_cb(
   147                                     const FLAC__StreamDecoder *decoder,
   148                                     const FLAC__Frame *frame,
   149                                     const FLAC__int32 *const buffer[],
   150                                     void *client_data)
   151 {
   152     FLAC_music *data = (FLAC_music *)client_data;
   153     size_t i;
   154 
   155     if (data->flac_data.total_samples == 0) {
   156         SDL_SetError ("Given FLAC file does not specify its sample count.");
   157         return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
   158     }
   159 
   160     if (data->flac_data.channels != 2 ||
   161         data->flac_data.bits_per_sample != 16) {
   162         SDL_SetError("Current FLAC support is only for 16 bit Stereo files.");
   163         return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
   164     }
   165 
   166     for (i = 0; i < frame->header.blocksize; i++) {
   167         FLAC__int16 i16;
   168         FLAC__uint16 ui16;
   169 
   170         // make sure we still have at least two bytes that can be read (one for
   171         // each channel)
   172         if (data->flac_data.max_to_read >= 4) {
   173             // does the data block exist?
   174             if (!data->flac_data.data) {
   175                 data->flac_data.data_len = data->flac_data.max_to_read;
   176                 data->flac_data.data_read = 0;
   177 
   178                 // create it
   179                 data->flac_data.data =
   180                     (char *)SDL_malloc (data->flac_data.data_len);
   181 
   182                 if (!data->flac_data.data) {
   183                     return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
   184                 }
   185             }
   186 
   187             i16 = (FLAC__int16)buffer[0][i];
   188             ui16 = (FLAC__uint16)i16;
   189 
   190             *((data->flac_data.data) + (data->flac_data.data_read++)) =
   191                                                             (char)(ui16);
   192             *((data->flac_data.data) + (data->flac_data.data_read++)) =
   193                                                             (char)(ui16 >> 8);
   194 
   195             i16 = (FLAC__int16)buffer[1][i];
   196             ui16 = (FLAC__uint16)i16;
   197 
   198             *((data->flac_data.data) + (data->flac_data.data_read++)) =
   199                                                             (char)(ui16);
   200             *((data->flac_data.data) + (data->flac_data.data_read++)) =
   201                                                             (char)(ui16 >> 8);
   202 
   203             data->flac_data.max_to_read -= 4;
   204 
   205             if (data->flac_data.max_to_read < 4) {
   206                 // we need to set this so that the read halts from the
   207                 // FLAC_getsome function.
   208                 data->flac_data.max_to_read = 0;
   209             }
   210         }
   211         else {
   212             // we need to write to the overflow
   213             if (!data->flac_data.overflow) {
   214                 data->flac_data.overflow_len =
   215                                             4 * (frame->header.blocksize - i);
   216                 data->flac_data.overflow_read = 0;
   217 
   218                 // make it big enough for the rest of the block
   219                 data->flac_data.overflow =
   220                     (char *)SDL_malloc (data->flac_data.overflow_len);
   221 
   222                 if (!data->flac_data.overflow) {
   223                     return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
   224                 }
   225             }
   226 
   227             i16 = (FLAC__int16)buffer[0][i];
   228             ui16 = (FLAC__uint16)i16;
   229 
   230             *((data->flac_data.overflow) + (data->flac_data.overflow_read++)) =
   231                                                             (char)(ui16);
   232             *((data->flac_data.overflow) + (data->flac_data.overflow_read++)) =
   233                                                             (char)(ui16 >> 8);
   234 
   235             i16 = (FLAC__int16)buffer[1][i];
   236             ui16 = (FLAC__uint16)i16;
   237 
   238             *((data->flac_data.overflow) + (data->flac_data.overflow_read++)) =
   239                                                             (char)(ui16);
   240             *((data->flac_data.overflow) + (data->flac_data.overflow_read++)) =
   241                                                             (char)(ui16 >> 8);
   242         }
   243     }
   244 
   245     return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
   246 }
   247 
   248 static void flac_metadata_music_cb(
   249                     const FLAC__StreamDecoder *decoder,
   250                     const FLAC__StreamMetadata *metadata,
   251                     void *client_data)
   252 {
   253     FLAC_music *data = (FLAC_music *)client_data;
   254 
   255     if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
   256         data->flac_data.sample_rate = metadata->data.stream_info.sample_rate;
   257         data->flac_data.channels = metadata->data.stream_info.channels;
   258         data->flac_data.total_samples =
   259                             metadata->data.stream_info.total_samples;
   260         data->flac_data.bits_per_sample =
   261                             metadata->data.stream_info.bits_per_sample;
   262         data->flac_data.sample_size = data->flac_data.channels *
   263                                         ((data->flac_data.bits_per_sample) / 8);
   264     }
   265 }
   266 
   267 static void flac_error_music_cb(
   268                 const FLAC__StreamDecoder *decoder,
   269                 FLAC__StreamDecoderErrorStatus status,
   270                 void *client_data)
   271 {
   272     // print an SDL error based on the error status
   273     switch (status) {
   274         case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
   275             SDL_SetError ("Error processing the FLAC file [LOST_SYNC].");
   276         break;
   277         case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER:
   278             SDL_SetError ("Error processing the FLAC file [BAD_HEADER].");
   279         break;
   280         case FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH:
   281             SDL_SetError ("Error processing the FLAC file [CRC_MISMATCH].");
   282         break;
   283         case FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM:
   284             SDL_SetError ("Error processing the FLAC file [UNPARSEABLE].");
   285         break;
   286         default:
   287             SDL_SetError ("Error processing the FLAC file [UNKNOWN].");
   288         break;
   289     }
   290 }
   291 
   292 /* Load an FLAC stream from an SDL_RWops object */
   293 FLAC_music *FLAC_new_RW(SDL_RWops *src, int freesrc)
   294 {
   295     FLAC_music *music;
   296     int init_stage = 0;
   297     int was_error = 1;
   298 
   299     if (!Mix_Init(MIX_INIT_FLAC)) {
   300         return NULL;
   301     }
   302 
   303     music = (FLAC_music *)SDL_malloc ( sizeof (*music));
   304     if (music) {
   305         /* Initialize the music structure */
   306         memset (music, 0, (sizeof (*music)));
   307         FLAC_stop (music);
   308         FLAC_setvolume (music, MIX_MAX_VOLUME);
   309         music->section = -1;
   310         music->src = src;
   311         music->freesrc = freesrc;
   312         music->flac_data.max_to_read = 0;
   313         music->flac_data.overflow = NULL;
   314         music->flac_data.overflow_len = 0;
   315         music->flac_data.overflow_read = 0;
   316         music->flac_data.data = NULL;
   317         music->flac_data.data_len = 0;
   318         music->flac_data.data_read = 0;
   319 
   320         init_stage++; // stage 1!
   321 
   322         music->flac_decoder = flac.FLAC__stream_decoder_new ();
   323 
   324         if (music->flac_decoder != NULL) {
   325             init_stage++; // stage 2!
   326 
   327             if (flac.FLAC__stream_decoder_init_stream(
   328                         music->flac_decoder,
   329                         flac_read_music_cb, flac_seek_music_cb,
   330                         flac_tell_music_cb, flac_length_music_cb,
   331                         flac_eof_music_cb, flac_write_music_cb,
   332                         flac_metadata_music_cb, flac_error_music_cb,
   333                         music) == FLAC__STREAM_DECODER_INIT_STATUS_OK ) {
   334                 init_stage++; // stage 3!
   335 
   336                 if (flac.FLAC__stream_decoder_process_until_end_of_metadata
   337                                         (music->flac_decoder)) {
   338                     was_error = 0;
   339                 } else {
   340                     SDL_SetError("FLAC__stream_decoder_process_until_end_of_metadata() failed");
   341                 }
   342             } else {
   343                 SDL_SetError("FLAC__stream_decoder_init_stream() failed");
   344             }
   345         } else {
   346             SDL_SetError("FLAC__stream_decoder_new() failed");
   347         }
   348 
   349         if (was_error) {
   350             switch (init_stage) {
   351                 case 3:
   352                     flac.FLAC__stream_decoder_finish( music->flac_decoder );
   353                 case 2:
   354                     flac.FLAC__stream_decoder_delete( music->flac_decoder );
   355                 case 1:
   356                 case 0:
   357                     SDL_free(music);
   358                     break;
   359             }
   360             return NULL;
   361         }
   362     } else {
   363         SDL_OutOfMemory();
   364         return NULL;
   365     }
   366 
   367     return music;
   368 }
   369 
   370 /* Start playback of a given FLAC stream */
   371 void FLAC_play(FLAC_music *music)
   372 {
   373     music->playing = 1;
   374 }
   375 
   376 /* Return non-zero if a stream is currently playing */
   377 int FLAC_playing(FLAC_music *music)
   378 {
   379     return(music->playing);
   380 }
   381 
   382 /* Read some FLAC stream data and convert it for output */
   383 static void FLAC_getsome(FLAC_music *music)
   384 {
   385     SDL_AudioCVT *cvt;
   386 
   387     /* GET AUDIO WAVE DATA */
   388     // set the max number of characters to read
   389     music->flac_data.max_to_read = 8192;
   390     music->flac_data.data_len = music->flac_data.max_to_read;
   391     music->flac_data.data_read = 0;
   392     if (!music->flac_data.data) {
   393         music->flac_data.data = (char *)SDL_malloc (music->flac_data.data_len);
   394     }
   395 
   396     // we have data to read
   397     while(music->flac_data.max_to_read > 0) {
   398         // first check if there is data in the overflow from before
   399         if (music->flac_data.overflow) {
   400             size_t overflow_len = music->flac_data.overflow_read;
   401 
   402             if (overflow_len > (size_t)music->flac_data.max_to_read) {
   403                 size_t overflow_extra_len = overflow_len -
   404                                                 music->flac_data.max_to_read;
   405 
   406                 SDL_memcpy (music->flac_data.data+music->flac_data.data_read,
   407                     music->flac_data.overflow, music->flac_data.max_to_read);
   408                 music->flac_data.data_read += music->flac_data.max_to_read;
   409                 SDL_memcpy (music->flac_data.overflow,
   410                     music->flac_data.overflow + music->flac_data.max_to_read,
   411                     overflow_extra_len);
   412                 music->flac_data.overflow_len = overflow_extra_len;
   413                 music->flac_data.overflow_read = overflow_extra_len;
   414                 music->flac_data.max_to_read = 0;
   415             } else {
   416                 SDL_memcpy (music->flac_data.data+music->flac_data.data_read,
   417                     music->flac_data.overflow, overflow_len);
   418                 music->flac_data.data_read += overflow_len;
   419                 SDL_free (music->flac_data.overflow);
   420                 music->flac_data.overflow = NULL;
   421                 music->flac_data.overflow_len = 0;
   422                 music->flac_data.overflow_read = 0;
   423                 music->flac_data.max_to_read -= overflow_len;
   424             }
   425         }
   426         else {
   427             if (!flac.FLAC__stream_decoder_process_single (
   428                                                         music->flac_decoder)) {
   429                 music->flac_data.max_to_read = 0;
   430             }
   431 
   432             if (flac.FLAC__stream_decoder_get_state (music->flac_decoder)
   433                                     == FLAC__STREAM_DECODER_END_OF_STREAM) {
   434                 music->flac_data.max_to_read = 0;
   435             }
   436         }
   437     }
   438 
   439     if (music->flac_data.data_read <= 0) {
   440         if (music->flac_data.data_read == 0) {
   441             music->playing = 0;
   442         }
   443         return;
   444     }
   445     cvt = &music->cvt;
   446     if (music->section < 0) {
   447         SDL_BuildAudioCVT (cvt, AUDIO_S16, (Uint8)music->flac_data.channels,
   448                         (int)music->flac_data.sample_rate, mixer.format,
   449                         mixer.channels, mixer.freq);
   450         if (cvt->buf) {
   451             SDL_free (cvt->buf);
   452         }
   453         cvt->buf = (Uint8 *)SDL_malloc (music->flac_data.data_len * cvt->len_mult);
   454         music->section = 0;
   455     }
   456     if (cvt->buf) {
   457         SDL_memcpy (cvt->buf, music->flac_data.data, music->flac_data.data_read);
   458         if (cvt->needed) {
   459             cvt->len = music->flac_data.data_read;
   460             SDL_ConvertAudio (cvt);
   461         }
   462         else {
   463             cvt->len_cvt = music->flac_data.data_read;
   464         }
   465         music->len_available = music->cvt.len_cvt;
   466         music->snd_available = music->cvt.buf;
   467     }
   468     else {
   469         SDL_SetError ("Out of memory");
   470         music->playing = 0;
   471     }
   472 }
   473 
   474 /* Play some of a stream previously started with FLAC_play() */
   475 int FLAC_playAudio(FLAC_music *music, Uint8 *snd, int len)
   476 {
   477     int mixable;
   478 
   479     while ((len > 0) && music->playing) {
   480         if (!music->len_available) {
   481             FLAC_getsome (music);
   482         }
   483         mixable = len;
   484         if (mixable > music->len_available) {
   485             mixable = music->len_available;
   486         }
   487         if (music->volume == MIX_MAX_VOLUME) {
   488             SDL_memcpy (snd, music->snd_available, mixable);
   489         }
   490         else {
   491             SDL_MixAudio (snd, music->snd_available, mixable, music->volume);
   492         }
   493         music->len_available -= mixable;
   494         music->snd_available += mixable;
   495         len -= mixable;
   496         snd += mixable;
   497     }
   498 
   499     return len;
   500 }
   501 
   502 /* Stop playback of a stream previously started with FLAC_play() */
   503 void FLAC_stop(FLAC_music *music)
   504 {
   505     music->playing = 0;
   506 }
   507 
   508 /* Close the given FLAC_music object */
   509 void FLAC_delete(FLAC_music *music)
   510 {
   511     if (music) {
   512         if (music->flac_decoder) {
   513             flac.FLAC__stream_decoder_finish (music->flac_decoder);
   514             flac.FLAC__stream_decoder_delete (music->flac_decoder);
   515         }
   516 
   517         if (music->flac_data.data) {
   518             SDL_free (music->flac_data.data);
   519         }
   520 
   521         if (music->flac_data.overflow) {
   522             SDL_free (music->flac_data.overflow);
   523         }
   524 
   525         if (music->cvt.buf) {
   526             SDL_free (music->cvt.buf);
   527         }
   528 
   529         if (music->freesrc) {
   530             SDL_RWclose(music->src);
   531         }
   532         SDL_free (music);
   533     }
   534 }
   535 
   536 /* Jump (seek) to a given position (time is in seconds) */
   537 void FLAC_jump_to_time(FLAC_music *music, double time)
   538 {
   539     if (music) {
   540         if (music->flac_decoder) {
   541             double seek_sample = music->flac_data.sample_rate * time;
   542 
   543             // clear data if it has data
   544             if (music->flac_data.data) {
   545                 SDL_free (music->flac_data.data);
   546                 music->flac_data.data = NULL;
   547             }
   548 
   549             // clear overflow if it has data
   550             if (music->flac_data.overflow) {
   551                 SDL_free (music->flac_data.overflow);
   552                 music->flac_data.overflow = NULL;
   553             }
   554 
   555             if (!flac.FLAC__stream_decoder_seek_absolute (music->flac_decoder,
   556                                                 (FLAC__uint64)seek_sample)) {
   557                 if (flac.FLAC__stream_decoder_get_state (music->flac_decoder)
   558                                         == FLAC__STREAM_DECODER_SEEK_ERROR) {
   559                     flac.FLAC__stream_decoder_flush (music->flac_decoder);
   560                 }
   561 
   562                 SDL_SetError
   563                     ("Seeking of FLAC stream failed: libFLAC seek failed.");
   564             }
   565         }
   566         else {
   567             SDL_SetError
   568                 ("Seeking of FLAC stream failed: FLAC decoder was NULL.");
   569         }
   570     }
   571     else {
   572         SDL_SetError ("Seeking of FLAC stream failed: music was NULL.");
   573     }
   574 }
   575 
   576 #endif /* FLAC_MUSIC */