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

📄 encode.c

📁 这是著名的TCPMP播放器在WINDWOWS,和WINCE下编译通过的源程序.笔者对其中的LIBMAD库做了针对ARM MPU的优化. 并增加了词幕功能.
💻 C
📖 第 1 页 / 共 5 页
字号:
			block_align = x;
			/* bits per sample */
			if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
				return EncoderSession_finish_error(&encoder_session);
			if(x != 8 && x != 16 && x != 24) {
				flac__utils_printf(stderr, 1, "%s: ERROR: unsupported bits-per-sample %u\n", encoder_session.inbasefilename, (unsigned)x);
				return EncoderSession_finish_error(&encoder_session);
			}
			else if(options.common.sector_align && x != 16) {
				flac__utils_printf(stderr, 1, "%s: ERROR: file has %u bits per sample, must be 16 for --sector-align\n", encoder_session.inbasefilename, (unsigned)x);
				return EncoderSession_finish_error(&encoder_session);
			}
			bps = x;
			if(bps * channels != block_align * 8) {
				flac__utils_printf(stderr, 1, "%s: ERROR: unsupported block alignment (%u), for bits-per-sample=%u, channels=%u\n", encoder_session.inbasefilename, block_align, bps, channels);
				return EncoderSession_finish_error(&encoder_session);
			}
			is_unsigned_samples = (x == 8);

			/* skip any extra data in the fmt sub-chunk */
			data_bytes -= 16;
			if(data_bytes > 0) {
				unsigned left, need;
				for(left = data_bytes; left > 0; ) {
					need = min(left, CHUNK_OF_SAMPLES);
					if(fread(ucbuffer_, 1U, need, infile) < need) {
						flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
						return EncoderSession_finish_error(&encoder_session);
					}
					left -= need;
				}
			}

			/*
			 * now that we know the sample rate, canonicalize the
			 * --skip string to a number of samples:
			 */
			flac__utils_canonicalize_skip_until_specification(&options.common.skip_specification, sample_rate);
			FLAC__ASSERT(options.common.skip_specification.value.samples >= 0);
			encoder_session.skip = (FLAC__uint64)options.common.skip_specification.value.samples;
			FLAC__ASSERT(!options.common.sector_align || encoder_session.skip == 0);

			got_fmt_chunk = true;
		}
		else if(xx == 0x61746164 && !got_data_chunk && got_fmt_chunk) { /* "data" */
			FLAC__uint64 total_samples_in_input, trim = 0;
			FLAC__bool pad = false;

			/* data size */
			if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
				return EncoderSession_finish_error(&encoder_session);
			data_bytes = xx;
			pad = (data_bytes & 1U) ? true : false;

			bytes_per_wide_sample = channels * (bps >> 3);

			/* *options.common.align_reservoir_samples will be 0 unless --sector-align is used */
			FLAC__ASSERT(options.common.sector_align || *options.common.align_reservoir_samples == 0);
			total_samples_in_input = data_bytes / bytes_per_wide_sample + *options.common.align_reservoir_samples;

			/*
			 * now that we know the input size, canonicalize the
			 * --until string to an absolute sample number:
			 */
			if(!canonicalize_until_specification(&options.common.until_specification, encoder_session.inbasefilename, sample_rate, encoder_session.skip, total_samples_in_input))
				return EncoderSession_finish_error(&encoder_session);
			encoder_session.until = (FLAC__uint64)options.common.until_specification.value.samples;
			FLAC__ASSERT(!options.common.sector_align || encoder_session.until == 0);

			if(encoder_session.skip > 0) {
				if(!fskip_ahead(infile, encoder_session.skip * bytes_per_wide_sample)) {
					flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
					return EncoderSession_finish_error(&encoder_session);
				}
			}

			data_bytes -= (unsigned)encoder_session.skip * bytes_per_wide_sample; /*@@@ WATCHOUT: 4GB limit */
			encoder_session.total_samples_to_encode = total_samples_in_input - encoder_session.skip;
			if(encoder_session.until > 0) {
				trim = total_samples_in_input - encoder_session.until;
				FLAC__ASSERT(total_samples_in_input > 0);
				FLAC__ASSERT(!options.common.sector_align);
				data_bytes -= (unsigned int)trim * bytes_per_wide_sample;
				encoder_session.total_samples_to_encode -= trim;
			}
			if(options.common.sector_align) {
				align_remainder = (unsigned)(encoder_session.total_samples_to_encode % 588);
				if(options.common.is_last_file)
					encoder_session.total_samples_to_encode += (588-align_remainder); /* will pad with zeroes */
				else
					encoder_session.total_samples_to_encode -= align_remainder; /* will stop short and carry over to next file */
			}

			/* +44 for the size of the WAV headers; this is just an estimate for the progress indicator and doesn't need to be exact */
			encoder_session.unencoded_size = encoder_session.total_samples_to_encode * bytes_per_wide_sample + 44;

			if(!EncoderSession_init_encoder(&encoder_session, options.common, channels, bps, sample_rate))
				return EncoderSession_finish_error(&encoder_session);

			/*
			 * first do any samples in the reservoir
			 */
			if(options.common.sector_align && *options.common.align_reservoir_samples > 0) {
				if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)options.common.align_reservoir, *options.common.align_reservoir_samples)) {
					print_error_with_state(&encoder_session, "ERROR during encoding");
					return EncoderSession_finish_error(&encoder_session);
				}
			}

			/*
			 * decrement the data_bytes counter if we need to align the file
			 */
			if(options.common.sector_align) {
				if(options.common.is_last_file) {
					*options.common.align_reservoir_samples = 0;
				}
				else {
					*options.common.align_reservoir_samples = align_remainder;
					data_bytes -= (*options.common.align_reservoir_samples) * bytes_per_wide_sample;
				}
			}

			/*
			 * now do from the file
			 */
			while(data_bytes > 0) {
				bytes_read = fread(ucbuffer_, sizeof(unsigned char), min(data_bytes, CHUNK_OF_SAMPLES * bytes_per_wide_sample), infile);
				if(bytes_read == 0) {
					if(ferror(infile)) {
						flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
						return EncoderSession_finish_error(&encoder_session);
					}
					else if(feof(infile)) {
						flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written);
						data_bytes = 0;
					}
				}
				else {
					if(bytes_read % bytes_per_wide_sample != 0) {
						flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
						return EncoderSession_finish_error(&encoder_session);
					}
					else {
						unsigned wide_samples = bytes_read / bytes_per_wide_sample;
						format_input(input_, wide_samples, false, is_unsigned_samples, channels, bps);

						if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
							print_error_with_state(&encoder_session, "ERROR during encoding");
							return EncoderSession_finish_error(&encoder_session);
						}
						data_bytes -= bytes_read;
					}
				}
			}

			if(trim > 0) {
				FLAC__ASSERT(!options.common.sector_align);
				if(!fskip_ahead(infile, trim * bytes_per_wide_sample)) {
					flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
					return EncoderSession_finish_error(&encoder_session);
				}
			}

			/*
			 * now read unaligned samples into reservoir or pad with zeroes if necessary
			 */
			if(options.common.sector_align) {
				if(options.common.is_last_file) {
					unsigned wide_samples = 588 - align_remainder;
					if(wide_samples < 588) {
						unsigned channel;

						info_align_zero = wide_samples;
						data_bytes = wide_samples * (bps >> 3);
						for(channel = 0; channel < channels; channel++)
							memset(input_[channel], 0, data_bytes);

						if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
							print_error_with_state(&encoder_session, "ERROR during encoding");
							return EncoderSession_finish_error(&encoder_session);
						}
					}
				}
				else {
					if(*options.common.align_reservoir_samples > 0) {
						FLAC__ASSERT(CHUNK_OF_SAMPLES >= 588);
						bytes_read = fread(ucbuffer_, sizeof(unsigned char), (*options.common.align_reservoir_samples) * bytes_per_wide_sample, infile);
						if(bytes_read == 0 && ferror(infile)) {
							flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
							return EncoderSession_finish_error(&encoder_session);
						}
						else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_wide_sample) {
							flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; read %u bytes; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)bytes_read, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written);
							data_bytes = 0;
						}
						else {
							info_align_carry = *options.common.align_reservoir_samples;
							format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, false, is_unsigned_samples, channels, bps);
						}
					}
				}
			}

			if(pad == true) {
				unsigned char tmp;

				if(fread(&tmp, 1U, 1U, infile) < 1U) {
					flac__utils_printf(stderr, 1, "%s: ERROR during read of data pad byte\n", encoder_session.inbasefilename);
					return EncoderSession_finish_error(&encoder_session);
				}
			}

			got_data_chunk = true;
		}
		else {
			if(xx == 0x20746d66 && got_fmt_chunk) { /* "fmt " */
				flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'fmt ' sub-chunk\n", encoder_session.inbasefilename);
			}
			else if(xx == 0x61746164) { /* "data" */
				if(got_data_chunk) {
					flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'data' sub-chunk\n", encoder_session.inbasefilename);
				}
				else if(!got_fmt_chunk) {
					flac__utils_printf(stderr, 1, "%s: ERROR: got 'data' sub-chunk before 'fmt' sub-chunk\n", encoder_session.inbasefilename);
					return EncoderSession_finish_error(&encoder_session);
				}
				else {
					FLAC__ASSERT(0);
				}
			}
			else {
				flac__utils_printf(stderr, 1, "%s: WARNING: skipping unknown sub-chunk '%c%c%c%c'\n", encoder_session.inbasefilename, (char)(xx&255), (char)((xx>>8)&255), (char)((xx>>16)&255), (char)(xx>>24));
			}
			/* sub-chunk size */
			if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
				return EncoderSession_finish_error(&encoder_session);
			else {
				unsigned long skip = xx+(xx & 1U);

				FLAC__ASSERT(skip<=LONG_MAX);
				if(!fskip_ahead(infile, skip)) {
					flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping unsupported sub-chunk\n", encoder_session.inbasefilename);
					return EncoderSession_finish_error(&encoder_session);
				}
			}
		}
	}

	return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero);
}

int flac__encode_raw(FILE *infile, long infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, raw_encode_options_t options)
{
	EncoderSession encoder_session;
	size_t bytes_read;
	const size_t bytes_per_wide_sample = options.channels * (options.bps >> 3);
	unsigned align_remainder = 0;
	int info_align_carry = -1, info_align_zero = -1;
	FLAC__uint64 total_samples_in_input = 0;;

	FLAC__ASSERT(!options.common.sector_align || options.channels == 2);
	FLAC__ASSERT(!options.common.sector_align || options.bps == 16);
	FLAC__ASSERT(!options.common.sector_align || options.sample_rate == 44100);
	FLAC__ASSERT(!options.common.sector_align || infilesize >= 0);
	FLAC__ASSERT(!options.common.replay_gain || options.channels <= 2);
	FLAC__ASSERT(!options.common.replay_gain || grabbag__replaygain_is_valid_sample_frequency(options.sample_rate));

	if(!
		EncoderSession_construct(
			&encoder_session,
#ifdef FLAC__HAS_OGG
			options.common.use_ogg,
#else
			/*use_ogg=*/false,
#endif
			options.common.verify,
			infile,
			infilename,
			outfilename
		)
	)
		return 1;

	/*
	 * now that we know the sample rate, canonicalize the
	 * --skip string to a number of samples:
	 */
	flac__utils_canonicalize_skip_until_specification(&options.common.skip_specification, options.sample_rate);
	FLAC__ASSERT(options.common.skip_specification.value.samples >= 0);
	encoder_session.skip = (FLAC__uint64)options.common.skip_specification.value.samples;
	FLAC__ASSERT(!options.common.sector_align || encoder_session.skip == 0);

	if(infilesize < 0)
		total_samples_in_input = 0;
	else {
		/* *options.common.align_reservoir_samples will be 0 unless --sector-align is used */
		FLAC__ASSERT(options.common.sector_align || *options.common.align_reservoir_samples == 0);
		total_samples_in_input = (unsigned)infilesize / bytes_per_wide_sample + *options.common.align_reservoir_samples;
	}

	/*
	 * now that we know the input size, canonicalize the

⌨️ 快捷键说明

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