music_flac.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 08 Dec 2008 00:27:32 +0000
changeset 386 695494546b3c
parent 382 50501e45c57b
child 409 2ba29d53be77
permissions -rw-r--r--
Updated copyright date
     1 /*
     2     SDL_mixer:  An audio mixer library based on the SDL library
     3     Copyright (C) 1997-2009 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 */