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