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