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

📄 cuesheet.c

📁 这是著名的TCPMP播放器在WINDWOWS,和WINCE下编译通过的源程序.笔者对其中的LIBMAD库做了针对ARM MPU的优化. 并增加了词幕功能.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* grabbag - Convenience lib for various routines common to several tools
 * Copyright (C) 2002,2003,2004,2005  Josh Coalson
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#include "share/grabbag.h"
#include "FLAC/assert.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

unsigned grabbag__cuesheet_msf_to_frame(unsigned minutes, unsigned seconds, unsigned frames)
{
	return ((minutes * 60) + seconds) * 75 + frames;
}

void grabbag__cuesheet_frame_to_msf(unsigned frame, unsigned *minutes, unsigned *seconds, unsigned *frames)
{
	*frames = frame % 75;
	frame /= 75;
	*seconds = frame % 60;
	frame /= 60;
	*minutes = frame;
}

/* since we only care about values >= 0 or error, returns < 0 for any illegal string, else value */
static int local__parse_int_(const char *s)
{
	int ret = 0;
	char c;

	if(*s == '\0')
		return -1;

	while('\0' != (c = *s++))
		if(c >= '0' && c <= '9')
			ret = ret * 10 + (c - '0');
		else
			return -1;

	return ret;
}

/* since we only care about values >= 0 or error, returns < 0 for any illegal string, else value */
static FLAC__int64 local__parse_int64_(const char *s)
{
	FLAC__int64 ret = 0;
	char c;

	if(*s == '\0')
		return -1;

	while('\0' != (c = *s++))
		if(c >= '0' && c <= '9')
			ret = ret * 10 + (c - '0');
		else
			return -1;

	return ret;
}

/* accept '[0-9]+:[0-9][0-9]?:[0-9][0-9]?', but max second of 59 and max frame of 74, e.g. 0:0:0, 123:45:67
 * return sample number or <0 for error
 */
static FLAC__int64 local__parse_msf_(const char *s)
{
	FLAC__int64 ret, field;
	char c;

	c = *s++;
	if(c >= '0' && c <= '9')
		field = (c - '0');
	else
		return -1;
	while(':' != (c = *s++)) {
		if(c >= '0' && c <= '9')
			field = field * 10 + (c - '0');
		else
			return -1;
	}

	ret = field * 60 * 44100;

	c = *s++;
	if(c >= '0' && c <= '9')
		field = (c - '0');
	else
		return -1;
	if(':' != (c = *s++)) {
		if(c >= '0' && c <= '9') {
			field = field * 10 + (c - '0');
			c = *s++;
			if(c != ':')
				return -1;
		}
		else
			return -1;
	}

	if(field >= 60)
		return -1;

	ret += field * 44100;

	c = *s++;
	if(c >= '0' && c <= '9')
		field = (c - '0');
	else
		return -1;
	if('\0' != (c = *s++)) {
		if(c >= '0' && c <= '9') {
			field = field * 10 + (c - '0');
			c = *s++;
		}
		else
			return -1;
	}

	if(c != '\0')
		return -1;

	if(field >= 75)
		return -1;

	ret += field * (44100 / 75);

	return ret;
}

static char *local__get_field_(char **s, FLAC__bool allow_quotes)
{
	FLAC__bool has_quote = false;
	char *p;

	FLAC__ASSERT(0 != s);

	if(0 == *s)
		return 0;

	/* skip leading whitespace */
	while(**s && 0 != strchr(" \t\r\n", **s))
		(*s)++;

	if(**s == 0) {
		*s = 0;
		return 0;
	}

	if(allow_quotes && (**s == '"')) {
		has_quote = true;
		(*s)++;
		if(**s == 0) {
			*s = 0;
			return 0;
		}
	}

	p = *s;

	if(has_quote) {
		*s = strchr(*s, '\"');
		/* if there is no matching end quote, it's an error */
		if(0 == *s)
			p = *s = 0;
		else {
			**s = '\0';
			(*s)++;
		}
	}
	else {
		while(**s && 0 == strchr(" \t\r\n", **s))
			(*s)++;
		if(**s) {
			**s = '\0';
			(*s)++;
		}
		else
			*s = 0;
	}

	return p;
}

static FLAC__bool local__cuesheet_parse_(FILE *file, const char **error_message, unsigned *last_line_read, FLAC__StreamMetadata *cuesheet, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset)
{
#if defined _MSC_VER || defined __MINGW32__
#define FLAC__STRCASECMP stricmp
#else
#define FLAC__STRCASECMP strcasecmp
#endif
	char buffer[4096], *line, *field;
	unsigned linelen, forced_leadout_track_num = 0;
	FLAC__uint64 forced_leadout_track_offset = 0;
	int in_track_num = -1, in_index_num = -1;
	FLAC__bool disc_has_catalog = false, track_has_flags = false, track_has_isrc = false, has_forced_leadout = false;
	FLAC__StreamMetadata_CueSheet *cs = &cuesheet->data.cue_sheet;

	cs->lead_in = is_cdda? 2 * 44100 /* The default lead-in size for CD-DA */ : 0;
	cs->is_cd = is_cdda;

	while(0 != fgets(buffer, sizeof(buffer), file)) {
		(*last_line_read)++;
		line = buffer;

		linelen = strlen(line);
		if(line[linelen-1] != '\n') {
			*error_message = "line too long";
			return false;
		}

		if(0 != (field = local__get_field_(&line, /*allow_quotes=*/false))) {
			if(0 == FLAC__STRCASECMP(field, "CATALOG")) {
				if(disc_has_catalog) {
					*error_message = "found multiple CATALOG commands";
					return false;
				}
				if(0 == (field = local__get_field_(&line, /*allow_quotes=*/true))) {
					*error_message = "CATALOG is missing catalog number";
					return false;
				}
				if(strlen(field) >= sizeof(cs->media_catalog_number)) {
					*error_message = "CATALOG number is too long";
					return false;
				}
				if(is_cdda && (strlen(field) != 13 || strspn(field, "0123456789") != 13)) {
					*error_message = "CD-DA CATALOG number must be 13 decimal digits";
					return false;
				}
				strcpy(cs->media_catalog_number, field);
				disc_has_catalog = true;
			}
			else if(0 == FLAC__STRCASECMP(field, "FLAGS")) {
				if(track_has_flags) {
					*error_message = "found multiple FLAGS commands";
					return false;
				}
				if(in_track_num < 0 || in_index_num >= 0) {
					*error_message = "FLAGS command must come after TRACK but before INDEX";
					return false;
				}
				while(0 != (field = local__get_field_(&line, /*allow_quotes=*/false))) {
					if(0 == FLAC__STRCASECMP(field, "PRE"))
						cs->tracks[cs->num_tracks-1].pre_emphasis = 1;
				}
				track_has_flags = true;
			}
			else if(0 == FLAC__STRCASECMP(field, "INDEX")) {
				FLAC__int64 xx;
				FLAC__StreamMetadata_CueSheet_Track *track = &cs->tracks[cs->num_tracks-1];
				if(in_track_num < 0) {
					*error_message = "found INDEX before any TRACK";
					return false;
				}
				if(0 == (field = local__get_field_(&line, /*allow_quotes=*/false))) {
					*error_message = "INDEX is missing index number";
					return false;
				}
				in_index_num = local__parse_int_(field);
				if(in_index_num < 0) {
					*error_message = "INDEX has invalid index number";
					return false;
				}
				FLAC__ASSERT(cs->num_tracks > 0);
				if(track->num_indices == 0) {
					/* it's the first index point of the track */
					if(in_index_num > 1) {
						*error_message = "first INDEX number of a TRACK must be 0 or 1";
						return false;
					}
				}
				else {
					if(in_index_num != track->indices[track->num_indices-1].number + 1) {
						*error_message = "INDEX numbers must be sequential";
						return false;
					}
				}
				if(is_cdda && in_index_num > 99) {
					*error_message = "CD-DA INDEX number must be between 0 and 99, inclusive";
					return false;
				}
				/*@@@ search for duplicate track number? */
				if(0 == (field = local__get_field_(&line, /*allow_quotes=*/false))) {
					*error_message = "INDEX is missing an offset after the index number";
					return false;

⌨️ 快捷键说明

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