Add support for grouping tags. From FS#7362.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14242 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Dan Everton 2007-08-08 10:19:56 +00:00
parent ecae04a9f2
commit eecfe9f1cb
15 changed files with 109 additions and 21 deletions

View file

@ -866,6 +866,9 @@ static char *get_token_value(struct gui_wps *gwps,
case WPS_TOKEN_METADATA_ALBUM_ARTIST: case WPS_TOKEN_METADATA_ALBUM_ARTIST:
return id3->albumartist; return id3->albumartist;
case WPS_TOKEN_METADATA_GROUPING:
return id3->grouping;
case WPS_TOKEN_METADATA_GENRE: case WPS_TOKEN_METADATA_GENRE:
return id3->genre_string; return id3->genre_string;

View file

@ -191,6 +191,7 @@ enum wps_token_type {
WPS_TOKEN_METADATA_ARTIST, WPS_TOKEN_METADATA_ARTIST,
WPS_TOKEN_METADATA_COMPOSER, WPS_TOKEN_METADATA_COMPOSER,
WPS_TOKEN_METADATA_ALBUM_ARTIST, WPS_TOKEN_METADATA_ALBUM_ARTIST,
WPS_TOKEN_METADATA_GROUPING,
WPS_TOKEN_METADATA_ALBUM, WPS_TOKEN_METADATA_ALBUM,
WPS_TOKEN_METADATA_GENRE, WPS_TOKEN_METADATA_GENRE,
WPS_TOKEN_METADATA_DISC_NUMBER, WPS_TOKEN_METADATA_DISC_NUMBER,

View file

@ -289,6 +289,11 @@ static void dump_wps_tokens(struct wps_data *data)
next_str(next)); next_str(next));
break; break;
case WPS_TOKEN_METADATA_GROUPING:
snprintf(buf, sizeof(buf), "%strack grouping",
next_str(next));
break;
case WPS_TOKEN_METADATA_GENRE: case WPS_TOKEN_METADATA_GENRE:
snprintf(buf, sizeof(buf), "%strack genre", snprintf(buf, sizeof(buf), "%strack genre",
next_str(next)); next_str(next));

View file

@ -200,6 +200,7 @@ static const struct wps_tag all_tags[] = {
{ WPS_TOKEN_METADATA_COMPOSER, "ic", WPS_REFRESH_STATIC, NULL }, { WPS_TOKEN_METADATA_COMPOSER, "ic", WPS_REFRESH_STATIC, NULL },
{ 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_GROUPING, "iG", 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_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 },
@ -213,6 +214,7 @@ static const struct wps_tag all_tags[] = {
{ WPS_TOKEN_METADATA_COMPOSER, "Ic", WPS_REFRESH_DYNAMIC, NULL }, { WPS_TOKEN_METADATA_COMPOSER, "Ic", WPS_REFRESH_DYNAMIC, NULL },
{ 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_GROUPING, "IG", 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_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 },

View file

@ -11017,3 +11017,17 @@
*: "Als Aufnahmeverzeichnis festlegen" *: "Als Aufnahmeverzeichnis festlegen"
</voice> </voice>
</phrase> </phrase>
<phrase>
id: LANG_ID3_GROUPING
desc: in tag viewer
user:
<source>
*: "[Work]"
</source>
<dest>
*: "[Werk]"
</dest>
<voice>
*: ""
</voice>
</phrase>

View file

@ -11004,3 +11004,17 @@
*: "Demos" *: "Demos"
</voice> </voice>
</phrase> </phrase>
<phrase>
id: LANG_ID3_GROUPING
desc: in tag viewer
user:
<source>
*: "[Work]"
</source>
<dest>
*: "[Work]"
</dest>
<voice>
*: ""
</voice>
</phrase>

View file

@ -280,6 +280,18 @@ long parse_tag(const char* name, char* value, struct mp3entry* id3,
{ {
p = &(id3->albumartist); p = &(id3->albumartist);
} }
else if (strcasecmp(name, "grouping") == 0)
{
p = &(id3->grouping);
}
else if (strcasecmp(name, "content group") == 0)
{
p = &(id3->grouping);
}
else if (strcasecmp(name, "contentgroup") == 0)
{
p = &(id3->grouping);
}
else else
{ {
len = parse_replaygain(name, value, id3, buf, buf_remaining); len = parse_replaygain(name, value, id3, buf, buf_remaining);

View file

@ -38,6 +38,7 @@
#define MP4_alac MP4_ID('a', 'l', 'a', 'c') #define MP4_alac MP4_ID('a', 'l', 'a', 'c')
#define MP4_calb MP4_ID(0xa9, 'a', 'l', 'b') #define MP4_calb MP4_ID(0xa9, 'a', 'l', 'b')
#define MP4_cART MP4_ID(0xa9, 'A', 'R', 'T') #define MP4_cART MP4_ID(0xa9, 'A', 'R', 'T')
#define MP4_cgrp MP4_ID(0xa9, 'g', 'r', 'p')
#define MP4_cgen MP4_ID(0xa9, 'g', 'e', 'n') #define MP4_cgen MP4_ID(0xa9, 'g', 'e', 'n')
#define MP4_cnam MP4_ID(0xa9, 'n', 'a', 'm') #define MP4_cnam MP4_ID(0xa9, 'n', 'a', 'm')
#define MP4_cwrt MP4_ID(0xa9, 'w', 'r', 't') #define MP4_cwrt MP4_ID(0xa9, 'w', 'r', 't')
@ -378,6 +379,11 @@ static bool read_mp4_tags(int fd, struct mp3entry* id3,
&id3->albumartist); &id3->albumartist);
break; break;
case MP4_cgrp:
read_mp4_tag_string(fd, size, &buffer, &buffer_left,
&id3->grouping);
break;
case MP4_calb: case MP4_calb:
read_mp4_tag_string(fd, size, &buffer, &buffer_left, read_mp4_tag_string(fd, size, &buffer, &buffer_left,
&id3->album); &id3->album);

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_GROUPING,
LANG_ID3_DISCNUM, LANG_ID3_DISCNUM,
LANG_ID3_TRACKNUM, LANG_ID3_TRACKNUM,
LANG_ID3_COMMENT, LANG_ID3_COMMENT,
@ -1193,7 +1194,10 @@ 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_DISCNUM*/ case 4:/*LANG_ID3_ALBUMARTIST*/
info=id3->grouping;
break;
case 5:/*LANG_ID3_DISCNUM*/
if (id3->disc_string) if (id3->disc_string)
info = id3->disc_string; info = id3->disc_string;
else if (id3->discnum) else if (id3->discnum)
@ -1202,7 +1206,7 @@ static char * id3_get_info(int selected_item, void* data, char *buffer)
info = buffer; info = buffer;
} }
break; break;
case 5:/*LANG_ID3_TRACKNUM*/ case 6:/*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)
@ -1211,13 +1215,13 @@ static char * id3_get_info(int selected_item, void* data, char *buffer)
info = buffer; info = buffer;
} }
break; break;
case 6:/*LANG_ID3_COMMENT*/ case 7:/*LANG_ID3_COMMENT*/
info=id3->comment; info=id3->comment;
break; break;
case 7:/*LANG_ID3_GENRE*/ case 8:/*LANG_ID3_GENRE*/
info = id3->genre_string; info = id3->genre_string;
break; break;
case 8:/*LANG_ID3_YEAR*/ case 9:/*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)
@ -1226,34 +1230,34 @@ static char * id3_get_info(int selected_item, void* data, char *buffer)
info = buffer; info = buffer;
} }
break; break;
case 9:/*LANG_ID3_LENGTH*/ case 10:/*LANG_ID3_LENGTH*/
format_time(buffer, MAX_PATH, id3->length); format_time(buffer, MAX_PATH, id3->length);
info=buffer; info=buffer;
break; break;
case 10:/*LANG_ID3_PLAYLIST*/ case 11:/*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 11:/*LANG_ID3_BITRATE*/ case 12:/*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 12:/*LANG_ID3_FREQUENCY*/ case 13:/*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 13:/*LANG_ID3_TRACK_GAIN*/ case 14:/*LANG_ID3_TRACK_GAIN*/
info=id3->track_gain_string; info=id3->track_gain_string;
break; break;
case 14:/*LANG_ID3_ALBUM_GAIN*/ case 15:/*LANG_ID3_ALBUM_GAIN*/
info=id3->album_gain_string; info=id3->album_gain_string;
break; break;
case 15:/*LANG_ID3_PATH*/ case 16:/*LANG_ID3_PATH*/
#else #else
case 13:/*LANG_ID3_PATH*/ case 17:/*LANG_ID3_PATH*/
#endif #endif
info=id3->path; info=id3->path;
break; break;

View file

@ -108,11 +108,11 @@ static long tempbuf_pos;
/* Tags we want to get sorted (loaded to the tempbuf). */ /* Tags we want to get sorted (loaded to the tempbuf). */
static const int sorted_tags[] = { tag_artist, tag_album, tag_genre, static const int sorted_tags[] = { tag_artist, tag_album, tag_genre,
tag_composer, tag_comment, tag_albumartist, tag_title }; tag_composer, tag_comment, tag_albumartist, tag_grouping, tag_title };
/* Uniqued tags (we can use these tags with filters and conditional clauses). */ /* Uniqued tags (we can use these tags with filters and conditional clauses). */
static const int unique_tags[] = { tag_artist, tag_album, tag_genre, static const int unique_tags[] = { tag_artist, tag_album, tag_genre,
tag_composer, tag_comment, tag_albumartist }; tag_composer, tag_comment, tag_albumartist, tag_grouping };
/* 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_discnumber, tag_tracknumber, tag_length, static const int numeric_tags[] = { tag_year, tag_discnumber, tag_tracknumber, tag_length,
@ -123,7 +123,7 @@ static const int numeric_tags[] = { tag_year, tag_discnumber, tag_tracknumber, t
/* 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", "discnumber", "tracknumber", "filename", "composer", "comment", "albumartist", "grouping", "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 = "lllllllllllllllllll"; /* (1 + TAG_COUNT) * l */ static const char *index_entry_ec = "llllllllllllllllllll"; /* (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";
@ -1549,6 +1549,7 @@ bool tagcache_fill_tags(struct mp3entry *id3, const char *filename)
id3->composer = get_tag_string(entry, tag_composer); id3->composer = get_tag_string(entry, tag_composer);
id3->comment = get_tag_string(entry, tag_comment); id3->comment = get_tag_string(entry, tag_comment);
id3->albumartist = get_tag_string(entry, tag_albumartist); id3->albumartist = get_tag_string(entry, tag_albumartist);
id3->grouping = get_tag_string(entry, tag_grouping);
id3->playcount = get_tag_numeric(entry, tag_playcount); id3->playcount = get_tag_numeric(entry, tag_playcount);
id3->rating = get_tag_numeric(entry, tag_rating); id3->rating = get_tag_numeric(entry, tag_rating);
@ -1615,6 +1616,7 @@ static void add_tagcache(char *path)
int offset = 0; int offset = 0;
int path_length = strlen(path); int path_length = strlen(path);
bool has_albumartist; bool has_albumartist;
bool has_grouping;
if (cachefd < 0) if (cachefd < 0)
return ; return ;
@ -1708,6 +1710,8 @@ static void add_tagcache(char *path)
/* String tags. */ /* String tags. */
has_albumartist = track.id3.albumartist != NULL has_albumartist = track.id3.albumartist != NULL
&& strlen(track.id3.albumartist) > 0; && strlen(track.id3.albumartist) > 0;
has_grouping = track.id3.grouping != NULL
&& strlen(track.id3.grouping) > 0;
ADD_TAG(entry, tag_filename, &path); ADD_TAG(entry, tag_filename, &path);
ADD_TAG(entry, tag_title, &track.id3.title); ADD_TAG(entry, tag_title, &track.id3.title);
@ -1724,6 +1728,14 @@ static void add_tagcache(char *path)
{ {
ADD_TAG(entry, tag_albumartist, &track.id3.artist); ADD_TAG(entry, tag_albumartist, &track.id3.artist);
} }
if (has_grouping)
{
ADD_TAG(entry, tag_grouping, &track.id3.grouping);
}
else
{
ADD_TAG(entry, tag_grouping, &track.id3.title);
}
entry.data_length = offset; entry.data_length = offset;
/* Write the header */ /* Write the header */
@ -1745,6 +1757,14 @@ static void add_tagcache(char *path)
{ {
write_item(track.id3.artist); write_item(track.id3.artist);
} }
if (has_grouping)
{
write_item(track.id3.grouping);
}
else
{
write_item(track.id3.title);
}
total_entry_count++; total_entry_count++;
} }

View file

@ -23,7 +23,7 @@
#include "id3.h" #include "id3.h"
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_grouping, tag_year,
tag_discnumber, 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 */
@ -31,7 +31,7 @@ enum tag_type { tag_artist = 0, tag_album, tag_genre, tag_title,
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 18 #define TAG_COUNT 19
/* 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 0x5443480A #define TAGCACHE_MAGIC 0x5443480b
/* 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

@ -200,6 +200,7 @@ static int get_tag(int *tag)
MATCH(tag, buf, "comment", tag_comment); MATCH(tag, buf, "comment", tag_comment);
MATCH(tag, buf, "albumartist", tag_albumartist); MATCH(tag, buf, "albumartist", tag_albumartist);
MATCH(tag, buf, "ensemble", tag_albumartist); MATCH(tag, buf, "ensemble", tag_albumartist);
MATCH(tag, buf, "grouping", tag_grouping);
MATCH(tag, buf, "genre", tag_genre); MATCH(tag, buf, "genre", tag_genre);
MATCH(tag, buf, "length", tag_length); MATCH(tag, buf, "length", tag_length);
MATCH(tag, buf, "Lm", tag_virt_length_min); MATCH(tag, buf, "Lm", tag_virt_length_min);

View file

@ -311,6 +311,7 @@ Tobias Schladt
John Zhou John Zhou
Charles Voelger Charles Voelger
Gerritt Gonzales Gerritt Gonzales
Dieter Pellkofer
The libmad team The libmad team
The wavpack team The wavpack team
The ffmpeg team The ffmpeg team

View file

@ -153,6 +153,7 @@ struct mp3entry {
char* composer; char* composer;
char* comment; char* comment;
char* albumartist; char* albumartist;
char* grouping;
int discnum; int discnum;
int tracknum; int tracknum;
int version; int version;

View file

@ -461,6 +461,8 @@ static const struct tag_resolver taglist[] = {
{ "TCOM", 4, offsetof(struct mp3entry, composer), NULL, false }, { "TCOM", 4, offsetof(struct mp3entry, composer), NULL, false },
{ "TPE2", 4, offsetof(struct mp3entry, albumartist), NULL, false }, { "TPE2", 4, offsetof(struct mp3entry, albumartist), NULL, false },
{ "TP2", 3, offsetof(struct mp3entry, albumartist), NULL, false }, { "TP2", 3, offsetof(struct mp3entry, albumartist), NULL, false },
{ "TIT1", 4, offsetof(struct mp3entry, grouping), NULL, false },
{ "TT1", 3, offsetof(struct mp3entry, grouping), NULL, false },
{ "COMM", 4, offsetof(struct mp3entry, comment), NULL, false }, { "COMM", 4, offsetof(struct mp3entry, comment), NULL, false },
{ "TCON", 4, offsetof(struct mp3entry, genre_string), &parsegenre, false }, { "TCON", 4, offsetof(struct mp3entry, genre_string), &parsegenre, false },
{ "TCO", 3, offsetof(struct mp3entry, genre_string), &parsegenre, false }, { "TCO", 3, offsetof(struct mp3entry, genre_string), &parsegenre, false },
@ -1192,6 +1194,8 @@ void adjust_mp3entry(struct mp3entry *entry, void *dest, void *orig)
entry->comment += offset; entry->comment += offset;
if (entry->albumartist) if (entry->albumartist)
entry->albumartist += offset; entry->albumartist += offset;
if (entry->grouping)
entry->grouping += offset;
#if CONFIG_CODEC == SWCODEC #if CONFIG_CODEC == SWCODEC
if (entry->track_gain_string) if (entry->track_gain_string)
entry->track_gain_string += offset; entry->track_gain_string += offset;