1
0
Fork 0
forked from len0rd/rockbox

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: case WPS_TOKEN_METADATA_GENRE:
return id3->genre_string; 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: case WPS_TOKEN_METADATA_TRACK_NUMBER:
if (id3->track_string) if (id3->track_string)
return 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_ARTIST,
WPS_TOKEN_METADATA_ALBUM, WPS_TOKEN_METADATA_ALBUM,
WPS_TOKEN_METADATA_GENRE, WPS_TOKEN_METADATA_GENRE,
WPS_TOKEN_METADATA_DISC_NUMBER,
WPS_TOKEN_METADATA_TRACK_NUMBER, WPS_TOKEN_METADATA_TRACK_NUMBER,
WPS_TOKEN_METADATA_TRACK_TITLE, WPS_TOKEN_METADATA_TRACK_TITLE,
WPS_TOKEN_METADATA_VERSION, WPS_TOKEN_METADATA_VERSION,

View file

@ -294,6 +294,10 @@ static void dump_wps_tokens(struct wps_data *data)
next_str(next)); next_str(next));
break; break;
case WPS_TOKEN_METADATA_DISC_NUMBER:
snprintf(buf, sizeof(buf), "%strack disc", next_str(next));
break;
case WPS_TOKEN_METADATA_TRACK_NUMBER: case WPS_TOKEN_METADATA_TRACK_NUMBER:
snprintf(buf, sizeof(buf), "%strack number", snprintf(buf, sizeof(buf), "%strack number",
next_str(next)); 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, "id", WPS_REFRESH_STATIC, NULL },
{ WPS_TOKEN_METADATA_ALBUM_ARTIST, "iA", 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_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_NUMBER, "in", WPS_REFRESH_STATIC, NULL },
{ WPS_TOKEN_METADATA_TRACK_TITLE, "it", WPS_REFRESH_STATIC, NULL }, { WPS_TOKEN_METADATA_TRACK_TITLE, "it", WPS_REFRESH_STATIC, NULL },
{ WPS_TOKEN_METADATA_VERSION, "iv", 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, "Id", WPS_REFRESH_DYNAMIC, NULL },
{ WPS_TOKEN_METADATA_ALBUM_ARTIST, "IA", 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_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_NUMBER, "In", WPS_REFRESH_DYNAMIC, NULL },
{ WPS_TOKEN_METADATA_TRACK_TITLE, "It", WPS_REFRESH_DYNAMIC, NULL }, { WPS_TOKEN_METADATA_TRACK_TITLE, "It", WPS_REFRESH_DYNAMIC, NULL },
{ WPS_TOKEN_METADATA_VERSION, "Iv", 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" *: "Can't write to recording directory"
</voice> </voice>
</phrase> </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); id3->tracknum = atoi(value);
p = &(id3->track_string); 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)) else if (((strcasecmp(name, "year") == 0) && (type == TAGTYPE_APE))
|| ((strcasecmp(name, "date") == 0) && (type == TAGTYPE_VORBIS))) || ((strcasecmp(name, "date") == 0) && (type == TAGTYPE_VORBIS)))
{ {

View file

@ -43,6 +43,7 @@
#define MP4_cwrt MP4_ID(0xa9, 'w', 'r', 't') #define MP4_cwrt MP4_ID(0xa9, 'w', 'r', 't')
#define MP4_ccmt MP4_ID(0xa9, 'c', 'm', 't') #define MP4_ccmt MP4_ID(0xa9, 'c', 'm', 't')
#define MP4_cday MP4_ID(0xa9, 'd', 'a', 'y') #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_esds MP4_ID('e', 's', 'd', 's')
#define MP4_ftyp MP4_ID('f', 't', 'y', 'p') #define MP4_ftyp MP4_ID('f', 't', 'y', 'p')
#define MP4_gnre MP4_ID('g', 'n', 'r', 'e') #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); &id3->genre_string);
break; 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: case MP4_trkn:
{ {
unsigned short n[2]; unsigned short n[2];

View file

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

View file

@ -115,7 +115,7 @@ static const int unique_tags[] = { tag_artist, tag_album, tag_genre,
tag_composer, tag_comment, tag_albumartist }; tag_composer, tag_comment, tag_albumartist };
/* Numeric tags (we can use these tags with conditional clauses). */ /* 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_bitrate, tag_playcount, tag_rating, tag_playtime, tag_lastplayed, tag_commitid,
tag_virt_length_min, tag_virt_length_sec, tag_virt_length_min, tag_virt_length_sec,
tag_virt_playtime_min, tag_virt_playtime_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! */ /* String presentation of the tags defined in tagcache.h. Must be in correct order! */
static const char *tags_str[] = { "artist", "album", "genre", "title", 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" }; "bitrate", "length", "playcount", "rating", "playtime", "lastplayed", "commitid" };
/* Status information of the tagcache. */ /* Status information of the tagcache. */
@ -188,7 +188,7 @@ struct master_header {
/* For the endianess correction */ /* For the endianess correction */
static const char *tagfile_entry_ec = "ss"; 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 *tagcache_header_ec = "lll";
static const char *master_header_ec = "llllll"; 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->score = get_tag_numeric(entry, tag_virt_autoscore) / 10;
id3->year = get_tag_numeric(entry, tag_year); 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->tracknum = get_tag_numeric(entry, tag_tracknumber);
id3->bitrate = get_tag_numeric(entry, tag_bitrate); id3->bitrate = get_tag_numeric(entry, tag_bitrate);
if (id3->bitrate == 0) if (id3->bitrate == 0)
@ -1699,6 +1700,7 @@ static void add_tagcache(char *path)
/* Numeric tags */ /* Numeric tags */
entry.tag_offset[tag_year] = track.id3.year; 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_tracknumber] = track.id3.tracknum;
entry.tag_offset[tag_length] = track.id3.length; entry.tag_offset[tag_length] = track.id3.length;
entry.tag_offset[tag_bitrate] = track.id3.bitrate; 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, enum tag_type { tag_artist = 0, tag_album, tag_genre, tag_title,
tag_filename, tag_composer, tag_comment, tag_albumartist, tag_year, 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, tag_playtime, tag_lastplayed, tag_commitid,
/* Virtual tags */ /* Virtual tags */
tag_virt_length_min, tag_virt_length_sec, tag_virt_length_min, tag_virt_length_sec,
tag_virt_playtime_min, tag_virt_playtime_sec, tag_virt_playtime_min, tag_virt_playtime_sec,
tag_virt_entryage, tag_virt_autoscore }; tag_virt_entryage, tag_virt_autoscore };
#define TAG_COUNT 17 #define TAG_COUNT 18
/* Maximum length of a single tag. */ /* Maximum length of a single tag. */
#define TAG_MAXLEN (MAX_PATH*2) #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 #define IDX_BUF_DEPTH 64
/* Tag Cache Header version 'TCHxx'. Increment when changing internal structures. */ /* 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. */ /* How much to allocate extra space for ramcache. */
#define TAGCACHE_RESERVE 32768 #define TAGCACHE_RESERVE 32768

View file

@ -6,6 +6,7 @@
# get overwritten automatically. # get overwritten automatically.
# Basic format declarations # 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" "%02d. %s - %02d:%02d" tracknum title Lm Ls ? tracknum > "0"
%format "fmt_title" "%s - %02d:%02d" title Lm Ls %format "fmt_title" "%s - %02d:%02d" title Lm Ls
%format "fmt_mostplayed" "%2d|%3d %s (%s)" playcount autoscore title artist %sort = "inverse" %limit = "100" %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, "title", tag_title);
MATCH(tag, buf, "filename", tag_filename); MATCH(tag, buf, "filename", tag_filename);
MATCH(tag, buf, "tracknum", tag_tracknumber); MATCH(tag, buf, "tracknum", tag_tracknumber);
MATCH(tag, buf, "discnum", tag_discnumber);
MATCH(tag, buf, "year", tag_year); MATCH(tag, buf, "year", tag_year);
MATCH(tag, buf, "playcount", tag_playcount); MATCH(tag, buf, "playcount", tag_playcount);
MATCH(tag, buf, "rating", tag_rating); MATCH(tag, buf, "rating", tag_rating);

View file

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

View file

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

View file

@ -351,6 +351,13 @@ static int parsetracknum( struct mp3entry* entry, char* tag, int bufferpos )
return 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 */ /* parse numeric value from string */
static int parseyearnum( struct mp3entry* entry, char* tag, int bufferpos ) 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 }, { "TALB", 4, offsetof(struct mp3entry, album), NULL, false },
{ "TAL", 3, offsetof(struct mp3entry, album), NULL, false }, { "TAL", 3, offsetof(struct mp3entry, album), NULL, false },
{ "TRK", 3, offsetof(struct mp3entry, track_string), &parsetracknum, 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 }, { "TRCK", 4, offsetof(struct mp3entry, track_string), &parsetracknum, false },
{ "TDRC", 4, offsetof(struct mp3entry, year_string), &parseyearnum, false }, { "TDRC", 4, offsetof(struct mp3entry, year_string), &parseyearnum, false },
{ "TYER", 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; return;
} }
entry->id3version = version; entry->id3version = version;
entry->tracknum = entry->year = 0; entry->tracknum = entry->year = entry->discnum = 0;
entry->title = entry->artist = entry->album = NULL; /* FIXME incomplete */ entry->title = entry->artist = entry->album = NULL; /* FIXME incomplete */
global_flags = header[5]; 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->filesize = filesize(fd);
entry->id3v2len = getid3v2len(fd); entry->id3v2len = getid3v2len(fd);
entry->tracknum = 0; entry->tracknum = 0;
entry->discnum = 0;
if(v1first) if(v1first)
v1found = setid3v1title(fd, entry); v1found = setid3v1title(fd, entry);
@ -1173,6 +1182,8 @@ void adjust_mp3entry(struct mp3entry *entry, void *dest, void *orig)
entry->genre_string += offset; entry->genre_string += offset;
if (entry->track_string) if (entry->track_string)
entry->track_string += offset; entry->track_string += offset;
if (entry->disc_string)
entry->disc_string += offset;
if (entry->year_string) if (entry->year_string)
entry->year_string += offset; entry->year_string += offset;
if (entry->composer) if (entry->composer)