ft2-clone

Fasttracker 2 clone
Log | Files | Refs | README | LICENSE

ft2_load_flac.c (11584B)


      1 /* FLAC sample loader
      2 **
      3 ** Note: Vol/loop sanitation is done in the last stage
      4 ** of sample loading, so you don't need to do that here.
      5 ** Do NOT close the file handle!
      6 */
      7 
      8 #ifdef HAS_LIBFLAC
      9 
     10 // hide POSIX warning for fileno()
     11 #ifdef _MSC_VER
     12 #pragma warning(disable: 4996)
     13 #endif
     14 
     15 #include <stdio.h>
     16 #include <stdint.h>
     17 #include <stdbool.h>
     18 #ifndef _WIN32
     19 #include <sys/types.h>
     20 #include <sys/stat.h>
     21 #include <unistd.h>
     22 #endif
     23 #include "../ft2_header.h"
     24 #include "../ft2_audio.h"
     25 #include "../ft2_sample_ed.h"
     26 #include "../ft2_sysreqs.h"
     27 #include "../ft2_sample_loader.h"
     28 
     29 #ifdef EXTERNAL_LIBFLAC
     30 #include <FLAC/stream_decoder.h>
     31 #else
     32 #include "../libflac/FLAC/stream_decoder.h"
     33 #endif
     34 
     35 static bool sample16Bit;
     36 static int16_t stereoSampleLoadMode = -1;
     37 static uint32_t numChannels, bitDepth, sampleLength, sampleRate, samplesRead;
     38 static sample_t *s;
     39 
     40 static FLAC__StreamDecoderReadStatus read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
     41 static FLAC__StreamDecoderSeekStatus seek_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
     42 static FLAC__StreamDecoderTellStatus tell_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
     43 static FLAC__StreamDecoderLengthStatus length_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
     44 static FLAC__bool eof_callback(const FLAC__StreamDecoder *decoder, void *client_data);
     45 static void metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
     46 static FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *const buffer[], void *client_data);
     47 static void error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
     48 
     49 bool loadFLAC(FILE *f, uint32_t filesize)
     50 {
     51 	s = &tmpSmp;
     52 
     53 	s->volume = 64;
     54 	s->panning = 128;
     55 
     56 	numChannels = 0;
     57 	bitDepth = 0;
     58 	sampleLength = 0;
     59 	sampleRate = 0;
     60 	samplesRead = 0;
     61 
     62 	FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new();
     63 	if (decoder == NULL)
     64 	{
     65 		loaderMsgBox("Error loading sample: Unable to allocate FLAC decoder!");
     66 		goto error;
     67 	}
     68 
     69 	FLAC__stream_decoder_set_metadata_respond_all(decoder);
     70 
     71 	FLAC__StreamDecoderInitStatus initStatus =
     72 		FLAC__stream_decoder_init_stream
     73 		(
     74 			decoder,
     75 			read_callback, seek_callback,
     76 			tell_callback, length_callback,
     77 			eof_callback, write_callback,
     78 			metadata_callback, error_callback,
     79 			f
     80 		);
     81 
     82 	if (initStatus != FLAC__STREAM_DECODER_INIT_STATUS_OK)
     83 	{
     84 		loaderMsgBox("Error loading sample: Unable to initialize FLAC decoder!");
     85 		goto error;
     86 	}
     87 
     88 	if (!FLAC__stream_decoder_process_until_end_of_stream(decoder))
     89 	{
     90 		loaderMsgBox("Error loading sample: Unable to decode FLAC!");
     91 		goto error;
     92 	}
     93 
     94 	FLAC__stream_decoder_finish(decoder);
     95 	FLAC__stream_decoder_delete(decoder);
     96 
     97 	setSampleC4Hz(s, sampleRate);
     98 
     99 	return true;
    100 
    101 error:
    102 	if (decoder != NULL) FLAC__stream_decoder_delete(decoder);
    103 
    104 	return false;
    105 
    106 	(void)filesize;
    107 }
    108 
    109 static FLAC__StreamDecoderReadStatus read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
    110 {
    111 	FILE *file = (FILE *)client_data;
    112 	if (*bytes > 0)
    113 	{
    114 		*bytes = fread(buffer, sizeof (FLAC__byte), *bytes, file);
    115 		if (ferror(file))
    116 			return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
    117 		else if (*bytes == 0)
    118 			return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
    119 		else
    120 			return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
    121 	}
    122 	else
    123 	{
    124 		return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
    125 	}
    126 
    127 	(void)decoder;
    128 }
    129 
    130 static FLAC__StreamDecoderSeekStatus seek_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
    131 {
    132 	FILE *file = (FILE *)client_data;
    133 
    134 	if (absolute_byte_offset > INT32_MAX)
    135 		return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
    136 
    137 	if (fseek(file, (int32_t)absolute_byte_offset, SEEK_SET) < 0)
    138 		return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
    139 	else
    140 		return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
    141 
    142 	(void)decoder;
    143 }
    144 
    145 static FLAC__StreamDecoderTellStatus tell_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
    146 {
    147 	FILE *file = (FILE *)client_data;
    148 	int32_t pos = ftell(file);
    149 
    150 	if (pos < 0)
    151 	{
    152 		return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
    153 	}
    154 	else
    155 	{
    156 		*absolute_byte_offset = (FLAC__uint64)pos;
    157 		return FLAC__STREAM_DECODER_TELL_STATUS_OK;
    158 	}
    159 
    160 	(void)decoder;
    161 }
    162 
    163 static FLAC__StreamDecoderLengthStatus length_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
    164 {
    165 	FILE *file = (FILE *)client_data;
    166 	struct stat filestats;
    167 
    168 	if (fstat(fileno(file), &filestats) != 0)
    169 	{
    170 		return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
    171 	}
    172 	else
    173 	{
    174 		*stream_length = (FLAC__uint64)filestats.st_size;
    175 		return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
    176 	}
    177 
    178 	(void)decoder;
    179 }
    180 
    181 static FLAC__bool eof_callback(const FLAC__StreamDecoder *decoder, void *client_data)
    182 {
    183 	FILE *file = (FILE *)client_data;
    184 	return feof(file) ? true : false;
    185 
    186 	(void)decoder;
    187 }
    188 
    189 static void metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
    190 {
    191 	if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO && metadata->data.stream_info.total_samples != 0)
    192 	{
    193 		bitDepth = metadata->data.stream_info.bits_per_sample;
    194 		numChannels = metadata->data.stream_info.channels;
    195 		sampleRate = metadata->data.stream_info.sample_rate;
    196 
    197 		sample16Bit = (bitDepth != 8);
    198 
    199 		int64_t tmp64 = metadata->data.stream_info.total_samples;
    200 		if (tmp64 > MAX_SAMPLE_LEN)
    201 			tmp64 = MAX_SAMPLE_LEN;
    202 
    203 		sampleLength = (uint32_t)tmp64;
    204 
    205 		s->length = sampleLength;
    206 		if (sample16Bit)
    207 			s->flags |= SAMPLE_16BIT;
    208 
    209 		stereoSampleLoadMode = -1;
    210 		if (numChannels == 2)
    211 			stereoSampleLoadMode = loaderSysReq(4, "System request", "This is a stereo sample...", NULL);
    212 	}
    213 
    214 	// check for RIFF chunks (loop/vol/pan information)
    215 	else if (metadata->type == FLAC__METADATA_TYPE_APPLICATION && !memcmp(metadata->data.application.id, "riff", 4))
    216 	{
    217 		const uint8_t *data = (const uint8_t *)metadata->data.application.data;
    218 
    219 		uint32_t chunkID  = *(uint32_t *)data; data += 4;
    220 		uint32_t chunkLen = *(uint32_t *)data; data += 4;
    221 
    222 		if (chunkID == 0x61727478 && chunkLen >= 8) // "xtra"
    223 		{
    224 			uint32_t xtraFlags = *(uint32_t *)data; data += 4;
    225 
    226 			// panning (0..256)
    227 			if (xtraFlags & 0x20) // set panning flag
    228 			{
    229 				uint16_t tmpPan = *(uint16_t *)data;
    230 				if (tmpPan > 255)
    231 					tmpPan = 255;
    232 
    233 				s->panning = (uint8_t)tmpPan;
    234 			}
    235 			data += 2;
    236 
    237 			// volume (0..256)
    238 			uint16_t tmpVol = *(uint16_t *)data;
    239 			if (tmpVol > 256)
    240 				tmpVol = 256;
    241 
    242 			s->volume = (uint8_t)((tmpVol + 2) / 4); // 0..256 -> 0..64 (rounded)
    243 		}
    244 
    245 		if (chunkID == 0x6C706D73 && chunkLen > 52) // "smpl"
    246 		{
    247 			data += 28; // seek to first wanted byte
    248 
    249 			uint32_t numLoops = *(uint32_t *)data; data += 4;
    250 			if (numLoops == 1)
    251 			{
    252 				data += 4+4; // skip "samplerData" and "identifier"
    253 
    254 				uint32_t loopType  = *(uint32_t *)data; data += 4;
    255 				uint32_t loopStart = *(uint32_t *)data; data += 4;
    256 				uint32_t loopEnd   = *(uint32_t *)data; data += 4;
    257 
    258 				s->loopStart = loopStart;
    259 				s->loopLength = (loopEnd+1) - loopStart;
    260 				s->flags |= (loopType == 0) ? LOOP_FWD : LOOP_BIDI;
    261 			}
    262 		}
    263 	}
    264 
    265 	else if (metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT)
    266 	{
    267 		uint32_t tmpSampleRate = 0, loopStart = 0, loopLength = 0;
    268 		for (uint32_t i = 0; i < metadata->data.vorbis_comment.num_comments; i++)
    269 		{
    270 			const char *tag = (const char *)metadata->data.vorbis_comment.comments[i].entry;
    271 			uint32_t length = metadata->data.vorbis_comment.comments[i].length;
    272 
    273 			if (length > 6 && !memcmp(tag, "TITLE=", 6))
    274 			{
    275 				length -= 6;
    276 				if (length > 22)
    277 					length = 22;
    278 
    279 				memcpy(s->name, &tag[6], length);
    280 				s->name[22] = '\0';
    281 
    282 				smpFilenameSet = true;
    283 			}
    284 
    285 			// the following tags haven't been tested!
    286 			else if (length > 11 && !memcmp(tag, "SAMPLERATE=", 11))
    287 			{
    288 				tmpSampleRate = atoi(&tag[11]);
    289 			}
    290 			else if (length > 10 && !memcmp(tag, "LOOPSTART=", 10))
    291 			{
    292 				loopStart = atoi(&tag[10]);
    293 			}
    294 			else if (length > 11 && !memcmp(tag, "LOOPLENGTH=", 11))
    295 			{
    296 				loopLength = atoi(&tag[11]);
    297 			}
    298 
    299 			if (loopLength > 0)
    300 			{
    301 				s->loopStart = loopStart;
    302 				s->loopLength = loopLength;
    303 
    304 				DISABLE_LOOP(s->flags);
    305 				s->flags |= LOOP_FWD;
    306 			}
    307 
    308 			if (tmpSampleRate > 0)
    309 				sampleRate = tmpSampleRate;
    310 		}
    311 	}
    312 
    313 	(void)client_data;
    314 	(void)decoder;
    315 }
    316 
    317 static FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *const buffer[], void *client_data)
    318 {
    319 	if (sampleLength == 0 || numChannels == 0)
    320 	{
    321 		loaderMsgBox("Error loading sample: The sample is empty or corrupt!");
    322 		return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
    323 	}
    324 
    325 	if (numChannels > 2)
    326 	{
    327 		loaderMsgBox("Error loading sample: Only mono/stereo FLACs are supported!");
    328 		return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
    329 	}
    330 
    331 	if (bitDepth != 8 && bitDepth != 16 && bitDepth != 24)
    332 	{
    333 		loaderMsgBox("Error loading sample: Only FLACs with a bitdepth of 8/16/24 are supported!");
    334 		return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
    335 	}
    336 
    337 	if (frame->header.number.sample_number == 0)
    338 	{
    339 		if (!allocateSmpData(s, sampleLength, sample16Bit))
    340 		{
    341 			loaderMsgBox("Error loading sample: Not enough memory!");
    342 			return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
    343 		}
    344 
    345 		samplesRead = 0;
    346 	}
    347 
    348 	uint32_t blockSize = frame->header.blocksize;
    349 
    350 	const uint32_t samplesAllocated = sampleLength;
    351 	if (samplesRead+blockSize > samplesAllocated)
    352 		blockSize = samplesAllocated-samplesRead;
    353 
    354 	if (stereoSampleLoadMode == STEREO_SAMPLE_CONVERT) // mix to mono
    355 	{
    356 		const int32_t *src32_L = buffer[0];
    357 		const int32_t *src32_R = buffer[1];
    358 
    359 		switch (bitDepth)
    360 		{
    361 			case 8:
    362 			{
    363 				int8_t *dst8 = s->dataPtr + samplesRead;
    364 				for (uint32_t i = 0; i < blockSize; i++)
    365 					dst8[i] = (int8_t)((src32_L[i] + src32_R[i]) >> 1);
    366 			}
    367 			break;
    368 
    369 			case 16:
    370 			{
    371 				int16_t *dst16 = (int16_t *)s->dataPtr + samplesRead;
    372 				for (uint32_t i = 0; i < blockSize; i++)
    373 					dst16[i] = (int16_t)((src32_L[i] + src32_R[i]) >> 1);
    374 			}
    375 			break;
    376 
    377 			case 24:
    378 			{
    379 				int16_t *dst16 = (int16_t *)s->dataPtr + samplesRead;
    380 				for (uint32_t i = 0; i < blockSize; i++)
    381 					dst16[i] = (int16_t)((src32_L[i] + src32_R[i]) >> ((24-16)+1));
    382 			}
    383 			break;
    384 
    385 			default: break;
    386 		}
    387 	}
    388 	else // mono sample
    389 	{
    390 		const int32_t *src32 = (stereoSampleLoadMode == STEREO_SAMPLE_READ_RIGHT) ? buffer[1] : buffer[0];
    391 
    392 		switch (bitDepth)
    393 		{
    394 			case 8:
    395 			{
    396 				int8_t *dst8 = s->dataPtr + samplesRead;
    397 				for (uint32_t i = 0; i < blockSize; i++)
    398 					dst8[i] = (int8_t)src32[i];
    399 			}
    400 			break;
    401 
    402 			case 16:
    403 			{
    404 				int16_t *dst16 = (int16_t *)s->dataPtr + samplesRead;
    405 				for (uint32_t i = 0; i < blockSize; i++)
    406 					dst16[i] = (int16_t)src32[i];
    407 			}
    408 			break;
    409 
    410 			case 24:
    411 			{
    412 				int16_t *dst16 = (int16_t *)s->dataPtr + samplesRead;
    413 				for (uint32_t i = 0; i < blockSize; i++)
    414 					dst16[i] = (int16_t)(src32[i] >> (24-16));
    415 			}
    416 			break;
    417 
    418 			default: break;
    419 		}
    420 	}
    421 
    422 	samplesRead += blockSize;
    423 	return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
    424 
    425 	(void)client_data;
    426 	(void)decoder;
    427 }
    428 
    429 static void error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
    430 {
    431 	(void)status;
    432 	(void)decoder;
    433 	(void)client_data;
    434 }
    435 #else
    436 typedef int prevent_compiler_warning; // kludge: prevent warning about empty .c file if HAS_LIBFLAC is not defined
    437 #endif