mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-17 04:25:47 -04:00
dep: Add libcue
This commit is contained in:
414
dep/libcue/src/cd.c
Normal file
414
dep/libcue/src/cd.c
Normal file
@ -0,0 +1,414 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2005, 2006, 2007, Svend Sorensen
|
||||
* Copyright (c) 2009, 2010 Jochen Keil
|
||||
* For license terms, see the file COPYING in this distribution.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "cd.h"
|
||||
|
||||
typedef struct Data Data;
|
||||
struct Data {
|
||||
int type; /* DataType */
|
||||
char *name; /* data source name */
|
||||
long start; /* start time for data */
|
||||
long length; /* length of data */
|
||||
};
|
||||
|
||||
struct Track {
|
||||
Data zero_pre; /* pre-gap generated with zero data */
|
||||
Data file; /* track data file */
|
||||
Data zero_post; /* post-gap generated with zero data */
|
||||
int mode; /* track mode */
|
||||
int sub_mode; /* sub-channel mode */
|
||||
int flags; /* flags */
|
||||
char *isrc; /* IRSC Code (5.22.4) 12 bytes */
|
||||
Cdtext *cdtext; /* CD-TEXT */
|
||||
Rem* rem;
|
||||
long index[MAXINDEX+1]; /* indexes (in frames) (5.29.2.5)
|
||||
* relative to start of file */
|
||||
};
|
||||
|
||||
struct Cd {
|
||||
int mode; /* disc mode */
|
||||
char *catalog; /* Media Catalog Number (5.22.3) */
|
||||
char *cdtextfile; /* Filename of CDText File */
|
||||
Cdtext *cdtext; /* CD-TEXT */
|
||||
Rem* rem;
|
||||
int ntrack; /* number of tracks in album */
|
||||
Track *track[MAXTRACK]; /* array of tracks */
|
||||
};
|
||||
|
||||
Cd *cd_init(void)
|
||||
{
|
||||
Cd *cd = NULL;
|
||||
cd = malloc(sizeof(Cd));
|
||||
|
||||
if(NULL == cd) {
|
||||
fprintf(stderr, "unable to create cd\n");
|
||||
} else {
|
||||
cd->mode = MODE_CD_DA;
|
||||
cd->catalog = NULL;
|
||||
cd->cdtextfile = NULL;
|
||||
cd->cdtext = cdtext_init();
|
||||
cd->rem = rem_new();
|
||||
cd->ntrack = 0;
|
||||
}
|
||||
|
||||
return cd;
|
||||
}
|
||||
|
||||
void track_delete(struct Track* track)
|
||||
{
|
||||
if (track != NULL)
|
||||
{
|
||||
cdtext_delete(track_get_cdtext(track));
|
||||
|
||||
rem_free(track_get_rem(track));
|
||||
|
||||
free(track->isrc);
|
||||
|
||||
free(track->zero_pre.name);
|
||||
|
||||
free(track->zero_post.name);
|
||||
|
||||
free(track->file.name);
|
||||
|
||||
free(track);
|
||||
}
|
||||
}
|
||||
|
||||
void cd_delete(struct Cd* cd)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (cd != NULL)
|
||||
{
|
||||
free(cd->catalog);
|
||||
|
||||
free(cd->cdtextfile);
|
||||
|
||||
for (i = 0; i < cd->ntrack; i++)
|
||||
track_delete(cd->track[i]);
|
||||
|
||||
cdtext_delete(cd_get_cdtext(cd));
|
||||
|
||||
rem_free(cd_get_rem(cd));
|
||||
|
||||
free(cd);
|
||||
}
|
||||
}
|
||||
|
||||
Track *track_init(void)
|
||||
{
|
||||
Track *track = NULL;
|
||||
track = malloc(sizeof(Track));
|
||||
|
||||
if (NULL == track) {
|
||||
fprintf(stderr, "unable to create track\n");
|
||||
} else {
|
||||
track->zero_pre.type = DATA_ZERO;
|
||||
track->zero_pre.name = NULL;
|
||||
track->zero_pre.start = -1;
|
||||
track->zero_pre.length = -1;
|
||||
|
||||
track->file.type = DATA_AUDIO;
|
||||
track->file.name = NULL;
|
||||
track->file.start = -1;
|
||||
track->file.length = -1;
|
||||
|
||||
track->zero_post.type = DATA_ZERO;
|
||||
track->zero_post.name = NULL;
|
||||
track->zero_post.start = -1;
|
||||
track->zero_post.length = -1;
|
||||
|
||||
track->mode = MODE_AUDIO;
|
||||
track->sub_mode = SUB_MODE_RW;
|
||||
track->flags = FLAG_NONE;
|
||||
track->isrc = NULL;
|
||||
track->cdtext = cdtext_init();
|
||||
track->rem = rem_new();
|
||||
|
||||
int i;
|
||||
for (i=0; i<=MAXINDEX; i++)
|
||||
track->index[i] = -1;
|
||||
}
|
||||
|
||||
return track;
|
||||
}
|
||||
|
||||
/*
|
||||
* cd structure functions
|
||||
*/
|
||||
void cd_set_mode(Cd *cd, int mode)
|
||||
{
|
||||
cd->mode = mode;
|
||||
}
|
||||
|
||||
enum DiscMode cd_get_mode(const Cd *cd)
|
||||
{
|
||||
return cd->mode;
|
||||
}
|
||||
|
||||
void cd_set_catalog(Cd *cd, char *catalog)
|
||||
{
|
||||
if (cd->catalog)
|
||||
free(cd->catalog);
|
||||
|
||||
cd->catalog = strdup(catalog);
|
||||
}
|
||||
|
||||
void cd_set_cdtextfile(Cd *cd, char *cdtextfile)
|
||||
{
|
||||
if (cd->cdtextfile)
|
||||
free(cd->cdtextfile);
|
||||
|
||||
cd->cdtextfile = strdup(cdtextfile);
|
||||
}
|
||||
|
||||
const char *cd_get_cdtextfile(const Cd *cd)
|
||||
{
|
||||
return cd->cdtextfile;
|
||||
}
|
||||
|
||||
Cdtext *cd_get_cdtext(const Cd *cd)
|
||||
{
|
||||
if (cd != NULL)
|
||||
return cd->cdtext;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Rem*
|
||||
cd_get_rem(const Cd* cd)
|
||||
{
|
||||
if (cd != NULL)
|
||||
return cd->rem;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Track *cd_add_track(Cd *cd)
|
||||
{
|
||||
if (MAXTRACK > cd->ntrack)
|
||||
cd->ntrack++;
|
||||
else
|
||||
fprintf(stderr, "too many tracks\n");
|
||||
|
||||
/* this will reinit last track if there were too many */
|
||||
cd->track[cd->ntrack - 1] = track_init();
|
||||
|
||||
return cd->track[cd->ntrack - 1];
|
||||
}
|
||||
|
||||
int cd_get_ntrack(const Cd *cd)
|
||||
{
|
||||
return cd->ntrack;
|
||||
}
|
||||
|
||||
Track *cd_get_track(const Cd *cd, int i)
|
||||
{
|
||||
if ((0 < i) && (i <= cd->ntrack) && (cd != NULL))
|
||||
return cd->track[i - 1];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* track structure functions
|
||||
*/
|
||||
|
||||
void track_set_filename(Track *track, char *filename)
|
||||
{
|
||||
if (track->file.name)
|
||||
free(track->file.name);
|
||||
|
||||
track->file.name = strdup(filename);
|
||||
}
|
||||
|
||||
const char *track_get_filename(const Track *track)
|
||||
{
|
||||
return track->file.name;
|
||||
}
|
||||
|
||||
void track_set_start(Track *track, long start)
|
||||
{
|
||||
track->file.start = start;
|
||||
}
|
||||
|
||||
long track_get_start(const Track *track)
|
||||
{
|
||||
return track->file.start;
|
||||
}
|
||||
|
||||
void track_set_length(Track *track, long length)
|
||||
{
|
||||
track->file.length = length;
|
||||
}
|
||||
|
||||
long track_get_length(const Track *track)
|
||||
{
|
||||
return track->file.length;
|
||||
}
|
||||
|
||||
void track_set_mode(Track *track, int mode)
|
||||
{
|
||||
track->mode = mode;
|
||||
}
|
||||
|
||||
enum TrackMode track_get_mode(const Track *track)
|
||||
{
|
||||
return track->mode;
|
||||
}
|
||||
|
||||
void track_set_sub_mode(Track *track, int sub_mode)
|
||||
{
|
||||
track->sub_mode = sub_mode;
|
||||
}
|
||||
|
||||
enum TrackSubMode track_get_sub_mode(const Track *track)
|
||||
{
|
||||
return track->sub_mode;
|
||||
}
|
||||
|
||||
void track_set_flag(Track *track, int flag)
|
||||
{
|
||||
track->flags |= flag;
|
||||
}
|
||||
|
||||
void track_clear_flag(Track *track, int flag)
|
||||
{
|
||||
track->flags &= ~flag;
|
||||
}
|
||||
|
||||
int track_is_set_flag(const Track *track, enum TrackFlag flag)
|
||||
{
|
||||
return track->flags & flag;
|
||||
}
|
||||
|
||||
void track_set_zero_pre(Track *track, long length)
|
||||
{
|
||||
track->zero_pre.length = length;
|
||||
}
|
||||
|
||||
long track_get_zero_pre(const Track *track)
|
||||
{
|
||||
return track->zero_pre.length;
|
||||
}
|
||||
|
||||
void track_set_zero_post(Track *track, long length)
|
||||
{
|
||||
track->zero_post.length = length;
|
||||
}
|
||||
|
||||
long track_get_zero_post(const Track *track)
|
||||
{
|
||||
return track->zero_post.length;
|
||||
}
|
||||
void track_set_isrc(Track *track, char *isrc)
|
||||
{
|
||||
if (track->isrc)
|
||||
free(track->isrc);
|
||||
|
||||
track->isrc = strdup(isrc);
|
||||
}
|
||||
|
||||
const char *track_get_isrc(const Track *track)
|
||||
{
|
||||
return track->isrc;
|
||||
}
|
||||
|
||||
Cdtext *track_get_cdtext(const Track *track)
|
||||
{
|
||||
if (track != NULL)
|
||||
return track->cdtext;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Rem*
|
||||
track_get_rem(const Track* track)
|
||||
{
|
||||
if (track != NULL)
|
||||
return track->rem;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void track_set_index(Track *track, int i, long ind)
|
||||
{
|
||||
if (i > MAXINDEX) {
|
||||
fprintf(stderr, "too many indexes\n");
|
||||
return;
|
||||
}
|
||||
|
||||
track->index[i] = ind;
|
||||
}
|
||||
|
||||
long track_get_index(const Track *track, int i)
|
||||
{
|
||||
if ((0 <= i) && (i <= MAXINDEX))
|
||||
return track->index[i];
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* dump cd information
|
||||
*/
|
||||
static void cd_track_dump(Track *track)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("zero_pre: %ld\n", track->zero_pre.length);
|
||||
printf("filename: %s\n", track->file.name);
|
||||
printf("start: %ld\n", track->file.start);
|
||||
printf("length: %ld\n", track->file.length);
|
||||
printf("zero_post: %ld\n", track->zero_post.length);
|
||||
printf("mode: %d\n", track->mode);
|
||||
printf("sub_mode: %d\n", track->sub_mode);
|
||||
printf("flags: 0x%x\n", track->flags);
|
||||
printf("isrc: %s\n", track->isrc);
|
||||
|
||||
for (i = 0; i <= MAXINDEX; ++i)
|
||||
if (track->index[i] != -1)
|
||||
printf("index %d: %ld\n", i, track->index[i]);
|
||||
|
||||
if (NULL != track->cdtext) {
|
||||
printf("cdtext:\n");
|
||||
cdtext_dump(track->cdtext, 1);
|
||||
}
|
||||
|
||||
if (track->rem != NULL)
|
||||
{
|
||||
printf("rem:\n");
|
||||
rem_dump(track->rem);
|
||||
}
|
||||
}
|
||||
|
||||
void cd_dump(Cd *cd)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("Disc Info\n");
|
||||
printf("mode: %d\n", cd->mode);
|
||||
printf("catalog: %s\n", cd->catalog);
|
||||
printf("cdtextfile: %s\n", cd->cdtextfile);
|
||||
if (NULL != cd->cdtext) {
|
||||
printf("cdtext:\n");
|
||||
cdtext_dump(cd->cdtext, 0);
|
||||
}
|
||||
|
||||
if (cd->rem != NULL)
|
||||
{
|
||||
printf("rem:\n");
|
||||
rem_dump(cd->rem);
|
||||
}
|
||||
|
||||
for (i = 0; i < cd->ntrack; ++i) {
|
||||
printf("Track %d Info\n", i + 1);
|
||||
cd_track_dump(cd->track[i]);
|
||||
}
|
||||
}
|
167
dep/libcue/src/cdtext.c
Normal file
167
dep/libcue/src/cdtext.c
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2005, 2006, 2007, Svend Sorensen
|
||||
* Copyright (c) 2009, 2010 Jochen Keil
|
||||
* For license terms, see the file COPYING in this distribution.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "cdtext.h"
|
||||
|
||||
struct Cdtext {
|
||||
int pti;
|
||||
int format;
|
||||
char *value;
|
||||
};
|
||||
|
||||
Cdtext *cdtext_init(void)
|
||||
{
|
||||
Cdtext *new_cdtext = NULL;
|
||||
|
||||
Cdtext cdtext[] = {
|
||||
{PTI_TITLE, FORMAT_CHAR, NULL},
|
||||
{PTI_PERFORMER, FORMAT_CHAR, NULL},
|
||||
{PTI_SONGWRITER, FORMAT_CHAR, NULL},
|
||||
{PTI_COMPOSER, FORMAT_CHAR, NULL},
|
||||
{PTI_ARRANGER, FORMAT_CHAR, NULL},
|
||||
{PTI_MESSAGE, FORMAT_CHAR, NULL},
|
||||
{PTI_DISC_ID, FORMAT_BINARY, NULL},
|
||||
{PTI_GENRE, FORMAT_BINARY, NULL},
|
||||
{PTI_TOC_INFO1, FORMAT_BINARY, NULL},
|
||||
{PTI_TOC_INFO2, FORMAT_BINARY, NULL},
|
||||
{PTI_RESERVED1, FORMAT_CHAR, NULL},
|
||||
{PTI_RESERVED2, FORMAT_CHAR, NULL},
|
||||
{PTI_RESERVED3, FORMAT_CHAR, NULL},
|
||||
{PTI_RESERVED4, FORMAT_CHAR, NULL},
|
||||
{PTI_UPC_ISRC, FORMAT_CHAR, NULL},
|
||||
{PTI_SIZE_INFO, FORMAT_BINARY, NULL},
|
||||
{PTI_END, FORMAT_CHAR, NULL}
|
||||
};
|
||||
|
||||
new_cdtext = (Cdtext *) calloc (sizeof (cdtext) / sizeof (Cdtext), sizeof (Cdtext));
|
||||
if (NULL == new_cdtext)
|
||||
fprintf (stderr, "problem allocating memory\n");
|
||||
else
|
||||
memcpy (new_cdtext, cdtext, sizeof(cdtext));
|
||||
|
||||
return new_cdtext;
|
||||
}
|
||||
|
||||
void cdtext_delete(Cdtext *cdtext)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (NULL != cdtext) {
|
||||
for (i = 0; PTI_END != cdtext[i].pti; i++)
|
||||
{
|
||||
free (cdtext[i].value);
|
||||
}
|
||||
free (cdtext);
|
||||
}
|
||||
}
|
||||
|
||||
/* return 0 if there is no cdtext, returns non-zero otherwise */
|
||||
int cdtext_is_empty(Cdtext *cdtext)
|
||||
{
|
||||
for (; PTI_END != cdtext->pti; cdtext++)
|
||||
if (NULL != cdtext->value)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* sets cdtext's pti entry to field */
|
||||
void cdtext_set(int pti, char *value, Cdtext *cdtext)
|
||||
{
|
||||
if (NULL != value) /* don't pass NULL to strdup */
|
||||
for (; PTI_END != cdtext->pti; cdtext++)
|
||||
if (pti == cdtext->pti) {
|
||||
free (cdtext->value);
|
||||
cdtext->value = strdup (value);
|
||||
}
|
||||
}
|
||||
|
||||
/* returns value for pti, NULL if pti is not found */
|
||||
const char *cdtext_get(enum Pti pti, const Cdtext *cdtext)
|
||||
{
|
||||
for (; PTI_END != cdtext->pti; cdtext++)
|
||||
if (pti == cdtext->pti)
|
||||
return cdtext->value;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *cdtext_get_key(int pti, int istrack)
|
||||
{
|
||||
const char *key = NULL;
|
||||
|
||||
switch (pti) {
|
||||
case PTI_TITLE:
|
||||
key = "TITLE";
|
||||
break;
|
||||
case PTI_PERFORMER:
|
||||
key = "PERFORMER";
|
||||
break;
|
||||
case PTI_SONGWRITER:
|
||||
key = "SONGWRITER";
|
||||
break;
|
||||
case PTI_COMPOSER:
|
||||
key = "COMPOSER";
|
||||
break;
|
||||
case PTI_ARRANGER:
|
||||
key = "ARRANGER";
|
||||
break;
|
||||
case PTI_MESSAGE:
|
||||
key = "MESSAGE";
|
||||
break;
|
||||
case PTI_DISC_ID:
|
||||
key = "DISC_ID";
|
||||
break;
|
||||
case PTI_GENRE:
|
||||
key = "GENRE";
|
||||
break;
|
||||
case PTI_TOC_INFO1:
|
||||
key = "TOC_INFO1";
|
||||
break;
|
||||
case PTI_TOC_INFO2:
|
||||
key = "TOC_INFO1";
|
||||
break;
|
||||
case PTI_RESERVED1:
|
||||
/* reserved */
|
||||
break;
|
||||
case PTI_RESERVED2:
|
||||
/* reserved */
|
||||
break;
|
||||
case PTI_RESERVED3:
|
||||
/* reserved */
|
||||
break;
|
||||
case PTI_RESERVED4:
|
||||
/* reserved */
|
||||
break;
|
||||
case PTI_UPC_ISRC:
|
||||
if (0 == istrack)
|
||||
key = "UPC_EAN";
|
||||
else
|
||||
key = "ISRC";
|
||||
break;
|
||||
case PTI_SIZE_INFO:
|
||||
key = "SIZE_INFO";
|
||||
break;
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
void cdtext_dump(Cdtext *cdtext, int istrack)
|
||||
{
|
||||
int pti;
|
||||
const char *value = NULL;
|
||||
|
||||
for (pti = 0; PTI_END != pti; pti++) {
|
||||
if (NULL != (value = cdtext_get(pti, cdtext))) {
|
||||
printf("%s: ", cdtext_get_key(pti, istrack));
|
||||
printf("%s\n", value);
|
||||
}
|
||||
}
|
||||
}
|
1842
dep/libcue/src/cue_parser.c
Normal file
1842
dep/libcue/src/cue_parser.c
Normal file
File diff suppressed because it is too large
Load Diff
126
dep/libcue/src/cue_parser.h
Normal file
126
dep/libcue/src/cue_parser.h
Normal file
@ -0,0 +1,126 @@
|
||||
/* A Bison parser, made by GNU Bison 3.3.2. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
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 3 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, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
/* Undocumented macros, especially those whose name start with YY_,
|
||||
are private implementation details. Do not rely on them. */
|
||||
|
||||
#ifndef YY_YY_CUE_PARSER_H_INCLUDED
|
||||
# define YY_YY_CUE_PARSER_H_INCLUDED
|
||||
/* Debug traces. */
|
||||
#ifndef YYDEBUG
|
||||
# define YYDEBUG 0
|
||||
#endif
|
||||
#if YYDEBUG
|
||||
extern int yydebug;
|
||||
#endif
|
||||
|
||||
/* Token type. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
enum yytokentype
|
||||
{
|
||||
NUMBER = 258,
|
||||
STRING = 259,
|
||||
CATALOG = 260,
|
||||
CDTEXTFILE = 261,
|
||||
FFILE = 262,
|
||||
BINARY = 263,
|
||||
MOTOROLA = 264,
|
||||
AIFF = 265,
|
||||
WAVE = 266,
|
||||
MP3 = 267,
|
||||
FLAC = 268,
|
||||
TRACK = 269,
|
||||
AUDIO = 270,
|
||||
MODE1_2048 = 271,
|
||||
MODE1_2352 = 272,
|
||||
MODE2_2336 = 273,
|
||||
MODE2_2048 = 274,
|
||||
MODE2_2342 = 275,
|
||||
MODE2_2332 = 276,
|
||||
MODE2_2352 = 277,
|
||||
TRACK_ISRC = 278,
|
||||
FLAGS = 279,
|
||||
PRE = 280,
|
||||
DCP = 281,
|
||||
FOUR_CH = 282,
|
||||
SCMS = 283,
|
||||
PREGAP = 284,
|
||||
INDEX = 285,
|
||||
POSTGAP = 286,
|
||||
TITLE = 287,
|
||||
PERFORMER = 288,
|
||||
SONGWRITER = 289,
|
||||
COMPOSER = 290,
|
||||
ARRANGER = 291,
|
||||
MESSAGE = 292,
|
||||
DISC_ID = 293,
|
||||
GENRE = 294,
|
||||
TOC_INFO1 = 295,
|
||||
TOC_INFO2 = 296,
|
||||
UPC_EAN = 297,
|
||||
ISRC = 298,
|
||||
SIZE_INFO = 299,
|
||||
DATE = 300,
|
||||
XXX_GENRE = 301,
|
||||
REPLAYGAIN_ALBUM_GAIN = 302,
|
||||
REPLAYGAIN_ALBUM_PEAK = 303,
|
||||
REPLAYGAIN_TRACK_GAIN = 304,
|
||||
REPLAYGAIN_TRACK_PEAK = 305
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Value type. */
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
|
||||
union YYSTYPE
|
||||
{
|
||||
#line 57 "cue_parser.y" /* yacc.c:1921 */
|
||||
|
||||
long ival;
|
||||
char *sval;
|
||||
|
||||
#line 114 "cue_parser.h" /* yacc.c:1921 */
|
||||
};
|
||||
|
||||
typedef union YYSTYPE YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
#endif
|
||||
|
||||
|
||||
extern YYSTYPE yylval;
|
||||
|
||||
int yyparse (void);
|
||||
|
||||
#endif /* !YY_YY_CUE_PARSER_H_INCLUDED */
|
374
dep/libcue/src/cue_parser.y
Normal file
374
dep/libcue/src/cue_parser.y
Normal file
@ -0,0 +1,374 @@
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 2004, 2005, 2006, 2007, Svend Sorensen
|
||||
* Copyright (c) 2009, 2010 Jochen Keil
|
||||
* For license terms, see the file COPYING in this distribution.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cd.h"
|
||||
#include "time.h"
|
||||
|
||||
#ifdef YY_BUF_SIZE
|
||||
#undef YY_BUF_SIZE
|
||||
#endif
|
||||
#define YY_BUF_SIZE 16384
|
||||
|
||||
#define YYDEBUG 1
|
||||
|
||||
char fnamebuf[PARSER_BUFFER];
|
||||
|
||||
/* debugging */
|
||||
//int yydebug = 1;
|
||||
|
||||
extern int yylineno;
|
||||
extern FILE* yyin;
|
||||
|
||||
static Cd *cd = NULL;
|
||||
static Track *track = NULL;
|
||||
static Track *prev_track = NULL;
|
||||
static Cdtext *cdtext = NULL;
|
||||
static Rem *rem = NULL;
|
||||
static char *prev_filename = NULL; /* last file in or before last track */
|
||||
static char *cur_filename = NULL; /* last file in the last track */
|
||||
static char *new_filename = NULL; /* last file in this track */
|
||||
|
||||
/* lexer interface */
|
||||
typedef struct yy_buffer_state* YY_BUFFER_STATE;
|
||||
|
||||
int yylex(void);
|
||||
void yyerror(const char*);
|
||||
YY_BUFFER_STATE yy_scan_string(const char*);
|
||||
YY_BUFFER_STATE yy_create_buffer(FILE*, int);
|
||||
void yy_switch_to_buffer(YY_BUFFER_STATE);
|
||||
void yy_delete_buffer(YY_BUFFER_STATE);
|
||||
|
||||
/* parser interface */
|
||||
int yyparse(void);
|
||||
Cd *cue_parse_file(FILE *fp);
|
||||
Cd *cue_parse_string(const char*);
|
||||
%}
|
||||
|
||||
%start cuefile
|
||||
|
||||
%union {
|
||||
long ival;
|
||||
char *sval;
|
||||
}
|
||||
|
||||
%token <ival> NUMBER
|
||||
%token <sval> STRING
|
||||
|
||||
/* global (header) */
|
||||
%token CATALOG
|
||||
%token CDTEXTFILE
|
||||
|
||||
%token FFILE
|
||||
%token BINARY
|
||||
%token MOTOROLA
|
||||
%token AIFF
|
||||
%token WAVE
|
||||
%token MP3
|
||||
%token FLAC
|
||||
|
||||
/* track */
|
||||
%token TRACK
|
||||
|
||||
%token <ival> AUDIO
|
||||
%token <ival> MODE1_2048
|
||||
%token <ival> MODE1_2352
|
||||
%token <ival> MODE2_2336
|
||||
%token <ival> MODE2_2048
|
||||
%token <ival> MODE2_2342
|
||||
%token <ival> MODE2_2332
|
||||
%token <ival> MODE2_2352
|
||||
|
||||
/* ISRC is with CD_TEXT */
|
||||
%token TRACK_ISRC
|
||||
|
||||
%token FLAGS
|
||||
%token <ival> PRE
|
||||
%token <ival> DCP
|
||||
%token <ival> FOUR_CH
|
||||
%token <ival> SCMS
|
||||
|
||||
%token PREGAP
|
||||
%token INDEX
|
||||
%token POSTGAP
|
||||
|
||||
/* CD-TEXT */
|
||||
%token <ival> TITLE
|
||||
%token <ival> PERFORMER
|
||||
%token <ival> SONGWRITER
|
||||
%token <ival> COMPOSER
|
||||
%token <ival> ARRANGER
|
||||
%token <ival> MESSAGE
|
||||
%token <ival> DISC_ID
|
||||
%token <ival> GENRE
|
||||
%token <ival> TOC_INFO1
|
||||
%token <ival> TOC_INFO2
|
||||
%token <ival> UPC_EAN
|
||||
%token <ival> ISRC
|
||||
%token <ival> SIZE_INFO
|
||||
|
||||
%type <ival> track_mode
|
||||
%type <ival> track_flag
|
||||
%type <ival> time
|
||||
%type <ival> cdtext_item
|
||||
|
||||
/* REM */
|
||||
%type <ival> rem_item
|
||||
%token <ival> DATE
|
||||
%token <ival> XXX_GENRE /* parsed in REM but stored in CD-TEXT */
|
||||
%token <ival> REPLAYGAIN_ALBUM_GAIN
|
||||
%token <ival> REPLAYGAIN_ALBUM_PEAK
|
||||
%token <ival> REPLAYGAIN_TRACK_GAIN
|
||||
%token <ival> REPLAYGAIN_TRACK_PEAK
|
||||
%%
|
||||
|
||||
cuefile
|
||||
: new_cd global_statements track_list
|
||||
;
|
||||
|
||||
new_cd
|
||||
: /* empty */ {
|
||||
cd = cd_init();
|
||||
cdtext = cd_get_cdtext(cd);
|
||||
rem = cd_get_rem(cd);
|
||||
}
|
||||
;
|
||||
|
||||
global_statements
|
||||
: /* empty */
|
||||
| global_statements global_statement
|
||||
;
|
||||
|
||||
global_statement
|
||||
: CATALOG STRING '\n' { cd_set_catalog(cd, $2); }
|
||||
| CDTEXTFILE STRING '\n' { cd_set_cdtextfile(cd, $2); }
|
||||
| cdtext
|
||||
| rem
|
||||
| track_data
|
||||
| error '\n'
|
||||
;
|
||||
|
||||
track_data
|
||||
: FFILE STRING file_format '\n' {
|
||||
if (NULL != new_filename) {
|
||||
yyerror("too many files specified\n");
|
||||
}
|
||||
if (track && track_get_index(track, 1) == -1) {
|
||||
track_set_filename (track, $2);
|
||||
} else {
|
||||
new_filename = strncpy(fnamebuf, $2, sizeof(fnamebuf));
|
||||
new_filename[sizeof(fnamebuf) - 1] = '\0';
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
track_list
|
||||
: track
|
||||
| track_list track
|
||||
;
|
||||
|
||||
track
|
||||
: new_track track_def track_statements
|
||||
;
|
||||
|
||||
file_format
|
||||
: BINARY
|
||||
| MOTOROLA
|
||||
| AIFF
|
||||
| WAVE
|
||||
| MP3
|
||||
| FLAC
|
||||
;
|
||||
|
||||
new_track
|
||||
: /*empty */ {
|
||||
/* save previous track, to later set length */
|
||||
prev_track = track;
|
||||
|
||||
track = cd_add_track(cd);
|
||||
cdtext = track_get_cdtext(track);
|
||||
rem = track_get_rem(track);
|
||||
|
||||
cur_filename = new_filename;
|
||||
if (NULL != cur_filename)
|
||||
prev_filename = cur_filename;
|
||||
|
||||
if (NULL == prev_filename)
|
||||
yyerror("no file specified for track");
|
||||
else
|
||||
track_set_filename(track, prev_filename);
|
||||
|
||||
new_filename = NULL;
|
||||
}
|
||||
;
|
||||
|
||||
track_def
|
||||
: TRACK NUMBER track_mode '\n' {
|
||||
track_set_mode(track, $3);
|
||||
}
|
||||
;
|
||||
|
||||
track_mode
|
||||
: AUDIO
|
||||
| MODE1_2048
|
||||
| MODE1_2352
|
||||
| MODE2_2336
|
||||
| MODE2_2048
|
||||
| MODE2_2342
|
||||
| MODE2_2332
|
||||
| MODE2_2352
|
||||
;
|
||||
|
||||
track_statements
|
||||
: track_statement
|
||||
| track_statements track_statement
|
||||
;
|
||||
|
||||
track_statement
|
||||
: cdtext
|
||||
| rem
|
||||
| FLAGS track_flags '\n'
|
||||
| TRACK_ISRC STRING '\n' { track_set_isrc(track, $2); }
|
||||
| PREGAP time '\n' { track_set_zero_pre(track, $2); }
|
||||
| INDEX NUMBER time '\n' {
|
||||
long prev_length;
|
||||
|
||||
/* Set previous track length if it has not been set */
|
||||
if (NULL != prev_track && NULL == cur_filename
|
||||
&& track_get_length (prev_track) == -1) {
|
||||
/* track shares file with previous track */
|
||||
prev_length = $3 - track_get_start(prev_track);
|
||||
track_set_length(prev_track, prev_length);
|
||||
}
|
||||
|
||||
if (1 == $2) {
|
||||
/* INDEX 01 */
|
||||
track_set_start(track, $3);
|
||||
|
||||
long idx00 = track_get_index (track, 0);
|
||||
|
||||
if (idx00 != -1 && $3 != 0)
|
||||
track_set_zero_pre (track, $3 - idx00);
|
||||
}
|
||||
|
||||
track_set_index (track, $2, $3);
|
||||
}
|
||||
| POSTGAP time '\n' { track_set_zero_post(track, $2); }
|
||||
| track_data
|
||||
| error '\n'
|
||||
;
|
||||
|
||||
track_flags
|
||||
: /* empty */
|
||||
| track_flags track_flag { track_set_flag(track, $2); }
|
||||
;
|
||||
|
||||
track_flag
|
||||
: PRE
|
||||
| DCP
|
||||
| FOUR_CH
|
||||
| SCMS
|
||||
;
|
||||
|
||||
cdtext
|
||||
: cdtext_item STRING '\n' { cdtext_set ($1, $2, cdtext); }
|
||||
;
|
||||
|
||||
cdtext_item
|
||||
: TITLE
|
||||
| PERFORMER
|
||||
| SONGWRITER
|
||||
| COMPOSER
|
||||
| ARRANGER
|
||||
| MESSAGE
|
||||
| DISC_ID
|
||||
| GENRE
|
||||
| TOC_INFO1
|
||||
| TOC_INFO2
|
||||
| UPC_EAN
|
||||
| ISRC
|
||||
| SIZE_INFO
|
||||
;
|
||||
|
||||
time
|
||||
: NUMBER
|
||||
| NUMBER ':' NUMBER ':' NUMBER { $$ = time_msf_to_frame($1, $3, $5); }
|
||||
;
|
||||
|
||||
rem
|
||||
: rem_item STRING '\n' { rem_set($1, $2, rem); }
|
||||
| XXX_GENRE STRING '\n' { cdtext_set($1, $2, cdtext); }
|
||||
;
|
||||
|
||||
rem_item
|
||||
: DATE
|
||||
| REPLAYGAIN_ALBUM_GAIN
|
||||
| REPLAYGAIN_ALBUM_PEAK
|
||||
| REPLAYGAIN_TRACK_GAIN
|
||||
| REPLAYGAIN_TRACK_PEAK
|
||||
;
|
||||
%%
|
||||
|
||||
/* lexer interface */
|
||||
|
||||
void yyerror (const char *s)
|
||||
{
|
||||
fprintf(stderr, "%d: %s\n", yylineno, s);
|
||||
}
|
||||
|
||||
static void reset_static_vars()
|
||||
{
|
||||
cd = NULL;
|
||||
track = NULL;
|
||||
prev_track = NULL;
|
||||
cdtext = NULL;
|
||||
rem = NULL;
|
||||
prev_filename = NULL;
|
||||
cur_filename = NULL;
|
||||
new_filename = NULL;
|
||||
}
|
||||
|
||||
Cd *cue_parse_file(FILE *fp)
|
||||
{
|
||||
YY_BUFFER_STATE buffer = NULL;
|
||||
|
||||
yyin = fp;
|
||||
|
||||
buffer = yy_create_buffer(yyin, YY_BUF_SIZE);
|
||||
|
||||
yy_switch_to_buffer(buffer);
|
||||
|
||||
Cd *ret_cd = NULL;
|
||||
|
||||
if (0 == yyparse()) ret_cd = cd;
|
||||
else ret_cd = NULL;
|
||||
|
||||
yy_delete_buffer(buffer);
|
||||
reset_static_vars();
|
||||
|
||||
return ret_cd;
|
||||
}
|
||||
|
||||
Cd *cue_parse_string(const char* string)
|
||||
{
|
||||
YY_BUFFER_STATE buffer = NULL;
|
||||
|
||||
buffer = yy_scan_string(string);
|
||||
|
||||
Cd *ret_cd = NULL;
|
||||
|
||||
if (0 == yyparse()) ret_cd = cd;
|
||||
else ret_cd = NULL;
|
||||
|
||||
yy_delete_buffer(buffer);
|
||||
reset_static_vars();
|
||||
|
||||
return ret_cd;
|
||||
}
|
2413
dep/libcue/src/cue_scanner.c
Normal file
2413
dep/libcue/src/cue_scanner.c
Normal file
File diff suppressed because it is too large
Load Diff
139
dep/libcue/src/cue_scanner.l
Normal file
139
dep/libcue/src/cue_scanner.l
Normal file
@ -0,0 +1,139 @@
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 2004, 2005, 2006, 2007, Svend Sorensen
|
||||
* Copyright (c) 2009, 2010 Jochen Keil
|
||||
* For license terms, see the file COPYING in this distribution.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cd.h"
|
||||
#include "cue_parser.h"
|
||||
|
||||
char yy_buffer[PARSER_BUFFER];
|
||||
|
||||
int yylex(void);
|
||||
%}
|
||||
|
||||
ws [ \t\r]
|
||||
nonws [^ \t\r\n]
|
||||
|
||||
%option yylineno
|
||||
%option noyywrap
|
||||
%option noinput
|
||||
%option nounput
|
||||
|
||||
%s NAME
|
||||
%x REM
|
||||
%x RPG
|
||||
%x SKIP
|
||||
|
||||
%%
|
||||
|
||||
\'([^\']|\\\')*\' |
|
||||
\"([^\"]|\\\")*\" {
|
||||
yylval.sval = strncpy( yy_buffer,
|
||||
++yytext,
|
||||
(yyleng > sizeof(yy_buffer) ? sizeof(yy_buffer) : yyleng));
|
||||
yylval.sval[(yyleng > sizeof(yy_buffer) ? sizeof(yy_buffer) : yyleng) - 2] = '\0';
|
||||
BEGIN(INITIAL);
|
||||
return STRING;
|
||||
}
|
||||
|
||||
<NAME>{nonws}+ {
|
||||
yylval.sval = strncpy( yy_buffer,
|
||||
yytext,
|
||||
(yyleng > sizeof(yy_buffer) ? sizeof(yy_buffer) : yyleng));
|
||||
yylval.sval[(yyleng > sizeof(yy_buffer) ? sizeof(yy_buffer) : yyleng)] = '\0';
|
||||
BEGIN(INITIAL);
|
||||
return STRING;
|
||||
}
|
||||
|
||||
CATALOG { BEGIN(NAME); return CATALOG; }
|
||||
CDTEXTFILE { BEGIN(NAME); return CDTEXTFILE; }
|
||||
|
||||
FILE { BEGIN(NAME); return FFILE; }
|
||||
BINARY { return BINARY; }
|
||||
MOTOROLA { return MOTOROLA; }
|
||||
AIFF { return AIFF; }
|
||||
WAVE { return WAVE; }
|
||||
MP3 { return MP3; }
|
||||
FLAC { return FLAC; }
|
||||
|
||||
TRACK { return TRACK; }
|
||||
AUDIO { yylval.ival = MODE_AUDIO; return AUDIO; }
|
||||
MODE1\/2048 { yylval.ival = MODE_MODE1; return MODE1_2048; }
|
||||
MODE1\/2352 { yylval.ival = MODE_MODE1_RAW; return MODE1_2352; }
|
||||
MODE2\/2336 { yylval.ival = MODE_MODE2; return MODE2_2336; }
|
||||
MODE2\/2048 { yylval.ival = MODE_MODE2_FORM1; return MODE2_2048; }
|
||||
MODE2\/2342 { yylval.ival = MODE_MODE2_FORM2; return MODE2_2342; }
|
||||
MODE2\/2332 { yylval.ival = MODE_MODE2_FORM_MIX; return MODE2_2332; }
|
||||
MODE2\/2352 { yylval.ival = MODE_MODE2_RAW; return MODE2_2352; }
|
||||
|
||||
FLAGS { return FLAGS; }
|
||||
PRE { yylval.ival = FLAG_PRE_EMPHASIS; return PRE; }
|
||||
DCP { yylval.ival = FLAG_COPY_PERMITTED; return DCP; }
|
||||
4CH { yylval.ival = FLAG_FOUR_CHANNEL; return FOUR_CH; }
|
||||
SCMS { yylval.ival = FLAG_SCMS; return SCMS; }
|
||||
|
||||
PREGAP { return PREGAP; }
|
||||
INDEX { return INDEX; }
|
||||
POSTGAP { return POSTGAP; }
|
||||
|
||||
TITLE { BEGIN(NAME); yylval.ival = PTI_TITLE; return TITLE; }
|
||||
PERFORMER { BEGIN(NAME); yylval.ival = PTI_PERFORMER; return PERFORMER; }
|
||||
SONGWRITER { BEGIN(NAME); yylval.ival = PTI_SONGWRITER; return SONGWRITER; }
|
||||
COMPOSER { BEGIN(NAME); yylval.ival = PTI_COMPOSER; return COMPOSER; }
|
||||
ARRANGER { BEGIN(NAME); yylval.ival = PTI_ARRANGER; return ARRANGER; }
|
||||
MESSAGE { BEGIN(NAME); yylval.ival = PTI_MESSAGE; return MESSAGE; }
|
||||
DISC_ID { BEGIN(NAME); yylval.ival = PTI_DISC_ID; return DISC_ID; }
|
||||
GENRE { BEGIN(NAME); yylval.ival = PTI_GENRE; return GENRE; }
|
||||
TOC_INFO1 { BEGIN(NAME); yylval.ival = PTI_TOC_INFO1; return TOC_INFO1; }
|
||||
TOC_INFO2 { BEGIN(NAME); yylval.ival = PTI_TOC_INFO2; return TOC_INFO2; }
|
||||
UPC_EAN { BEGIN(NAME); yylval.ival = PTI_UPC_ISRC; return UPC_EAN; }
|
||||
ISRC/{ws}+\" { BEGIN(NAME); yylval.ival = PTI_UPC_ISRC; return ISRC; }
|
||||
SIZE_INFO { BEGIN(NAME); yylval.ival = PTI_SIZE_INFO; return SIZE_INFO; }
|
||||
|
||||
ISRC { BEGIN(NAME); return TRACK_ISRC; }
|
||||
|
||||
REM { BEGIN(REM); /* exclusive rules for special exceptions */ }
|
||||
|
||||
<REM>DATE { BEGIN(NAME); yylval.ival = REM_DATE; return DATE; }
|
||||
<REM>GENRE { BEGIN(NAME); yylval.ival = PTI_GENRE; return XXX_GENRE; }
|
||||
<REM>REPLAYGAIN_ALBUM_GAIN { BEGIN(RPG); yylval.ival = REM_REPLAYGAIN_ALBUM_GAIN;
|
||||
return REPLAYGAIN_ALBUM_GAIN; }
|
||||
<REM>REPLAYGAIN_ALBUM_PEAK { BEGIN(RPG); yylval.ival = REM_REPLAYGAIN_ALBUM_PEAK;
|
||||
return REPLAYGAIN_ALBUM_PEAK; }
|
||||
<REM>REPLAYGAIN_TRACK_GAIN { BEGIN(RPG); yylval.ival = REM_REPLAYGAIN_TRACK_GAIN;
|
||||
return REPLAYGAIN_TRACK_GAIN; }
|
||||
<REM>REPLAYGAIN_TRACK_PEAK { BEGIN(RPG); yylval.ival = REM_REPLAYGAIN_TRACK_PEAK;
|
||||
return REPLAYGAIN_TRACK_PEAK; }
|
||||
|
||||
<REM>{ws}+ { BEGIN(REM); }
|
||||
<REM>. { BEGIN(REM); }
|
||||
<REM>\n { BEGIN(INITIAL); }
|
||||
|
||||
<RPG>{nonws}+ {
|
||||
yylval.sval = strncpy( yy_buffer,
|
||||
yytext,
|
||||
(yyleng > sizeof(yy_buffer) ? sizeof(yy_buffer) : yyleng));
|
||||
yylval.sval[(yyleng > sizeof(yy_buffer) ? sizeof(yy_buffer) : yyleng)] = '\0';
|
||||
BEGIN(SKIP);
|
||||
return STRING;
|
||||
}
|
||||
|
||||
<RPG>{ws}+ { BEGIN(RPG); }
|
||||
|
||||
<SKIP>.*\n { BEGIN(INITIAL); yylineno++; return '\n'; }
|
||||
|
||||
{ws}+ { /* ignore whitespace */ }
|
||||
|
||||
[[:digit:]]+ { yylval.ival = atoi(yytext); return NUMBER; }
|
||||
: { return yytext[0]; }
|
||||
|
||||
^{ws}*\n { yylineno++; /* blank line */ }
|
||||
\n { yylineno++; return '\n'; }
|
||||
. { fprintf(stderr, "bad character '%c'\n", yytext[0]); }
|
||||
|
||||
%%
|
140
dep/libcue/src/rem.c
Normal file
140
dep/libcue/src/rem.c
Normal file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Jochen Keil
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY Jochen Keil ''AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL Jochen Keil BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "rem.h"
|
||||
|
||||
struct Rem {
|
||||
unsigned int cmt;
|
||||
char *value;
|
||||
};
|
||||
|
||||
Rem*
|
||||
rem_new( void)
|
||||
{
|
||||
Rem* new_rem = NULL;
|
||||
|
||||
Rem rem[] = {
|
||||
{REM_DATE, NULL},
|
||||
{REM_REPLAYGAIN_ALBUM_GAIN, NULL},
|
||||
{REM_REPLAYGAIN_ALBUM_PEAK, NULL},
|
||||
{REM_REPLAYGAIN_TRACK_GAIN, NULL},
|
||||
{REM_REPLAYGAIN_TRACK_PEAK, NULL},
|
||||
{REM_END, NULL}
|
||||
};
|
||||
|
||||
/* sizeof(rem) = number of elements in rem[] * sizeof(Rem) */
|
||||
new_rem = (Rem*)calloc(sizeof(rem) / sizeof(Rem), sizeof(Rem));
|
||||
if (new_rem == NULL)
|
||||
fprintf(stderr, "rem_new(): problem allocating memory\n");
|
||||
else
|
||||
memcpy(new_rem, rem, sizeof(rem));
|
||||
|
||||
return new_rem;
|
||||
}
|
||||
|
||||
void
|
||||
rem_free( Rem* rem)
|
||||
{
|
||||
if (rem == NULL)
|
||||
return;
|
||||
|
||||
Rem* ptr = rem;
|
||||
|
||||
do
|
||||
{
|
||||
free(ptr->value);
|
||||
}
|
||||
while ((++ptr)->cmt != REM_END);
|
||||
|
||||
free(rem);
|
||||
}
|
||||
|
||||
int
|
||||
rem_is_emtpy( Rem* rem)
|
||||
{
|
||||
if (rem == NULL)
|
||||
return 1;
|
||||
|
||||
do
|
||||
{
|
||||
if (rem->value != NULL)
|
||||
return 0;
|
||||
} while ((++rem)->cmt != REM_END);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
rem_set( unsigned int cmt,
|
||||
char* value,
|
||||
Rem* rem)
|
||||
{
|
||||
if (rem == NULL || value == NULL)
|
||||
return;
|
||||
|
||||
do
|
||||
{
|
||||
if (rem->cmt == cmt)
|
||||
{
|
||||
free(rem->value);
|
||||
rem->value = strdup(value);
|
||||
return;
|
||||
}
|
||||
} while ((++rem)->cmt != REM_END);
|
||||
}
|
||||
|
||||
const char*
|
||||
rem_get( RemType cmt,
|
||||
Rem* rem)
|
||||
{
|
||||
if (rem == NULL)
|
||||
return NULL;
|
||||
|
||||
do
|
||||
{
|
||||
if (rem->cmt == cmt)
|
||||
{
|
||||
if (rem->value != NULL)
|
||||
return rem->value;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
} while ((++rem)->cmt != REM_END);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
rem_dump( Rem* rem)
|
||||
{
|
||||
if (rem == NULL)
|
||||
return;
|
||||
|
||||
do
|
||||
{
|
||||
printf("REM %u: %s\n", rem->cmt, rem->value);
|
||||
} while ((++rem)->cmt != REM_END);
|
||||
}
|
36
dep/libcue/src/time.c
Normal file
36
dep/libcue/src/time.c
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* time.c -- time functions
|
||||
*
|
||||
* Copyright (C) 2004, 2005, 2006, 2007 Svend Sorensen
|
||||
* For license terms, see the file COPYING in this distribution.
|
||||
*/
|
||||
|
||||
#include "time.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
long time_msf_to_frame(int m, int s, int f)
|
||||
{
|
||||
return (m * 60 + s) * 75 + f;
|
||||
}
|
||||
|
||||
void time_frame_to_msf(long frame, int *m, int *s, int *f)
|
||||
{
|
||||
*f = frame % 75; /* 0 <= frames <= 74 */
|
||||
frame /= 75;
|
||||
*s = frame % 60; /* 0 <= seconds <= 59 */
|
||||
frame /= 60;
|
||||
*m = frame; /* 0 <= minutes */
|
||||
}
|
||||
|
||||
/* print frame in mm:ss:ff format */
|
||||
char *time_frame_to_mmssff(long f)
|
||||
{
|
||||
static char msf[9];
|
||||
int minutes, seconds, frames;
|
||||
|
||||
time_frame_to_msf(f, &minutes, &seconds, &frames);
|
||||
sprintf(msf, "%02d:%02d:%02d", minutes, seconds, frames);
|
||||
|
||||
return msf;
|
||||
}
|
Reference in New Issue
Block a user