⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 decode.c

📁 这是著名的TCPMP播放器在WINDWOWS,和WINCE下编译通过的源程序.笔者对其中的LIBMAD库做了针对ARM MPU的优化. 并增加了词幕功能.
💻 C
📖 第 1 页 / 共 4 页
字号:
		flac__analyze_init(aopts);

	return true;
}

void DecoderSession_destroy(DecoderSession *d, FLAC__bool error_occurred)
{
	if(0 != d->fout && d->fout != stdout) {
		fclose(d->fout);
		if(error_occurred)
			unlink(d->outfilename);
	}
}

FLAC__bool DecoderSession_init_decoder(DecoderSession *decoder_session, decode_options_t decode_options, const char *infilename)
{
	FLAC__uint32 test = 1;

	is_big_endian_host_ = (*((FLAC__byte*)(&test)))? false : true;

#ifdef FLAC__HAS_OGG
	if(decoder_session->is_ogg) {
		decoder_session->decoder.ogg.file = OggFLAC__file_decoder_new();

		if(0 == decoder_session->decoder.ogg.file) {
			flac__utils_printf(stderr, 1, "%s: ERROR creating the decoder instance\n", decoder_session->inbasefilename);
			return false;
		}

		OggFLAC__file_decoder_set_md5_checking(decoder_session->decoder.ogg.file, true);
		OggFLAC__file_decoder_set_filename(decoder_session->decoder.ogg.file, infilename);
		if(!decode_options.use_first_serial_number)
			OggFLAC__file_decoder_set_serial_number(decoder_session->decoder.ogg.file, decode_options.serial_number);
		if (0 != decoder_session->cue_specification)
			OggFLAC__file_decoder_set_metadata_respond(decoder_session->decoder.ogg.file, FLAC__METADATA_TYPE_CUESHEET);
		if (decoder_session->replaygain.spec.apply)
			OggFLAC__file_decoder_set_metadata_respond(decoder_session->decoder.ogg.file, FLAC__METADATA_TYPE_VORBIS_COMMENT);

		/*
		 * The three ugly casts here are to 'downcast' the 'void *' argument of
		 * the callback down to 'OggFLAC__FileDecoder *'.  In C++ this would be
		 * unnecessary but here the cast makes the C compiler happy.
		 */
		OggFLAC__file_decoder_set_write_callback(decoder_session->decoder.ogg.file, (FLAC__StreamDecoderWriteStatus (*)(const OggFLAC__FileDecoder *, const FLAC__Frame *, const FLAC__int32 * const [], void *))write_callback);
		OggFLAC__file_decoder_set_metadata_callback(decoder_session->decoder.ogg.file, (void (*)(const OggFLAC__FileDecoder *, const FLAC__StreamMetadata *, void *))metadata_callback);
		OggFLAC__file_decoder_set_error_callback(decoder_session->decoder.ogg.file, (void (*)(const OggFLAC__FileDecoder *, FLAC__StreamDecoderErrorStatus, void *))error_callback);
		OggFLAC__file_decoder_set_client_data(decoder_session->decoder.ogg.file, decoder_session);

		if(OggFLAC__file_decoder_init(decoder_session->decoder.ogg.file) != OggFLAC__FILE_DECODER_OK) {
			print_error_with_state(decoder_session, "ERROR initializing decoder");
			return false;
		}
	}
	else
#else
	(void)decode_options;
#endif
	{
		decoder_session->decoder.flac.file = FLAC__file_decoder_new();

		if(0 == decoder_session->decoder.flac.file) {
			flac__utils_printf(stderr, 1, "%s: ERROR creating the decoder instance\n", decoder_session->inbasefilename);
			return false;
		}

		FLAC__file_decoder_set_md5_checking(decoder_session->decoder.flac.file, true);
		FLAC__file_decoder_set_filename(decoder_session->decoder.flac.file, infilename);
		if (0 != decoder_session->cue_specification)
			FLAC__file_decoder_set_metadata_respond(decoder_session->decoder.flac.file, FLAC__METADATA_TYPE_CUESHEET);
		if (decoder_session->replaygain.spec.apply)
			FLAC__file_decoder_set_metadata_respond(decoder_session->decoder.flac.file, FLAC__METADATA_TYPE_VORBIS_COMMENT);
		/*
		 * The three ugly casts here are to 'downcast' the 'void *' argument of
		 * the callback down to 'FLAC__FileDecoder *'.
		 */
		FLAC__file_decoder_set_write_callback(decoder_session->decoder.flac.file, (FLAC__StreamDecoderWriteStatus (*)(const FLAC__FileDecoder *, const FLAC__Frame *, const FLAC__int32 * const [], void *))write_callback);
		FLAC__file_decoder_set_metadata_callback(decoder_session->decoder.flac.file, (void (*)(const FLAC__FileDecoder *, const FLAC__StreamMetadata *, void *))metadata_callback);
		FLAC__file_decoder_set_error_callback(decoder_session->decoder.flac.file, (void (*)(const FLAC__FileDecoder *, FLAC__StreamDecoderErrorStatus, void *))error_callback);
		FLAC__file_decoder_set_client_data(decoder_session->decoder.flac.file, decoder_session);

		if(FLAC__file_decoder_init(decoder_session->decoder.flac.file) != FLAC__FILE_DECODER_OK) {
			print_error_with_state(decoder_session, "ERROR initializing decoder");
			return false;
		}
	}

	return true;
}

FLAC__bool DecoderSession_process(DecoderSession *d)
{
#ifdef FLAC__HAS_OGG
	if(d->is_ogg) {
		if(!OggFLAC__file_decoder_process_until_end_of_metadata(d->decoder.ogg.file)) {
			flac__utils_printf(stderr, 2, "\n");
			print_error_with_state(d, "ERROR while decoding metadata");
			return false;
		}
		if(OggFLAC__file_decoder_get_state(d->decoder.ogg.file) != OggFLAC__FILE_DECODER_OK && OggFLAC__file_decoder_get_state(d->decoder.ogg.file) != OggFLAC__FILE_DECODER_END_OF_FILE) {
			flac__utils_printf(stderr, 2, "\n");
			print_error_with_state(d, "ERROR during metadata decoding");
			return false;
		}
	}
	else
#endif
	{
		if(!FLAC__file_decoder_process_until_end_of_metadata(d->decoder.flac.file)) {
			flac__utils_printf(stderr, 2, "\n");
			print_error_with_state(d, "ERROR while decoding metadata");
			return false;
		}
		if(FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_OK && FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_END_OF_FILE) {
			flac__utils_printf(stderr, 2, "\n");
			print_error_with_state(d, "ERROR during metadata decoding");
			return false;
		}
	}
	if(d->abort_flag)
		return false;

	/* write the WAVE/AIFF headers if necessary */
	if(!write_necessary_headers(d)) {
		d->abort_flag = true;
		return false;
	}

	if(d->skip_specification->value.samples > 0) {
		const FLAC__uint64 skip = (FLAC__uint64)d->skip_specification->value.samples;

#ifdef FLAC__HAS_OGG
		if(d->is_ogg) {
			if(!OggFLAC__file_decoder_seek_absolute(d->decoder.ogg.file, skip)) {
				print_error_with_state(d, "ERROR seeking while skipping bytes");
				return false;
			}
			if(!OggFLAC__file_decoder_process_until_end_of_file(d->decoder.ogg.file) && !d->aborting_due_to_until) {
				flac__utils_printf(stderr, 2, "\n");
				print_error_with_state(d, "ERROR while decoding frames");
				return false;
			}
			if(OggFLAC__file_decoder_get_state(d->decoder.ogg.file) != OggFLAC__FILE_DECODER_OK && OggFLAC__file_decoder_get_state(d->decoder.ogg.file) != OggFLAC__FILE_DECODER_END_OF_FILE && !d->aborting_due_to_until) {
				flac__utils_printf(stderr, 2, "\n");
				print_error_with_state(d, "ERROR during decoding");
				return false;
			}
		}
		else
#endif
		{
			if(!FLAC__file_decoder_seek_absolute(d->decoder.flac.file, skip)) {
				print_error_with_state(d, "ERROR seeking while skipping bytes");
				return false;
			}
			if(!FLAC__file_decoder_process_until_end_of_file(d->decoder.flac.file) && !d->aborting_due_to_until) {
				flac__utils_printf(stderr, 2, "\n");
				print_error_with_state(d, "ERROR while decoding frames");
				return false;
			}
			if(FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_OK && FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_END_OF_FILE && !d->aborting_due_to_until) {
				flac__utils_printf(stderr, 2, "\n");
				print_error_with_state(d, "ERROR during decoding");
				return false;
			}
		}
	}
	else {
#ifdef FLAC__HAS_OGG
		if(d->is_ogg) {
			if(!OggFLAC__file_decoder_process_until_end_of_file(d->decoder.ogg.file) && !d->aborting_due_to_until) {
				flac__utils_printf(stderr, 2, "\n");
				print_error_with_state(d, "ERROR while decoding data");
				return false;
			}
			if(OggFLAC__file_decoder_get_state(d->decoder.ogg.file) != OggFLAC__FILE_DECODER_OK && OggFLAC__file_decoder_get_state(d->decoder.ogg.file) != OggFLAC__FILE_DECODER_END_OF_FILE && !d->aborting_due_to_until) {
				flac__utils_printf(stderr, 2, "\n");
				print_error_with_state(d, "ERROR during decoding");
				return false;
			}
		}
		else
#endif
		{
			if(!FLAC__file_decoder_process_until_end_of_file(d->decoder.flac.file) && !d->aborting_due_to_until) {
				flac__utils_printf(stderr, 2, "\n");
				print_error_with_state(d, "ERROR while decoding data");
				return false;
			}
			if(FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_OK && FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_END_OF_FILE && !d->aborting_due_to_until) {
				flac__utils_printf(stderr, 2, "\n");
				print_error_with_state(d, "ERROR during decoding");
				return false;
			}
		}
	}

	if((d->is_wave_out || d->is_aiff_out) && ((d->total_samples * d->channels * ((d->bps+7)/8)) & 1)) {
		if(flac__utils_fwrite("\000", 1, 1, d->fout) != 1) {
			print_error_with_state(d, d->is_wave_out?
				"ERROR writing pad byte to WAVE data chunk" :
				"ERROR writing pad byte to AIFF SSND chunk"
			);
			return false;
		}
	}

	return true;
}

int DecoderSession_finish_ok(DecoderSession *d)
{
	FLAC__bool md5_failure = false;

#ifdef FLAC__HAS_OGG
	if(d->is_ogg) {
		if(d->decoder.ogg.file) {
			md5_failure = !OggFLAC__file_decoder_finish(d->decoder.ogg.file) && !d->aborting_due_to_until;
			print_stats(d);
			OggFLAC__file_decoder_delete(d->decoder.ogg.file);
		}
	}
	else
#endif
	{
		if(d->decoder.flac.file) {
			md5_failure = !FLAC__file_decoder_finish(d->decoder.flac.file) && !d->aborting_due_to_until;
			print_stats(d);
			FLAC__file_decoder_delete(d->decoder.flac.file);
		}
	}
	if(d->analysis_mode)
		flac__analyze_finish(d->aopts);
	if(md5_failure) {
		flac__utils_printf(stderr, 1, "\r%s: WARNING, MD5 signature mismatch\n", d->inbasefilename);
	}
	else {
		flac__utils_printf(stderr, 2, "\r%s: %s         \n", d->inbasefilename, d->test_only? "ok           ":d->analysis_mode?"done           ":"done");
	}
	DecoderSession_destroy(d, /*error_occurred=*/false);
	if((d->is_wave_out || d->is_aiff_out) && d->wave_chunk_size_fixup.needs_fixup)
		if(!fixup_wave_chunk_size(d->outfilename, d->is_wave_out, d->wave_chunk_size_fixup.riff_offset, d->wave_chunk_size_fixup.data_offset, d->wave_chunk_size_fixup.frames_offset, (FLAC__uint32)d->samples_processed, d->channels, d->bps))
			return 1;
	return 0;
}

int DecoderSession_finish_error(DecoderSession *d)
{
#ifdef FLAC__HAS_OGG
	if(d->is_ogg) {
		if(d->decoder.ogg.file) {
			OggFLAC__file_decoder_finish(d->decoder.ogg.file);
			OggFLAC__file_decoder_delete(d->decoder.ogg.file);
		}
	}
	else
#endif
	{
		if(d->decoder.flac.file) {
			FLAC__file_decoder_finish(d->decoder.flac.file);
			FLAC__file_decoder_delete(d->decoder.flac.file);
		}
	}
	if(d->analysis_mode)
		flac__analyze_finish(d->aopts);
	DecoderSession_destroy(d, /*error_occurred=*/true);
	return 1;
}

FLAC__bool canonicalize_until_specification(utils__SkipUntilSpecification *spec, const char *inbasefilename, unsigned sample_rate, FLAC__uint64 skip, FLAC__uint64 total_samples_in_input)
{
	/* convert from mm:ss.sss to sample number if necessary */
	flac__utils_canonicalize_skip_until_specification(spec, sample_rate);

	/* special case: if "--until=-0", use the special value '0' to mean "end-of-stream" */
	if(spec->is_relative && spec->value.samples == 0) {
		spec->is_relative = false;
		return true;
	}

	/* in any other case the total samples in the input must be known */
	if(total_samples_in_input == 0) {
		flac__utils_printf(stderr, 1, "%s: ERROR, cannot use --until when FLAC metadata has total sample count of 0\n", inbasefilename);
		return false;
	}

	FLAC__ASSERT(spec->value_is_samples);

	/* convert relative specifications to absolute */
	if(spec->is_relative) {
		if(spec->value.samples <= 0)
			spec->value.samples += (FLAC__int64)total_samples_in_input;
		else
			spec->value.samples += skip;
		spec->is_relative = false;
	}

	/* error check */
	if(spec->value.samples < 0) {
		flac__utils_printf(stderr, 1, "%s: ERROR, --until value is before beginning of input\n", inbasefilename);
		return false;
	}
	if((FLAC__uint64)spec->value.samples <= skip) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -