music_flac.c
author Sam Lantinga <slouken@libsdl.org>
Sat, 03 Oct 2009 20:43:33 +0000
changeset 419 e27fe0bfe470
parent 409 2ba29d53be77
child 436 8ec227cabdd4
permissions -rw-r--r--
Sam Lantinga - Sat Oct 3 13:33:36 PDT 2009
* MOD support uses libmikmod and is dynamically loaded by default
     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, 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, SEEK_END);
   137 
   138 	if (SDL_RWseek (data->rwops, pos, 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, 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, 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 		// make sure we still have at least two bytes that can be read (one for
   193 		// each channel)
   194 		if (data->flac_data.max_to_read >= 4) {
   195 			// does the data block exist?
   196 			if (!data->flac_data.data) {
   197 				data->flac_data.data_len = data->flac_data.max_to_read;
   198 				data->flac_data.data_read = 0;
   199 
   200 				// create it
   201 				data->flac_data.data =
   202 									(char *)malloc (data->flac_data.data_len);
   203 
   204 				if (!data->flac_data.data) {
   205 					return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
   206 				}
   207 			}
   208 
   209 			FLAC__int16 i16;
   210 			FLAC__uint16 ui16;
   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 			FLAC__int16 i16;
   253 			FLAC__uint16 ui16;
   254 
   255 			i16 = (FLAC__int16)buffer[0][i];
   256 			ui16 = (FLAC__uint16)i16;
   257 
   258 			*((data->flac_data.overflow) + (data->flac_data.overflow_read++)) =
   259 															(char)(ui16);
   260 			*((data->flac_data.overflow) + (data->flac_data.overflow_read++)) =
   261 															(char)(ui16 >> 8);
   262 
   263 			i16 = (FLAC__int16)buffer[1][i];
   264 			ui16 = (FLAC__uint16)i16;
   265 
   266 			*((data->flac_data.overflow) + (data->flac_data.overflow_read++)) =
   267 															(char)(ui16);
   268 			*((data->flac_data.overflow) + (data->flac_data.overflow_read++)) =
   269 															(char)(ui16 >> 8);
   270 		}
   271 	}
   272 
   273 	return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
   274 }
   275 
   276 static void flac_metadata_music_cb(
   277 					const FLAC__StreamDecoder *decoder,
   278 					const FLAC__StreamMetadata *metadata,
   279 					void *client_data)
   280 {
   281 	FLAC_music *data = (FLAC_music *)client_data;
   282 
   283 	if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
   284 		data->flac_data.sample_rate = metadata->data.stream_info.sample_rate;
   285 		data->flac_data.channels = metadata->data.stream_info.channels;
   286 		data->flac_data.total_samples =
   287 							metadata->data.stream_info.total_samples;
   288 		data->flac_data.bits_per_sample =
   289 							metadata->data.stream_info.bits_per_sample;
   290 		data->flac_data.sample_size = data->flac_data.channels *
   291 										((data->flac_data.bits_per_sample) / 8);
   292 	}
   293 }
   294 
   295 static void flac_error_music_cb(
   296 				const FLAC__StreamDecoder *decoder,
   297 				FLAC__StreamDecoderErrorStatus status,
   298 				void *client_data)
   299 {
   300 	// print an SDL error based on the error status
   301 	switch (status) {
   302 		case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
   303 			SDL_SetError ("Error processing the FLAC file [LOST_SYNC].");
   304 		break;
   305 		case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER:
   306 			SDL_SetError ("Error processing the FLAC file [BAD_HEADER].");
   307 		break;
   308 		case FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH:
   309 			SDL_SetError ("Error processing the FLAC file [CRC_MISMATCH].");
   310 		break;
   311 		case FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM:
   312 			SDL_SetError ("Error processing the FLAC file [UNPARSEABLE].");
   313 		break;
   314 		default:
   315 			SDL_SetError ("Error processing the FLAC file [UNKNOWN].");
   316 		break;
   317 	}
   318 }
   319 
   320 /* Load an FLAC stream from an SDL_RWops object */
   321 FLAC_music *FLAC_new_RW(SDL_RWops *rw)
   322 {
   323 	FLAC_music *music;
   324 	int init_stage = 0;
   325 	int was_error = 1;
   326 
   327 	music = (FLAC_music *)malloc ( sizeof (*music));
   328 	if (music) {
   329 		/* Initialize the music structure */
   330 		memset (music, 0, (sizeof (*music)));
   331 		FLAC_stop (music);
   332 		FLAC_setvolume (music, MIX_MAX_VOLUME);
   333 		music->section = -1;
   334 		music->rwops = rw;
   335 		music->flac_data.max_to_read = 0;
   336 		music->flac_data.overflow = NULL;
   337 		music->flac_data.overflow_len = 0;
   338 		music->flac_data.overflow_read = 0;
   339 		music->flac_data.data = NULL;
   340 		music->flac_data.data_len = 0;
   341 		music->flac_data.data_read = 0;
   342 
   343 		if (Mix_InitFLAC () >= 0) {
   344 			init_stage++; // stage 1!
   345 
   346 			music->flac_decoder = flac.FLAC__stream_decoder_new ();
   347 
   348 			if (music->flac_decoder != NULL) {
   349 				init_stage++; // stage 2!
   350 
   351 				if (flac.FLAC__stream_decoder_init_stream(
   352 							music->flac_decoder,
   353 							flac_read_music_cb, flac_seek_music_cb,
   354 							flac_tell_music_cb, flac_length_music_cb,
   355 							flac_eof_music_cb, flac_write_music_cb,
   356 							flac_metadata_music_cb, flac_error_music_cb,
   357 							music) == FLAC__STREAM_DECODER_INIT_STATUS_OK ) {
   358 					init_stage++; // stage 3!
   359 
   360 					if (flac.FLAC__stream_decoder_process_until_end_of_metadata
   361 											(music->flac_decoder)) {
   362 						was_error = 0;
   363 					}
   364 				}
   365 			}
   366 		}
   367 
   368 		if (was_error) {
   369 			switch (init_stage) {
   370 				case 3:
   371 					flac.FLAC__stream_decoder_finish( music->flac_decoder );
   372 				case 2:
   373 					flac.FLAC__stream_decoder_delete( music->flac_decoder );
   374 				case 1:
   375 					Mix_QuitFLAC();
   376 				case 0:
   377 					free(music);
   378 					SDL_RWclose(rw);
   379 					break;
   380 			}
   381 
   382 			SDL_SetError ("There was an error in stage [%d] of FLAC init.",
   383 							init_stage);
   384 
   385 			return NULL;
   386 		}
   387 	}
   388 	else {
   389 		SDL_OutOfMemory();
   390 	}
   391 
   392 	return music;
   393 }
   394 
   395 /* Start playback of a given FLAC stream */
   396 void FLAC_play(FLAC_music *music)
   397 {
   398 	music->playing = 1;
   399 }
   400 
   401 /* Return non-zero if a stream is currently playing */
   402 int FLAC_playing(FLAC_music *music)
   403 {
   404 	return(music->playing);
   405 }
   406 
   407 /* Read some FLAC stream data and convert it for output */
   408 static void FLAC_getsome(FLAC_music *music)
   409 {
   410 	int section;
   411 	SDL_AudioCVT *cvt;
   412 
   413 	/* GET AUDIO wAVE DATA */
   414 	// set the max number of characters to read
   415 	music->flac_data.max_to_read = 8192;
   416 
   417 	// clear out the data buffer if it exists
   418 	if (music->flac_data.data) {
   419 		free (music->flac_data.data);
   420 	}
   421 
   422 	music->flac_data.data_len = music->flac_data.max_to_read;
   423 	music->flac_data.data_read = 0;
   424 	music->flac_data.data = (char *)malloc (music->flac_data.data_len);
   425 
   426 	// we have data to read
   427 	while(music->flac_data.max_to_read > 0) {
   428 		// first check if there is data in the overflow from before
   429 		if (music->flac_data.overflow) {
   430 			size_t overflow_len = music->flac_data.overflow_read;
   431 
   432 			if (overflow_len > music->flac_data.max_to_read) {
   433 				size_t overflow_extra_len = overflow_len -
   434 												music->flac_data.max_to_read;
   435 
   436 				char* new_overflow = (char *)malloc (overflow_extra_len);
   437 				memcpy (music->flac_data.data+music->flac_data.data_read,
   438 					music->flac_data.overflow, music->flac_data.max_to_read);
   439 				music->flac_data.data_read += music->flac_data.max_to_read;
   440 				memcpy (new_overflow,
   441 					music->flac_data.overflow + music->flac_data.max_to_read,
   442 					overflow_extra_len);
   443 				free (music->flac_data.overflow);
   444 				music->flac_data.overflow = new_overflow;
   445 				music->flac_data.overflow_len = overflow_extra_len;
   446 				music->flac_data.overflow_read = 0;
   447 				music->flac_data.max_to_read = 0;
   448 			}
   449 			else {
   450 				memcpy (music->flac_data.data+music->flac_data.data_read,
   451 					music->flac_data.overflow, overflow_len);
   452 				music->flac_data.data_read += overflow_len;
   453 				free (music->flac_data.overflow);
   454 				music->flac_data.overflow = NULL;
   455 				music->flac_data.overflow_len = 0;
   456 				music->flac_data.overflow_read = 0;
   457 				music->flac_data.max_to_read -= overflow_len;
   458 			}
   459 		}
   460 		else {
   461 			if (!flac.FLAC__stream_decoder_process_single (
   462 														music->flac_decoder)) {
   463 				music->flac_data.max_to_read = 0;
   464 			}
   465 
   466 			if (flac.FLAC__stream_decoder_get_state (music->flac_decoder)
   467 									== FLAC__STREAM_DECODER_END_OF_STREAM) {
   468 				music->flac_data.max_to_read = 0;
   469 			}
   470 		}
   471 	}
   472 
   473 	if (music->flac_data.data_read <= 0) {
   474 		if (music->flac_data.data_read == 0) {
   475 			music->playing = 0;
   476 		}
   477 		return;
   478 	}
   479 	cvt = &music->cvt;
   480 	if (section != music->section) {
   481 
   482 		SDL_BuildAudioCVT (cvt, AUDIO_S16, (Uint8)music->flac_data.channels,
   483 						(int)music->flac_data.sample_rate, mixer.format,
   484 		                mixer.channels, mixer.freq);
   485 		if (cvt->buf) {
   486 			free (cvt->buf);
   487 		}
   488 		cvt->buf = (Uint8 *)malloc (music->flac_data.data_len * cvt->len_mult);
   489 		music->section = section;
   490 	}
   491 	if (cvt->buf) {
   492 		memcpy (cvt->buf, music->flac_data.data, music->flac_data.data_read);
   493 		if (cvt->needed) {
   494 			cvt->len = music->flac_data.data_read;
   495 			SDL_ConvertAudio (cvt);
   496 		}
   497 		else {
   498 			cvt->len_cvt = music->flac_data.data_read;
   499 		}
   500 		music->len_available = music->cvt.len_cvt;
   501 		music->snd_available = music->cvt.buf;
   502 	}
   503 	else {
   504 		SDL_SetError ("Out of memory");
   505 		music->playing = 0;
   506 	}
   507 }
   508 
   509 /* Play some of a stream previously started with FLAC_play() */
   510 int FLAC_playAudio(FLAC_music *music, Uint8 *snd, int len)
   511 {
   512 	int mixable;
   513 
   514 	while ((len > 0) && music->playing) {
   515 		if (!music->len_available) {
   516 			FLAC_getsome (music);
   517 		}
   518 		mixable = len;
   519 		if (mixable > music->len_available) {
   520 			mixable = music->len_available;
   521 		}
   522 		if (music->volume == MIX_MAX_VOLUME) {
   523 			memcpy (snd, music->snd_available, mixable);
   524 		}
   525 		else {
   526 			SDL_MixAudio (snd, music->snd_available, mixable, music->volume);
   527 		}
   528 		music->len_available -= mixable;
   529 		music->snd_available += mixable;
   530 		len -= mixable;
   531 		snd += mixable;
   532 	}
   533 
   534 	return len;
   535 }
   536 
   537 /* Stop playback of a stream previously started with FLAC_play() */
   538 void FLAC_stop(FLAC_music *music)
   539 {
   540 	music->playing = 0;
   541 }
   542 
   543 /* Close the given FLAC_music object */
   544 void FLAC_delete(FLAC_music *music)
   545 {
   546 	if (music) {
   547 		if (music->flac_decoder) {
   548 			flac.FLAC__stream_decoder_finish (music->flac_decoder);
   549 			flac.FLAC__stream_decoder_delete (music->flac_decoder);
   550 		}
   551 
   552 		if (music->flac_data.data) {
   553 			free (music->flac_data.data);
   554 		}
   555 
   556 		if (music->flac_data.overflow) {
   557 			free (music->flac_data.overflow);
   558 		}
   559 
   560 		if (music->cvt.buf) {
   561 			free (music->cvt.buf);
   562 		}
   563 
   564 		free (music);
   565 
   566 		Mix_QuitFLAC ();
   567 	}
   568 }
   569 
   570 /* Jump (seek) to a given position (time is in seconds) */
   571 void FLAC_jump_to_time(FLAC_music *music, double time)
   572 {
   573 	if (music) {
   574 		if (music->flac_decoder) {
   575 			double seek_sample = music->flac_data.sample_rate * time;
   576 
   577 			// clear data if it has data
   578 			if (music->flac_data.data) {
   579 				free (music->flac_data.data);
   580 				music->flac_data.data = NULL;
   581 			}
   582 
   583 			// clear overflow if it has data
   584 			if (music->flac_data.overflow) {
   585 				free (music->flac_data.overflow);
   586 				music->flac_data.overflow = NULL;
   587 			}
   588 
   589 			if (!flac.FLAC__stream_decoder_seek_absolute (music->flac_decoder,
   590 												(FLAC__uint64)seek_sample)) {
   591 				if (flac.FLAC__stream_decoder_get_state (music->flac_decoder)
   592 										== FLAC__STREAM_DECODER_SEEK_ERROR) {
   593 					flac.FLAC__stream_decoder_flush (music->flac_decoder);
   594 				}
   595 
   596 				SDL_SetError
   597 					("Seeking of FLAC stream failed: libFLAC seek failed.");
   598 			}
   599 		}
   600 		else {
   601 			SDL_SetError
   602 				("Seeking of FLAC stream failed: FLAC decoder was NULL.");
   603 		}
   604 	}
   605 	else {
   606 		SDL_SetError ("Seeking of FLAC stream failed: music was NULL.");
   607 	}
   608 }
   609 
   610 #endif /* FLAC_MUSIC */