Index: apps/screens.c
===================================================================
--- apps/screens.c (revision 13721)
+++ apps/screens.c (working copy)
@@ -1131,6 +1131,7 @@
LANG_ID3_ARTIST,
LANG_ID3_ALBUM,
LANG_ID3_ALBUMARTIST,
+ LANG_ID3_GROUPING,
LANG_ID3_TRACKNUM,
LANG_ID3_COMMENT,
LANG_ID3_GENRE,
@@ -1172,7 +1173,10 @@
case 3:/*LANG_ID3_ALBUMARTIST*/
info=id3->albumartist;
break;
- case 4:/*LANG_ID3_TRACKNUM*/
+ case 4:/*LANG_ID3_GROUPING*/
+ info=id3->grouping;
+ break;
+ case 5:/*LANG_ID3_TRACKNUM*/
if (id3->track_string)
info = id3->track_string;
else if (id3->tracknum)
@@ -1181,13 +1185,13 @@
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)
@@ -1196,34 +1200,34 @@
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_FRECUENCY*/
+ case 12:/*LANG_ID3_FRECUENCY*/
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;
Index: apps/metadata/mp4.c
===================================================================
--- apps/metadata/mp4.c (revision 13721)
+++ apps/metadata/mp4.c (working copy)
@@ -37,6 +37,7 @@
#define MP4_alac MP4_ID('a', 'l', 'a', 'c')
#define MP4_calb MP4_ID(0xa9, 'a', 'l', 'b')
#define MP4_cART MP4_ID(0xa9, 'A', 'R', 'T')
+#define MP4_cgrp MP4_ID(0xa9, 'g', 'r', 'p')
#define MP4_cnam MP4_ID(0xa9, 'n', 'a', 'm')
#define MP4_cwrt MP4_ID(0xa9, 'w', 'r', 't')
#define MP4_esds MP4_ID('e', 's', 'd', 's')
@@ -378,6 +379,11 @@
&id3->album);
break;
+ case MP4_cgrp:
+ read_mp4_tag_string(fd, size, &buffer, &buffer_left,
+ &id3->grouping);
+ break;
+
case MP4_cwrt:
read_mp4_tag_string(fd, size, &buffer, &buffer_left,
&id3->composer);
Index: apps/metadata/metadata_common.c
===================================================================
--- apps/metadata/metadata_common.c (revision 13721)
+++ apps/metadata/metadata_common.c (working copy)
@@ -242,6 +242,18 @@
{
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
{
len = parse_replaygain(name, value, id3, buf, buf_remaining);
Index: apps/lang/deutsch.lang
===================================================================
--- apps/lang/deutsch.lang (revision 13721)
+++ apps/lang/deutsch.lang (working copy)
@@ -10643,3 +10643,17 @@
*: "US/Kanada"
+
+ id: LANG_ID3_GROUPING
+ desc: in tag viewer
+ user:
+
+ *: "[Work]"
+
+
+ *: "[Werk]"
+
+
+ *: ""
+
+
Index: apps/lang/english.lang
===================================================================
--- apps/lang/english.lang (revision 13721)
+++ apps/lang/english.lang (working copy)
@@ -11006,3 +11006,17 @@
*: "Use File .talk Clips"
+
+ id: LANG_ID3_GROUPING
+ desc: in tag viewer
+ user:
+
+ *: "[Work]"
+
+
+ *: "[Work]"
+
+
+ *: ""
+
+
Index: apps/gui/gwps-common.c
===================================================================
--- apps/gui/gwps-common.c (revision 13721)
+++ apps/gui/gwps-common.c (working copy)
@@ -859,6 +859,9 @@
case WPS_TOKEN_METADATA_ALBUM_ARTIST:
return id3->albumartist;
+ case WPS_TOKEN_METADATA_GROUPING:
+ return id3->grouping;
+
case WPS_TOKEN_METADATA_GENRE:
return id3->genre_string;
Index: apps/gui/wps_debug.c
===================================================================
--- apps/gui/wps_debug.c (revision 13721)
+++ apps/gui/wps_debug.c (working copy)
@@ -289,6 +289,11 @@
next_str(next));
break;
+ case WPS_TOKEN_METADATA_GROUPING:
+ snprintf(buf, sizeof(buf), "%strack grouping",
+ next_str(next));
+ break;
+
case WPS_TOKEN_METADATA_GENRE:
snprintf(buf, sizeof(buf), "%strack genre",
next_str(next));
Index: apps/gui/gwps.h
===================================================================
--- apps/gui/gwps.h (revision 13721)
+++ apps/gui/gwps.h (working copy)
@@ -191,6 +191,7 @@
WPS_TOKEN_METADATA_ARTIST,
WPS_TOKEN_METADATA_COMPOSER,
WPS_TOKEN_METADATA_ALBUM_ARTIST,
+ WPS_TOKEN_METADATA_GROUPING,
WPS_TOKEN_METADATA_ALBUM,
WPS_TOKEN_METADATA_GENRE,
WPS_TOKEN_METADATA_TRACK_NUMBER,
Index: apps/gui/wps_parser.c
===================================================================
--- apps/gui/wps_parser.c (revision 13721)
+++ apps/gui/wps_parser.c (working copy)
@@ -200,6 +200,7 @@
{ WPS_TOKEN_METADATA_COMPOSER, "ic", 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_GROUPING, "iG", WPS_REFRESH_STATIC, NULL },
{ WPS_TOKEN_METADATA_GENRE, "ig", WPS_REFRESH_STATIC, NULL },
{ WPS_TOKEN_METADATA_TRACK_NUMBER, "in", WPS_REFRESH_STATIC, NULL },
{ WPS_TOKEN_METADATA_TRACK_TITLE, "it", WPS_REFRESH_STATIC, NULL },
@@ -212,6 +213,7 @@
{ WPS_TOKEN_METADATA_COMPOSER, "Ic", 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_GROUPING, "IG", WPS_REFRESH_DYNAMIC, NULL },
{ WPS_TOKEN_METADATA_GENRE, "Ig", WPS_REFRESH_DYNAMIC, NULL },
{ WPS_TOKEN_METADATA_TRACK_NUMBER, "In", WPS_REFRESH_DYNAMIC, NULL },
{ WPS_TOKEN_METADATA_TRACK_TITLE, "It", WPS_REFRESH_DYNAMIC, NULL },
Index: apps/tagcache.c
===================================================================
--- apps/tagcache.c (revision 13721)
+++ apps/tagcache.c (working copy)
@@ -108,11 +108,11 @@
/* Tags we want to get sorted (loaded to the tempbuf). */
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). */
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). */
static const int numeric_tags[] = { tag_year, tag_tracknumber, tag_length,
@@ -123,7 +123,7 @@
/* 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", "grouping", "year", "tracknumber",
"bitrate", "length", "playcount", "rating", "playtime", "lastplayed", "commitid" };
/* Status information of the tagcache. */
@@ -170,7 +170,7 @@
/* 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";
@@ -1531,6 +1531,7 @@
id3->composer = get_tag_string(entry, tag_composer);
id3->comment = get_tag_string(entry, tag_comment);
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->rating = get_tag_numeric(entry, tag_rating);
@@ -1596,6 +1597,7 @@
int offset = 0;
int path_length = strlen(path);
bool has_albumartist;
+ bool has_grouping;
if (cachefd < 0)
return ;
@@ -1688,6 +1690,8 @@
/* String tags. */
has_albumartist = track.id3.albumartist != NULL
&& 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_title, &track.id3.title);
@@ -1704,6 +1708,14 @@
{
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;
/* Write the header */
@@ -1725,6 +1737,14 @@
{
write_item(track.id3.artist);
}
+ if (has_grouping)
+ {
+ write_item(track.id3.grouping);
+ }
+ else
+ {
+ write_item(track.id3.title);
+ }
total_entry_count++;
}
Index: apps/tagcache.h
===================================================================
--- apps/tagcache.h (revision 13721)
+++ apps/tagcache.h (working copy)
@@ -23,7 +23,7 @@
#include "id3.h"
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_tracknumber, tag_bitrate, tag_length, tag_playcount, tag_rating,
tag_playtime, tag_lastplayed, tag_commitid,
/* Virtual tags */
@@ -31,7 +31,7 @@
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 @@
#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
Index: apps/tagtree.c
===================================================================
--- apps/tagtree.c (revision 13721)
+++ apps/tagtree.c (working copy)
@@ -200,6 +200,8 @@
MATCH(tag, buf, "comment", tag_comment);
MATCH(tag, buf, "albumartist", tag_albumartist);
MATCH(tag, buf, "ensemble", tag_albumartist);
+ MATCH(tag, buf, "grouping", tag_grouping);
+ MATCH(tag, buf, "contentgroup", tag_grouping);
MATCH(tag, buf, "genre", tag_genre);
MATCH(tag, buf, "length", tag_length);
MATCH(tag, buf, "Lm", tag_virt_length_min);
Index: firmware/export/id3.h
===================================================================
--- firmware/export/id3.h (revision 13721)
+++ firmware/export/id3.h (working copy)
@@ -149,6 +149,7 @@
char* composer;
char* comment;
char* albumartist;
+ char* grouping;
int tracknum;
int version;
int layer;
Index: firmware/id3.c
===================================================================
--- firmware/id3.c (revision 13721)
+++ firmware/id3.c (working copy)
@@ -449,7 +449,9 @@
{ "TYE", 3, offsetof(struct mp3entry, year_string), &parseyearnum, false },
{ "TCOM", 4, offsetof(struct mp3entry, composer), 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 },
{ "TCON", 4, offsetof(struct mp3entry, genre_string), &parsegenre, false },
{ "TCO", 3, offsetof(struct mp3entry, genre_string), &parsegenre, false },
@@ -1178,6 +1180,8 @@
entry->comment += offset;
if (entry->albumartist)
entry->albumartist += offset;
+ if (entry->grouping)
+ entry->grouping += offset;
#if CONFIG_CODEC == SWCODEC
if (entry->track_gain_string)
entry->track_gain_string += offset;