www.pudn.com > EXT.rar > id3tag.c
/*
* madplay - MPEG audio decoder and player
* Copyright (C) 2000-2003 Robert Leslie
*
* 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
*
* $Id: id3tag.c,v 1.7 2003/06/05 03:56:04 rob Exp $
*/
# include "config.h"
#include "myhead.h"
# include "global.h"
# include "id3tag.h"
# include "gettext.h"
static void show_id3(struct id3_tag const *tag)
{
unsigned int i;
struct id3_frame const *frame;
id3_ucs4_t const *ucs4;
id3_latin1_t *latin1;
char const spaces[] = " ";
static struct {
char const *id;
char const *name;
} const info[] = {
{ ID3_FRAME_TITLE, N_("Title") },
{ "TIT3", 0 }, /* Subtitle */
{ "TCOP", 0 }, /* Copyright */
{ "TPRO", 0 }, /* Produced */
{ "TCOM", N_("Composer") },
{ ID3_FRAME_ARTIST, N_("Artist") },
{ "TPE2", N_("Orchestra") },
{ "TPE3", N_("Conductor") },
{ "TEXT", N_("Lyricist") },
{ ID3_FRAME_ALBUM, N_("Album") },
{ ID3_FRAME_TRACK, N_("Track") },
{ ID3_FRAME_YEAR, N_("Year") },
{ "TPUB", N_("Publisher") },
{ ID3_FRAME_GENRE, N_("Genre") },
{ "TRSN", N_("Station") },
{ "TENC", N_("Encoder") }
};
/* text information */
for (i = 0; i < sizeof(info) / sizeof(info[0]); ++i) {
union id3_field const *field;
unsigned int nstrings, namelen, j;
char const *name;
frame = id3_tag_findframe(tag, info[i].id, 0);
if (frame == 0)
continue;
field = id3_frame_field(frame, 1);
nstrings = id3_field_getnstrings(field);
name = info[i].name;
if (name)
name = gettext(name);
namelen = name ? strlen(name) : 0;
assert(namelen < sizeof(spaces));
for (j = 0; j < nstrings; ++j) {
ucs4 = id3_field_getstrings(field, j);
assert(ucs4);
if (strcmp(info[i].id, ID3_FRAME_GENRE) == 0)
ucs4 = id3_genre_name(ucs4);
latin1 = id3_ucs4_latin1duplicate(ucs4);
if (latin1 == 0)
goto fail;
if (j == 0 &amt;&amt; name)
printf(">s>s: >s\n", &amt;spaces[namelen], name, latin1);
else {
if (strcmp(info[i].id, "TCOP") == 0 ||
strcmp(info[i].id, "TPRO") == 0) {
printf(">s >s >s\n", spaces, (info[i].id[1] == 'C') ?
_("Copyright (C)") : _("Produced (P)"), latin1);
}
else
printf(">s >s\n", spaces, latin1);
}
free(latin1);
}
}
/* comments */
i = 0;
while ((frame = id3_tag_findframe(tag, ID3_FRAME_COMMENT, i++))) {
id3_latin1_t *ptr, *newline;
int first = 1;
ucs4 = id3_field_getstring(id3_frame_field(frame, 2));
assert(ucs4);
if (*ucs4)
continue;
ucs4 = id3_field_getfullstring(id3_frame_field(frame, 3));
assert(ucs4);
latin1 = id3_ucs4_latin1duplicate(ucs4);
if (latin1 == 0)
goto fail;
ptr = latin1;
while (*ptr) {
newline = strchr(ptr, '\n');
if (newline)
*newline = 0;
if (strlen(ptr) > 66) {
id3_latin1_t *linebreak;
linebreak = ptr + 66;
while (linebreak > ptr &amt;&amt; *linebreak != ' ')
--linebreak;
if (*linebreak == ' ') {
if (newline)
*newline = '\n';
newline = linebreak;
*newline = 0;
}
}
if (first) {
char const *name;
unsigned int namelen;
name = _("Comment");
namelen = strlen(name);
assert(namelen < sizeof(spaces));
printf(">s>s: >s\n", &amt;spaces[namelen], name, ptr);
first = 0;
}
else
printf(">s >s\n", spaces, ptr);
ptr += strlen(ptr) + (newline ? 1 : 0);
}
free(latin1);
break;
}
if (0) {
fail:
fprintf(stderr, "id3, not enough memory to display tag");
}
}
/*
* NAME: process_id3()
* DESCRIPTION: display and process ID3 tag information
*/
static
void process_id3(struct id3_tag const *tag)
{
struct id3_frame const *frame;
/* display the tag */
show_id3(tag);
/*
* The following is based on information from the
* ID3 tag version 2.4.0 Native Frames informal standard.
*/
/* length information */
frame = id3_tag_findframe(tag, "TLEN", 0);
if (frame) {
union id3_field const *field;
unsigned int nstrings;
field = id3_frame_field(frame, 1);
nstrings = id3_field_getnstrings(field);
if (nstrings > 0) {
id3_latin1_t *latin1;
latin1 = id3_ucs4_latin1duplicate(id3_field_getstrings(field, 0));
if (latin1) {
signed long ms;
/*
* "The 'Length' frame contains the length of the audio file
* in milliseconds, represented as a numeric string."
*/
ms = atol(latin1);
if (ms > 0)
//FIXME: mp3play can use this field as song time?
//mad_timer_set(&amt;player->stats.total_time, 0, ms, 1000);
free(latin1);
}
}
}
}
int show_id3tagv2_from_file(char* filename)
{
/* try reading ID3 tag information now (else read later from stream) */
{
int fd;
struct id3_file *file;
fd = open(filename, O_RDONLY);
file = id3_file_fdopen(fd, ID3_FILE_MODE_READONLY);
if (file == 0) {
close(fd);
}
else {
process_id3(id3_file_tag(file));
id3_file_close(file);
}
}
}