Add support for parsing the disc number tag from metadata and use of it in the database. Patch originally from FS#4961 with some minor tweaks by me.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14154 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Dan Everton 2007-08-03 10:00:42 +00:00
parent 1fbf847eed
commit f4a61f0c4a
15 changed files with 92 additions and 19 deletions

View file

@ -876,6 +876,15 @@ static char *get_token_value(struct gui_wps *gwps,
case WPS_TOKEN_METADATA_GENRE:
return id3->genre_string;
case WPS_TOKEN_METADATA_DISC_NUMBER:
if (id3->disc_string)
return id3->disc_string;
if (id3->discnum) {
snprintf(buf, buf_size, "%d", id3->discnum);
return buf;
}
return NULL;
case WPS_TOKEN_METADATA_TRACK_NUMBER:
if (id3->track_string)
return id3->track_string;

View file

@ -193,6 +193,7 @@ enum wps_token_type {
WPS_TOKEN_METADATA_ALBUM_ARTIST,
WPS_TOKEN_METADATA_ALBUM,
WPS_TOKEN_METADATA_GENRE,
WPS_TOKEN_METADATA_DISC_NUMBER,
WPS_TOKEN_METADATA_TRACK_NUMBER,
WPS_TOKEN_METADATA_TRACK_TITLE,
WPS_TOKEN_METADATA_VERSION,

View file

@ -294,6 +294,10 @@ static void dump_wps_tokens(struct wps_data *data)
next_str(next));
break;
case WPS_TOKEN_METADATA_DISC_NUMBER:
snprintf(buf, sizeof(buf), "%strack disc", next_str(next));
break;
case WPS_TOKEN_METADATA_TRACK_NUMBER:
snprintf(buf, sizeof(buf), "%strack number",
next_str(next));

View file

@ -201,6 +201,7 @@ static const struct wps_tag all_tags[] = {
{ WPS_TOKEN_METADATA_ALBUM, "id", WPS_REFRESH_STATIC, NULL },
{ WPS_TOKEN_METADATA_ALBUM_ARTIST, "iA", WPS_REFRESH_STATIC, NULL },
{ WPS_TOKEN_METADATA_GENRE, "ig", WPS_REFRESH_STATIC, NULL },
{ WPS_TOKEN_METADATA_DISC_NUMBER, "ik", WPS_REFRESH_STATIC, NULL },
{ WPS_TOKEN_METADATA_TRACK_NUMBER, "in", WPS_REFRESH_STATIC, NULL },
{ WPS_TOKEN_METADATA_TRACK_TITLE, "it", WPS_REFRESH_STATIC, NULL },
{ WPS_TOKEN_METADATA_VERSION, "iv", WPS_REFRESH_STATIC, NULL },
@ -213,6 +214,7 @@ static const struct wps_tag all_tags[] = {
{ WPS_TOKEN_METADATA_ALBUM, "Id", WPS_REFRESH_DYNAMIC, NULL },
{ WPS_TOKEN_METADATA_ALBUM_ARTIST, "IA", WPS_REFRESH_DYNAMIC, NULL },
{ WPS_TOKEN_METADATA_GENRE, "Ig", WPS_REFRESH_DYNAMIC, NULL },
{ WPS_TOKEN_METADATA_DISC_NUMBER, "Ik", WPS_REFRESH_DYNAMIC, NULL },
{ WPS_TOKEN_METADATA_TRACK_NUMBER, "In", WPS_REFRESH_DYNAMIC, NULL },
{ WPS_TOKEN_METADATA_TRACK_TITLE, "It", WPS_REFRESH_DYNAMIC, NULL },
{ WPS_TOKEN_METADATA_VERSION, "Iv", WPS_REFRESH_DYNAMIC, NULL },

View file

@ -11054,3 +11054,17 @@
*: "Can't write to recording directory"
</voice>
</phrase>
<phrase>
id: LANG_ID3_DISCNUM
desc: in tag viewer
user:
<source>
*: "[Discnum]"
</source>
<dest>
*: "[Discnum]"
</dest>
<voice>
*: ""
</voice>
</phrase>

View file

@ -224,6 +224,11 @@ long parse_tag(const char* name, char* value, struct mp3entry* id3,
id3->tracknum = atoi(value);
p = &(id3->track_string);
}
else if (strcasecmp(name, "discnumber") == 0 || strcasecmp(name, "disc") == 0)
{
id3->discnum = atoi(value);
p = &(id3->disc_string);
}
else if (((strcasecmp(name, "year") == 0) && (type == TAGTYPE_APE))
|| ((strcasecmp(name, "date") == 0) && (type == TAGTYPE_VORBIS)))
{

View file

@ -43,6 +43,7 @@
#define MP4_cwrt MP4_ID(0xa9, 'w', 'r', 't')
#define MP4_ccmt MP4_ID(0xa9, 'c', 'm', 't')
#define MP4_cday MP4_ID(0xa9, 'd', 'a', 'y')
#define MP4_disk MP4_ID('d', 'i', 's', 'k')
#define MP4_esds MP4_ID('e', 's', 'd', 's')
#define MP4_ftyp MP4_ID('f', 't', 'y', 'p')
#define MP4_gnre MP4_ID('g', 'n', 'r', 'e')
@ -422,6 +423,15 @@ static bool read_mp4_tags(int fd, struct mp3entry* id3,
&id3->genre_string);
break;
case MP4_disk:
{
unsigned short n[2];
read_mp4_tag(fd, size, (char*) &n, sizeof(n));
id3->disknum = betoh16(n[1]);
}
break;
case MP4_trkn:
{
unsigned short n[2];

View file

@ -1151,6 +1151,7 @@ static const int id3_headers[]=
LANG_ID3_ARTIST,
LANG_ID3_ALBUM,
LANG_ID3_ALBUMARTIST,
LANG_ID3_DISCNUM,
LANG_ID3_TRACKNUM,
LANG_ID3_COMMENT,
LANG_ID3_GENRE,
@ -1192,7 +1193,16 @@ static char * id3_get_info(int selected_item, void* data, char *buffer)
case 3:/*LANG_ID3_ALBUMARTIST*/
info=id3->albumartist;
break;
case 4:/*LANG_ID3_TRACKNUM*/
case 4:/*LANG_ID3_DISCNUM*/
if (id3->disc_string)
info = id3->disc_string;
else if (id3->discnum)
{
snprintf(buffer, MAX_PATH, "%d", id3->discnum);
info = buffer;
}
break;
case 5:/*LANG_ID3_TRACKNUM*/
if (id3->track_string)
info = id3->track_string;
else if (id3->tracknum)
@ -1201,13 +1211,13 @@ static char * id3_get_info(int selected_item, void* data, char *buffer)
info = buffer;
}
break;
case 5:/*LANG_ID3_COMMENT*/
case 6:/*LANG_ID3_COMMENT*/
info=id3->comment;
break;
case 6:/*LANG_ID3_GENRE*/
case 7:/*LANG_ID3_GENRE*/
info = id3->genre_string;
break;
case 7:/*LANG_ID3_YEAR*/
case 8:/*LANG_ID3_YEAR*/
if (id3->year_string)
info = id3->year_string;
else if (id3->year)
@ -1216,34 +1226,34 @@ static char * id3_get_info(int selected_item, void* data, char *buffer)
info = buffer;
}
break;
case 8:/*LANG_ID3_LENGTH*/
case 9:/*LANG_ID3_LENGTH*/
format_time(buffer, MAX_PATH, id3->length);
info=buffer;
break;
case 9:/*LANG_ID3_PLAYLIST*/
case 10:/*LANG_ID3_PLAYLIST*/
snprintf(buffer, MAX_PATH, "%d/%d", playlist_get_display_index(),
playlist_amount());
info=buffer;
break;
case 10:/*LANG_ID3_BITRATE*/
case 11:/*LANG_ID3_BITRATE*/
snprintf(buffer, MAX_PATH, "%d kbps%s", id3->bitrate,
id3->vbr ? str(LANG_ID3_VBR) : (const unsigned char*) "");
info=buffer;
break;
case 11:/*LANG_ID3_FREQUENCY*/
case 12:/*LANG_ID3_FREQUENCY*/
snprintf(buffer, MAX_PATH, "%ld Hz", id3->frequency);
info=buffer;
break;
#if CONFIG_CODEC == SWCODEC
case 12:/*LANG_ID3_TRACK_GAIN*/
case 13:/*LANG_ID3_TRACK_GAIN*/
info=id3->track_gain_string;
break;
case 13:/*LANG_ID3_ALBUM_GAIN*/
case 14:/*LANG_ID3_ALBUM_GAIN*/
info=id3->album_gain_string;
break;
case 14:/*LANG_ID3_PATH*/
case 15:/*LANG_ID3_PATH*/
#else
case 12:/*LANG_ID3_PATH*/
case 13:/*LANG_ID3_PATH*/
#endif
info=id3->path;
break;

View file

@ -115,7 +115,7 @@ static const int unique_tags[] = { tag_artist, tag_album, tag_genre,
tag_composer, tag_comment, tag_albumartist };
/* Numeric tags (we can use these tags with conditional clauses). */
static const int numeric_tags[] = { tag_year, tag_tracknumber, tag_length,
static const int numeric_tags[] = { tag_year, tag_discnumber, tag_tracknumber, tag_length,
tag_bitrate, tag_playcount, tag_rating, tag_playtime, tag_lastplayed, tag_commitid,
tag_virt_length_min, tag_virt_length_sec,
tag_virt_playtime_min, tag_virt_playtime_sec,
@ -123,7 +123,7 @@ static const int numeric_tags[] = { tag_year, tag_tracknumber, tag_length,
/* String presentation of the tags defined in tagcache.h. Must be in correct order! */
static const char *tags_str[] = { "artist", "album", "genre", "title",
"filename", "composer", "comment", "albumartist", "year", "tracknumber",
"filename", "composer", "comment", "albumartist", "year", "discnumber", "tracknumber",
"bitrate", "length", "playcount", "rating", "playtime", "lastplayed", "commitid" };
/* Status information of the tagcache. */
@ -188,7 +188,7 @@ struct master_header {
/* For the endianess correction */
static const char *tagfile_entry_ec = "ss";
static const char *index_entry_ec = "llllllllllllllllll"; /* (1 + TAG_COUNT) * l */
static const char *index_entry_ec = "lllllllllllllllllll"; /* (1 + TAG_COUNT) * l */
static const char *tagcache_header_ec = "lll";
static const char *master_header_ec = "llllll";
@ -1556,6 +1556,7 @@ bool tagcache_fill_tags(struct mp3entry *id3, const char *filename)
id3->score = get_tag_numeric(entry, tag_virt_autoscore) / 10;
id3->year = get_tag_numeric(entry, tag_year);
id3->discnum = get_tag_numeric(entry, tag_discnumber);
id3->tracknum = get_tag_numeric(entry, tag_tracknumber);
id3->bitrate = get_tag_numeric(entry, tag_bitrate);
if (id3->bitrate == 0)
@ -1699,6 +1700,7 @@ static void add_tagcache(char *path)
/* Numeric tags */
entry.tag_offset[tag_year] = track.id3.year;
entry.tag_offset[tag_discnumber] = track.id3.discnum;
entry.tag_offset[tag_tracknumber] = track.id3.tracknum;
entry.tag_offset[tag_length] = track.id3.length;
entry.tag_offset[tag_bitrate] = track.id3.bitrate;

View file

@ -24,14 +24,14 @@
enum tag_type { tag_artist = 0, tag_album, tag_genre, tag_title,
tag_filename, tag_composer, tag_comment, tag_albumartist, tag_year,
tag_tracknumber, tag_bitrate, tag_length, tag_playcount, tag_rating,
tag_discnumber, tag_tracknumber, tag_bitrate, tag_length, tag_playcount, tag_rating,
tag_playtime, tag_lastplayed, tag_commitid,
/* Virtual tags */
tag_virt_length_min, tag_virt_length_sec,
tag_virt_playtime_min, tag_virt_playtime_sec,
tag_virt_entryage, tag_virt_autoscore };
#define TAG_COUNT 17
#define TAG_COUNT 18
/* Maximum length of a single tag. */
#define TAG_MAXLEN (MAX_PATH*2)
@ -43,7 +43,7 @@ enum tag_type { tag_artist = 0, tag_album, tag_genre, tag_title,
#define IDX_BUF_DEPTH 64
/* Tag Cache Header version 'TCHxx'. Increment when changing internal structures. */
#define TAGCACHE_MAGIC 0x54434809
#define TAGCACHE_MAGIC 0x5443480A
/* How much to allocate extra space for ramcache. */
#define TAGCACHE_RESERVE 32768

View file

@ -6,6 +6,7 @@
# get overwritten automatically.
# Basic format declarations
%format "fmt_title" "%d.%02d. %s" discnum tracknum title ? discnum > "0"
%format "fmt_title" "%02d. %s - %02d:%02d" tracknum title Lm Ls ? tracknum > "0"
%format "fmt_title" "%s - %02d:%02d" title Lm Ls
%format "fmt_mostplayed" "%2d|%3d %s (%s)" playcount autoscore title artist %sort = "inverse" %limit = "100"

View file

@ -209,6 +209,7 @@ static int get_tag(int *tag)
MATCH(tag, buf, "title", tag_title);
MATCH(tag, buf, "filename", tag_filename);
MATCH(tag, buf, "tracknum", tag_tracknumber);
MATCH(tag, buf, "discnum", tag_discnumber);
MATCH(tag, buf, "year", tag_year);
MATCH(tag, buf, "playcount", tag_playcount);
MATCH(tag, buf, "rating", tag_rating);

View file

@ -309,6 +309,7 @@ Johnathon Mihalop
Rene Allkivi
Tobias Schladt
John Zhou
Charles Voelger
The libmad team
The wavpack team
The ffmpeg team

View file

@ -147,11 +147,13 @@ struct mp3entry {
char* artist;
char* album;
char* genre_string;
char* disc_string;
char* track_string;
char* year_string;
char* composer;
char* comment;
char* albumartist;
int discnum;
int tracknum;
int version;
int layer;

View file

@ -351,6 +351,13 @@ static int parsetracknum( struct mp3entry* entry, char* tag, int bufferpos )
return bufferpos;
}
/* parse numeric value from string */
static int parsediscnum( struct mp3entry* entry, char* tag, int bufferpos )
{
entry->discnum = atoi( tag );
return bufferpos;
}
/* parse numeric value from string */
static int parseyearnum( struct mp3entry* entry, char* tag, int bufferpos )
{
@ -446,6 +453,7 @@ static const struct tag_resolver taglist[] = {
{ "TALB", 4, offsetof(struct mp3entry, album), NULL, false },
{ "TAL", 3, offsetof(struct mp3entry, album), NULL, false },
{ "TRK", 3, offsetof(struct mp3entry, track_string), &parsetracknum, false },
{ "TPOS", 4, offsetof(struct mp3entry, disc_string), &parsediscnum, false },
{ "TRCK", 4, offsetof(struct mp3entry, track_string), &parsetracknum, false },
{ "TDRC", 4, offsetof(struct mp3entry, year_string), &parseyearnum, false },
{ "TYER", 4, offsetof(struct mp3entry, year_string), &parseyearnum, false },
@ -693,7 +701,7 @@ static void setid3v2title(int fd, struct mp3entry *entry)
return;
}
entry->id3version = version;
entry->tracknum = entry->year = 0;
entry->tracknum = entry->year = entry->discnum = 0;
entry->title = entry->artist = entry->album = NULL; /* FIXME incomplete */
global_flags = header[5];
@ -1112,6 +1120,7 @@ bool get_mp3_metadata(int fd, struct mp3entry *entry, const char *filename, bool
entry->filesize = filesize(fd);
entry->id3v2len = getid3v2len(fd);
entry->tracknum = 0;
entry->discnum = 0;
if(v1first)
v1found = setid3v1title(fd, entry);
@ -1173,6 +1182,8 @@ void adjust_mp3entry(struct mp3entry *entry, void *dest, void *orig)
entry->genre_string += offset;
if (entry->track_string)
entry->track_string += offset;
if (entry->disc_string)
entry->disc_string += offset;
if (entry->year_string)
entry->year_string += offset;
if (entry->composer)