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