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